その機械学習プロセス、自動化できませんか？

ここ数年、機械学習を使った研究開発やアプリケーション作成、データ分析がしやすい環境が整ってきました。機械学習フレームワークとしては、scikit-learn や TensorFlow が整備され、各クラウドベンダーからは機械学習用APIや学習/運用用のインフラが提供され、誰でも最先端の機械学習に触れられる時代になりました。

<!--最適化が必要な理由-->
このような環境で自社の競争力を強化するには、機械学習プロセスの最適化による生産性向上が一つの手です。研究開発においては、アルゴリズムの開発をすばやく行わなければ競合に先んじられ、論文を書かれてしまうでしょう。また、アプリケーション作成やデータ分析業務での生産性向上が競争力強化に役立つのは言うまでもありません。

<!--解決策としてのAutoML-->
そこで本記事では、機械学習プロセスを自動化する技術であるAutomated Machine Learning（AutoML）の概要について紹介します。具体的には、AutoMLとは何か、なぜ必要か、どんなことができるのか、といった話を説明し、次の行動に繋げられるようにします。記事の構成としては、最初に一般的な機械学習プロセスについて説明し、次にAutoMLについて説明します。最後にAutoMLの将来について述べます。

# 一般的な機械学習プロセス

本記事をご覧の方はご存知の通り、「機械学習はアルゴリズムにデータを与えるだけで何か良い結果が出る」というものではありません。性能を出すためには多くの作業が必要です。典型的な作業には、データ収集、データクリーニング、特徴エンジニアリング、モデル選択、ハイパーパラメータチューニング、モデルの評価といった作業が含まれます。下のような図を一度は見たことがあるでしょう。

