RandomForest
バギングで作成したデータから弱い決定木をたくさん作り、多数決で予測値を決める。
各木の作成は並列計算で作成できる
「ランダム」
- データセットがランダム : バギング
- 分岐時に使用する特徴量空間がランダムで絞られる : デフォルト値では、分類タスクでは$\sqrt N$個、回帰タスクでは$\frac{N}{3}$個の特徴量をランダムにサンプリングしてノード分割候補が作られる
※N:もとの全体データが持つ特徴量数(説明変数の種類数)、ユーザー指定可能なハイパーパラメータ
ランダム特徴量選択について:
(誤解:「1本の木モデルは$\sqrt{N}$個の特徴量のみ作成される」 ← この解釈は誤りなので注意)
ノード分割時に、$\sqrt{N}$個の特徴量が候補に挙がり、その中でジニ不純度を最も減らす特徴量で分岐が行われる。
1つの木の中には全特徴量が採用されており、ノード分割回数が∞回だと、確率収束的に全特徴量が同じ回数使われる。
まとめ:
- バギング(ブートストラップ)を使用したアンサンブル
- 各ノード分割時に、特徴量もランダムに少数選択される
- 並列計算可能
特徴量重要度 feature_importance
sklearnの場合、学習済みモデルには「model.feature_importances_」という量が作成されている。
これは各木で分割時に取得したジニ不純度(または、情報エントロピー。ランダムフォレストモデル作成時のメトリック(criterion)設定値に基づく)の値を、各説明変数にて合計したもの。
以下のページからイメージ拝借
https://qiita.com/haruki_yasui/items/a83428361fce6b6fbb42
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
model = RandomForestClassifier(n_estimators = 100, max_depth = 5)
model.fit(X = x_train, y = t_train)
labels = x_train.columns
importances = model.feature_importances_
plt.figure(figsize = (10,6))
plt.barh(y = range(len(importances)), width = importances)
plt.yticks(ticks = range(len(labels)), labels = labels)
plt.show()
ジニ不純度、分割時の情報ゲイン(分岐に依る不純度の減少量)の総和を、特徴量ごとに表示。
※特徴量がノードごとに(デフォルトで)$\sqrt{N}$個(or N/3個)に絞られたのちに分岐されるという特徴から、特徴量が使用される回数(候補回数)は平等でない。
沢山使われた特徴量が有利になる。
また、相関のある変数があると、この変数間でImportance値を分け合ったり、またはスケールの問題で一方のみ選択されるなどが起こり信頼できない値になり得る。
なのでPermutation Importanceの方が余計なことを考えなくていいかもしれない。
Permutation Importance:「特徴量が壊れたら困る度合」。特徴量(説明変数)内で、値をランダムシャッフル(特定の列に着目し、その行番号を入れ替える=無意味な特徴量になる。このとき、元の特徴量を使用した予測のスコアとシャッフル後の予測スコアの差を、Permutation Importanceとする。)
<参考>
決定木の可視化もできるが、あくまで1つの木のデータを表示するのみ。
以下ページから引用し、少し説明補足。
https://nuco.co.jp/blog/article/pUxZwJ5K
# 特徴量名とクラス名を定義
feature_names = [f'Feature {i+1}' for i in range(X_train.shape[1])]
feature_names = train_data.columns.tolist()
class_names = [str(i) for i in np.unique(y_train)]
# 最初の決定木を可視化
# max_depthでどのくらいの深さまで表示させるかを調整
plt.figure(figsize=(20, 10))
plot_tree(clf.estimators_[0],
filled=True,
feature_names=feature_names,
class_names=class_names,
rounded=True,
proportion=False,
precision=2,
max_depth=2)
plt.show()
- plot_tree : sklearnの関数。決定木の描画。matplotlibを使用して描画される
- clf.estimators_[0] : 決定木の1つをスライスして選択している(選択した1つの木に於ける決定木構造を表示する)


