01机器学习模型无法解释的原因前几天在同行交流群里,有一个话题在群里讨论的很热烈,也就是机器学习模型怎么解释,因为在风控领域,如果一个模型不能很好的解释,一般是不会通过的,尤其是在银行,所以大部分同行都会用LR模拟。但是,机器学习的模型算法那么多,不去用岂不是很浪费?而且有些算法非常好用,至少从效果上来说是这样,比如XGBoost、GBDT、Adaboost。那么,有同学会问,为什么这些算法没有解释性呢?事实上,它是这样的。刚才说的模型是一些集成的模型,都是由复杂的树结构组成的。对于人类来说,我们很难直观地解释这个客户为什么不好,到底是什么?特性让他烂?02特征重要性方法盘点其实像XGBoost这样的模型还是有解释性的。我们经常看到人们用信息增益和节点分裂数来衡量特征的重要性,但这真的合理吗?在解释是否合理之前,有两个概念需要先普及一下:1)一致性是指一个模型的特征重要性,它不会因为我们改变某个特征而改变它的重要性。例如,模型A的特征X1的重要性为10,那么如果我们在模型中对特征X2增加一些权重来增加其重要性,重新计算重要性后,特征X1的重要性仍然为10。不一致可能会导致特征与与重要性较低的特征相比,重要性更高的特征更不重要。2)个体化是指可以针对个体进行重要性的计算,而不需要将整个数据集一起计算。好了,有了上面的理解,我们来看看目前常见的特征重要性计算方法:1)TreeSHAP:即Shapley加法解释,基于博弈论和局部解释的统一思想,通过树积分和加法Activationshapvalues用于特征归属。2)Saabas:一种个性化的启发式特征归因方法。3)mean(|TreeSHAP|):一种基于个性化启发式SHAP平均的全局属性方法。4)Gain:Gain,Breiman等人提出的全局特征重要性计算方法,可在XGBoost、scikitlearn等包中调用。它是分裂中给定特征的杂质。缩减值通常用于特征选择。5)SplitCount:分裂次数,指的是给定特征被用于分裂的次数(因为越重要越容易被引用,和论文引用差不多)。6)Permutation:即排序排列,是指随机排列某个特征,看模型效果误差的变化。如果特征很重要,模型误差会变化特别大。其中只有1-2属于individualization,3-6属于globalstatistics,也就是说需要整个数据集来计算。至于一致性的情况,我们有一个例子来证明:有2个模型,模型A和模型B,其中A和B是完全一致的,但是我们在计算预测值的时候,强行加入了模型B的Cough这个特征10分。如下图(点击放大):从实验结果可以看出以上六种方法的区别:1)Saabas、Gain、SplitCount不满足一致性要求。改变一个特征的权重后,原来的特征重要性发生了变化,直接导致了重要性排序的变化。2)满足一致性要求的方法只有TreeSHAP和Permutation,Permutation是全局方法,所以只剩下TreeSHAP。03SHAP可能是出路,究竟什么是SHAPSHAP(ShapleyAdditiveexPlanation)是解释任何机器学习模型输出的统一方法。SHAP将博弈论与局部解释联系起来,根据期望表达唯一可能的一致且局部准确的加性特征分配方法。以上是官方定义。初看不明。还是可以结合论文(ConsistentIndividualizedFeatureAttributionforTreeEnsembles)。定义2.1。加性特征归因方法有一个解释模型g,它是二元变量的线性函数M是输入特征的数量,?i'是特征的贡献。φ0是一个常数(指所有样本的预测均值)。SHAP值具有唯一解,同时具有三个特征:LocalAccuracy、Missingness和Consistency。1)LocalAccuracy:局部精度,表示每个特征的重要性之和等于整个Function的重要性2)Missingness:缺失,表示缺失值对特征的重要性没有贡献。3)Consistency:一致性,即改变模型不会改变特征的重要性。总之,SHAP值可能是唯一能满足我们要求的方法,而我们上面提到的XGBoost和GBDT都是树模型,所以这里会用到TREESHAP。04SHAP案例显示0401SHAP的安装非常简单。可以通过终端pip安装或者conda安装pipinstallshaporcondainstall-cconda-forgeshap0402来讲解树集成模型。目前TREESHAP支持的树集成模型包括XGBoost和LightGBM、CatBoost以及scikit-learn树模型,可以看看下面的demo:importxgboostimportshap#loadJSvisualizationcodetonotebookshap.initjs()"""训练XGBoost模型,以及SHAP"""X,y=shap.datasets.boston()model=xgboost.train({"learning_rate":0.01},xgboost.DMatrix(X,label=y),100)"""中提供了相关数据集通过SHAP值解释预测值(同样的方法也适用于LightGBM、CatBoost和scikit-learnmodels)"""explainer=shap.TreeExplainer(model)shap_values=explainer.shap_values(X)#Visualinterpretation(usematplotlib=TruetoavoidJavascript)shap.force_plot(explainer.expected_value,shap_values[0,:],X.iloc[0,:])输出:上图显示了每个特征的重要性,会提前计算一个均值,预测值向红色一侧会变高,反之亦然。此数据集具有以下功能:'CRIM'、'ZN'、'INDUS'、'CHAS'、'NOX'、'RM'、'AGE'、'DIS'、'RAD'、'TAX'、'PTRATIO'、'B','LSTAT'#visualizethetrainingsetpredictionsshap.force_plot(explainer.expected_value,shap_values,X)输出:上图展示了各个特征之间的交互(输出图是交互的)。但为了了解单个特征如何影响模型的输出,我们可以将该特征的SHAP值与数据集中所有示例的特征值进行比较。由于SHAP值表示模型输出中属性的变化,下图表示预测房价如何随着RM(一个地区每间房屋的平均房间数)的变化而变化。单个RM值的垂直分散表示与其他特征的相互作用。为了帮助揭示这些交互依赖关系,dependency_plot会自动选择另一个要着色的特征。例如,RAD着色用于突出显示RM(每户平均房间数)在RAD值较高的地区对房价的影响较小。"""创建SHAP图展示单个特征在整个数据集中的表现,每个点代表一个样本"""shap.dependence_plot("RM",shap_values,X)输出:为了得到整体水平对于每个特征的重要性,我们可以绘制出所有特征对所有样本的SHAP值,然后根据SHAP值之和进行降序排序。颜色代表特征重要性(红色代表高,蓝色代表低),每个点代表一个样本。"""绘制所有特征的重要性排序图"""shap.summary_plot(shap_values,X)输出:我们也可以只显示SHAP值的所有样本的均值,并绘制条形图。shap.summary_plot(shap_values,X,plot_type="bar")输出:参考文献[1]解释模型预测的统一方法http://papers.nips.cc/paper/7...[2]TreeEnsembles的一致个性化特征属性https://arxiv.org/pdf/1802.03...[3]可解释的机器学习https://christophm.github.io/...[4]shap官方文档https://github.com/slundberg/。..本文由博客多发平台OpenWrite发布!
