01 機器學習模型不可解釋的原因
前些天在同行交流群里,有個話題一直在群里熱烈地討論,那就是 如何解釋機器學習模型 ,因為在風控領域,一個模型如果不能得到很好的解釋一般都不會被通過的,在銀行里會特別的常見,所以大多數同行都是會用 LR 來建模。但是,機器學習的模型算法這么多,不用豈不是很浪費?而且有些算法還十分好用的,至少在效果上,如XGBoost、GBDT、Adaboost。
那么,有同學就會問了,為什么這些算法會沒有解釋性呢?其實是這樣子的,剛剛所說的那些模型都是一些集成模型,都是由復雜的樹結構去組成的模型,對於人類來說我們很難直觀地去解釋為什么這個客戶就是爛,到底是什么特征導致他爛?
02 特征重要度方法盤點
其實像XGBoost之類的模型還算是有解釋性的了,我們常常都會看到有人用信息增益、節點分裂數來衡量特征的重要度,但是這真的是合理的嗎?
在解釋是否合理前,有2個概念需要先給大家普及一下:
1)一致性
指的是一個模型的特征重要度,不會因為我們更改了某個特征,而改變其重要度。比如A模型的特征X1的重要度是10,那么如果我們在模型里給特征X2加些權重以增大其重要度,重新計算重要度后,特征X1的重要度仍是10。不一致性可能會導致具有重要度較大的特征比具有重要度較小的特征更不重要。
2)個體化
指的是重要度的計算是可以針對個體,而不需要整個數據集一起計算。
好了,有了上面的認識,下面就來盤點一下目前常見的特征重要度計算的方法:
1)Tree SHAP:即 shapley加法解釋,基於博弈論和局部解釋的統一思想,通過樹集成和加法方法激活shap值用於特征歸因。
2)Saabas:一種個性化啟發式特征歸因方法。
3)mean(| Tree SHAP |):基於個性化的啟發式SHAP平均的全局屬性方法。
4)Gain:即增益,由Breiman等人提出的一種全局的特征重要度計算方法,在XGBoost、scikit learn等包中都可以調用,它是給定特征在分裂中所帶來的不純度的減少值,經常會被用來做特征選擇。
5)Split Count:即分裂次數統計,指的是給定特征被用於分裂的次數(因為越重要的越容易被引用,和論文引用差不多一個道理吧)。
6)Permutation:即排序置換,指的是隨機排列某個特征,看下模型效果誤差的變化,如果特征重要的話,模型誤差會變化得特別大。
其中,屬於個體化的僅有1-2,3-6均屬於全局性統計,也就是說需要整個數據集進去計算的。
而對於一致性情況,我們有一個例子來證明:
有2個模型,Model A 和 Model B,其中A和B完全一致,但是我們在計算預測值的時候,強行給 Model B 的 特征 Cough 加上 10分。如下圖所示(點擊看大圖):
從實驗結果可以看出以上6種方法的差別:
1)Saabas、Gain、Split Count均不滿足 一致性 的要求,在改變了某個特征的權重之后,原先的特征重要度發生了改變,也直接導致重要度排序的改變。
2)而滿足一致性要求的方法只有 Tree SHAP 和 Permutation了,而Permutation又是全局的方法,因此就只剩下了 Tree SHAP了。
03 SHAP可能是出路,SHAP到底是什么
SHAP(Shapley Additive exPlanation)是解釋任何機器學習模型輸出的統一方法。SHAP將博弈論與局部解釋聯系起來,根據期望表示唯一可能的一致和局部精確的加性特征歸屬方法。
以上是官方的定義,乍一看不知所雲,可能還是要結合論文(Consistent Individualized Feature Attribution for Tree Ensembles)來看了。
Definition 2.1. Additive feature attribution methods have an explanation model g that is a linear function of binary variables
M是輸入特征的個數, ϕi’ 就是特征的貢獻度。ϕ0 是一個常數(指的是所有樣本的預測均值)。SHAP 值有唯一的解,也具有3個特性:Local Accuracy、Missingness、Consistency。
1)Local Accuracy:即局部准確性,表示每個特征的重要度之和等於整個Function的重要度
2)Missingness:即缺失性,表示缺失值對於特征的重要度沒有貢獻。
3)Consistency:即一致性,表示改變模型不會對特征的重要度造成改變。
簡單來說,SHAP值可能是唯一能夠滿足我們要求的方法,而我們上面講到的XGBoost、GBDT等都是樹模型,所以這里會用到 TREE SHAP。
04 SHAP的案例展示
0401 SHAP的安裝
安裝還是蠻簡單的,可以通過終端的pip安裝或者conda安裝
pip install shap
or
conda install -c conda-forge shap
0402 對樹集成模型進行解釋性展示
目前TREE SHAP可以支持的樹集成模型有XGBoost, LightGBM, CatBoost, and scikit-learn tree models,可以看看下面的demo:
import xgboost
import shap
# load JS visualization code to notebook
shap.initjs()
"""訓練 XGBoost 模型,SHAP里提供了相關數據集"""
X,y = shap.datasets.boston()
model = xgboost.train({"learning_rate": 0.01}, xgboost.DMatrix(X, label=y), 100)
"""
通過SHAP值來解釋預測值
(同樣的方法也適用於 LightGBM, CatBoost, and scikit-learn models)
"""
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
# 可視化解釋性 (use matplotlib=True to avoid Javascript)
shap.force_plot(explainer.expected_value, shap_values[0,:], X.iloc[0,:])
output:
上面的圖展示了每個特征的重要度,會預先計算好一個均值,將預測值變得更高的偏向於紅色這邊,反之藍色。
這個數據集有這些特征:'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT'
# visualize the training set predictions
shap.force_plot(explainer.expected_value, shap_values, X)
output:
上圖可以看出每個特征之間的相互作用(輸出圖是可以交互的)。
但是為了理解單個特性如何影響模型的輸出,我們可以將該特性的SHAP值與數據集中所有示例的特性值進行比較。由於SHAP值代表了模型輸出中的一個特性的變化,下面的圖代表了預測的房價隨着RM(一個區域中每棟房子的平均房間數)的變化而變化的情況。
單一RM值的垂直色散表示與其他特征的相互作用。要幫助揭示這些交互依賴關系,dependence_plot 自動選擇 另一個特征來着色。比如使用RAD着色,突顯了RM(每戶平均房數)對RAD的值較高地區的房價影響較小。
"""創建一個SHAP圖用於展示 單一特征在整個數據集的表現情況,每個點代表一個樣本"""
shap.dependence_plot("RM", shap_values, X)
output:
為了得到整體水平上每個特征的重要度情況,我們可以畫出所有特征對於所有sample的SHAP值,然后根據SHAP值之和來降序排序,顏色代表特征重要度(紅色代表高,藍色代表低),每個點代表一個樣本。
"""畫出所有特征的重要度排序圖"""
shap.summary_plot(shap_values, X)
output:
我們也可以只是顯示SHAP值的所有樣本的均值,畫出bar圖。
shap.summary_plot(shap_values, X, plot_type="bar")
output:
References
[1] A Unified Approach to Interpreting Model Predictions
http://papers.nips.cc/paper/7062-a-unified-approach-to-interpreting-model-predictions.pdf
[2] Consistent Individualized Feature Attribution for Tree Ensembles
https://arxiv.org/pdf/1802.03888.pdf
[3] Interpretable Machine Learning
https://christophm.github.io/interpretable-ml-book/
[4] shap 官方文檔
https://github.com/slundberg/shap
本文由博客一文多發平台 OpenWrite 發布!