为什么 sklearn 线性回归对通过 (0,0) 的直线给出非零截距?

Why does sklearn linear regression give a non-zero intercept for a line passing through (0,0)?

给定一条线的一些数据点 y = 3x:

from sklearn import datasets, linear_model
X = [[1],[2],[3],[4],[5]]
y = [[3],[6],[9],[12],[15]]
regr = linear_model.LinearRegression()
regr.fit(X,y)

然后:

regr.predict([[6], [7], [8], [9], [10]])

如预期的那样给出:

array([[ 18.],
       [ 21.],
       [ 24.],
       [ 27.],
       [ 30.]])

regr.coef_ 是 3,正如预期的那样。但是为什么 regr.intercept_ 不是 0?

regr.intercept_
array([ -3.55271368e-15])

这是一个浮点数问题 -- 这个数字 非常 接近于 0。您可以使用 numpy 的内置测试套件来检查

>>> from numpy.testing import assert_almost_equal
>>> assert_almost_equal(regr.intercept_, 0)

要回答为什么 数字不为零,您可以进入以下兔子洞:

  • sklearn 使用 scipy.linalg.lstsq 拟合线性回归,
  • scipy.linalg.lstsq 使用 LAPACK 中的 gelssAx = b,
  • 的最小二乘解
  • gelssA的奇异值分解求解。

我猜 gelss 是引入微小错误的地方。

-3.55271368e-15也可以写成0.000 000 000 000 003 552 713,所以你可以认为它是零和一个舍入误差...

剩下的只是假设,因为我没有阅读 sklearn 的资料,但它不是真正为零的原因可能是

  • LinearRegression.fit() 必须解决一个最小化问题(找到 ab 以最小化 ax+b 模型和数据集之间的平方误差)。
  • 为了解决这个问题,可能会使用收敛于解决方案的迭代算法(梯度下降?)
  • 它的结束条件可能类似于Stop when abs(error(step n) - error(step n+1)) < epsilon。 epsilon 是一个固定的小值。

编辑: 也就是说,这不是神经网络。 我很确定线性(或多项式)回归可以通过推导平方误差表达式来精确求解。我觉得 sklearn 是这样实现的很奇怪。