fit_intercept参数如何影响scikit learn中的线性回归

6
我正在尝试拟合一个线性模型,我的数据集已经归一化处理,其中每个特征都被最大可能值除以。因此,这些值的范围为0-1。现在我从之前的帖子Linear Regression vs Closed form Ordinary least squares in Python中了解到,当fit_intercept参数设置为false时,scikit learn中的线性回归产生与闭合形式OLS相同的结果。我不太明白fit_intercept是如何工作的。
对于任何线性问题,如果y是预测值。
y(w, x) = w_0 + w_1 x_1 + ... + w_p x_p

在整个模块中,向量w = (w_1, ..., w_p) 被表示为 coef_ ,w_0 被表示为 intercept_。
在闭式OLS中,我们还有一个偏置值 w_0,并在计算点积之前引入向量 X_0=[1...1],然后使用矩阵乘法和逆矩阵求解。
w = np.dot(X.T, X) 
w1 = np.dot(np.linalg.pinv(w), np.dot(X.T, Y))

fit_intercept 为True时,scikit-learn线性回归会解决预测值y的问题。 y(w, x) = w_0 + w_1 x_1 + ... + w_p x_p + b 其中b是截距项。
在模型中使用 fit_intercept 有何不同,何时应将其设置为True/False?我试图查看源代码,似乎系数被某些比例标准化。
if self.fit_intercept:
    self.coef_ = self.coef_ / X_scale
    self.intercept_ = y_offset - np.dot(X_offset, self.coef_.T)
else:
    self.intercept_ = 0

这个缩放操作到底是做什么的。我想解释一下两种方法(线性回归、闭合式OLS)中的系数,但由于只是将fit_intercept设置为True/False会导致线性回归的不同结果,我无法确定它们背后的直觉。哪种更好,为什么?

OLS的链接答案中没有截距项。你提供了一些伪代码(或者至少看起来像)。正确实现它,你将获得相等的结果(如果你在归一化方面没有差异)。 - sascha
我使用fit_intercept=False获得了更接近的结果。但是我的问题有点理论性。假设我想根据上述步骤找到的系数提取重要特征。现在,仅设置fit_intercept True/False就会给出完全不同的结果,那么哪个更好考虑呢?在所有机器学习书籍中,线性回归方法都是在没有截距参数的情况下解决它的,但scikit-learn引入了它。 - Farzana Yusuf
http://cs229.stanford.edu/notes/cs229-notes1.pdf,我也跟随过Andrew Ng的机器学习课程。所以这个fit_intercept是我无法与我所知道的联系起来的东西。是否有任何论文参考,我可以查找fit_intercept的解释。 - Farzana Yusuf
1
有很多资源。我无法想象你没有碰巧发现任何有用的东西。例如这里。如果你没有充分的理由不这样做,就使用它吧。 - sascha
2个回答

4
让我们退一步来考虑你说的以下句子:
“由于对线性回归设置fit_intercept True/False会得到不同的结果”
这并不完全正确。它可能不同,也可能相同,这完全取决于你的数据。了解回归权重计算中涉及了哪些内容会有所帮助。我的意思是:你的输入(x)数据长什么样?
了解你的输入数据以及理解为什么很重要,将有助于你认识到为什么有时会得到不同的结果,而在其他情况下结果却相同。
数据设置
让我们设置一些测试数据:
import numpy as np
from sklearn.linear_model import LinearRegression

np.random.seed(1243)

x = np.random.randint(0,100,size=10)
y = np.random.randint(0,100,size=10)

我们的xy变量看起来像这样:
   X   Y
  51  29
   3  73
   7  77
  98  29
  29  80
  90  37
  49   9
  42  53
   8  17
  65  35

无拦截模型

回想一下,回归权重的计算有一个封闭形式的解,我们可以使用正规方程获得:

regression

使用这种方法,我们获得了单个回归系数,因为我们只有一个预测变量:

x = x.reshape(-1,1)
w = np.dot(x.T, x)
w1 = np.dot(np.linalg.pinv(w), np.dot(x.T, y))

print(w1)
[ 0.53297593]

