我正在尝试拟合线性模型,并且我的数据集被归一化,其中每个要素除以最大可能值。所以这些值的范围是0-1。现在我从上一篇文章中了解Linear Regression vs Closed form Ordinary least squares in Python scikit中的线性回归学习当fit_intercept
参数设置为false时,与闭合形式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时,如果y是预测值,则scikit-learn线性回归可以解决问题。
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
真/假给出了线性回归的不同结果,我不能完全决定它们背后的直觉。哪一个更好,为什么?
答案 0 :(得分:0)
在不赘述数学公式的细节的情况下,当拟合截距设置为false时,估计器会故意将截距设置为零,这会影响其他回归变量,因为误差减少的“责任”落在这些因素上。因此,如果对拦截项的存在很敏感,则在两种情况下结果都可能有很大不同。缩放可移动原点,从而允许相同的闭环解决方案适用于拦截模型和无拦截模型。
答案 1 :(得分:0)
让我们退后一步,考虑一下您说的以下句子:
由于仅将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
回想一下,权重的计算有一个封闭形式的解决方案,我们可以使用正态方程获得:
使用此方法,由于只有一个预测变量,所以我们得到一个回归系数:
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学习:
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]
注意2件事:
x
预测变量x
时,fit_intercept = True
的系数与上面的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设置为True,这会理解系数值会发生变化,但是当数据中包含1的列时,它将与法线方程式相匹配
因此,当考虑相同的基础模型时,True / False实际上不会给您带来不同的结果(与正常方程相比)。您观察到的差异是因为您正在查看两个不同的统计模型(一个带有截距项,另一个没有截距项)。 fit_intercept
参数存在的原因是,您可以创建一个拦截模型,而无需手动添加该1的列。它有效地使您可以在两个基础统计模型之间切换。