こんばんは。座禅いぬです。今XAI(explainable AI:説明可能性の高いAI)についていろいろ調べているのですが、XAIの概念を理解するときに出てくるわけわからん数字の一つがSHAP値です。こちらはなんとか簡単にわかるようにできないか調べた、自分用メモです。
まずそもそもシャープレイ値というものがあります。「みんなが一緒に成果を出したとき、各メンバーの“貢献度”をどうやって公平に分配するか」を考えるための方法として考え出されたようです。ゲーム理論の文脈で生まれましたが、機械学習やってると特徴量の貢献度知りたいよね?ということで生まれたのがSHAPというpythonライブラリ、およびその値を指してSHAP値とかよく呼んでるみたいです。
じゃあシャープレイ値ってなんや?
わかりやすい例:友だちと協力してお菓子作りをする
シチュエーション
友だち4人(Aさん, Bさん, Cさん, Dさん)が集まってクッキーを作ることにしました。
おいしいクッキーができたら、それをみんなで山分けしたい!
でも、材料を持ち寄った人、道具を用意した人、レシピを考えた人、実際に動いた人…それぞれ貢献度が違いますよね。
そこで「誰がどのくらいクッキー作りに貢献したか」を定量的に評価し、クッキーを公平に分ける(あるいは「ご褒美」をわける)にはどうしたらいいでしょうか?
「貢献度」を測るむずかしさ
たとえば「小麦粉を用意したAさん」がいないと、クッキーは作れないから重要そう。
でも実はBさんが同じ小麦粉を用意できたかもしれないので、Aさんだけが絶対に必要とは言い切れないかも…。CさんのレシピやDさんのオーブンだって、どれもないとクッキーは完成しないし…。
みんなそれぞれがどのくらい「必要」だったのかを数字であらわすのは意外と大変ですよね。
シャープレイ値の考え方
そこでシャープレイ値の登場です。「みんなが集まるとどれだけ成果が出るか」をベースにして、それぞれが加わることで成果がどのくらい増えたかを元に計算します。
1. 全員が協力したときの成果を把握する
→ クッキーの合計価値をたとえば「10枚分のクッキー」とします。
2. メンバーが参加する「順番」を全部考える
「A→B→C→Dの順で集まったらどうなる?」「B→A→D→Cなら?」「D→C→B→Aなら?」…というふうに、全員が参加するまでの順番の組み合わせをすべて網羅します(4人なら4!=24通り)。
この「順番」というのがポイントで、誰がいつ参加したかで「すでにいた人たち+新しく加わる人」がもたらす“追加の”成果を計算するためです。
3. 各メンバーが「自分の番が来たとき、どれだけ成果を上乗せしたか」をそれぞれの順番で計算する
たとえばある順番で、「Aが最初にいたときの成果(0枚分)にAが貢献してクッキーの土台ができたから2枚分になった」とか、「Cが3番目に加わったとき、それまでは4枚分しか作れなかったところをCのおかげでレシピが整って+3枚分増えて7枚分になった」とか、そうやって「追加」がどれくらいあったかを全員分で記録していきます。
4. 「追加の成果」を全ての順番で平均する
24通りすべてのシナリオを考慮した上で、Aさんがどれだけ貢献したのか、Bさんがどれだけ貢献したのか…を平均して出します。これを「シャープレイ値」と呼びます。
言いかえると、誰がいつ来ても同じ評価になるように不公平がない計算方法になっているわけです。こうすると、「人数が異なる集まりすべてを考慮しても、最終的に誰がどのくらい貢献したか」を公平に測ることができます。
概念のポイント
全ての参加順序を考慮する
ただ「Aがいなかったらどうなるか」「Bがいなかったらどうなるか」だけでなく、どのタイミングで誰が入ったかという場合分けをすべて行うので、ちょっと計算は大変です。しかし、これによって「Aがいないとそもそも何もできなかった」「Bが先にいなくてもCが代わりをしたかもしれない」などのケースごとに評価できるのが強みです。
平均を取ることで「誰かだけが得をしない」仕組み
ある順番で見ると、Aの貢献は大きく見えてBの貢献が小さいかもしれない。
でも、別の順番だとBがいなければ成り立たない場面があったかもしれない。
そうした状況を全部ならして評価するので、公平感が出ます。
チーム全体の成果の合計が、各個人のシャープレイ値を足した値とちょうど一致する
つまり
Aさんのシャープレイ値 + Bさんのシャープレイ値 + Cさんのシャープレイ値 + Dさんのシャープレイ値 = 全体の成果
「貢献の割り当て」なので、トータルが上回ったり下回ったりしないように、ぴったり配分されます。
機械学習における使い方 (かんたんに)
機械学習のモデルで「なぜこの予測が出たの?」を説明したいときがあります。
例:AIが「この人は将来、ある病気になる確率が高い」という予測を出したとき、どの入力情報(年齢、体重、血圧など)がその予測にどれくらい影響したのか?
シャープレイ値の考え方を使ってみましょう!
「年齢のデータを加えたら、どれだけ予測結果に差が出た?」 「血圧のデータが新しく加わったら、どのくらい精度(または確信度)が上がった?」…というふうに、一つひとつの特徴(入力データの要素)が持つ“追加貢献”の平均を出します。
これが「特徴量(要素)ごとのシャープレイ値」となり、「どれだけ予測モデルに影響を与えたか」を見える化するわけです。
なんか計算めちゃくちゃ大変そうですよね。そこで登場するのがPythonライブラリのSHAP!計算から図による可視化までできちゃうので、よく用いられています。ただやっぱり計算量が多いので重い。そこで軽量化のため計算方法を変えるなどの工夫をしています。
なので、正確にはシャープレイ値ではなく近似値を求めているそうです。ちょっと混乱しやすい部分ですが、「まあだいたい同じやん?」でよさそうですね。
まとめ
シャープレイ値は「チームプレイで成果を出したとき、それぞれのメンバー(もしくは要素)がどのくらい貢献したか」を公平に計算するために、「いろんな順番や組み合わせを総合的に見て、それぞれがもたらす追加の価値をきちんと評価し、最終的にその貢献をみんなに割り振ろう」という考え方です。
それを応用し、機械学習の特徴量の寄与度を計算します。図による可視化を含めた便利なPythonライブラリがSHAP。そこで使われているシャープレイ値とだいたい同じノリのやつがSHAP値!あーよかったすっきりした。間違ってる部分あったらご指摘お願いします!