Python 3.x 拟合截距参数如何影响scikit学习的线性回归

Python 3.x 拟合截距参数如何影响scikit学习的线性回归,python-3.x,scikit-learn,statistics,regression,linear-regression,Python 3.x,Scikit Learn,Statistics,Regression,Linear Regression,我试图拟合一个线性模型,我的数据集被标准化,其中每个特征被最大可能值所除。因此,值的范围为0-1。现在我从我之前在scikit学习中发布的线性回归中了解到,当fit\u intercept参数设置为false时,会产生与闭式OLS相同的结果。我不太明白fit\u intercept的工作原理 对于任何线性问题,如果y是预测值 y(w, x) = w_0 + w_1 x_1 + ... + w_p x_p 在模块中,向量w=(w_1,…,w_p)表示为coef_,w_0表示为截距_ 在闭式OLS

我试图拟合一个线性模型,我的数据集被标准化,其中每个特征被最大可能值所除。因此,值的范围为0-1。现在我从我之前在scikit学习中发布的线性回归中了解到,当
fit\u intercept
参数设置为false时,会产生与闭式OLS相同的结果。我不太明白
fit\u intercept
的工作原理

对于任何线性问题,如果y是预测值

y(w, x) = w_0 + w_1 x_1 + ... + w_p x_p
在模块中,向量w=(w_1,…,w_p)表示为coef_,w_0表示为截距_

在闭式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\u intercept
为真时,如果y是预测值,则scikit learn线性回归将解决该问题

y(w, x) = w_0 + w_1 x_1 + ... + w_p x_p
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会给线性回归带来不同的结果,我不能完全确定它们背后的直觉。哪一个更好?为什么?

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

让我们后退一步,考虑下面的句子: 因为仅设置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]
现在,让我们看看scikit learn何时设置
fit\u intercept=False

clf = LinearRegression(fit_intercept=False)

print(clf.fit(x, y).coef_)
[ 0.53297593]
当我们改为设置
fit\u 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
    预测变量的回归系数
  • 当我们设置
    fit_intercept=True
  • 那么,在上面的scikit学习模型中,为什么真与假之间存在差异?因为在一个案例中,没有建立拦截模型。在另一种情况下,基础模型包含一个截距,当您在求解正态方程时手动添加一个截距项/列时,可以确认该截距

    如果要在scikit学习中使用此新设计矩阵,则无论您为
    fit_intercept
    设置True还是False,预测变量的系数都不会改变(由于居中,截距值会有所不同,但这与本讨论无关):

    总结 您得到的输出(即系数值)将完全取决于您输入到这些计算中的矩阵(无论是其正态方程、scikit学习还是任何其他)

    在模型中使用fit_intercept有何不同?何时应将其设置为True/False

    如果您的设计矩阵不包含1列,则正态方程和scikit学习(
    fit_intercept=False
    )将为您提供相同的答案(如您所述)。但是,如果您将参数设置为True,那么如果您使用1的列计算,您得到的答案实际上将与正常方程相同

    什么时候设置为真/假?顾名思义,如果不希望在模型中包含截距,则将其设置为False。如果确实需要截距,请将其设置为True,并理解系数值将发生变化,但当数据包含1的列时,将匹配法线方程方法

    所以真/假实际上并不会给你不同的结果(与正常的equa相比)