![一般的な機械学習プロセス](https://d2mxuefqeaa7sj.cloudfront.net/s_4731BEEF09487717D1D4BE5F2EF5E8D30A7337C68C079008DCEB768F1A654D47_1541392849981_+2018-11-05+13.40.13.png)
出典: [Evaluation of a Tree-based Pipeline Optimization Tool for Automating Data Science](https://arxiv.org/abs/1603.06212)


最近よく使われているディープラーニングでも多くの作業が必要なことには変わりありません。確かに、ディープラーニングではモデルが特徴を学習してくれるため、特徴エンジニアリングの労力は減るかもしれません。しかし、プロセス全体は伝統的な機械学習と同様なので、データの前処理やハイパーパラメータのチューニングが必要なことには変わりません。また、高い性能を出すためには、ニューラルネットワークのアーキテクチャ設計に多くの時間を費やす必要があります。

<!--計算時間が長い-->

このように、機械学習には多くの作業が必要で時間がかかることから自動化技術の重要性が増しています。

# AutoMLとは？

AutoML（Automated Machine Learning）は、機械学習プロセスの自動化を目的とした技術のことです。機械学習に多くの作業が必要なのは先に述べたとおりですが、AutoMLでは機械学習の各プロセスを自動化してエンジニアの生産性を向上させること、また誰でも機械学習を使えるようになることを目指しています。したがって、究極的な目標は、生データを与えたら、何らかの処理をして、良い結果を出すことだと言えるでしょう。

データサイエンティストの数が急激に増えていることもAutoMLを後押しする背景となっています。以下の図はLinkedInでデータサイエンティストの数を調査した結果です。図を見ると、その数が指数関数的に増えていることがわかります。2010年から2015年の5年間でおよそ2倍、2018年までなら推定で8倍に増えています。

![データサイエンティストの増加](http://www.dataversity.net/wp-content/uploads/2015/10/ds.png?x38402)
出典: [Study Shows That the Number of Data Scientists Has Doubled in 4 Years](http://www.dataversity.net/study-shows-that-the-number-of-data-scientists-has-doubled-in-4-years/)

データサイエンティストの数が急激に増えたことで、高度な分析をできる人手が足りていないという現状があります。そのような人手不足を補うために、データ分析や機械学習の適応経験が少ないエンジニアを助けるようなツールが必要となってきました。その目的に合致するのがAutoMLというわけです。

<!--
以下の図は多くのデータサイエンティストに質問して得られた「機械学習プロセス中で最も時間を消費しているのはどこか」というアンケートの結果です。この結果では60%の人がデータクリーニングを挙げており、19%がデータ収集を挙げています。AutoMLでこれらのプロセスを自動化することで生産性を上げることができます。
-->
<!--
勘違いされると嫌なので述べておきますが、AutoMLの技術は今のところデータサイエンティストを置き換えるものではなく、生産性を向上させるツールです。要するに、scikit-learnやJupyter、統合開発環境によって生産性を向上させているのと同じように、AutoMLの技術で機械学習プロセスの生産性を向上させようということです。
-->

ここまでで、AutoMLの重要性が増している理由について述べました。次節からは各プロセスで従来行われている処理とAutoMLによる効率化について見ていきましょう。

# AutoMLで行われること

本節では機械学習の各プロセスでAutoMLがどのように生産性向上に寄与するかを説明します。対象とするプロセスは、ハイパーパラメータチューニング、モデル選択、特徴エンジニアリングの3つです。各プロセスについて、何をするプロセスなのか、なぜその処理が必要か、従来どうしていたか、AutoMLではどうしているかの3点から説明します。

![出典: https://arxiv.org/pdf/1603.06212.pdf](https://d2mxuefqeaa7sj.cloudfront.net/s_4731BEEF09487717D1D4BE5F2EF5E8D30A7337C68C079008DCEB768F1A654D47_1541392849981_+2018-11-05+13.40.13.png)
出典: [Evaluation of a Tree-based Pipeline Optimization Tool for Automating Data Science](https://arxiv.org/abs/1603.06212)




## ハイパーパラメータチューニング

ハイパーパラメータチューニングは、ハイパーパラメータを最適な値に調整するプロセスです。各機械学習モデルには様々なハイパーパラメータが存在します。たとえば、ランダムフォレストなら木の深さや数をハイパーパラメータとして持っています。これらのハイパーパラメータはデータから学習するものではなく、モデルを学習させる前に設定しておく必要があります。

ハイパーパラメータチューニングが必要な理由として、機械学習フレームワークのデフォルトのパラメータでは良い性能が出ないことが多いという点を挙げることができます。以下の図は、scikit-learn に含まれる様々な機械学習アルゴリズムについて、ハイパーパラメータをデフォルト値からチューニングしたときに、性能がどれだけ向上したかを表しています。

![ハイパーパラメータチューニングの効果](https://d2mxuefqeaa7sj.cloudfront.net/s_4731BEEF09487717D1D4BE5F2EF5E8D30A7337C68C079008DCEB768F1A654D47_1541481855932_+2018-11-06+14.23.35.png)
出典: [Data-driven Advice for Applying Machine Learning to Bioinformatics Problems](https://arxiv.org/abs/1708.05070)

結果を見ると、アルゴリズムによって改善の度合いは異なりますが、ハイパーパラメータをチューニングすることで性能が向上することがわかります。平均的には正解率で3〜5%程度の改善が見られたという結果になっています。つまり、ハイパーパラメータは明らかにチューニングする価値があり、デフォルトのパラメータを信用し過ぎるべきではないということを示唆しています。

チューニングによって性能向上が見込めるとはいえ、数多くのハイパーパラメータを手動でチューニングするのは骨が折れる作業です。たとえば、ハイパーパラメータ数が5個あり、各ハイパーパラメータに対して平均で3つの値をテストするのだとすれば、組合せは3の5乗（=273）通り存在します。これらすべての組み合わせに対して手動でチューニングをするのは非生産的な行為です。また、以下の図のようにモデルが複雑化すれば、手動でのチューニングは現実的ではなくなります。

![Residual Network](https://qiita-image-store.s3.amazonaws.com/0/77079/eda892b5-2f4a-9a3d-2d05-70a1f11f5681.png)
出典: [Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385)

そこで、AutoMLでは従来人手で行っていたハイパーパラメータチューニングを自動化することを考えます。自動化により、チューニングの効率が向上するだけでなく、人が直感的に決めたパラメータによるバイアスを取り除くことにも繋がります。具体的には以下のような手法が使われています。

* グリッドサーチ(GridSearch)
* ランダムサーチ(RandomSearch)
* ベイズ最適化(Bayesian Optimization)

このうち、最もよく使われているのはグリッドサーチとランダムサーチでしょう。それらの違いは以下の図のように表されます。

![グリッドサーチとランダムサーチの違い](https://d2mxuefqeaa7sj.cloudfront.net/s_4D9423BDCD2991311F9AD3FD6B5041DF749E86A8152E9CD2999944A9A41AAAFF_1542687358247_+2018-11-20+13.15.16.png)
出典: [Random Search for Hyper-Parameter Optimization](http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf)

グリッドサーチは、伝統的によく使われているハイパーパラメータチューニングの手法で、あらかじめ各ハイパーパラメータの候補値を複数設定して、すべての組合せを試すことでチューニングします。たとえば、$C$ と $\gamma$ という2つのパラメータがあり、それぞれ、$C \in$ {10, 100, 1000}, $\gamma \in$ {0.1, 0.2, 0.5, 1.0}という候補値を設定した場合、3x4=12の組み合わせについて試します。

<!--
グリッドサーチの課題
モデルにとって重要なパラメータは少数なので、グリッドサーチは非効率
-->

一方、ランダムサーチはパラメータに対する分布を指定し、そこから値をサンプリングしてチューニングする手法です。たとえば、グリッドサーチでは $C$ に対して $C \in$ {10, 100, 1000} のような離散値を与えていたのに対して、ランダムサーチでは、パラメータ $\lambda=100$ の指数分布のような確率分布を与え、そこから値をサンプリングします。少数のハイパーパラメータが性能に大きく影響を与える場合に効果的な手法です。

グリッドサーチやランダムサーチの課題として、見込みのないハイパーパラメータに時間を費やしがちな点を挙げることができます。この原因としては、グリッドサーチやランダムサーチでは以前に得られた結果を利用していない点を挙げられます。

では、以前に得られた結果を利用すると、どのようにハイパーパラメータを選べるのでしょうか？ 以下の図を御覧ください。この図はランダムフォレストのハイパーパラメータの一つである`n_estimator`の数を変化させたときの性能を示しています。スコアの値が高い方が性能が良いのだとすれば、`n_estimator`が200近辺を探索するより、800近辺を探索した方が効率が良さそうな事がわかると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/77079/e802c778-73f8-245c-cf3e-575de37d2bca.png)
出典: [A Conceptual Explanation of Bayesian Hyperparameter Optimization for Machine Learning](https://towardsdatascience.com/a-conceptual-explanation-of-bayesian-model-based-hyperparameter-optimization-for-machine-learning-b8172278050f)

最近使われるようになってきたベイズ最適化を用いたハイパーパラメータチューニングは、以前の結果を使って次に探索するハイパーパラメータを選ぶ手法です。これにより、有望そうなところを中心にハイパーパラメータを探索することができます。人間が行う探索に近いことをしているとも言えるでしょう。ディープラーニングを含む機械学習のモデルに対して、比較的良いハイパーパラメータを探索できることが知られています。

ベイズ最適化の仕組みについてこれ以上詳しく解説するとこの記事では終わらないので、最後に最適化に使えるソフトウェアを紹介しましょう。ここでは以下のソフトウェアを挙げました。

* [GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)
* [RandomizedSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html)
* [hyperopt](https://github.com/hyperopt/hyperopt)
* [hyperas](https://github.com/maxpumperla/hyperas)

[GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)と[RandomizedSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html)はご存知 scikit-learn に組み込まれているクラスです。scikit-learn を使っている場合には一番使いやすいのではないかと思います。 scikit-learn に限らず使いたいなら、[ParameterGrid](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.ParameterGrid.html) を使うのが選択肢に挙がると思います。ParameterGrid を使うことでハイパーパラメータの組み合わせを生成することができます。

[hyperopt](https://github.com/hyperopt/hyperopt) はランダムサーチとベイズ最適化によるハイパーパラメータチューニングを行えるPythonパッケージです。ベイズ最適化の方はTPEと呼ばれるアルゴリズムをサポートしています。[hyperas](https://github.com/maxpumperla/hyperas) はKeras用のhyperoptラッパーです。私のようにKerasをよく使うユーザにはこちらの方が使いやすいと思います。

## モデル選択

モデル選択は、データを学習させるのに使う機械学習アルゴリズムを選ぶプロセスです。モデルにはSVMやランダムフォレスト、ニューラルネットワークなど多くの種類があります。その中から、解きたい問題に応じて選びます。たとえば、解釈性が重要な場合は決定木などのモデルが選ばれるでしょうし、とにかく性能を出したいという場合はニューラルネットワークが候補になるでしょう。

モデル選択が必要な理由として、すべての問題に最適な機械学習アルゴリズムは存在しないという点を挙げることができます。以下の図は165個のデータセットについて、モデル間の性能の勝敗について検証した結果を示しています。左側の列はモデルの名前が書かれており、良い結果となったモデルから順に並んでいます。

![出典: https://arxiv.org/pdf/1708.05070.pdf](https://d2mxuefqeaa7sj.cloudfront.net/s_4731BEEF09487717D1D4BE5F2EF5E8D30A7337C68C079008DCEB768F1A654D47_1541481933766_+2018-11-06+14.25.14.png)
出典: [Data-driven Advice for Applying Machine Learning to Bioinformatics Problems](https://arxiv.org/abs/1708.05070)

結果を見ると、Gradient Tree Boosting（GTB）やランダムフォレスト、SVMは良く、逆にNBは悪いことがわかります。また、ほとんどの場合においてGradient Tree Boostingは良い結果なのですが、NBでも1%のデータセットではGTBに勝っているという結果になっています。ちなみに、足しても100%にならないのは、少なくとも正解率で1%以上上回った場合を勝利としているからです。

要するに何が言いたいかというと、確かにGTBやRandomForestは良い結果を出しますが、すべての問題で勝てる最適なアルゴリズムは存在しないということです。これは機械学習を行う上で重要な点で、機械学習を使って問題を解く際には、多くの機械学習アルゴリズムについて考慮する必要があるということをこの実験結果は示唆しています。

ただ、実際のプロジェクトでは多くの機械学習アルゴリズムを考慮できているとはいい難い状況です。その原因の一つには、人間のバイアスが関係しています。たとえば、「GTBは毎回良い結果を出すからこれを使っておけばいいんだ」というのは一つのバイアスです。確かにそれはたいていの場合正しいかもしれません。しかし、上図が示すように、実際には人間のバイアスは悪い方向に働くこともあるのです。

人間のバイアスを軽減させるために有効な手の一つとして、データセットの特徴に応じて選ぶモデルを決定する仕組みを構築しておく手があります。以下は scikit-learn が公開している機械学習アルゴリズムを選択するためのチートシートです。ただ、この方法にもシートを作成した人のバイアスが入っている、多くのアルゴリズムを考慮できていないといった問題があります。

![model_selection.png](https://qiita-image-store.s3.amazonaws.com/0/77079/a08ab345-1427-2ef9-1558-b576d823d3ea.png)
出典: [Choosing the right estimator](https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html)

そういうわけでAutoMLでは機械学習アルゴリズムの選択を自動的に行うことを考えます。モデル選択を自動化することにより、人間のバイアスを排除しつつ、様々なモデルを考慮することができます。モデル選択についてはハイパーパラメータチューニングと切り離せない話なので、話としてはここまでにしておきます。

お話だけだと退屈なので、ここでソフトウェアを紹介しましょう。モデル選択の機能を組み込んだソフトウェアは商用・非商用問わずに数多くありますが、今回はその中から [TPOT](https://github.com/EpistasisLab/tpot) を紹介します。

[TPOT](https://github.com/EpistasisLab/tpot) は、scikit-learnライクなAPIで使えるAutoMLのツールです。機能としてはモデル選択とハイパーパラメータチューニングを行ってくれます。また、タスクとしては分類と回帰を解くことができます。

scikit-learnを使ったことがある人であれば、TPOTを使うのは非常に簡単です。たとえば、分類問題を解く場合は、`TPOTClassifier`をインポートし、データを与えて学習させるだけです。以下ではMNISTを学習させています。

```python
from tpot import TPOTClassifier
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
    
digits = load_digits()
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target,
                                                    train_size=0.75, test_size=0.25)
    
tpot = TPOTClassifier(generations=5, population_size=20, verbosity=2)
tpot.fit(X_train, y_train)
print(tpot.score(X_test, y_test))
```

学習が終わると以下に示すように最も良かったパイプラインとそのスコアを表示します。今回の場合、入力に`PolynomialFeatures`を適用した後、モデルに`LogisticRegression`を使うのが最も良い結果になりました。ハイパーパラメータが設定されていることも確認できます。スコア自体はよくありませんでしたが、手軽さは確認できたかと思います。

```bash
Generation 1 - Current best internal CV score: 0.9651912264496657                                                                                                   
Generation 2 - Current best internal CV score: 0.9822200910854291                                                                                                   
Generation 3 - Current best internal CV score: 0.9822200910854291                                                                                                   
Generation 4 - Current best internal CV score: 0.9822200910854291                                                                                                   
Generation 5 - Current best internal CV score: 0.9822200910854291                                                                                                   
                                                           
Best pipeline: LogisticRegression(PolynomialFeatures(input_matrix, degree=2, include_bias=False, interaction_only=False), C=15.0, dual=True, penalty=l2)
0.9844444444444445
```

### ニューラルアーキテクチャサーチ

モデル選択と関係する話として、最近よく話題になるニューラルアーキテクチャサーチ（Neural Architecture Search: NAS）について述べておきましょう。NASもAutoMLの一部と捉えられます。ニュースでも大きく取り上げられ、New York Timesでは「AIを構築できるAIを構築する」（[Building A.I. That Can Build A.I.](https://www.nytimes.com/2017/11/05/technology/machine-learning-artificial-intelligence-ai.html)）というタイトルで記事が書かれています。

<img width="640" alt="スクリーンショット 2018-12-03 9.56.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/927594bd-0f91-3d6c-0793-c2c59be23e63.png">

<!--ニューラルアーキテクチャサーチとは?-->
ニューラルアーキテクチャサーチとは、ニューラルネットワークの構造設計を自動化する技術です。実際には、ニューラルネットワークを使ってネットワークアーキテクチャを生成し、ハイパーパラメータチューニングをしつつ学習させています。

<!--どういうことをしているのか-->
基本的な枠組みは以下の図のようになっています。まず、コントローラと呼ばれるRNNがアーキテクチャをサンプリングします。次に、サンプリングした結果を使って、ネットワークを構築します。そして、構築したネットワークを学習し、検証用データセットに対して評価を行います。この評価結果を使って、より良いアーキテクチャを設計できるようにコントローラを更新します。以上の操作を繰り返し行うことで良いアーキテクチャを探索しています。

<img width="893" alt="スクリーンショット 2018-12-03 10.14.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/846d28c4-f023-98c6-e9da-ab580ad20bad.png">
出典: [Neural Architecture Search with Reinforcement Learning](http://rll.berkeley.edu/deeprlcoursesp17/docs/quoc_barret.pdf)

<!--ニューラルネットワークアーキテクチャ設計の課題-->
ニューラルネットワークの設計を自動化したいのにはいくつかの理由があります。その一つとしてニューラルネットワークのアーキテクチャを設計するのは高度な専門知識が必要で非常に難しい点を挙げられます。よいアーキテクチャを作るためには試行錯誤が必要で、これには時間もお金もかかります。これでは活用できるのが少数の研究者やエンジニアだけに限られてしまいます。

<!--NASによる課題の解決-->
このような理由からニューラルアーキテクチャサーチで設計から学習まで自動化しようという話になりました。NASによって、アーキテクチャの設計、ハイパーパラメータチューニング、学習を自動化することができ、誰にでも利用できるようになります。これはつまり、ドメインエキスパートによるニューラルネットワークの活用に道が開かれることを意味しています。

<!--NASの課題-->
そんなNASの課題としては計算量の多さを挙げられます。たとえば、[Neural Architecture Search with Reinforcement Learning](http://rll.berkeley.edu/deeprlcoursesp17/docs/quoc_barret.pdf)では、アーキテクチャを探索するのに 800 GPUで28日間かかっています。また、[NASNet](https://arxiv.org/abs/1707.07012)では、500 GPU を使用して4日間かかっています。これでは一般の研究者や開発者が利用するのは現実的ではありません。

<!--解決策-->
高速化の手段の一つとして使われるのが転移学習です。[Efficient Neural Architecture Search via Parameter Sharing](https://arxiv.org/abs/1802.03268)ではすべての重みをスクラッチで学習させるのではなく、学習済みのモデルから転移学習させて使うことで高速化をしています。その結果、学習時間は 1 GPU で半日までに抑えられています。

最後にNASを提供しているサービスとOSSについて紹介します。

NASを提供するサービスとして最も有名なのはGoogleの [Cloud AutoML](https://cloud.google.com/automl/) でしょう。Cloud AutoMLでは画像認識、テキスト分類、翻訳に関して学習させることができます。データさえ用意すれば、誰でも簡単に良いモデルを作って使えるのが特徴です。一方、お金が結構かかるのと、学習したモデルをエクスポートできないのが欠点です。

NASに使えるOSSとしてはAuto-Kerasがあります。Auto-Kerasは、scikit-learnライクなAPIで使えるオープンソースのAutoMLのツールです。こちらは、Texas A&M大学のDATA Labとコミュニティによって開発されました。論文としては、2018年に発表された「Auto-Keras: Efficient Neural Architecture Search with Network Morphism」が基となっています。目標としては、機械学習の知識のないドメインエキスパートでも簡単にディープラーニングを使えるようにすることです。

Auto-Kerasもscikit-learnを触ったことがある人であれば使うのは簡単です。以下のようにして分類器を定義し、`fit`メソッドを使って学習させるだけです。以下のコードはAuto-KerasにMNISTを学習させるコードです。`fit`メソッドで学習をして最適なアーキテクチャを探索します。その後、`final_fit`で探索を終えて得られた最適なアーキテクチャで学習し直します。

```python
import autokeras as ak
from keras.datasets import mnist


if __name__ == '__main__':
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    x_train = x_train.reshape(x_train.shape + (1,))
    x_test = x_test.reshape(x_test.shape + (1,))

    clf = ak.ImageClassifier(verbose=True)
    clf.fit(x_train, y_train, time_limit=12 * 60 * 60)
    clf.final_fit(x_train, y_train, x_test, y_test, retrain=True)
    print(clf.evaluate(x_test, y_test))
```

学習を始めると以下のような表示がされます。`Father Model`に親モデルのIDが書いてあり、その隣に変更点が書いてあります。そして、学習が終わるとその結果が`Loss`と`Metric Value`に表示されます。このモデルの場合は、正解率で`0.9952`だったことを表しています。

```python
+----------------------------------------------+
|               Training model 8               |
+----------------------------------------------+

+--------------------------------------------------------------------------+
|    Father Model ID     |                 Added Operation                 |
+--------------------------------------------------------------------------+
|           6            |    to_deeper_model 68 Conv2d(512, 512, 5, 1)    |
+--------------------------------------------------------------------------+
Saving model.
+--------------------------------------------------------------------------+
|        Model ID        |          Loss          |      Metric Value      |
+--------------------------------------------------------------------------+
|           8            |  0.07076152432709933   |         0.9952         |
+--------------------------------------------------------------------------+
```

<!--最後に注意点なのですが、学習自体はCPUでもできるので動かして遊ぶ分にはそれでいいと思いますが、。-->

## 特徴エンジニアリング

<!--特徴エンジニアリングとは-->
特徴エンジニアリング（Feature Engineering）は、機械学習アルゴリズムがうまく学習できるような特徴を作成するプロセスのことです。特徴エンジニアリングは機械学習を使ったシステムを作る際の基礎であり、ここで良い特徴を得られれば、機械学習アルゴリズムでも良い性能を出すことができます。ただし、良い特徴を得るのは非常に難しく、時間のかかる部分でもあります。

<!--特徴-->
機械学習における特徴（Feature）とは、観察される現象の測定可能な特性のことです。以下の例は、タイタニック号の生存者情報を含むデータセットの一部です。各列は、分析に使用できる測定可能なデータである年齢（Age）、性別（Sex）、料金（Fare）などを含みます。これらがデータセットの特徴量です。

![タイタニック号の生存者情報を含むデータセット](https://d2mxuefqeaa7sj.cloudfront.net/s_4D9423BDCD2991311F9AD3FD6B5041DF749E86A8152E9CD2999944A9A41AAAFF_1542604736481_titanic.png)

<!--特徴エンジニアリングが必要な理由-->
特徴エンジニアリングが重要な理由として、良い特徴を得ることで機械学習アルゴリズムの予測性能が大きく変わる点を挙げることができます。たとえば、タイタニック号のデータセットの例で言うなら、乗客名をそのまま特徴として使っても良い性能は得られないでしょう。しかし、名前から敬称（Mr. Mrs. Sir.など）を抽出して使えば性能向上に役立つでしょう。なぜなら、社会的地位の高さや既婚者か否かといった情報は救命ボートに乗る際に考慮されただろうと考えられるからです。

<!--特徴エンジニアリングの課題。難しさ-->
伝統的に、特徴エンジニアリングは人間によって行われてきましたが、それには2つの問題点がありました。一つは良い特徴を思いつくのは難しいという点です。良い特徴を思いつくためにはドメインの知識が必要な場合もあり、一筋縄ではいきません。もう一つは、時間がかかるという点です。単に思いつくだけではなく、それを検証することも含めると、特徴エンジニアリングは非常に時間のかかる作業です。実際に機械学習のどの部分で時間がかかるかをデータサイエンティストに尋ねると特徴エンジニアリングは上位に位置します。

<!--AutoMLでの解決方法-->
AutoMLでは、人間によって行われてきた特徴エンジニアリングを自動化します。これにより、先に述べた2つの問題を軽減することができます。以下では実際にAutoMLにおいて特徴エンジニアリングがどのように行われるのかについて説明します。ここでは、AutoMLのサービスである **DataRobot** での自動化と、特徴エンジニアリングを自動化するためのツールである **featuretools** を例にとって説明しましょう。

<!--DataRobotでの解決方法-->
まずはAutoMLのサービスである [DataRobot](https://www.datarobot.com/) ではどうしているかを紹介しましょう。以下の述べる内容は、DataRobotのブログ記事「[Automated Feature Engineering](https://blog.datarobot.com/automated-feature-engineering)」に基づいています。2018年6月28日の記事ですが内容が古くなっている可能性はありますので、その点はご留意ください。

DataRobotではエキスパートシステムを構築することで特徴エンジニアリングを自動化しています。具体的には以下のようなことをしています。

* 特徴の生成
* 特徴エンジニアリングが必要なモデルを知る
* 各モデルに有効な特徴エンジニアリングの種類を知る
* システマティックにモデルを比較して、特徴エンジニアリングとモデルの最も良い組み合わせを知る

これらの操作をDataRobotでは model blueprint を使って行っています。ここで、model blueprint とは、[こちらの記事](https://blog.datarobot.com/data/model-blueprints-add-value-datarobot)によると、前処理、特徴エンジニアリング、学習、チューニングといった処理のシーケンスのことのようです。以下が model blueprint の例です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/77079/6f64da13-dd83-e89a-3031-3474dafda65c.png)
出典: [Automated Feature Engineering](https://blog.datarobot.com/automated-feature-engineering)

この model blueprint では、DataRobotのシステムはL2正則化を入れたロジスティック回帰に対するデータを用意しています。具体的に行っている特徴エンジニアリングとしては、One-Hotエンコーディング、欠損値の補完、標準化の3つです。

より複雑な例としては以下の Gradient Boosted Greedy Treesに対する model blueprint があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/77079/041490b8-eb7e-55f8-bd8b-7d33891d82ab.png)
出典: [Automated Feature Engineering](https://blog.datarobot.com/automated-feature-engineering)


これまでのところをまとめましょう。まず、DataRobotでは前処理からチューニングまでのパイプラインを定義したmodel blueprintが多数用意されていいます。それらのmodel blueprintをデータに対して適用し、その結果を比較して最も良いモデルと特徴エンジニアリングの組み合わせを決めているということをしているようです。

DataRobotの方法も良いのですが、作り込みが必要で真似しにくい感じのやり方なので [featuretools](https://github.com/Featuretools/featuretools) についても紹介しておきます。featuretools はPython製のオープンソースの特徴エンジニアリング自動化ツールです。featuretools を使うことで特徴を自動的に生成することができます。

featuretools では Deep Feature Synthesis(DFS) と呼ばれる方法で新たな特徴を生成しています。DFSでは primitive と呼ばれる関数を使ってデータの集約と変換を行います。primitive の例としては、列の平均や最大値を取る関数を挙げることができます。また自分で定義した関数を primitive として使うこともできます。

百聞は一見にしかずということで、実際にやってみましょう。まずはデモ用のカスタマートランザクションデータを生成します。

```python
>>> import featuretools as ft
>>> es = ft.demo.load_mock_customer(return_entityset=True)
>>> es
Entityset: transactions
  Entities:
    transactions [Rows: 500, Columns: 5]
    products [Rows: 5, Columns: 2]
    sessions [Rows: 35, Columns: 4]
    customers [Rows: 5, Columns: 3]
  Relationships:
    transactions.product_id -> products.product_id
    transactions.session_id -> sessions.session_id
    sessions.customer_id -> customers.customer_id
```

生成されたデータには4つのテーブル(transactions, products, sessions, customers)と3つの関係が定義されています。このうち、`customers`テーブルを対象にprimitiveを適用して特徴を生成します。以下がそのコードです。

```python
>>> feature_matrix, features_defs = ft.dfs(entityset=es, target_entity="customers")
>>> feature_matrix.head(5)
            zip_code  COUNT(sessions)                  ...                   MODE(sessions.MONTH(session_start)) MODE(sessions.WEEKDAY(session_start))
customer_id                                            ...                                                                                            
1              60091               10                  ...                                                     1                                     2
2              02139                8                  ...                                                     1                                     2
3              02139                5                  ...                                                     1                                     2
4              60091                8                  ...                                                     1                                     2
5              02139                4                  ...                                                     1                                     2
```

`features_defs`から以下のような特徴を自動的に生成していることがわかります。　ここで、`MODE`や`SUM`、`STD`というのが primitive です。つまり、`SUM(transactions.amount)`は`transactions`テーブルの`amount`列の合計を特徴として加えるということを意味しています。

```python
>>> pprint(features_defs)
[<Feature: zip_code>,
 <Feature: COUNT(sessions)>,
 <Feature: NUM_UNIQUE(sessions.device)>,
 <Feature: MODE(sessions.device)>,
 <Feature: SUM(transactions.amount)>,
 <Feature: STD(transactions.amount)>,
 <Feature: MAX(transactions.amount)>,
 <Feature: SKEW(transactions.amount)>,
 <Feature: MIN(transactions.amount)>,
 <Feature: MEAN(transactions.amount)>,
 <Feature: COUNT(transactions)>,
 ...
 <Feature: MODE(sessions.WEEKDAY(session_start))>]
```

featuretoolsではこのように特徴を生成することで、特徴エンジニアリングにかかる時間を軽減することができます。

# AutoMLのソフトウェア

AutoMLのための数多くのソフトウェアやサービスがすでに公開されています。ここでは、OSSと非OSSという2つの区分で分けると以下に列挙するソフトウェアがあります。

OSS

* [auto-Weka](https://www.cs.ubc.ca/labs/beta/Projects/autoweka/)
* [auto-sklearn](https://automl.github.io/auto-sklearn/stable/)
* [Auto-Keras](https://autokeras.com/)
* [TPOT](http://epistasislab.github.io/tpot/)
* [H2O AutoML](http://docs.h2o.ai/h2o/latest-stable/h2o-docs/automl.html)
* [devol](https://github.com/joeddav/devol)
* [optuna](https://github.com/pfnet/optuna)

非OSS

* [DataRobot](https://www.datarobot.com/)
* [H2o.ai Driverless AI](https://www.h2o.ai/products/h2o-driverless-ai/)
* [Google Cloud AutoML](https://cloud.google.com/automl/)


# AutoMLの将来

最後はAutoMLの将来についての私見です。まず、AutoMLは将来的にはデータクリーニングのプロセスも扱えるようになるのではないかと考えています。たとえば、テキストのような非構造化データを分析にすぐに使えるようにテーブルデータに変換するといったことです。次に、大規模データにスケールするような方法が出てくるでしょう。Cloud AutoMLを試してみるとわかるのですが、サンプルの小さなデータに対してでさえ計算時間が結構かかります。将来的にはいわゆるビッグデータに対しても使えるようになるでしょう。最後に、性能が人間を上回るようになるでしょう。現在でも一部のデータセットでは人間に匹敵する性能を出していますが、将来的には人間が考えつかないような特徴であるとかネットワークアーキテクチャを生み出せるようになるでしょう。そういう意味では、Alpha Goに似たところはあるかもしれません。


# おわりに

ここ数年で最先端の機械学習に触れやすい環境ができてきました。このような環境で競争力を強化するには、機械学習プロセスの最適化が一つの手です。本記事では、機械学習プロセスを自動化する技術であるAutoMLの概要について紹介しました。本記事で紹介した内容以外にも、環境構築やモデルのデプロイといった部分の効率化も必要ですが、そのへんはまたの機会にしましょう。本記事が皆様のお役に立ったのであれば幸いです。

私のTwitterアカウントでも機械学習や自然言語処理に関する情報をつぶやいています。
[@Hironsan](https://twitter.com/Hironsan13)

この分野にご興味のある方のフォローをお待ちしています。

# 参考資料

**特徴エンジニアリング**

* [Why Automated Feature Engineering Will Change the Way You Do Machine Learning](https://towardsdatascience.com/why-automated-feature-engineering-will-change-the-way-you-do-machine-learning-5c15bf188b96?gi=2978fbc2ade3)
* [Deep Feature Synthesis: How Automated Feature Engineering Works](https://blog.featurelabs.com/deep-feature-synthesis/)
* [Automated Feature Engineering](https://blog.datarobot.com/automated-feature-engineering)

**ニューラルアーキテクチャサーチ**

* [Neural Architecture Search with Reinforcement Learning](http://rll.berkeley.edu/deeprlcoursesp17/docs/quoc_barret.pdf)
* [Learning Transferable Architectures for Scalable Image Recognition](https://arxiv.org/abs/1707.07012)
* [Efficient Neural Architecture Search via Parameter Sharing](https://arxiv.org/abs/1802.03268)
* [Everything you need to know about AutoML and Neural Architecture Search](https://towardsdatascience.com/everything-you-need-to-know-about-automl-and-neural-architecture-search-8db1863682bf)
* [Understanding AutoML and Neural Architecture Search](https://medium.com/aifrontiers/understand-automl-and-neural-architecture-search-4260a0942116)
* [An Opinionated Introduction to AutoML and Neural Architecture Search](https://www.fast.ai/2018/07/16/auto-ml2/)
* [What do machine learning practitioners actually do?](https://www.fast.ai/2018/07/12/auto-ml-1/)

**ハイパーパラメータチューニング**

* [Random Search for Hyper-Parameter Optimization](http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf)
* [A Conceptual Explanation of Bayesian Hyperparameter Optimization for Machine Learning](https://towardsdatascience.com/a-conceptual-explanation-of-bayesian-model-based-hyperparameter-optimization-for-machine-learning-b8172278050f)
* [機械学習モデルのハイパパラメータ最適化](https://www.slideshare.net/greetech/ss-110811527)
* [機械学習のためのベイズ最適化入門](https://www.slideshare.net/hoxo_m/ss-77421091)