手元の学習データや解決したいタスクに最適な機械学習モデルを迅速に見つけたい。様々な機械学習モデルのトレーニングを行い性能の比較をしたい。そんな時に役に立つのが、機械学習の自動化(Automated Machine Learning、AutoML)です。

本記事ではAutoMLで何ができるのか紹介し、テーブルデータを題材にPythonで利用できるAutoMLライブラリの使用例を解説します。

AutoMLとは

AutoMLとは、通常は人間の手で行なわれる機械学習モデルの開発を、文字通り自動化することを指します。AutoMLで自動化される範囲としては、機械学習モデルの開発における以下に示す工程が挙げられます。

  • データの前処理、クリーニング
  • 適切な特徴量の選択と作成(特徴量エンジニアリング)
  • モデルの学習
  • ハイパーパラメータ最適化
  • モデルの性能評価と最適なモデルの選択
  • モデルのアンサンブル

これらの作業には専門的な知識や作業コストが要求されるというハードルがありますが、AutoMLを利用することで、最小限の労力と機械学習の専門知識で、高品質のカスタム機械学習モデルを作成できるようになります。従ってAutoMLは、機械学習の知識を持たない人でも、高性能な機械学習モデルの構築を可能にすると期待されている技術です。

現在、様々なAutoMLのライブラリが開発されています。各ライブラリごとに扱えるデータの種類、前処理手法、モデルアルゴリズム、アンサンブル手法などが異なっています。

auto-sklearn

auto-sklearnは、機械学習ライブラリのscikit-learnを中心に構築されたAutoMLのライブラリです。University of Freiburg, GermanyのFeurerらによって2015年に発表[5]されて以来、開発が続けられています。2020年にAuto-Sklearn 2.0が発表されており[6]、experimental版ですがライブラリでも使えるようになっています[1]

ここでは、auto-sklearnを使ったAutoMLの実行例を追いながら、解説します。なお、Pythonコード自体の詳細な説明は、本記事では扱いませんが、Google Colaboratory上で実行できるようにコードを公開していますので、手元で試されたい場合はこちらをご参照ください[7]

利用例の題材(タイタニックデータセット)

本記事では、テーブルデータの分類問題をAutoMLを使って解いてみることにします。

タイタニックデータセットは、タイタニック号沈没事故における乗員の生存状況の情報を含むデータセットです。1309件の「表形式データ(年齢や性別などの13項目)」と「ラベル(生存状況)」から構成されます。各乗員の特徴から生存者を予測するタスクが、機械学習の例題として、よく利用されています。著名なデータ分析コンペのKaggleでは、チュートリアルで使われています。

以降ではAutoMLを使って、タイタニック号の乗員が生存したかどうかを予測することを目指します。

トレーニングの実行

auto-sklearnで分類問題タスクを解く場合、下記のようにモデルのトレーニングを実行できます。

import autosklearn.classification

model = autosklearn.classification.AutoSklearnClassifier(
    metric=autosklearn.metrics.accuracy,  # 評価関数
    time_left_for_this_task=120,  # トータルの時間制限 (秒)
    per_run_time_limit=30,  # モデルごとの時間制限 (秒)
    memory_limit=3072,  # メモリ使用量制限 (MB)
    # デフォルトの設定は 'holdout',  'train_size'=0.67
    resampling_strategy='holdout',  # 検証データの分割法
    resampling_strategy_arguments={'train_size': 0.67},  # 分割パラメータ
    n_jobs=1,  # 実行 CPU コア数
    seed=2,  # シード
    ensemble_size=50  # 最終的なアンサンブルに含まれるモデルの最大数
)
model.fit(X_train, y_train, X_test, y_test)

ここで、model.fit()関数に渡されているデータは下記の通りです。

  • X_train: 学習データの入力
  • y_train: 学習データの正解ラベル
  • X_test: テストデータの入力
  • y_test: テストデータの正解ラベル

X_testy_testは学習時には必須ではありませんが、指定することで学習の途中にそのテストデータセットに対する評価を実行して記録することができます。

トレーニング実行時のauto-sklearnの主要な設定に関して、以下で解説します。

評価関数(メトリクス)

モデルの性能評価に使われるメトリクスを指定します。指定しなかった場合は、タスクごとに異なるデフォルトのメトリクスが設定されます。今回の実行例では、正解率(accuracy)を指定しています。

実行時間とメモリ使用量の制限

