
導入
こんにちは。株式会社HACARUS データサイエンティストの山下です。
HACARUSは業務で機械学習モデルを取り扱っており、様々な学習手法や解釈手法をブログで紹介しています。
前回の記事では、機械学習モデルの解釈手法であるPDP、 ICE plotや d-ICEという、どんなモデルにも適用できる解釈手法をご紹介しました。PDP, ICE plot では、各特徴量が予測に与える効果を簡単に可視化できる反面、特徴量間の相互作用がある場合には上手く機能せず、d-ICE を使用すると相互作用があるかどうかはわかりますが、具体的のどのような相互作用かどうかは分からないという弱点がありました。
そこで今回は、特徴量間の相互作用を自動で発見するためのモデリング手法である RuleFit を紹介します。
手法の説明
機械学習モデルの最も基本的なものの1つに、線形回帰モデルがあります。線形回帰では特徴量が予測に与える影響は線形であると考え、その影響を傾きと切片として求めることで、予測モデルを作成します。
線形回帰モデルはシンプルで解釈性が高い一方で、線形性や独立性といった仮定が多いため、非線形効果や特徴量間の相互作用がある場合などを考慮できません。
逆に特徴量間の相互作用を考慮できるモデルの1つに、決定木モデルがあります。決定木モデルでは、複数の特徴量を参照する決定規則によって相互作用を考慮できますが、データの線形性は考慮できません。そのため、特徴量の値が少し変わっても予測結果が変化しなかったり、ある値を超えると予測結果が急激に変化することもあり、本来予測結果が滑らかに変化するべきときには決定木は適切ではありません。
相互作用を含む線形モデルを作成する場合、一般的な方法としては相互作用項を人の直観で新たな特徴量として付け加える方法があります。では、この相互作用項を発見して追加するという作業は自動化できないのでしょうか。実は、今回紹介する RuleFit という手法は、決定木と線形モデルをうまく組み合わせることで、データから自動で相互作用を発見し、それを考慮した線形モデルを作ることができるのです。
詳しくは「Interpretable Machine Learning の RuleFitの章」をご覧ください。
HACARUSでは、Interpretable Machine Learning の和訳も公開しておりますので、日本語で読みたい方はこちらをご覧ください。
RuleFit では、まずはデータセットから決定木モデルを学習し、決定規則を作成します。そしてインスタンスに対し、得られた決定規則に基づく新たな特徴量を追加します。例えば、決定木が `身長 170cm 以上、かつ、体重 70kg 以下` という規則を学習したのであれば、インスタンスが条件を満たすなら `1`、そうでないなら `0` を持つように新たな特徴量を加えます。
この新しい特徴量を含めて線形回帰モデルを学習することで、相互作用を考慮した線形回帰を行うことができます。モデルの解釈性のことも考慮すると、決定木を学習する際は深さは 3 程度にすることが推奨されています。また、RuleFit で本質的に重要な相互作用かどうかを知るために、Lasso を用いて特徴量選択を行うことも有用です。それでは、この RuleFit を実際のデータに対して使用してみましょう。
利用例
Python では、「Interpretable Machine Learning」の著者が RuleFit を実装し、MIT ライセンスでパッケージを公開しています。今回はそのパッケージを用いて、実際にRuleFitを利用してみましょう。
ここで使用するコードは、Google Colab でも公開しているので、興味がある方はそちらもご覧ください。
まずはパッケージをインストールします。
pip install git+git://github.com/christophM/rulefit.git
ここで `pip install rulefit` としてしまうと、異なるパッケージをインストールしてしまうので注意が必要です。
次に、適当なデータセットを読み込みます。今回は scikit-learn のカリフォルニアの住宅価格データセットを使います。
from sklearn.datasets import fetch_california_housing
dataset = fetch_california_housing()
X = dataset.data
features=dataset.feature_names
y = dataset.target
データセットの中身も見ておきましょう。
import pandas as pd
pd.DataFrame(X, columns=features)
データセットにはインスタンスが 20640 個、特徴量が 8 個あるようです。特徴量の内容は以下のとおりです。インスタンスは個別の住宅ではなく、カリフォルニア内の地区であることに注意しましょう。
– MedInc:収入の中央値
– HouseAge:築年数の中央値
– AveRooms:部屋数の平均値
– AveBedrms:寝室数の平均値
– Population:人口
– AveOccup:住宅占有率の平均値
– Latitude:緯度
– Longitude:経度
目的変数は住宅の平均価格なので、今回の予測は回帰問題になります。このデータに対し、RuleFit の学習を行います。まずはモデルの引数を何も与えずに試してみましょう。
from sklearn.model_selection import train_test_split
from rulefit import RuleFit
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
rf = RuleFit()
rf.fit(X_train, y_train, feature_names=features)
学習したモデルを用いてテストデータに対して予測を行い、予測の性能を RMSE で評価します。
RuleFit の RMSE は `0.487` であり、線形回帰モデル(LassoCV)では `0.728`、決定木モデル(DecisionTreeRegressor)では `0.732` となりました。
RuleFit では、線形性と相互作用のどちらもを考慮できるため、線形回帰モデルや決定木よりも性能が改善されているようです。
次に、RuleFit で得られた相互作用について確認してみましょう。
rules = rf.get_rules()
rules = rules[rules.coef != 0].sort_values(by=”importance”, ascending=False)
#ruleが長すぎて表示が省略される場合用
pd.set_option(“display.max_colwidth”, 999)
rules.head(10)
`rule` は特徴量の名前で、`type` は特徴量の種類を表しており、`linear` なら元からデータセットに含まれていた特徴量、`rule` なら決定規則により新たに作られた特徴量を意味します。
`coef` は線形回帰モデルにおける重みであり、これが大きいほど、その特徴量が予測に与える影響が大きいと言えます。
`support` はその決定規則に該当するインスタンスの割合で、`linear` の特徴量では 1、`rule` の特徴量では 0 から 1 までの値となります。`importance` は特徴量重要度で、`coef` や `support` を基に算出されます。具体的な算出方法は「Interpretable Machine Learning」を参照してください。
`rule` の中身を見てみると、重複する条件があったり、閾値の桁数が多すぎたりして少し見づらいので、整理しておきます(詳細は、Python コード参照)。
重要とされた特徴量を見てみると、緯度と経度で細かく場合分けされており、結局それぞれの地区での価格を覚えて再現しているように見えます。デフォルト設定だと規則数の上限が `max_rules=2000` となっており、細かい規則を作りすぎてしまうようです。
「緯度と経度」という相互作用(組み合わせ)が意味を持つ特徴量を抽出できたのは良いことですが、相互作用項が多すぎるとモデルの解釈性が下がってしまうので、規則の数を 50 に絞ってみましょう。
rf = RuleFit(max_rules=50, random_state=0)
rf.fit(X, y, feature_names=features)
y_pred=rf.predict(X)
rules = rf.get_rules()
rules = rules[rules.coef != 0].sort_values(by=”importance”, ascending=False)
rules.rule = arrange_conditions(rules.rule, features, n_round=3)
rules.head(10)
相互作用項の数を減らしたところ、RMSE は `0.636` と多少大きくなりましたが、抽出された相互作用を見ると解釈がしやすくなっていることがわかります。
考察
重要とされた特徴量を、もう少し詳しく見てみます。
まず `type` が `linear` となっているものについては、単純な解釈ができます。その特徴量が増減することで、重み(`coef`)に応じて予測値も線形的に増減するため、`Latitude`, `Longitude`, `AveOccup` は住宅価格に負の影響を、`MedInc`, `HouseAge`, `AveBedrms` は正の影響を与えるというモデルになっています。
緯度と経度(`Latitude`, `Longitude`)についても、こうして見ると「南や西(カリフォルニアでは、海沿いの発展したエリア)の方が住宅価格が高い」という傾向として解釈できます。
収入(`MedInc`)が高いエリアでは住宅価格が上がるのも自然です。
次に、`type` が `rule` となっているものについて解釈していきます。ここでは `2.832 < MedInc <= 4.579 & AveOccup <= 2.04` について考えてみます。
`2.832 < MedInc <= 4.579 & AveOccup <= 2.04` の重み `0.333869` から、`2.832 < MedInc <= 4.579` かつ `AveOccup <= 2.04` の場合には、そうでないときと比較すると、住宅価格が `0.333869` 上昇すると言えます。図で書くと以下のような状況です。
収入が中程度の地域では、住宅占有率の低いエリアの方が住宅価格が高くなっています。これは、一般的に住宅の付近に駅や大型ショッピングモールなどがあると住宅の価格が上がる傾向にあるので、その特徴が RuleFit によって得られていると考えられます。
RuleFit の解釈方法は、線形回帰モデルや決定木と比べて少々複雑になりますが、相互作用をデータから発見してくれるため、人間のバイアスに囚われずに意外な発見ができる可能性があります。
まとめ
今回は、相互作用をデータから自動で発見できる RuleFit の紹介をしました。RuleFit では、線形性と相互作用の両方を兼ね備えており、モデルの解釈性も高い手法と言えます。
決定規則の数を増やせば予測性能は上がるかもしれませんが、解釈性とのトレードオフがあります。このバランスを自分で決められるのも RuleFit の魅力の1つかもしれません。