アンサンブル手法
田中VPoE:「ランダムフォレストや勾配ブースティングも広い意味ではアンサンブル手法だが、さらに高精度を目指すための手法がある。異なるモデルを組み合わせる Voting、Stacking、Blending だ。」
あなた:「異なるアルゴリズムを組み合わせるんですか?」
田中VPoE:「そうだ。ロジスティック回帰、ランダムフォレスト、LightGBM は、それぞれ得意なパターンが違う。組み合わせることで、単体では捉えられないパターンもカバーできる。」
アンサンブル学習の基本
異なるモデルの予測を組み合わせることで、単体のモデルより高い精度を実現する手法です。
なぜアンサンブルが有効か
- 各モデルの弱点を他のモデルが補完する
- 予測のバリアンスが減少し、安定性が向上する
- 過学習のリスクが軽減される
Voting(投票)
複数モデルの予測を多数決(分類)または平均(回帰)で統合します。
Hard Voting
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
import lightgbm as lgb
# Hard Voting: 各モデルの予測クラスで多数決
voting_hard = VotingClassifier(
estimators=[
('lr', LogisticRegression(max_iter=1000, random_state=42)),
('rf', RandomForestClassifier(n_estimators=100, random_state=42)),
('lgbm', lgb.LGBMClassifier(n_estimators=100, random_state=42, verbose=-1)),
],
voting='hard',
)
voting_hard.fit(X_train_scaled, y_train)
y_pred = voting_hard.predict(X_test_scaled)
from sklearn.metrics import f1_score
print(f"Hard Voting F1: {f1_score(y_test, y_pred):.3f}")
Soft Voting
# Soft Voting: 各モデルの予測確率を平均
voting_soft = VotingClassifier(
estimators=[
('lr', LogisticRegression(max_iter=1000, random_state=42)),
('rf', RandomForestClassifier(n_estimators=100, random_state=42)),
('lgbm', lgb.LGBMClassifier(n_estimators=100, random_state=42, verbose=-1)),
],
voting='soft',
weights=[1, 2, 3], # モデルの重み(精度が高いモデルに大きい重み)
)
voting_soft.fit(X_train_scaled, y_train)
y_pred = voting_soft.predict(X_test_scaled)
print(f"Soft Voting F1: {f1_score(y_test, y_pred):.3f}")
Soft Voting は確率を使うため、一般的に Hard Voting より高精度です。
Stacking(スタッキング)
第1層のモデルの予測を特徴量として、第2層のメタモデルが最終予測を行います。
from sklearn.ensemble import StackingClassifier
stacking = StackingClassifier(
estimators=[
('lr', LogisticRegression(max_iter=1000, random_state=42)),
('rf', RandomForestClassifier(n_estimators=100, random_state=42)),
('lgbm', lgb.LGBMClassifier(n_estimators=100, random_state=42, verbose=-1)),
],
final_estimator=LogisticRegression(random_state=42),
cv=5, # 第1層の予測を交差検証で生成
stack_method='predict_proba',
)
stacking.fit(X_train_scaled, y_train)
y_pred = stacking.predict(X_test_scaled)
print(f"Stacking F1: {f1_score(y_test, y_pred):.3f}")
Stacking の仕組み
第1層(ベースモデル):
ロジスティック回帰 → 予測確率 p1
ランダムフォレスト → 予測確率 p2
LightGBM → 予測確率 p3
第2層(メタモデル):
入力: [p1, p2, p3]
出力: 最終予測
交差検証で第1層の予測を生成するため、データリーケージを防ぎます。
Blending(ブレンディング)
Stacking の簡略版です。ホールドアウトデータで第1層の予測を生成します。
from sklearn.model_selection import train_test_split
# ブレンディング用にデータを分割
X_train_blend, X_blend, y_train_blend, y_blend = train_test_split(
X_train, y_train, test_size=0.3, random_state=42, stratify=y_train
)
# 第1層: ベースモデルの学習と予測
base_models = {
'lr': LogisticRegression(max_iter=1000, random_state=42),
'rf': RandomForestClassifier(n_estimators=100, random_state=42),
'lgbm': lgb.LGBMClassifier(n_estimators=100, random_state=42, verbose=-1),
}
blend_features = pd.DataFrame()
test_features = pd.DataFrame()
for name, model in base_models.items():
model.fit(X_train_blend, y_train_blend)
blend_features[name] = model.predict_proba(X_blend)[:, 1]
test_features[name] = model.predict_proba(X_test)[:, 1]
# 第2層: メタモデル
meta_model = LogisticRegression(random_state=42)
meta_model.fit(blend_features, y_blend)
y_pred = meta_model.predict(test_features)
print(f"Blending F1: {f1_score(y_test, y_pred):.3f}")
手法の比較
| 手法 | 精度 | 実装難度 | 計算コスト | データリーケージ |
|---|---|---|---|---|
| Voting | 中 | 低 | 低 | なし |
| Stacking | 高 | 中 | 高 | CV で防止 |
| Blending | 高 | 中 | 中 | データ分割で防止 |
使い分けの目安
- 手軽に精度を上げたい: Soft Voting
- 最高精度を追求: Stacking
- Stacking が重い場合: Blending
- 解釈性を維持したい: Voting(各モデルの寄与が明確)
アンサンブルの注意点
- 多様性が重要: 似たモデルを組み合わせても効果が薄い
- 計算コスト: モデル数に比例して増加する
- 複雑度: デバッグや運用が難しくなる
- 過学習: Stacking のメタモデルが過学習する場合がある
まとめ
- Voting: 複数モデルの多数決/平均で予測(簡単で効果的)
- Stacking: 第1層の予測をメタモデルで統合(高精度)
- Blending: Stacking の簡略版(ホールドアウトベース)
- 多様なモデルを組み合わせることが成功のポイント
- 計算コストと複雑度のトレードオフを考慮する
チェックリスト
- Voting の Hard/Soft の違いを説明できる
- Stacking の2層構造を理解した
- Blending と Stacking の違いを把握した
- アンサンブルの注意点を理解した
次のステップへ
次のレッスンでは、AutoML ツールを使った自動モデル構築を学びます。
推定読了時間: 30分