我正在使用linalg.lstsq在这样的函数中构建回归线:
def lsreg(x, y):
if not isinstance(x, np.ndarray):
x = np.array(x)
if not isinstance(y, np.ndarray):
y = np.array(y)
A = np.array([x, np.ones(len(x))])
ret = np.linalg.lstsq(A.T, y)
return ret[0]
并将其称为:
x = np.array([10000001, 10000002, 10000003])
y = np.array([3.0, 4.0, 5.0])
regress = lsreg(x, y)
fit = regress[0]*x + regress[1]
print fit
,输出y得到:
[ 3. 4. 5.]
到目前为止,这么好。现在,如果我像这样改变x:
x = np.array([100000001, 100000002, 100000003])
y = np.array([3.0, 4.0, 5.0])
regress = lsreg(x, y)
fit = regress[0]*x + regress[1]
print fit
我得到了
[ 3.99999997 4.00000001 4.00000005]
而不是接近3,4和5的东西。
有关正在发生的事情的任何线索?
答案 0 :(得分:2)
你的问题是由于在解决病态系统方程时出现的数值误差。
In [115]: np.linalg.lstsq(A.T, y)
Out[115]:
(array([ 3.99999993e-08, 3.99999985e-16]),
array([], dtype=float64),
1,
array([ 1.73205084e+08, 1.41421352e-08]))
请注意,np.linalg.lstsq为您输入矩阵形成的矩阵AA.T的等级返回“1”。这意味着它认为你的矩阵是1级,因此是病态的(因为你的最小二乘系统是2 x 2方程组,它应该是2级)。接近0的第二个奇异值证实了这一点。这就是“错误”结果的原因。您应该按照“数值线性代数数值误差”的方式进行谷歌搜索,以了解有关此问题的更多信息。
答案 1 :(得分:0)
我尝试了scipy:
from scipy import stats
x = np.array([100000001, 100000002, 100000003])
y = np.array([3.0, 4.0, 5.0])
res = stats.linregress(x, y)
print x*res[0] + res[1]
我得到了:
[ 3. 4. 5.]