如何使用sklearn计算单条预测结果的特征贡献权重
单条预测结果的特征贡献量化实现方案
针对单条样本的特征影响分析,不要使用模型训练输出的全局特征重要性——该值是全数据集的平均贡献,无法匹配单条预测的专属特征权重。最简洁的兼容方案是使用SHAP库,可直接对接所有sklearn模型,同时支持量化占比计算和可视化输出。
前置依赖安装
执行命令安装所需包:pip install shap pandas numpy matplotlib
可直接复用的示例代码
代码完全匹配你的数据集结构(3个取值1-5的数值特征、二分类预测结果),替换成你自己训练好的模型即可运行:
import pandas as pd import numpy as np from sklearn.ensemble import RandomForestClassifier import shap import matplotlib.pyplot as plt # ---------------------- 1. 模型训练部分(替换成你自己的训练逻辑即可) np.random.seed(42) # 构造和你字段一致的示例数据集 data = pd.DataFrame({ 'id': range(1000), 'X_1': np.random.randint(1,6,1000), 'X_2': np.random.randint(1,6,1000), 'X_3': np.random.randint(1,6,1000), 'result': np.random.randint(0,2,1000) # 二分类标签,对应"通过/未通过测试" }) X = data[['X_1','X_2','X_3']] y = data['result'] # 训练模型,可替换为你自己训练完成的model对象 model = RandomForestClassifier() model.fit(X, y) # ---------------------- 2. 单条样本[1,2,3]的特征贡献计算 # 树模型用TreeExplainer速度最快,非树模型(逻辑回归/SVM等)替换为shap.KernelExplainer(model, X.sample(100))即可 explainer = shap.TreeExplainer(model) target_sample = np.array([[1,2,3]]) # 你需要解释的预测样本 # 计算每个特征对当前样本的贡献值 shap_values = explainer.shap_values(target_sample) # 二分类场景取正类("通过测试"对应类别)的贡献值,回归任务直接取shap_values[0]即可 sample_shap = shap_values[1][0] if len(shap_values) == 2 else shap_values[0] # ---------------------- 3. 计算各特征贡献占比 total_contrib_abs = np.sum(np.abs(sample_shap)) contrib_result = pd.DataFrame({ '特征名': X.columns, '贡献值': np.round(sample_shap, 4), '贡献占比(%)': np.round(np.abs(sample_shap)/total_contrib_abs*100, 2) }).sort_values('贡献占比(%)', ascending=False) print("单条预测的特征贡献量化结果:") print(contrib_result) # ---------------------- 4. 可视化输出 plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决matplotlib中文显示乱码问题 # 力导向图:展示特征把预测结果从基准值推到最终值的作用方向和幅度 shap.force_plot( explainer.expected_value[1], sample_shap, target_sample, feature_names=X.columns, matplotlib=True, show=False ) plt.title("样本[1,2,3]预测结果的特征贡献力导向图") plt.show() # 柱状图:直观对比三个特征的贡献占比高低 plt.figure(figsize=(6,3)) plt.bar(contrib_result['特征名'], contrib_result['贡献占比(%)'], color=['#ff7f0e','#1f77b4','#2ca02c']) plt.ylabel('贡献占比(%)') plt.title('各特征对当前预测结果的贡献占比对比') plt.show()
结果说明
- 打印输出的贡献占比完全针对
model.predict([1,2,3])这条单预测结果计算,和全数据集的全局特征重要性无关 - 贡献值为正代表该特征将预测结果向"通过测试"的方向推动,为负代表将结果向"未通过"方向推动
- 柱状图可直接对比三个特征的影响大小,能直观看出X_1、X_2的贡献是否高于X_3
- 所有sklearn内置模型都可以用上述逻辑解释,仅需根据模型类型切换解释器初始化代码即可
内容的提问来源于stack exchange,提问作者Hammad Shahzad
相关产品推荐
相关产品推荐

