使用eli5提取XGBoost特征重要性全为正,如何区分对响应变量的正负影响
为什么eli5输出的XGBoost特征重要性全为正值
你看到的全正结果是特征重要性的计算逻辑决定的:eli5默认输出的XGBoost特征重要性,本质是特征在所有树节点分割时带来的增益总和/出现频次/样本覆盖量,只衡量特征对模型降低预测损失的贡献幅度,不反映特征和响应变量的作用方向,所以天然没有负值。
区分特征正负向作用的可行方法
- 单样本预测解释法:直接调用eli5的单样本解释接口
eli5.show_prediction(),可以输出单个样本上每个特征对最终预测结果的拉动方向,输出项前的正号代表该特征推高了当前样本的预测值,负号代表压低了预测值。如果需要得到全局的平均方向,可批量统计所有测试样本上每个特征的作用方向均值即可。示例调用代码:# 解释测试集第一个样本的预测逻辑 eli5.show_prediction(xgb_model, X_test.iloc[0], feature_names=your_feature_names) - 部分依赖图(PDP)法:绘制单个特征和模型预测值的部分依赖曲线,可直观看到特征取值变化时预测值的整体变化趋势:曲线整体随特征取值上升而升高,代表特征整体为正向作用;反之则为负向作用,同时还能观测到非线性作用规律。可直接调用Sklearn的内置工具实现,示例调用代码:
from sklearn.inspection import PartialDependenceDisplay # 绘制前3个特征的部分依赖图 PartialDependenceDisplay.from_estimator(xgb_model, X=X_train, features=[0,1,2], feature_names=your_feature_names) - SHAP值法:SHAP值本身自带方向属性,正值代表特征推高了预测结果,负值代表压低了预测结果,同时还能对应特征的贡献幅度。对所有样本的单个特征SHAP值取平均,结果为正则该特征整体呈正向作用,为负则整体呈负向作用。XGBoost支持原生输出SHAP值,也可以通过shap包计算,示例调用代码:
import shap explainer = shap.TreeExplainer(xgb_model) shap_values = explainer.shap_values(X_test) # 计算单个特征的全局平均作用方向 feature_0_avg_shap = shap_values[:,0].mean() - 相关系数参考法:如果是线性关系较强的场景,可以直接计算特征和响应变量的皮尔逊相关系数,系数为正代表线性正相关,为负代表线性负相关,该方法只能作为初步参考,无法反映模型学到的非线性作用规律。
内容的提问来源于stack exchange,提问作者Sandro
相关产品推荐
相关产品推荐