AutoMLでは、時間をかければかけるほど多くのモデルとパラメータの組み合わせを探索できるため、より性能の良いモデルを発見しやすくなります。しかし、ずっと待っているわけにもいかないので、実行時間を設定してその範囲内でベストなモデルを最終的な結果とします。つまり、使用できるリソースの制限は、最適化の実行時間とテストできるモデルの数とのトレードオフの関係にあります。

実行時間制限に関しては、明確なガイドラインを作成することは難しいですが、トータルで1日、1つのモデルごとの実行時間で30分の制限が推奨されています[2]

メモリ使用量の制限はデフォルトで3GBに設定されています。データセットの大きさに依存しますが、3GBまたは6GBで十分なことがほとんどです。もし、実行中にメモリ制限に到達した場合は、その時点でトレーニングが停止されます[3]

今回の実行例では、デモンストレーションが目的のため、トータルで2分、1つのモデルごとの実行時間で30秒の制限を指定しています。メモリ使用量の制限は、デフォルト値を指定しています。

探索空間の制限

auto-sklearnが探索対象のモデルアルゴリズムや前処理方法を制限することができます。探索の必要がないアルゴリズムが分かっていれば、探索対象から除外することで、それ以外のアルゴリズムを効率的に探索できます。また、特定のアルゴリズムのみに絞って探索することも可能です。

前処理方法の探索は行わないような制限も可能です。前処理方法のみ自前でやる場合やモデルのみ探索したい場合に使うと良さそうです。明らかに予測結果に影響を与えない特徴量があれば、予め手動で除去しておくことで、探索空間が狭められるためAutoMLが最適なモデルを見つけやすくなります。例のnotebookでは、チケット番号や乗客の名前といった、事故生存とは明らかに無関係な特徴量は手動で削除しています。

auto-sklearnでは、get_configuration_space()関数を利用することで、あらかじめ探索される設定空間を把握することができます。

今回の実行例では、特に探索空間に制限は設けずに実行します。

検証のためのデータ分割方法の選択

auto-sklearnが複数のモデルを比較する際に、学習と検証のために元々の入力データセットを分割します。よく使われるもので「ホールドアウト法」がありますが、いくつかの分割方法(resampling strategies)がサポートされています。

デフォルトでは、ホールドアウト法で、全体の67%のデータが学習に、33%のデータが検証に使われます。サポートされている分割方法の他に、独自の分割方法を選択することも可能です。詳細はドキュメントをご参照ください。

今回の実行例では、デフォルトの設定で実行します。

アンサンブル

アンサンブルとは、複数のモデルを組み合わせてモデルを作ること、もしくは予測を行う方法です。アンサンブルによって、モデル性能の向上が見込まれます。一方で複数のモデルを利用するため、単一のモデルのみ利用する場合に比べて、計算コストが高くなるデメリットもあります。シンプルなアンサンブルの方法としては、複数のモデルの予測値の平均をとる方法が挙げられます。

auto-sklearnではCaruana et al. (2004)が発表した手法を使って、検証データセットに対する予測性能をベースにモデルアンサンブルを構築しています。アンサンブル構築に関連するハイパーパラメータ (ensemble_size) を使って、アンサンブルに含めるモデルの数を指定できます。

今回の実行例では、デフォルトの設定で実行します。

結果を確認する

正解率

auto-sklearnを使った学習結果を確認していきます。学習データとテストデータに対する正解率は下記のように確認できます。

s = model.score(X_train, y_train)
print(f"Train score {s}")
s = model.score(X_test, y_test)
print(f"Test score {s}")
Train score 0.9050218340611353
Test score 0.7938931297709924

今回の結果では、学習データに対して0.905、テストデータに対して0.794の正解率となりました。探索時間の制限をもっと長くすることで、性能向上は見込まれます。

アルゴリズム探索の統計

下記のように、アルゴリズムの探索結果を確認することができます。

print(model.sprint_statistics())
auto-sklearn results:
  Dataset name: titanic_example
  Metric: accuracy
  Best validation score: 0.825083
  Number of target algorithm runs: 25
  Number of successful target algorithm runs: 23
  Number of crashed target algorithm runs: 0
  Number of target algorithms that exceeded the time limit: 2
  Number of target algorithms that exceeded the memory limit: 0

今回はそれぞれのアルゴリズムで30秒を制限時間として設定しましたが、2個のアルゴリズムが時間制限を超えてしまっていることがわかります。学習に成功したアルゴリズムは合計23個で、validationデータ (学習時に自動で resampling strategiesにより入力データを分割して作成される) に対するベストスコアは0.825となっています。

ベストモデルと個別のモデルの確認

探索されたそれぞれのアルゴリズムの詳細は下記のように、leaderboard()関数で確認できます。detailed=Trueを指定することで、より詳細に確認できます。