现在,让我们来看一下当我们设置fit_intercept = False时的scikit-learn:
clf = LinearRegression(fit_intercept=False)

print(clf.fit(x, y).coef_)
[ 0.53297593]

当我们将fit_intercept = True设置为真时会发生什么?
clf = LinearRegression(fit_intercept=True)

print(clf.fit(x, y).coef_)
[-0.35535884]

似乎将 fit_intercept 设置为 True 和 False 会得到不同的答案,而只有当我们将其设置为 False 时才会得到“正确”的答案,但这并不完全正确...
截距模型
此时,我们必须考虑我们的输入数据实际上是什么。在上面的模型中,我们的数据矩阵(也称为特征矩阵或设计矩阵)只是包含我们的 x 值的单个向量。变量 y 没有包含在设计矩阵中。如果我们想要在模型中添加一个截距,一种常见的方法是向设计矩阵添加一列 1,使 x 变成:
x_vals = x.flatten()
x = np.zeros((10, 2))
x[:,0] = 1
x[:,1] = x_vals

   intercept     x
0        1.0  51.0
1        1.0   3.0
2        1.0   7.0
3        1.0  98.0
4        1.0  29.0
5        1.0  90.0
6        1.0  49.0
7        1.0  42.0
8        1.0   8.0
9        1.0  65.0

现在,当我们将此作为我们的设计矩阵时,我们可以再次尝试使用闭式解决方案:
w = np.dot(x.T, x)
w1 = np.dot(np.linalg.pinv(w), np.dot(x.T, y))

print(w1)
[ 59.60686058  -0.35535884]

请注意以下两点:

  1. 我们现在有两个系数。第一个是截距,第二个是 x 预测变量的回归系数。
  2. 当我们设置 fit_intercept=True 时,x 的系数与上面的 scikit-learn 输出的系数匹配。

那么在上面的 scikit-learn 模型中,为什么 True 和 False 之间会有区别呢?因为在一个案例中,并没有建模拦截器。而在另一个案例中,底层模型包含了一个拦截器,在解决正常方程式时手动添加一个拦截器项/列可以证实这一点。

如果你要在scikit-learn中使用这个新的设计矩阵,无论你将fit_intercept设为True或False,预测变量的系数都不会改变(由于居中而导致的截距值不相关),但在这次讨论中并不重要)。

clf = LinearRegression(fit_intercept=False)
print(clf.fit(x, y).coef_)
[ 59.60686058  -0.35535884]

clf = LinearRegression(fit_intercept=True)
print(clf.fit(x, y).coef_)
[ 0.         -0.35535884]

总结

你得到的输出(即系数值)完全取决于你输入到这些计算中的矩阵(无论是正规方程、scikit-learn还是其他任何东西)。

在模型中使用fit_intercept有什么不同,应该在什么情况下将其设置为True/False?

如果你的设计矩阵不包含一个1的列,则正规方程和scikit-learn (fit_intercept = False)将给出相同的答案(正如你所指出的那样)。然而,如果你将参数设置为True,则你得到的答案实际上与正规方程计算得到的结果相同,如果你计算时包括了一个1的列。

什么情况下应该设置为True/False?顾名思义,当你不想在你的模型中包含截距时,你应该将其设置为False。当你想要一个截距时,你应该将其设置为True,理解系数值将会改变,但是当你的数据包括一个1的列时,它将匹配正规方程方法。

因此,True/False实际上并不会给你带来不同的结果(与正规方程相比),当考虑相同的基本模型时。你观察到的差异是因为你正在看两个不同的统计模型(一个带有截距项,一个不带)。fit_intercept参数存在的原因是让你能够创建一个截距模型,而无需手动添加那个1的列。它有效地允许你在两个基本统计模型之间切换。


2

不必深入数学公式的细节,当拟合截距设置为false时,估计器会故意将截距设置为零,这反过来会影响其他回归因子,因为误差减少的“责任”落在这些因素上。因此,如果结果对截距项的存在敏感,则两种情况下的结果可能会非常不同。缩放移动原点,从而允许相同的闭环解决方案适用于有或没有截距的模型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接