Pythonを用いたアンサンブル学習とハイパーパラメータ最適化の実践ガイド

アンサンブル学習の全体像

単一モデルでは限界が見えた際、複数の「弱い学習器」を組み合わせることで精度を大きく向上させる手法がアンサンブル学習である。本記事では代表的な3パターン——Bagging、Boosting、Voting——を取り上げ、scikit-learnを使った実装例を示す。

Bagging系手法

Bagged Decision Trees

Bootstrap標本を複数生成し、それぞれで決定木を学習させた後、多数決で最終予測を決定する。分散の大きいデータセットに有効。

import pandas as pd
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

df = pd.read_csv('pima.csv', header=None,
                 names=['preg','glu','bp','skin','ins','bmi','dpf','age','label'])
X, y = df.iloc[:, :-1].values, df.iloc[:, -1].values

cv = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
base = DecisionTreeClassifier(random_state=42)
bag = BaggingClassifier(base_estimator=base, n_estimators=100, random_state=42)
print('Bagged Trees accuracy:', cross_val_score(bag, X, y, cv=cv).mean())

Random Forest

決定木の学習時に特徴量のランダムな部分集合を用いることで、相関の低い多様な木を生成。過学習抑制効果が高い。

from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_estimators=100, max_features='sqrt', random_state=42)
print('Random Forest accuracy:', cross_val_score(rf, X, y, cv=cv).mean())

Extra Trees

各ノードで閾値もランダムに決定するため、より高いバイアスを許容しつつ分散を大幅に削減。計算速度も速い。

from sklearn.ensemble import ExtraTreesClassifier

et = ExtraTreesClassifier(n_estimators=100, max_features='sqrt', random_state=42)
print('Extra Trees accuracy:', cross_val_score(et, X, y, cv=cv).mean())

Boosting系手法

AdaBoost

誤分類されたサンプルの重みを増やしながら学習器を追加していく。単純な決定木(stump)でも高精度を達成できる。

from sklearn.ensemble import AdaBoostClassifier

ada = AdaBoostClassifier(n_estimators=50, learning_rate=0.8, random_state=42)
print('AdaBoost accuracy:', cross_val_score(ada, X, y, cv=cv).mean())

Gradient Boosting

残差(負の勾配)を段階的に学習させることで、回帰・分類の両方に柔軟に対応。木の深さや学習率が重要なハイパーパラメータ。

from sklearn.ensemble import GradientBoostingClassifier

gb = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)
print('Gradient Boosting accuracy:', cross_val_score(gb, X, y, cv=cv).mean())

Voting

異なるアルゴリズムの予測を多数決で統合。ロジスティック回帰、SVM、決定木など多様なモデルを混在させることで、盲点を補完できる。

from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier

lr = LogisticRegression(max_iter=1000)
svc = SVC(probability=True)
tree = DecisionTreeClassifier()

eclf = VotingClassifier(estimators=[('lr', lr), ('svc', svc), ('tree', tree)], voting='soft')
print('Voting accuracy:', cross_val_score(eclf, X, y, cv=cv).mean())

ハイパーパラメータ最適化

Grid Search

指定した離散値を網羅的に探索。パラメータ数が少ない場合に有効。

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Ridge

param_grid = {'alpha': [1e-3, 1e-2, 1e-1, 1, 10]}
ridge = Ridge()
grid = GridSearchCV(ridge, param_grid, cv=cv, scoring='accuracy')
grid.fit(X, y)
print('Best alpha:', grid.best_params_, 'Score:', grid.best_score_)

Randomized Search

連続分布からのランダムサンプリングにより、膨大な組み合わせを効率的に探索。パラメータ空間が広い場合に有利。

from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import loguniform

param_dist = {'alpha': loguniform(1e-4, 1e2)}
rand = RandomizedSearchCV(ridge, param_distributions=param_dist, n_iter=100, cv=cv, random_state=42)
rand.fit(X, y)
print('Best alpha:', rand.best_params_, 'Score:', rand.best_score_)

パラメータ数が3以下ならGrid Search、それ以上ならRandomized Searchを選択すると計算コストと精度のバランスが取りやすい。

タグ: Scikit-learn ensemble-learning random-forest gradient-boosting hyperparameter-tuning

7月17日 22:41 投稿