ysaz (ImanazaS) blog

最近はデータ分析や機械学習が中心。たまに音楽や書評。

機械学習モデルによる予測結果の解釈(Shap値の使い方)

なぜ予測結果の解釈が必要か

機械学習というか広義のAIは、予測や認識を高い精度で実施することは得意です。
しかし、その演算過程がブラックボックスになりがちで、人間がその結果の背景にある根拠や判断理由を理解することが困難という課題が存在します。

いくら予測精度が高くても、人間がその結果をどう解釈し、どう次のアクションにつなげていけば良いかがわからなければ、人間がAIを使いこなすことはできないでしょう。

Shap値を使えば何がわかるか

そもそも機械学習モデルとは、目的変数を特徴量(学習の入力に使う測定可能な特性)データで予測することで成り立っています。
そのため特徴量が予測結果に大きな影響を与えるはずで、どの特徴量がどのように結果へ影響したかを示すことは、極めて重要です。

ちなみにXGBoostやlightGBMにもFeature Importanceという特徴量の算出ができるメソッドが備わっており、どの特徴量がモデルの予測結果へ寄与しているかを出力することはできるのですが、効いている方向がプラスなのかマイナスなのかがわからないという課題があります。

今回取り扱うShap(SHapley Additive exPlanationsの略)値とは、まさに各特徴量が予測結果にどのような影響を与えたかを、正負の方向を含めて、定量的に示すものを指します。*1*2

Shap値計算の実行例

pipでインストールしたら、ライブラリを読み込むことで使用可能です。

import shap

# Jupyterで表示させるために、JSを読み込む
shap.initjs()

まずは必要なデータセットを読み込み、XGBoost, LightGBM, CatBoost等の勾配ブースティングモデルで学習させます。
次にTreeExplainerという勾配ブースティング用のインスタンスを使って学習したモデルを読み込み、特徴量データからShap値を計算します。

model = xgboost.train({"learning_rate": 0.01}, xgboost.DMatrix(X, label=y), 100)

explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)

特徴量の貢献度を可視化

用いるデータセットは面白そうなものであれば何でも良いのですが、ここではKaggleで公開されている以下の2018 FIFAワールドカップ ロシア大会のデータセットを使います。
www.kaggle.com

一試合における選手のプレーデータ(得点数、ボール保持率、反則の数等)から、その選手が試合の最優秀選手となったかどうかを予測(結果を0〜1のレンジで提示)するものです。

summary_plot

まずはsummary_plotを使って特徴量全体の寄与度を示します。

shap.summary_plot(shap_values, X)

上から貢献度の高い順に並んでおり、Goal Scored(得点ゴール数)、Off-Target(ゴールから外れたシュートの数)、Corners(コーナーキックの数)がトップ3です。
横軸はShap値と目的変数への貢献度です。

少し複雑ですが、赤色、青色で特徴量の大小が表現されており、例えばGoal Scoredで見ると、赤色は得点が多いことを示しており、赤色の分布がShap値プラス(右)寄りとなっているため、目的変数と正の相関(得点数が多いと最優秀選手になりやすい)があると言えます。
反対に、青色は得点が少ないことを示しており、青色の分布がShap値マイナス(左)寄りとなっているため、目的変数とは負の相関(得点が少ないと最優秀選手になりにくい)があります。

f:id:nami3373:20191102215612p:plain

force_plot

force_plotを使うと、サンプルごとの特徴量の貢献度を可視化することができるので、先程計算したShap値から一番はじめのサンプルを可視化すると以下のようになります。

shap.force_plot(explainer.expected_value, shap_values[0,:], X.iloc[0,:])

スコアは0.76であり、正解ラベル最優秀選手のサンプルですが、得点数=5、コーナーキック=6というのがスコアの押し上げに効いているのがとても良くわかる例と言えます。
f:id:nami3373:20191102215245p:plain


次は全データにforce_plotを適用した例です。

shap.force_plot(explainer.expected_value, shap_values, X)

左から右に全128サンプルを予測スコアの高い順に並べ替えた結果が以下の図になります。
予測スコア結果に対して、特にGoal Scoredの寄与度が大きいことが、その面積の大きさに表されていると言えます。
なお、赤色と青色のちょうど狭間に引かれている白い線が、予測スコアに該当します。

左端から70番目くらいまでのサンプル(スコアが0.5〜0.8)は赤いGoal Scored部分の面積が目立っており、得点が高いため予測スコアが高くなっている選手が多いと推測できます。
一方、70番目から128番目までのサンプル(スコアが0.2〜0.5)は青いGoal Scored部分の面積が目立っており、先ほどとは反対に、得点が低いことが予測スコアに影響していると考えられます。

f:id:nami3373:20191102222924p:plain

まとめ

このように目的変数と特徴量との相関関係を可視化して明らかにすることで、機械学習モデルに対する理解を一層深めることができます。
解釈結果を新たな特徴量づくりに活かして、さらなるモデル精度向上を狙うこともできますし、ビジネスシーンでは、何かしらの打ち手につながるきっかけにすることもできます。