機械学習の流れ(現時点での理解)

どんな記事か
--
書籍などを通じて学んだ機械学習の流れを備忘録的に記している。

(注)実装パートはこの記事には含まれていない。機械学習モデルを作るときのお気持ちを読むものだと理解してほしい。また、これが正しい！というものでもない。

「データあるし予測とかしたらいけるやろ、実装も軽そうやし2時間あれば終わるわ」
確かにそう、一言に言うとそう。でもいざやってみるとデータの前処理、特徴量選択、モデル選択等々迷った。

この記事では、以下のパートから構成される。気になるところがあれば、シチュエーションを読んでから、各項目を読み進めてほしい。

- データの確認
- 特徴量選択
- モデル選択
- パラメータチューニング



シチュエーション
--
今回は、データが与えられていてそれらから特定の値を予測するモデルを構築するという場面を想定している。
例えば部屋の大きさ、家賃、アパート名、光熱費、空き部屋の数、住んでいる人数がデータとして与えられていて(１００件くらいのデータ)、住んでいる人数を予測するという場面である。(要するに回帰)
ただし、アパート名の重複は今回の問題では許さない。
予測される値(今回は住んでいる人数)のことを目的変数、それ以外を説明変数という。


データの分析
--
まずはデータをじっくりみよう。
- 欠損値は含まれていないか？
- データの分布はどうなっているだろうか？
- 分散はどれくらいなのか？
- カテゴリ変数はあるだろうか？(どう変換しよう？)

これらについて調べていこう。

**なぜ欠損値を確認する必要があるか？**
データが欠損値を含む場合、ほとんどの場合はうまく回帰できない。(モデルが欠損値がないことを前提としている)
なので、欠損値を補完する処理が別途必要。一応欠損値があってもXGboost(勾配ブースティング木)とかはいいらしい。

欠損値の補完方法などは、追記していけたらと思う。


**データの分布と分散を調べてみよう**
特徴量のスケーリングをする際にデータの分布によって処理を変えるので、データの分布を調べよう。
データの分布を知るために、平均値と中央値、分散を一旦は見てみよう(ちゃんと見たければviolinplotとかを使用)
平均値と中央値が極端に離れていたら、分布が歪んでるかも。


**カテゴリ変数**
カテゴリ変数は数値でないデータで、そのままではモデルの学習には使えない。
それだと困るので、学習に用いるために様々な手法で変換される。

**カテゴリ変数の変換**
カテゴリ変数の変換にはいくつか種類がある。
今回はアパート名[むつみ荘、さくら荘、ロイヤルヒルズ練馬、またずれ荘]を変換することを考える。

- ワンホット：[1 0 0 0],[0 1 0 0],[0 0 1 0],[0 0 0 1]のように各項目のどれに当てはまるかが1で表される。多重共線性の問題に注意しなくてはならない。
- ダミー変数化：[1 0 0],[0 1 0],[0 0 1],[0 0 0]ワンホットとかなり近いが、１次元減っている。これによって多重共線性の問題は緩和されるらしい。
- ラベルエンコーディング：むつみ荘は１、さくら荘は２のようにラベルを貼っていく方法。ただし、カテゴリ変数に順序関係(S,M,Lとか)がない場合以外は不適。
- 埋め込み：[0.2,-0.6]みたいにニューラルネット等を用いてカテゴリ変数の埋め込み表現を獲得する。

特徴量選択
--
与えられたデータから、なんとなく部屋の大きさと住んでいる人数は関係がありそうであるが、アパート名は関係なさそう。ということは理解できるであろう。
実際にモデルを構築する際には予測に利用する特徴量を選択するのが一般的である。余計な特徴量があるとかえってモデルの性能が劣化するようだ。なので、今回はアパート名は特徴量から除外しよう。

さて、これでよかったのか？

確かに関係なさそうで、実際におそらくそうであろう。
しかし特徴量の選択に説明を求められたとき、「なんとなく」では済まされない。

特徴量選択には様々な手法が存在しているが3つに大別される。
- Filter法：学習の前にデータを見て決める
- Wrapper法：モデルに入れていって試す
- Embedded法：モデルに特徴量選択を任せる

詳しいことは調べれば出てくるのでそちらをどうぞ。今回はFilter法(のはず)でやってみよう。

**相関係数を計算しよう**
目的変数と説明変数の相関係数を算出すると両者の「線形的な」関係がわかる。
決して相関がないというだけでその特徴量を削除してはいけない。
目的変数と説明変数の関係だけを調べてもいけない。説明変数間でも相関関係があるかもしれないからである。
説明変数間に相関関係が強くあるとき、それは「多重共線性」という問題を抱えていることになる。

多重共線性があると線形モデルを用いて回帰等を行うならうまくいかないことが多いらしい。
もし線形モデルを利用する(つもり)なら、VIFと呼ばれる指標があり、これを元に特徴量の削減を行おう。
他にも、主成分分析を行うことで特徴量を減らすというのも考えられる。

**HSICを計算しよう**
一方HSICは変数同士の「非線形な」関係もわかる。
扱いに関しては不勉強なのでよくわかっていない。あくまで筆者もこの領域を勉強しているところである。

**根拠を説明してみよう**
今回の例であるなら、アパート名はシチュエーションより、重複しない。
このとき、単にカテゴリ変数をダミー変数化すると非常に疎な(ほとんどが0)ベクトルができてしまう。疎なベクトルは一般に機械学習には不向きである。(使いたいなら埋め込み表現を獲得するのが良さそう)
また、アパート名は固有名詞であり、そのほかの情報で補完可能であると考えた。とか。

