Scikit-learn逻辑回归优化:对比Statsmodels变量显著性分析
二分类任务中逻辑回归的变量筛选与Scikit-learn实现
我正在开展二分类预测任务,使用逻辑回归模型。已知借助Statsmodels可通过p值识别显著变量,移除不显著变量来优化模型性能。
Statsmodels 实现代码与结果
import statsmodels.api as sm # 添加常数项以获取截距 X_train_std_sm = sm.add_constant(X_train_std) # 拟合模型 log_reg = sm.Logit(y_train, X_train_std_sm).fit() # 展示结果 log_reg.summary()
输出结果:
Logit Regression Results Dep. Variable: y No. Observations: 1050 Model: Logit Df Residuals: 1043 Method: MLE Df Model: 6 Date: Wed, 17 Aug 2022 Pseudo R-squ.: 0.9562 Time: 13:26:12 Log-Likelihood: -29.285 converged: True LL-Null: -668.34 Covariance Type: nonrobust LLR p-value: 5.935e-273 coef std err z P>|z| [0.025 0.975] const 1.9836 0.422 4.699 0.000 1.156 2.811 x1 0.1071 0.414 0.259 0.796 -0.704 0.918 x2 -0.4270 0.395 -1.082 0.279 -1.200 0.346 x3 -0.7979 0.496 -1.610 0.107 -1.769 0.173 x4 -3.5670 0.702 -5.085 0.000 -4.942 -2.192 x5 -2.1548 0.608 -3.542 0.000 -3.347 -0.962 x6 5.4692 0.929 5.885 0.000 3.648 7.291
从结果可见,6个变量中有3个p值大于5%(x1、x2、x3),需移除这些不显著变量后重新训练模型。
我的问题
- 能否用Scikit-learn实现同样的变量筛选操作?
- 如何用Scikit-learn识别并移除p值>5%的变量?
- 如何用Scikit-learn提升逻辑回归模型的性能?
- 是否需要先用Statsmodels筛选变量,再用Scikit-learn建模?
我的Scikit-learn代码
from sklearn.model_selection import train_test_split from sklearn import preprocessing from sklearn.linear_model import LogisticRegression from sklearn import metrics import pandas as pd # 数据转换 y = df.is_genuine.values X = df[df.columns[1:]].values X_name = df[df.columns[1:]].columns # 拆分数据集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y) # 标准化数据 std_scale = preprocessing.StandardScaler().fit(X_train) X_train_std = std_scale.transform(X_train) X_test_std = std_scale.transform(X_test) # 逻辑回归建模 reg_log = LogisticRegression(penalty='none', solver='newton-cg') reg_log.fit(X_train_std, y_train) # 训练集准确率 reg_log.score(X_train_std, y_train) >>> 0.9914285714285714 # 预测 y_pred = reg_log.predict(X_test_std) # 结果整理 pred = pd.DataFrame(X_test_std, columns=X_name) pred['is_genuine'] = y_test pred['pred_reglog'] = y_pred pred['is_genuine_reglog'] = pred['pred_reglog'].apply(lambda x: True if x > 0 else False) # 测试集准确率 print(metrics.accuracy_score(y_test, y_pred)) >>> 0.9888888888888889
解答
1. 能用Scikit-learn实现变量筛选吗?
可以,但Scikit-learn本身没有直接输出p值的逻辑回归API,需结合Statsmodels或自定义计算实现基于p值的筛选,也可通过Scikit-learn自带的特征选择工具达成类似效果。
2. 用Scikit-learn识别并移除p值>5%的变量
有两种常用方式:
- 方式一:结合Statsmodels计算p值后筛选
先用Statsmodels拟合模型得到变量p值,再在Scikit-learn数据集中保留p值≤0.05的变量,代码示例:import statsmodels.api as sm # 给训练集添加常数项 X_train_sm = sm.add_constant(X_train_std) logit_model = sm.Logit(y_train, X_train_sm).fit() # 获取变量p值(排除截距项) p_values = logit_model.pvalues[1:] # 筛选显著变量的索引 mask = p_values <= 0.05 # 得到筛选后的训练/测试集 X_train_std_selected = X_train_std[:, mask] X_test_std_selected = X_test_std[:, mask] - 方式二:自定义计算p值(基于Scikit-learn模型参数)
逻辑回归的z值可通过系数除以标准误得到,标准误需通过计算Hessian矩阵的逆获取,该方法较繁琐,不如直接用Statsmodels便捷。
3. 用Scikit-learn提升逻辑回归模型性能
- 正则化:Scikit-learn的
LogisticRegression默认带L2正则化(penalty='l2'),可调整C参数(正则化强度的倒数,C越小正则化越强)防止过拟合;也可使用L1正则化(penalty='l1',需搭配solver='saga'或'liblinear'),自动将不重要变量的系数压缩至0,实现特征选择。 - 特征工程:除p值筛选外,可使用
SelectKBest(选择K个最优特征)、SelectFromModel(基于模型系数筛选)等Scikit-learn特征选择工具。 - 参数调优:用
GridSearchCV或RandomizedSearchCV搜索最优的solver、C、penalty等参数,示例:from sklearn.model_selection import GridSearchCV param_grid = {'penalty': ['l1', 'l2'], 'C': [0.01, 0.1, 1, 10, 100], 'solver': ['liblinear', 'saga']} grid_search = GridSearchCV(LogisticRegression(), param_grid, cv=5) grid_search.fit(X_train_std, y_train) best_model = grid_search.best_estimator_ - 数据预处理:确保数据标准化/归一化(你已完成),处理缺失值、异常值,对类别变量进行编码等。
4. 是否需要先用Statsmodels筛选变量,再用Scikit-learn建模?
不是必须的,但这种方式实用性很强:
- Statsmodels的优势是输出详细统计指标(p值、置信区间等),适合统计层面的变量显著性验证;
- Scikit-learn的优势是API简洁、集成交叉验证与调参工具,适合工程化部署与模型优化。
- 你可先用Statsmodels筛选显著变量,再将筛选后的数据集放入Scikit-learn训练模型;也可直接用Scikit-learn的正则化或特征选择工具完成筛选与建模。若需严格的统计显著性验证,优先用Statsmodels筛选;若更关注预测性能,直接用Scikit-learn的工具即可。
内容的提问来源于stack exchange,提问作者Lilly_Co
相关产品推荐
相关产品推荐