model.leaderboard(detailed=False, ensemble_only=True, sort_by='cost')

rankが探索されたモデルの順位、costはvalidationデータセットに対するロス(今回の場合、1 – accuracy)を意味しています[4]。ensemble_weightは、最終的なアンサンブルの中で、それぞれのモデルに割り当てられた重みです。単体では、ランダムフォレストが最も性能が良いモデルであるということが確認できました。

個別の重みとモデルはget_models_with_weights()関数で取得できます。下記のように、単体のモデルを取り出して予測することが可能です。ランダムフォレストモデルを取り出して、テストデータに対する正解率を出しています。

list_models = model.get_models_with_weights()
model_rf = list_models[6][1]
model_rf.score(X_test, y_test.astype("int"))
0.7913486005089059

単体で最も性能が良かったモデルの正解率0.791となりました。アンサンブルが0.794だったので、アンサンブルのほうが高くなっています。

一方で、推論速度はアンサンブルより単体のモデルの方が早いです。これは、アンサンブルの場合複数のモデルで推論を行なった上で最終的な結果を出すためです。下記は、アンサンブルと単体で推論を10回繰り返して速度を測定した結果です。

%%time
for i in range(10):
  y_pred = model.predict(X_test)
CPU times: user 8.28 s, sys: 2.26 s, total: 10.5 s
Wall time: 7.71 s
%%time
for i in range(10):
  y_pred_rf = model_rf.predict(X_test)
CPU times: user 882 ms, sys: 3.96 ms, total: 885 ms
Wall time: 874 ms

単体のモデルがアンサンブルより、約10倍速いことがわかります。

従って、アンサンブルを使うかどうかは推論速度とモデルの性能のトレードオフの関係にあります。推論速度が許容範囲にあるのか、すこしの性能向上のために推論速度を犠牲にしてよいのか、ユースケースに合わせて決める必要があります。

モデルの説明

機械学習モデルはブラックボックスになりやすく、近年、モデルの説明性、解釈性が注目されて来ています[8]

モデル解釈のための機能として、auto-sklearnではscikit-learnのinspect moduleを使って、何が予測値に影響を与えているかを確認することができます。

下記は、permutation importanceをプロットした図です。permutation importanceは、特徴量の値を入れ替えたときの性能の変化を見ることで特徴量の有用性を計る手法です。

sex(性別)が最も有用性が高く、次点がpclass(乗客のクラスで社会経済的地位を示す)であることがわかります。従って、性別と社会経済的地位が、事故生存と強く関係していると言えます。

他のAutoMLライブラリ

auto-sklearn以外にも、様々なOSSのAutoMLツールが公開されています。それぞれ扱うアルゴリズムやデータの種類が異なっています。ここでは、その中からいくつかピックアップしてご紹介します。

Auto-sklearn 2.0

現在、auto-sklearn 2.0のexperimental版が提供されています。notebookに実行例を記載しています。従来のauto-sklearnに比べて、2.0の方がパフォーマンス面で優れていると報告されています[6]

AutoGluon

AutoGluonはAWSによって開発されているAutoMLライブラリです。テーブルデータ、画像、自然言語を対象にAutoMLを実行できます。

タイタニックデータを対象にした、AutoGluonの利用例を下記のnotebookで公開しています。
https://github.com/hnishi/hello-automl/blob/main/autogluon_titanic.ipynb

H2O

H2O AutoMLH2O.aiによって開発されているJava製のAutoMLツールで、Python Interfaceが提供されています。モデル説明のための機能が充実していて、簡易にそれらを呼び出すことができます。

タイタニックデータを対象にした、H2O Python Moduleの利用例を下記のnotebookで公開しています。
https://github.com/hnishi/hello-automl/blob/main/h2o_titanic.ipynb

まとめ

以上、ざっくりとAutoMLで何ができるかをテーブルデータを題材にご紹介しました。従来は人間の手で様々なアルゴリズムや前処理手法を比較しながら試行錯誤してきましたが、今後はAutoMLにお任せして、AutoMLの結果をじっくり解析していくという流れが広まっていくかもしれません。

ただ注意点として、AutoMLが便利だとしても、ある程度のデータ分析や機械学習の知識が必要とされることが多いです。例えば、AutoMLには扱えるアルゴリズム、前処理、後処理に制限があるため、より良い性能を得るためには AutoML の守備範囲以外に人間の手を加えることで更に性能向上できる場合があります。AutoMLを上手く利用して、機械学習モデルを活用していきましょう。

参考文献