在3D中拟合一条线

时间:2010-02-19 17:37:02

标签: python numpy linear-algebra curve-fitting

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

感谢。

2 个答案:

答案 0 :(得分:41)

如果您尝试预测其他两个值中的一个值,那么您应该使用lstsq并将a参数作为您的自变量(加上一列1来估算截距)和{ {1}}作为因变量。

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

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

svd

以下是它的样子:a 3d plot of a fitted line

答案 1 :(得分:3)

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

遵循documentation示例:

import numpy as np

pts = np.add.accumulate(np.random.random((10,3)))
x,y,z = pts.T

# this will find the slope and x-intercept of a plane
# parallel to the y-axis that best fits the data
A_xz = np.vstack((x, np.ones(len(x)))).T
m_xz, c_xz = np.linalg.lstsq(A_xz, z)[0]

# again for a plane parallel to the x-axis
A_yz = np.vstack((y, np.ones(len(y)))).T
m_yz, c_yz = np.linalg.lstsq(A_yz, z)[0]

# the intersection of those two planes and
# the function for the line would be:
# z = m_yz * y + c_yz
# z = m_xz * x + c_xz
# or:
def lin(z):
    x = (z - c_xz)/m_xz
    y = (z - c_yz)/m_yz
    return x,y

#verifying:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure()
ax = Axes3D(fig)
zz = np.linspace(0,5)
xx,yy = lin(zz)
ax.scatter(x, y, z)
ax.plot(xx,yy,zz)
plt.savefig('test.png')
plt.show()

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