如何在Scikit-learn逻辑回归Pipeline中查看单样本预测的特征影响?
单样本特征贡献拆解实现方法(适配你现有逻辑回归Pipeline)
你目前已经完成了带标准化步骤的逻辑回归Pipeline搭建、全局特征重要性可视化,要实现单样本层面的输入影响分析,本质是将每个样本的预测过程拆解为各特征的独立贡献分量,可基于现有训练好的Pipeline直接计算,不需要重新拟合模型。
核心实现逻辑
逻辑回归的预测本质是线性计算过程:
样本的最终logit得分 = 模型截距 + Σ( 标准化后的样本特征值 × 模型对应特征系数 )
最终正类预测概率 = sigmoid(上述logit得分)
单样本的特征贡献,就是把上述求和过程拆解开——每个特征对应的「标准化值 × 模型系数」,就是这个特征对当前样本logit得分的具体影响值,所有特征贡献加总后加截距,就是这个样本的完整预测分。
可直接复用的代码(和你现有Pipeline完全兼容)
第一步:提取Pipeline内已训练完成的组件
# 从已训练的Pipeline中取出对应步骤的对象,无需重新拟合 scaler_step = pipeline.named_steps['standardscaler'] logit_model_step = pipeline.named_steps['logisticregressioncv'] # 对测试集执行和训练时完全一致的标准化操作,避免数据泄露 X_test_scaled = scaler_step.transform(X_test) # 计算逐样本逐特征的贡献值:和X_test_scaled维度完全对齐 # 每行对应1个测试样本,每列对应该样本在对应特征上的贡献大小 sample_feat_contrib = X_test_scaled * logit_model_step.coef_[0] # 转为带特征名、样本索引的DataFrame,方便后续查看 sample_contrib_df = pd.DataFrame( sample_feat_contrib, columns=X_train.columns, index=X_test.index ) # 提取模型截距,用于后续核对计算结果 model_intercept = logit_model_step.intercept_[0]
第二步:筛选低预测概率样本并逐一生成贡献可视化
匹配你“单独分析预测值偏低样本组”的需求,可按如下逻辑筛选概率最低的10个样本,逐个查看每个特征的影响:
import numpy as np # 拿到所有测试样本的正类预测概率 y_pred_proba = pipeline.predict_proba(X_test)[:, 1] # 按预测概率从小到大排序,取排名前10的低概率样本索引 low_prob_sample_index = np.argsort(y_pred_proba)[:10] # 遍历每个低概率样本,生成单独的特征贡献图 for sample_pos in low_prob_sample_index: sample_idx = X_test.index[sample_pos] # 取出当前样本的所有特征贡献,按数值从小到大排序 current_contrib = sample_contrib_df.loc[sample_idx].sort_values() plt.figure(figsize=(8, 6)) # 贡献为正(拉高正类预测)的用红色,贡献为负(拉低正类预测)的用蓝色 bar_colors = ['#d62728' if val > 0 else '#1f77b4' for val in current_contrib.values] current_contrib.plot.barh(color=bar_colors) # 绘制截距参考线,直观展示基准分位置 plt.axvline( x=model_intercept, linestyle='--', color='grey', label=f'模型基准截距值: {model_intercept:.2f}' ) plt.title( f'样本{sample_idx}的预测特征贡献\n' f'最终正类预测概率: {y_pred_proba[sample_pos]:.3f}' ) plt.xlabel('对logit得分的贡献值(数值越大,越会推高正类预测概率)') plt.legend() plt.tight_layout() plt.show()
结果说明
- 横向条形长度对应该特征对当前样本预测的影响大小:距离0点越远,影响越强
- 条形方向对应影响方向:条形在0点右侧(正贡献)代表这个特征推高了该样本的正类预测概率;在0点左侧(负贡献)代表这个特征拉低了该样本的正类预测概率
- 和你之前画的全局系数图的核心区别:全局系数是固定的特征权重,代表特征整体对模型的影响方向;单样本贡献是「固定权重 × 当前样本在该特征上的实际取值」,同一个特征权重,在不同样本上的贡献方向、大小都可能存在差异
校验说明
可以随便抽一个样本做核对:把该样本的所有特征贡献值加总,再加上模型截距,得到的结果和pipeline.decision_function(X_test)返回的logit得分完全一致,不存在计算偏差。
这种计算方式和线性模型的SHAP贡献值结果完全等价,不需要额外安装第三方依赖就能实现。
内容的提问来源于stack exchange,提问作者ekselan
相关产品推荐
相关产品推荐

