メインコンテンツへスキップ

5.2.5 アンサンブル学習:Forest、Boosting、Stacking

Bagging と Boosting の比較図

アンサンブル学習は複数のモデルを組み合わせ、1つのモデルの弱点が最終予測を支配しにくくします。表形式データでは、古典的機械学習の中でも特に強い手法群です。

まず二つの主線を見る

アンサンブル学習ファミリー漫画

最初からモデル名を暗記しないでください。まず二つの考え方を分けます。

ルートイメージ代表モデル主な利点主なリスク
Bagging複数モデルを並列に学習して投票Random Forest安定し、分散を下げる大きくなり、説明しづらい
Boosting後続モデルが前の誤りを補正GBDT、XGBoost、LightGBM、CatBoost精度が強い制御しないと過学習しやすい
Stacking基本モデルの予測をメタモデルへ渡すStackingClassifier異なるモデル群を組み合わせる交差検証なしだとリークする

比較実験を動かす

ch05_ensemble_lab.py を作成します。

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier, StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, f1_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier

data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
data.data,
data.target,
test_size=0.25,
random_state=42,
stratify=data.target,
)

models = {
"single_tree": DecisionTreeClassifier(max_depth=4, random_state=42),
"random_forest": RandomForestClassifier(
n_estimators=200,
max_depth=6,
random_state=42,
),
"gradient_boost": GradientBoostingClassifier(
n_estimators=120,
learning_rate=0.05,
max_depth=2,
random_state=42,
),
}

models["stacking_cv"] = StackingClassifier(
estimators=[
("rf", models["random_forest"]),
("gb", models["gradient_boost"]),
("lr", make_pipeline(
StandardScaler(),
LogisticRegression(max_iter=2000, random_state=42),
)),
],
final_estimator=LogisticRegression(max_iter=2000, random_state=42),
cv=5,
)

for name, model in models.items():
model.fit(X_train, y_train)
pred = model.predict(X_test)
print(f"{name:<15} accuracy={accuracy_score(y_test, pred):.3f} f1={f1_score(y_test, pred):.3f}")

rf = models["random_forest"]
importances = rf.feature_importances_
top = importances.argsort()[-3:][::-1]
print("top_rf_features=")
for idx in top:
print(f"- {data.feature_names[idx]}: {importances[idx]:.3f}")

実行します。

python ch05_ensemble_lab.py

期待される出力:

single_tree     accuracy=0.944 f1=0.956
random_forest accuracy=0.958 f1=0.967
gradient_boost accuracy=0.944 f1=0.956
stacking_cv accuracy=0.986 f1=0.989
top_rf_features=
- worst perimeter: 0.146
- worst area: 0.140
- worst concave points: 0.109

アンサンブル学習実験結果図

sklearn のバージョンによりスコアが少し変わることがあります。比較表と重要特徴量をプロジェクト証拠として残します。

結果を読む

単一木は baseline です。Random Forest は多くの異なる木を平均するため、たいてい安定します。

Boosting は小さなデータセットで常に勝つわけではありません。木の深さ、learning rate、木の本数、検証性能を制御する必要があります。

Stacking は異なるモデル群を組み合わせるため、この例では勝つことがあります。ただし、交差検証が必須です。メタモデルが基モデルの学習行に対する予測を直接見ると、情報リークになります。

Bagging:Random Forest

アンサンブル学習の投票と森の図

Random Forest はランダム化されたデータ視点で多くの決定木を学習し、その予測を平均または投票します。

最初に見る設定:

パラメータ何を制御するか初心者の目安
n_estimators木の数100 から 300
max_depth木の深さ小さく始めて増やす
min_samples_leaf葉に必要な最小サンプル数過学習時に増やす
random_state再現性学習中は必ず設定

Boosting:GBDT とツール群

GBDT 残差補正漫画

Boosting は順番にモデルを作ります。

最初の小さな木 -> 誤りを見る -> 次の小さな木が誤りに集中 -> 繰り返す

sklearn では、まず GradientBoostingClassifier または HistGradientBoostingClassifier から始めます。実際の表形式プロジェクトでは XGBoost、LightGBM、CatBoost もよく使いますが、sklearn baseline が見える前に外部ライブラリへ飛ばないでください。

Boosting ツール選択漫画

Boosting の最初の調整順:

手順変えるもの理由
1learning_raten_estimators歩幅と学習ラウンド数を制御
2max_depth / leaf 設定複雑さを制御
3検証または early stopping過学習を止める
4特徴量前処理信号品質を上げる

Stacking を安全に使う

リークを避ける Stacking ワークフロー漫画

Stacking が信頼できるのは、メタモデルが out-of-fold 予測を見る場合です。

CV fold 内で基モデルを学習 -> out-of-fold 予測を集める -> メタモデルを学習 -> holdout test で評価

手作業で学習行の予測をそのままメタモデルに渡すのではなく、sklearn の StackingClassifier(cv=5) を優先します。

モデルをどう選ぶか

状況まず使う
強く安定した baseline がほしいRandom Forest
表形式データに非線形が多いGradient Boosting / XGBoost / LightGBM
カテゴリ特徴量が多いbaseline 後に CatBoost
複数のモデル群が補完し合う交差検証つき Stacking
説明しやすさを優先浅い木または Random Forest の特徴量重要度

よくある失敗

症状最初に確認よくある修正
アンサンブルが単一木とあまり変わらない特徴量が弱い、分割が不安定特徴量追加、交差検証
学習は良いがテストが悪い過学習深さを下げ、leaf を増やし、検証を入れる
Boosting が木を増やすほど悪化ラウンド数が多すぎるlearning rate を下げる、early stopping
Stacking が異常に完璧情報リークout-of-fold 予測または StackingClassifier(cv=...)
特徴量重要度を読みすぎる特徴量が相関しているpermutation importance や ablation で確認

練習

  1. Random Forest の max_depth6 から 3None に変える。
  2. Gradient Boosting の learning_rate0.05 から 0.2 に変える。
  3. Stacking が交差検証なしだとなぜリークするか説明する。
  4. モデル比較表を保存し、最初に本番へ出すモデルを一段落で説明する。

通過チェック

次を説明できれば先へ進めます。

  • Bagging と Boosting の違い。
  • Random Forest が単一木より安定しやすい理由。
  • Boosting に検証制御が必要な理由。
  • Stacking に交差検証が必須な理由。
  • leaderboard 最高スコアが、常に本番最適とは限らない理由。