我尝试用 SKLearn 为一个相当大的数据集做一个 LR,该数据集有大约 600 个虚拟变量,只有很少的区间变量(我的数据集中有 300 K 行),由此产生的混淆矩阵看起来很可疑。我想检查返回的系数和方差分析的重要性,但我找不到如何访问它。有可能吗?对于包含大量虚拟变量的数据,最佳策略是什么?非常感谢!
问问题
32718 次
1 回答
23
Scikit-learn 故意不支持统计推断。如果您想要开箱即用的系数显着性检验(以及更多),您可以使用Statsmodels的Logit估计器。这个包模仿了 R 中的接口模型,所以你会觉得它很熟悉。glm
如果您仍想坚持使用 scikit-learn LogisticRegression,您可以使用渐近近似来分布最大似然估计。准确地说,对于一个最大似然估计向量theta
,它的方差-协方差矩阵可以估计为inverse(H)
,其中H
是对数似然的 Hessian 矩阵theta
。这正是下面的函数所做的:
import numpy as np
from scipy.stats import norm
from sklearn.linear_model import LogisticRegression
def logit_pvalue(model, x):
""" Calculate z-scores for scikit-learn LogisticRegression.
parameters:
model: fitted sklearn.linear_model.LogisticRegression with intercept and large C
x: matrix on which the model was fit
This function uses asymtptics for maximum likelihood estimates.
"""
p = model.predict_proba(x)
n = len(p)
m = len(model.coef_[0]) + 1
coefs = np.concatenate([model.intercept_, model.coef_[0]])
x_full = np.matrix(np.insert(np.array(x), 0, 1, axis = 1))
ans = np.zeros((m, m))
for i in range(n):
ans = ans + np.dot(np.transpose(x_full[i, :]), x_full[i, :]) * p[i,1] * p[i, 0]
vcov = np.linalg.inv(np.matrix(ans))
se = np.sqrt(np.diag(vcov))
t = coefs/se
p = (1 - norm.cdf(abs(t))) * 2
return p
# test p-values
x = np.arange(10)[:, np.newaxis]
y = np.array([0,0,0,1,0,0,1,1,1,1])
model = LogisticRegression(C=1e30).fit(x, y)
print(logit_pvalue(model, x))
# compare with statsmodels
import statsmodels.api as sm
sm_model = sm.Logit(y, sm.add_constant(x)).fit(disp=0)
print(sm_model.pvalues)
sm_model.summary()
的输出print()
是相同的,它们恰好是系数 p 值。
[ 0.11413093 0.08779978]
[ 0.11413093 0.08779979]
sm_model.summary()
还打印格式良好的 HTML 摘要。
于 2017-11-02T15:38:18.030 回答