Python分类任务:如何按类别分别计算特征重要性
二分类场景下按类别维度计算特征重要性的落地方案
常规调用LogisticRegression、LGBMClassifier输出的都是全局特征重要性,会混合特征对两个类别的贡献,没法直接筛选单类别高显著性特征,以下三种方案都可以直接落地,分别拿到对正类、负类区分度高的特征:
- 基于SHAP值的单类别贡献统计(推荐)
这个方法适配所有常规模型,结果精度最高,不会出现贡献混淆的问题:- 模型训练完成后,计算全量样本的SHAP值,每个样本的每个特征都会得到一个具体的贡献数值,代表该特征把模型预测结果往某个类别推动的强度
- 将所有样本按真实标签拆分为正类、负类两个子集
- 对正类子集,计算每个特征的SHAP值均值:均值为正且绝对值越大,说明该特征对模型判定为正类的正向驱动作用越强,属于对正类显著性高的特征
- 对负类子集,同样计算每个特征的SHAP值均值:均值为负且绝对值越大,说明该特征对模型判定为负类的驱动作用越强,属于对负类显著性高的特征
核心代码参考:
拿到两个数组后直接按值排序,就能得到两个类别各自的高显著性特征列表。import shap # 前置条件:model为训练完成的二分类模型,X为特征矩阵,y为0/1二分类标签 explainer = shap.TreeExplainer(model) shap_values = explainer.shap_values(X) # 二分类场景下shap_values[1]存储所有样本对正类的贡献值 pos_feat_importance = shap_values[1][y == 1].mean(axis=0) # 正类样本各特征平均贡献 neg_feat_importance = shap_values[1][y == 0].mean(axis=0) # 负类样本各特征平均贡献 - 基于单类分布差异的统计检验
如果不需要绑定特定模型,想从数据本身的统计属性筛选特征,可以直接用分组检验的思路:- 对连续型特征,分别计算特征在单类样本中的分布和其余样本分布的差异,用KS检验、t检验都可以,p值越小、分布差异越大,说明特征对该类别的显著性越高
- 对类别型特征,用卡方检验计算特征取值和单类标签的关联强度,关联度越高说明特征对该类别的区分能力越强
这个方法完全不受模型训练偏差影响,结果可解释性更强,适合做特征初筛。
- One-vs-Rest拆分训练提取特征重要性(改造成本最低)
不需要引入额外工具包,基于你现在用的sklearn、lightgbm接口就能实现:- 第一次训练时把正类样本标记为1,负类样本标记为0,训练二分类器,直接读取模型的特征重要性(LR取模型系数、LightGBM取
feature_importances_),得到的就是特征对判定正类的贡献排序 - 第二次训练时把负类样本标记为1,正类样本标记为0,训练同结构的二分类器,读取到的特征重要性就是特征对判定负类的贡献排序
注意用LR的时候要关注系数符号:系数为正代表特征值越高,模型越倾向于将样本判为当前目标类,系数为负则相反。
- 第一次训练时把正类样本标记为1,负类样本标记为0,训练二分类器,直接读取模型的特征重要性(LR取模型系数、LightGBM取
避坑提示:不要直接用全局特征重要性拆分单类贡献。全局重要性会混合特征对两个类别的作用:比如某个特征同时对正类有强正向贡献、对负类有强负向贡献,全局重要性会给它打高分,但你没法区分它的作用偏向;如果某个特征只对负类有强区分度、对正类几乎无影响,全局重要性可能会低估它的作用,导致漏选。
内容的提问来源于stack exchange,提问作者Vitalii
相关产品推荐
相关产品推荐

