【问题标题】:Python scikit learn Linear Model Parameter Standard ErrorPython scikit学习线性模型参数标准误差
【发布时间】:2014-04-18 08:34:03
【问题描述】:

我正在使用 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)

我知道如何通过 coef_ 和 intercept_ 访问系数和截距,预测也很简单。我想访问这个简单模型的参数的方差-协方差矩阵,以及这些参数的标准误差。我熟悉 R 和 vcov() 函数,似乎 scipy.optimize 有一些功能(Getting standard errors on fitted parameters using the optimize.leastsq method in python) - sklearn 是否有任何功能可以访问这些统计信息??

感谢您对此的任何帮助。

-瑞恩

【问题讨论】:

    标签: python scikit-learn linear-regression variance


    【解决方案1】:

    不,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
    

    docs

    【讨论】:

    • 有没有什么方法可以用你可以从 scikit 回归模型中得到的任何数字来计算 scikit-learn 的标准误差?我知道 statsmodels 提供了这些数据,但我需要 statsmodels 没有的 l2-penalty。
    • 我不知道。对于 L2-penalty 和 n > p,我想你可以写出公式。对于 n
    • 这并不能直接回答问题,但是对于预测误差,您可以得到如here 所述的均方误差,这是朝着预测标准误差迈出的一步。
    • 有关@eickenberg 答案的更详细版本,请参阅:stackoverflow.com/questions/31523921/…
    【解决方案2】:

    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_)
    
    [-0.28671532]
    [[ 0.17501115 -0.6928708   0.22336584]]
    

    用线性代数重现这个

    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)
    
    [[-0.28671532]
     [ 0.17501115]
     [-0.6928708 ]
     [ 0.22336584]]
    

    计算参数估计的标准误

    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}")
    
    SE(beta_hat[0]): 0.2468580488280805
    SE(beta_hat[1]): 0.2965501221823944
    SE(beta_hat[2]): 0.3518847753610169
    SE(beta_hat[3]): 0.3250760291745124
    

    statsmodels确认

    import statsmodels.api as sm
    ols = sm.OLS(y.values, X_with_intercept)
    ols_result = ols.fit()
    ols_result.summary()
    
    ...
    ==============================================================================
                     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
    ==============================================================================
    

    好的,完成了!

    【讨论】:

    • 太好了。非常感谢!
    • 我的数据集在sigma_squared_hat = residual_sum_of_squares[0, 0] / (N - p) 收到invalid index to scalar variable.residual_sum_of_squares 计算为numpy.float64。我在这里错过了什么?
    • @Bharat 生成residual_sum_of_squares 的代码是什么?
    • 那么,当你使用弹性网络来收缩系数的时候呢……
    【解决方案3】:

    每个预测变量列的随机格式都相同。所以,这就像运行三个模拟:

    import pandas as pd
    import numpy as np
    from sklearn import linear_model
    randn = np.random.randn
    
    X = pd.DataFrame(randn(10,1))
    y = pd.DataFrame(randn(10,1)) 
    model = linear_model.LinearRegression()
    model.fit(X=X, y=y)
    y_pred = model.predict(X)
    print(y)
    print(y_pred)
    residuals = y - y_pred
    residuals['c'] = residuals.iloc[:, 0]**2
    sq = residuals['c']
    print(sq)
    standard_error = (sum(sq)/(10-2))**0.5
    print(standard_error)
    

    【讨论】:

      猜你喜欢
      • 2013-10-24
      • 2017-12-01
      • 2016-10-01
      • 2020-06-15
      • 2019-04-19
      • 2017-04-26
      • 2016-01-18
      • 2021-09-22
      • 2013-05-14
      相关资源
      最近更新 更多