Python機械学習ライブラリScikit-learn その47:手書き数字のデータセットを使ってEnsembleClassifiersを試してみる

目次

機械学習ライブラリScikit-learn

前回、機械学習ライブラリScikit-learnの手書き数字のデータセットを使って、SVCモデルとKNeighborsClassifierを試してみました。

今回は残る一つ(?)、EnsembleClassifiersを試してみましょう。

とはいっても、EnsembleClassifiersとはどういったモデルなのか?

SVCの元になっているSVM(サポートベクターマシン)は、データを2次元グラフにプロットし、線を引いてそれぞれのデータを分類する方法でした。

またKNeighborsClassifierは、あるデータから近傍にあるデータは同じカテゴリに分類するというものでした。

Ensembleという言葉からはそのような特徴的な意味を受け取ることはできません。

ということでまずはEnsembleClassifiersがどういうモデルなのか、ざっくりと勉強しましょう。

EnsembleClassifiersの概要

では勉強のためにScikit-learnの解説ページを見てみます。

「Ensemble Methods」のところには何やらたくさんのclassifierとregressorがあります。

classifierがここのところ使っているデータを分類するモデル「分類器」で、regressorが回帰をするためのモデルですね。

もう少し詳しく知るために、「User guide」のところにある「Ensemble methods」をクリックしてみましょう。

これによると…

The goal of ensemble methods is to combine the predictions of several base estimators built with a given learning algorithm in order to improve generalizability / robustness over a single estimator.

https://scikit-learn.org/stable/modules/ensemble.html#ensemble

つまりいくつかの機械学習モデルを組み合わせて、より良い予想をするというのが「Ensemble methods」ということです。

Ensembleをカタカナで書くと「アンサンブル」、訳すと「合唱」となるのですが、どちらかというと色々なものを混ぜてより良くするという感覚でしょうか。

そのため、「EnsembleClassifiers」とは一つの機械学習モデルを示しているものではなく、ベースとなる機械学習の組み合わせ方によって何通りもあるということになります。

また先ほどの解説ページには大別して二つあるとも書かれています。

一つ目は「averaging methods」です。

In averaging methods, the driving principle is to build several estimators independently and then to average their predictions. On average, the combined estimator is usually better than any of the single base estimator because its variance is reduced.

Examples: Bagging methods, Forests of randomized trees, …

https://scikit-learn.org/stable/modules/ensemble.html#ensemble

いくつかの機械学習モデルで予想をし、その予想の平均値を答えとする方法ということです。

こちらには「Bagging methods」や「Forests of randomized trees」などが当てはまるらしいです。

二つ目は「boosting methods」です。

By contrast, in boosting methods, base estimators are built sequentially and one tries to reduce the bias of the combined estimator. The motivation is to combine several weak models to produce a powerful ensemble.

Examples: AdaBoost, Gradient Tree Boosting, …

https://scikit-learn.org/stable/modules/ensemble.html#ensemble

ベースとなる機械学習モデルで予想したのち、バイアスを減らすため、連続的に他の機械学習モデルでも予想をするという方法のようです。

こちらには「AdaBoost」、「Gradient Tree Boosting」が当てはまるとのことです。

さすがに一つ一つどう組み合わせているのかを勉強し、解説するのは結構大変そうなので、また使う時になったら勉強しましよう。

ということで「EnsembleClassifiers」に関しての概要は勉強終わり。

とりあえず試してみる

とりあえず試してみようと思うのですが、一体どういうEnsembleClassifiersがあるのか、もう一度確認してみましょう。

これによると

  • AdBoostClassifier
  • BaggingClassifier
  • ExtraTreesClassifier
  • GradientBoostingClassifier
  • RandomForestClassifier
  • StackingClassifier
  • VotingClassifier
  • HistGradientBoostingClassifier

 があるようです。

今回は細かいことは抜きにして、とりあえず試していきます。

まずはデータの読み込みから。

<セル1>

from sklearn.datasets import load_digits

digits = load_digits(as_frame=True)

digits.frame

実行結果

次に比較対象として「LinearSVC」モデルで機械学習させ、予想精度を出しておきましょう。

<セル2>

from sklearn.svm import LinearSVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = LinearSVC(max_iter=1000000)
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.95

ではここからEnsembleClassifiersを試していきましょう。

基本的にインポートとモデルの読み込み部を変えるだけです。

AdBoostClassifier

<セル3>

from sklearn.ensemble import AdaBoostClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = AdaBoostClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.2861111111111111

BaggingClassifier

<セル4>

from sklearn.ensemble import BaggingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = BaggingClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.9333333333333333

ExtraTreesClassifier

<セル5>

from sklearn.ensemble import ExtraTreesClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = ExtraTreesClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.9916666666666667

GradientBoostingClassifier

<セル6>

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = GradientBoostingClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.9527777777777777

RandomForestClassifier

<セル7>

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = RandomForestClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.9694444444444444

StackingClassifier

<セル8>

from sklearn.ensemble import StackingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = StackingClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-4c0f565bc467> in <module>
      8 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
      9 
---> 10 model = StackingClassifier()
     11 model.fit(x_train, y_train)
     12 pred = model.predict(x_test)

/opt/anaconda3/lib/python3.7/site-packages/sklearn/utils/validation.py in inner_f(*args, **kwargs)
     71                           FutureWarning)
     72         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 73         return f(**kwargs)
     74     return inner_f
     75 

TypeError: __init__() missing 1 required positional argument: 'estimators'

StackingClassifierはそのまま使ったらエラーになってしまいました。

こちらのページによると、どうやら機械学習モデルを自分で組み合わせる必要があるようです。

また必要になったら学習するということで今回は保留。

VotingClassifier

<セル9>

from sklearn.ensemble import VotingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = VotingClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-c26e6ae69a87> in <module>
      8 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
      9 
---> 10 model = VotingClassifier()
     11 model.fit(x_train, y_train)
     12 pred = model.predict(x_test)

/opt/anaconda3/lib/python3.7/site-packages/sklearn/utils/validation.py in inner_f(*args, **kwargs)
     71                           FutureWarning)
     72         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 73         return f(**kwargs)
     74     return inner_f
     75 

TypeError: __init__() missing 1 required positional argument: 'estimators'

VotingClassifierもStackingClassifier同様、自分で機械学習モデルを組み合わせる必要があるようです。

こちらも必要に応じて勉強するということで保留。

HistGradientBoostingClassifier

<セル10>

from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x = digits.frame.iloc[:, 0:-1]
y = digits.frame.iloc[:, -1]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)

model = HistGradientBoostingClassifier()
model.fit(x_train, y_train)
pred = model.predict(x_test)

print(accuracy_score(y_test, pred))

実行結果
0.9694444444444444

HistGradientBoostingClassifierの注意点はインポートにあります。

モデルのインポート「from sklearn.ensemble import HistGradientBoostingClassifier」だけではなく、こちらのインポート文「from sklearn.experimental import enable_hist_gradient_boosting」も必要なようです。

とりあえずやってみて、「LinearSVC」モデルよりも予想精度が良くなったもの、悪くなったもの様々でした。

今回はEnsembleClassifiersは複数の機械学習モデルを組み合わせたモデルであって、その中には色々なモデルがあるということが分かったのでそれで良しとしましょう。

次回はせっかくなので、数字ではない画像を出したら、どう予想されるのか試してみたいと思います。

ではでは今回はこんな感じで。

よかったらシェアしてね!

コメント

コメントする

目次
閉じる