他にも、相関係数やHSICの結果から特徴量を削除した。とか。

今回はFilter法で説明しているが、ランダムフォレストを利用したBorutaなどで特徴量選択を行うのも考えられる。

モデル選択
--
機械学習モデルは非常に多い。この中からどれが良いのかを選ぶのが難しいのは当然。
scikit-learnなどがモデル選択のチートシートを公開しているのでそれを参照すると良いかも。

**なにがしたいか**
機械学習は大きく分けるとデータに正解がある「教師あり学習」、データに正解がない「教師なし学習」がある。(他にも強化学習や半教師あり学習などいろいろあるけど。。。)
データを用いて予測がしたいなら前者になる。前者でも、値そのものを教えてほしいなら「回帰」、グループを教えてほしいなら「分類」になる。

**どんなデータか**
機械学習モデルはデータの大きさによって得意不得意がある。

**なにを求めているか**
精度重視ならニューラルネット、速さ重視なら線形モデル、予測した結論を説明したいなら決定木、のようにある程度の棲み分けはされている。

**ニューラルネット**
とにかく精度重視ならこれ。ただし欠点もしっかりある。例えばデータが少ないとそれほど良い成績は出ない。あと結果の説明ができない。(モデルの大きさによるが)学習に時間もかかる。データがたくさんあって、とにかく精度重視ならこれっぽい。

**線形モデル**
速さ重視ならこれ。行列の計算をするだけなので超早い。
基底関数の選び方で非線形な関係もいける。

**決定木**
データがそれほどないときは困ったら決定木のアンサンブル選んどけば良い気がする。非線形な関係も捉えられて、結果の説明がしやすい。特徴量の重要度も出してくれる。

決定木のアンサンブルは主に、
- ブースティング：勾配ブースティング木
- バギング：ランダムフォレスト
がある。
ブースティングは「先人に習う」で前のモデルが間違えたデータに重みをつけて学習していく。
バギングは「3人よれば文殊の知恵」で一つ一つのモデルの平均を取ることで最終的な結論を出す。中身のモデルたちが過学習を起こしていても、平均を取られることでそれが緩和されるらしい。

**AIC(赤池情報量規準)**
「基準」でないことに注意。
どっちが良いモデルなのかを教えてくれる指標。まだ勉強中なので、これについてもまとめて投稿したいと考えている。



パラメータチューニング
--
ハイパーパラメータとは、人手で調節しなくてはならないパラメータを指す。
ランダムフォレストなら決定木の数、深さなどのことである。
実は、モデルの性能について重要なハイパーパラメータはごく一部しかないということが実験からわかっている。(Low Effective Dimensionalityという)
ハイパーパラメータチューニングは以下の二つに大別される。

- ブラックボックス最適化：目的間数値のみを利用して最適化。モデルの詳細に依存しない。こっちが主流
- グレーボックス最適化：対象問題の特徴から得られる最適化に有用な情報を活用してブラックボックスを高速化。

これらの手法の例を見てみよう

**ブラックボックス最適化**

- グリッドサーチ：愚直にパラメータの組み合わせを全部試す
- ランダムサーチ：乱数に基づいてパラメータの組み合わせを試す
- ベイズ最適化：ハイパーパラメータのチューニングで最も成功している。この手法は以下を繰り返す。
観測データから代理モデル(評価コストが高い目的関数や有望なパラメータ設定を近似)を構築 → 代理モデルから獲得関数(効率的に有望なパラメータをサンプルする指標)を計算、次に評価するパラメータ設定を選択 → 設定したパラメータを評価する

他にも進化計算やNelder-Mead法(SVM,CNNで活躍)などもある。

**グレーボックス最適化**

グレーボックス最適化は対象問題に仮定を与えて高速化をおこなっている。

- データのサブサンプリング：損失関数がデータの増減に対してある程度ロバスト。目的関数の評価コストを下げて高速化
- 学習の早期打ち切り：学習が反復可能、損失関数が学習経過に対してある程度ロバスト。目的関数の評価コストを下げて高速化
- ウォームスタート：過去に解いたハイパーパラメータ最適化問題の結果を利用して最適化

他にもベイジアンニューラルネットワークなどに基づく手法などもある。

終わりに
--
今回は、機械学習の流れについてざっくりと学んだことをまとめてみた。
各項目について詳細に知る必要がある場合は参考文献をあげておくので、そちらを参照してほしい。

参考文献
--
- Alice Zheng , Amanda Casari. 機械学習のための特徴量エンジニアリング ―その原理とPythonによる実践.  株式会社ホクソエム. オライリージャパン, 2019, 224p.
- Andreas C. Muller , Sarah Guido.Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎. 中田 秀基.オライリージャパン, 2017 , 392p.
- Valliappa Lakshmanan, Sara Robinson,Michael Munn. 機械学習デザインパターン ―データ準備、モデル構築、MLOpsの実践上の問題と解決. 鷲崎 弘宜 , 竹内 広宜 , 名取 直毅 , 吉岡 信和.オライリージャパン, 2021,414p.
- 尾崎嘉彦ほか. 機械学習におけるハイパーパラメータ最適化手法：概要と特徴. 電子情報通信学会論文誌D. 2020, Vol.J103-D, pp.615-631.