前回に引き続き、scikit-learn 0.22.0 の新機能の紹介です。
複数の機械学習モデルを組み合わせて使う方法の一つに、スタッキング(Stacking)があります。
簡単に言えば、いつくかの機械学習のモデルの予測結果を特徴量として、別のモデルが最終的な予測を行うものです。
アイデアは単純で、効果もあるらしいのですが、これをscikit-learnでやろうとすると、少し面倒だったので僕はあまり使ってきませんでした。
それが、 StackingClassifier と StackingRegressor という 二つの機能がscikit-learnに実装され、
手軽にできそうな期待が出てきたので、試してみました。
とりあえず、 StackingClassifier (分類)の方をやってみます。
サンプルのコードを参考しながら、 iris を digitsに変えてやってみました。
ランダムフォレストと、線形SVMの出力を特徴量にして、ロジスティック回帰で予測しています。
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import StackingClassifier
# データの準備
X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
stratify=y,
random_state=42,
)
# 1段目として、二つのモデルを構築。
# 初期値の max_iter では収束しなかったので大きめの値を設定
estimators = [
('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
('svr', make_pipeline(
StandardScaler(),
LinearSVC(max_iter=4000, random_state=42)
)
)
]
clf = StackingClassifier(
estimators=estimators,
final_estimator=LogisticRegression(max_iter=600),
)
clf.fit(X_train, y_train)
print("正解率:", clf.score(X_test, y_test))
# 正解率: 0.96
そこそこの正解率が出ましたね。
ちなみに、同じパラメータのランダムフォレストと線形SVM、の単体の正解率は次のようになります。
make_pipeline(
StandardScaler(),
LinearSVC(max_iter=4000, random_state=42)
).fit(X_train, y_train).score(X_test, y_test)
# 0.9511111111111111
RandomForestClassifier(
n_estimators=10,
random_state=42
).fit(X_train, y_train).score(X_test, y_test)
# 0.9333333333333333
確かにスタッキングしたモデルの方が正解率が高くなっていました。