Python 在3D中拟合直线

Python 在3D中拟合直线,python,numpy,linear-algebra,curve-fitting,Python,Numpy,Linear Algebra,Curve Fitting,是否有任何算法可以从一组3D数据点返回直线方程?我可以从2D数据集中找到很多可以给出直线方程的数据源,但在3D中没有 谢谢。如果您的数据表现得相当好,那么找到组件距离的最小二乘和就足够了。然后你可以找到z独立于x,然后又独立于y的线性回归 举个例子: 如果您想最小化从直线(与直线正交)到3-空间中的点的实际正交距离(我不确定这是否称为线性回归)。然后,我将构建一个计算RSS的函数,并使用scipy.optimize最小化函数来解决它。如果您试图从其他两个值中预测一个值,那么您应该使用lstsq和

是否有任何算法可以从一组3D数据点返回直线方程?我可以从2D数据集中找到很多可以给出直线方程的数据源,但在3D中没有


谢谢。

如果您的数据表现得相当好,那么找到组件距离的最小二乘和就足够了。然后你可以找到z独立于x,然后又独立于y的线性回归

举个例子:


如果您想最小化从直线(与直线正交)到3-空间中的点的实际正交距离(我不确定这是否称为线性回归)。然后,我将构建一个计算RSS的函数,并使用scipy.optimize最小化函数来解决它。

如果您试图从其他两个值中预测一个值,那么您应该使用
lstsq
a
参数作为自变量(加上一列1来估计截距)和
b
作为因变量

另一方面,如果您只想得到数据的最佳拟合线,即如果将数据投影到该数据上,将使实际点与其投影之间的平方距离最小化的线,那么您需要的是第一个主分量

定义它的一种方法是,其方向向量是通过数据平均值的协方差矩阵对应于最大特征值的特征向量的线。这就是说,
eig(cov(data))
是一种非常糟糕的计算方法,因为它会进行大量不必要的计算和复制,并且可能比使用
svd
更不准确。见下文:

import numpy as np

# Generate some data that lies along a line

x = np.mgrid[-2:5:120j]
y = np.mgrid[1:9:120j]
z = np.mgrid[-5:3:120j]

data = np.concatenate((x[:, np.newaxis], 
                       y[:, np.newaxis], 
                       z[:, np.newaxis]), 
                      axis=1)

# Perturb with some Gaussian noise
data += np.random.normal(size=data.shape) * 0.4

# Calculate the mean of the points, i.e. the 'center' of the cloud
datamean = data.mean(axis=0)

# Do an SVD on the mean-centered data.
uu, dd, vv = np.linalg.svd(data - datamean)

# Now vv[0] contains the first principal component, i.e. the direction
# vector of the 'best fit' line in the least squares sense.

# Now generate some points along this best fit line, for plotting.

# I use -7, 7 since the spread of the data is roughly 14
# and we want it to have mean 0 (like the points we did
# the svd on). Also, it's a straight line, so we only need 2 points.
linepts = vv[0] * np.mgrid[-7:7:2j][:, np.newaxis]

# shift by the mean to get the line in the right place
linepts += datamean

# Verify that everything looks right.

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as m3d

ax = m3d.Axes3D(plt.figure())
ax.scatter3D(*data.T)
ax.plot3D(*linepts.T)
plt.show()

下面是它的样子:

集合中有多少个点?如果大于2,是否需要最小二乘拟合线?你想要什么形式的方程?z=f(x,y)或参数?我应该更具描述性。我想要一条最小二乘参数线。我有来自传感器的300个3D(x,y,z)数据点,这些数据点应该在空间中形成一条直线。实际上,你不需要数字优化器——这是一个二次优化问题,可以用SVD以闭合形式轻松解决,请参见我的答案。:)我如何产生这条线的梯度?有可能在这种情况下得到多项式拟合吗@DWF有人能解释一下为什么主方向是
vv
的第一行吗?我在互联网上发现了相互矛盾的说法,它通常说它应该是对应于最小奇异值的正确奇异值。这将是vv的最后一行,否?计算SVD在时间和内存上是二次的。即使只有10k点,这种方法也需要很多秒,而且我会出现内存不足的错误。有没有更有效的方法可以更有效地计算方向向量?如果您只需要第一个主分量,那么优化秩1近似的均方重建误差将为您提供该方法。谷歌搜索“降阶SVD”应该会发现一些东西。在协作过滤的背景下,这里进行一些讨论:
import numpy as np

# Generate some data that lies along a line

x = np.mgrid[-2:5:120j]
y = np.mgrid[1:9:120j]
z = np.mgrid[-5:3:120j]

data = np.concatenate((x[:, np.newaxis], 
                       y[:, np.newaxis], 
                       z[:, np.newaxis]), 
                      axis=1)

# Perturb with some Gaussian noise
data += np.random.normal(size=data.shape) * 0.4

# Calculate the mean of the points, i.e. the 'center' of the cloud
datamean = data.mean(axis=0)

# Do an SVD on the mean-centered data.
uu, dd, vv = np.linalg.svd(data - datamean)

# Now vv[0] contains the first principal component, i.e. the direction
# vector of the 'best fit' line in the least squares sense.

# Now generate some points along this best fit line, for plotting.

# I use -7, 7 since the spread of the data is roughly 14
# and we want it to have mean 0 (like the points we did
# the svd on). Also, it's a straight line, so we only need 2 points.
linepts = vv[0] * np.mgrid[-7:7:2j][:, np.newaxis]

# shift by the mean to get the line in the right place
linepts += datamean

# Verify that everything looks right.

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as m3d

ax = m3d.Axes3D(plt.figure())
ax.scatter3D(*data.T)
ax.plot3D(*linepts.T)
plt.show()