【问题标题】:Why does sklearn linear regression give a non-zero intercept for a line passing through (0,0)?为什么 sklearn 线性回归对通过 (0,0) 的线给出非零截距?
【发布时间】:2016-03-04 11:52:31
【问题描述】:

给定线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 + 舍入误差。

标签: python scikit-learn linear-regression


【解决方案1】:

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

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

要回答为什么这个数字不为零,你可以去下面的兔子洞:

  • sklearn 使用scipy.linalg.lstsq 来拟合线性回归,
  • scipy.linalg.lstsq 使用来自LAPACKgelss 来找到Ax = b 的最小二乘解,
  • gelss 使用A 的奇异值分解来解决。

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

【讨论】:

    【解决方案2】:

    -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 是这样实现的,我觉得很奇怪。

    【讨论】:

    • 在这种情况下,线性回归只能通过解析求解,不需要像你描述的那样的迭代算法。舍入误差解释了差异,而不是梯度下降收敛。
    • 是的,我已经在答案的底部写了这个......也许我应该完全删除整个答案。
    • 我会留下它,那里仍然有很好的信息。没有看到您的编辑,抱歉,我只是想指出,在这种情况下,sklearn 不可能不使用分析方法来解决线性回归。
    猜你喜欢
    • 2020-12-03
    • 2015-05-30
    • 2020-10-28
    • 2018-06-11
    • 2021-02-20
    • 2018-05-16
    • 2019-02-23
    • 2022-01-09
    • 2021-07-19
    相关资源
    最近更新 更多