Python scikit学习线性模型参数标准错误

Rya*_*yan 12 python variance linear-regression scikit-learn

我正在使用sklearn,特别是linear_model模块.在拟合简单的线性之后

import pandas as pd
import numpy as np
from sklearn import linear_model
randn = np.random.randn

X = pd.DataFrame(randn(10,3), columns=['X1','X2','X3'])
y = pd.DataFrame(randn(10,1), columns=['Y'])        

model = linear_model.LinearRegression()
model.fit(X=X, y=y)
Run Code Online (Sandbox Code Playgroud)

我看到我如何通过coef_和intercept_访问系数和截距,预测也很简单.我想访问这个简单模型的参数的方差 - 协方差矩阵,以及这些参数的标准误差.我熟悉R和vcov()函数,似乎scipy.optimize有一些功能(使用python中的optimize.leastsq方法获取拟合参数的标准错误) - sklearn是否具有访问这些统计信息的任何功能??

感谢任何帮助.

-Ryan

gri*_*tis 17

tl;博士

不是使用 scikit-learn,但您可以使用一些线性代数手动计算。我在下面的例子中这样做。

还有一个带有此代码的 jupyter 笔记本:https ://gist.github.com/grisaitis/cf481034bb413a14d3ea851dab201d31

什么和为什么

您估计的标准误差只是您估计方差的平方根。你估计的方差是多少?如果你假设你的模型有高斯误差,它是:

Var(beta_hat) = inverse(X.T @ X) * sigma_squared_hat

然后的标准误差beta_hat[i]Var(beta_hat)[i, i] ** 0.5

所有你必须计算sigma_squared_hat。这是模型高斯误差的估计值。这不是先验已知的,但可以用残差的样本方差来估计。

您还需要在数据矩阵中添加一个截距项。Scikit-learn 在LinearRegression类中自动执行此操作。因此,要自己计算,您需要将其添加到 X 矩阵或数据框中。

如何

在您的代码之后开始,

显示您的 scikit-learn 结果

print(model.intercept_)
print(model.coef_)
Run Code Online (Sandbox Code Playgroud)
[-0.28671532]
[[ 0.17501115 -0.6928708   0.22336584]]
Run Code Online (Sandbox Code Playgroud)

用线性代数重现这个

N = len(X)
p = len(X.columns) + 1  # plus one because LinearRegression adds an intercept term

X_with_intercept = np.empty(shape=(N, p), dtype=np.float)
X_with_intercept[:, 0] = 1
X_with_intercept[:, 1:p] = X.values

beta_hat = np.linalg.inv(X_with_intercept.T @ X_with_intercept) @ X_with_intercept.T @ y.values
print(beta_hat)
Run Code Online (Sandbox Code Playgroud)
[[-0.28671532]
 [ 0.17501115]
 [-0.6928708 ]
 [ 0.22336584]]
Run Code Online (Sandbox Code Playgroud)

计算参数估计的标准误差

y_hat = model.predict(X)
residuals = y.values - y_hat
residual_sum_of_squares = residuals.T @ residuals
sigma_squared_hat = residual_sum_of_squares[0, 0] / (N - p)
var_beta_hat = np.linalg.inv(X_with_intercept.T @ X_with_intercept) * sigma_squared_hat
for p_ in range(p):
    standard_error = var_beta_hat[p_, p_] ** 0.5
    print(f"SE(beta_hat[{p_}]): {standard_error}")
Run Code Online (Sandbox Code Playgroud)
SE(beta_hat[0]): 0.2468580488280805
SE(beta_hat[1]): 0.2965501221823944
SE(beta_hat[2]): 0.3518847753610169
SE(beta_hat[3]): 0.3250760291745124
Run Code Online (Sandbox Code Playgroud)

确认 statsmodels

import statsmodels.api as sm
ols = sm.OLS(y.values, X_with_intercept)
ols_result = ols.fit()
ols_result.summary()
Run Code Online (Sandbox Code Playgroud)
...
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const         -0.2867      0.247     -1.161      0.290      -0.891       0.317
x1             0.1750      0.297      0.590      0.577      -0.551       0.901
x2            -0.6929      0.352     -1.969      0.096      -1.554       0.168
x3             0.2234      0.325      0.687      0.518      -0.572       1.019
==============================================================================
Run Code Online (Sandbox Code Playgroud)

耶,完成了!


eic*_*erg 7

不,scikit-learn没有建立用于进行推断的错误估计。Statsmodels可以。

import statsmodels.api as sm
ols = sm.OLS(y, X)
ols_result = ols.fit()
# Now you have at your disposition several error estimates, e.g.
ols_result.HC0_se
# and covariance estimates
ols_result.cov_HC0
Run Code Online (Sandbox Code Playgroud)

查看文件