我正在测试一些代码,这些代码除其他外将对某些数据运行形式y = m * x + b
的线性回归。为简单起见,我将x和y数据设置为相等,期望模型对斜率返回1,对截距返回0。但是,那不是我所看到的。这是一个超级精炼的示例,主要取自numpy docs:
>>> y = np.arange(5)
>>> x = np.arange(5)
>>> A = np.vstack([x, np.ones(5)]).T
>>> np.linalg.lstsq(A, y)
(array([ 1.00000000e+00, -8.51331872e-16]), array([ 7.50403936e-31]), 2, array([ 5.78859314, 1.22155205]))
>>> # ^slope ^intercept ^residuals ^rank ^singular values
Numpy找到最合适的真实线(一)的精确斜率,但报告截距虽然很小,但不为零。此外,即使可以通过线性方程式
y = 1 * x + 0
完美建模数据,但由于找不到此精确方程式,因此numpy报告的残差很小但非零。作为健全性检查,我用R(我的“母语”语言)进行了尝试,并观察到类似的结果:
> x <- c(0 : 4)
> y <- c(0 : 4)
> lm(y ~ x)
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept) x
-3.972e-16 1.000e+00
我的问题是,为什么以及在什么情况下会发生这种情况?寻找适合的模型是一种人工产物,还是总是在回归输出中添加一点我们通常看不到的噪声?在这种情况下,答案几乎肯定可以接近零,因此我主要是出于学术上的好奇心。但是,我也想知道是否存在某些情况,这种影响相对于数据而言可以被放大到微不足道。
我现在可能已经揭示了这一点,但是我基本上对低级编程语言一无所知,尽管我曾经粗略地了解如何“手工”完成这种线性代数,但它早已从我脑海。
最佳答案
看起来像数值误差,y截距非常小。
Python(包括numpy)默认情况下使用双精度浮点数。这些数字的格式设置为具有52位系数(有关浮点说明,请参见this,有关“基本”的科学符号说明,请参见this)
在您的情况下,您发现y截距为〜4e-16。事实证明,52位系数的精度约为2e-16。基本上,在回归中,您从与其非常相似的东西中减去了一个数量级为1的数字,并达到了双浮点数的数值精度。
关于python - 当x = y时,Numpy和R在线性回归中给出非零截距,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29281817/