让我们退一步来考虑你说的以下句子:
“由于对线性回归设置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)
我们的
x
和
y
变量看起来像这样:
X Y
51 29
3 73
7 77
98 29
29 80
90 37
49 9
42 53
8 17
65 35
无拦截模型
回想一下,回归权重的计算有一个封闭形式的解,我们可以使用正规方程获得:
![regression](https://chart.googleapis.com/chart?cht=tx&chl=(%7BX%7D'X)%5E%7B-1%7D%7BX%7D'Y)
使用这种方法,我们获得了单个回归系数,因为我们只有一个预测变量:
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]
请注意以下两点:
- 我们现在有两个系数。第一个是截距,第二个是
x
预测变量的回归系数。
- 当我们设置
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的列。它有效地允许你在两个基本统计模型之间切换。