見出し画像

機械学習を解釈する#01 PFI

 近年機械学習の研究と開発が進み、機械学習をはじめたばかりの方でも簡単に精度の高い予測モデルを構築できるようになりました。具体的にはニューラルネットワーク、勾配ブースティング決定木、ランダムフォレストなどです。しかし、これらの手法は精度が高い一方で、線形回帰モデルなどの従来の統計モデルと比べて解釈性が低いという欠点を持っています。
 そこで、今回は上記のモデルでも適用できる【特徴量の重要度を知る技術】について、紹介します!

なぜ特徴量の重要度を知る必要があるのか

 技術の説明に入る前に、そもそも特徴量の重要度を知る必要性について少し触れます。 
 モデルに予測をかけた時に、「精度さえ出ればいい!予測した理由はどうでもいい!」というシチュエーションはあまりなく、特に実務では予測した理由を説明する必要があるかと思います(多分...)。そのほかにも特徴量の重要度を知ることで、具体的に以下の恩恵が得られます。
・特徴量の重要度がドメイン知識に沿っているかを確認することで、モデルのデバッグが行える。
・重要度の高い特徴量を特定することで、その特徴量に介入を加えKPI改善に貢献できる。

Permutation Feature Importance(PFI)とは

 ようやくですが、ここから技術の説明に入ります。PFIは、予測誤差の増加分から特徴量の重要度を知る代表的な手法です。具体的には特徴量の値をシャッフルすることで、その特徴量の情報を【使えない】状態を作り出し、精度を比較するというものです。

画像1

 図を見れば直感的にもイメージできると思います。行っていることは要するに【重要度が知りたい特徴量の情報を有り無しで比較する】それだけです。そしてPFIが比較しているのはあくまで精度なので、どんな機械学習モデルにも適用できるというのが嬉しい点です。

 具体例として3つの特徴量(a, b, c)を用いて学習した機械学習モデルを考え、特徴量aについてPFIを計算する手順は以下の通りです。
①:3つの特徴量(a, b, c)を用いて学習させたモデルを用意し、テストデータで予測誤差を出す。これをベースラインとする。
②:テストデータの特徴量aの値のみをシャッフルし、①と同じ学習済みモデルをを用いてシャッフル済みデータに対して予想を行い、予測誤差を計算する。
③:②の予測誤差と①のベースラインの予測誤差を比較する。予測誤差の増加率または差分を計算し、この大きさを特徴量重要度とする。
④:②と③の手順を特徴量b, cに対しても同様に行う。
⑤:全ての特徴量の特徴量重要度が計算できたら、重要度の大きさを比較し、どの特徴量が重要なのかを確認する。

 すごくシンプルな考えですね。実際、ある特徴量がすごく重要だった場合、その特徴量をシャッフルするとモデルは的外れな予測値を出すでしょう。

PFIの実装

 では、実際にPFIを実装して特徴量の重要度を見てみましょう。今回はscikit-learnに用意されてあるボストン市の住宅価格データセットを使用します。データセットの詳細についてはscikit-learnに付属しているデータセットを参照してください。モデルはランダムフォレストを使います。

# ライブラリのインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.inspection import permutation_importance
from sklearn.ensemble import RandomForestRegressor
boston = load_boston()
df = pd.concat([pd.DataFrame(data=boston.data, columns=boston.feature_names), pd.Series(data=boston.target, name='y')], axis=1)
画像2
# 学習用データとテスト用データを作成
X = df[df.columns[df.columns != 'y']]
y = df['y']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# ベースラインモデルの作成
rf = RandomForestRegressor(random_state=0).fit(X_train, y_train)

念の為、決定係数を見ておきましょう

from sklearn.metrics import r2_score
r2_score(y_test, rf.predict(X_test)) # 0.7952684623500126

ベースラインができたので、PFIを計算します。

# PFIの計算
pfi = permutation_importance(
   estimator = rf,
   X = X_test,
   y = y_test,
   scoring = 'neg_root_mean_squared_error', # 評価指標はRMSEを指定
   n_repeats = 5, # シャッフルの回数
   n_jobs = 1,
   random_state = 0
)
# 計算したPFIをデータフレームで降順表示
df_pfi = pd.DataFrame(
   data={'var_name': X_test.columns, 'importance': pfi['importances_mean']}).sort_values('importance', ascending=False)
画像3
# 計算したPFIを昇順で定義し直し
df_pfi = pd.DataFrame(
   data={'var_name': X_test.columns, 'importance': pfi['importances_mean']}).sort_values('importance')

# 可視化
plt.figure(figsize=(10, 6))
plt.barh(df_pfi['var_name'], df_pfi['importance'])
plt.title('Permutation difference', fontsize=20)
plt.xlabel('defference', fontsize=12)
plt.grid()
plt.show()
画像4

グラフを見てみると特に重要な特徴量が2つあり、1つは地域の低所得者の割合である【LSTAT】、もう1つは平均的な部屋の数である【RM】だとわかりました。

まとめ

 PFIを用いることで、任意のブラックボックスモデルに対して、特徴量の重要度という解釈性を与えることができました。
 PFIはモデルがどの特徴量の影響を強く受けているかをマクロ的な観点で解釈することができ、概観をつかむには便利です。ただ【重要度】という観点でしか解釈することができず、その特徴量の値が大きくなれば予測値は大きくなるのか小さくなるのか、また変化の傾向は線形なのか非線形なのかは把握することができません。
 次回は、PFIでは解決できない特徴量と予測値の関係を知る目的によく適した解釈手法であるPartial Dependence(PD)について紹介します!


この記事が気に入ったらサポートをしてみませんか?