三维空间N个数据点的直线拟合问题咨询
我有N个位于同一直线上的三维数据点,y方向固定,需将x、z对y进行拟合。以6个沿y轴分布的数据点为例:
x=[0,0,0,0,0,0] y=[1,2,3,4,5,6] z=[0,0,0,0,0,0]
我需要获取最优拟合参数、拟合优度(gof)及拟合误差。目前使用最小二乘法拟合得到的reduced chi²小于1,怀疑可能过拟合或存在理解误区,现提出两个问题:
- 上述示例中得到的reduced chi²为0,这是否合理?
- 最小二乘法是否适用于该场景?SVD是否是更优选择?
当前使用的拟合代码如下:
import scipy.optimize import numpy as np #define a model (line) def linear(params, y): a, b = params data = [a * y[i] + b for i in range(0, len(y))] return data #define the residuals that need to me minimized def fitting_cost(params, x, y, z): a_x, b_x, a_z, b_z = params x_pred = linear((a_x, b_x), y) z_pred = linear((a_z, b_z), y) res_x = [x_pred[i] - x[i] for i in range(0, 6)] res_z = [z_pred[i] - z[i] for i in range(0, 6)] return res_x + res_z #do the fit and return parameters plus gof def least_squares_fit(x, y, z): sp = [0,0,0,0] result = scipy.optimize.leastsq(fitting_cost, sp, args=(x, y, z), full_output=True) s_sq = (result[2]['fvec'] ** 2).sum() / ( len(result[2]['fvec']) - len(result[0])) return result[0], s_sq
问题1:reduced chi²为0是否合理?
完全合理。示例数据中x和z的所有值都是0,用线性模型x = a_x*y + b_x和z = a_z*y + b_z拟合时,最优参数必然是a_x=0, b_x=0、a_z=0, b_z=0——此时预测值与真实值完全重合,残差平方和为0。
reduced chi²的计算公式为(残差平方和)/(自由度),这里残差平方和为0,无论自由度(总残差数12减去参数数4,即8)是多少,结果都为0。这不是过拟合,而是模型完美匹配了数据——因为数据本身完全符合x=0、z=0的线性关系。
问题2:最小二乘法是否适用?SVD是不是更优选择?
最小二乘法的适用性
最小二乘法完全适用于该场景。你的需求是拟合x、z关于y的线性模型,最小二乘法是解决这类线性回归问题的标准方法,在数据噪声服从正态分布的假设下,它能给出无偏的最优参数估计。
不过当前代码可以简化:x和z的拟合相互独立,无需将四个参数放在一起拟合,分开对x-y、z-y做线性回归会更高效,也更容易计算拟合优度和误差。比如使用numpy.polyfit直接做一元线性回归,或者scipy.stats.linregress,这些工具会直接返回R²、标准误差等指标,比手动编写残差函数更简洁可靠。
SVD的角色
SVD(奇异值分解)并非与最小二乘法对立的方法,它是实现最小二乘法的一种数值手段。当用最小二乘法求解线性方程组Ax = b时,若矩阵A存在秩亏或数值不稳定的情况,SVD能提供更稳定的解。
在你的场景中,数据无噪声且矩阵满秩,普通最小二乘法(如QR分解)与SVD得到的结果一致。只有当数据存在共线性、或噪声过大导致数值不稳定时,SVD的优势才会显现。因此不存在“SVD更优”的说法,它是最小二乘法的一种实现方式,而非替代方案。
内容的提问来源于stack exchange,提问作者Doe. joe

