Coursera Machine Learningのまとめ(機械学習適用に関するアドバイス編)

#はじめに
ニューラルネットワーク編に引き続き、Week6の様々なモデルの評価方法や精度向上の方法を勉強していく。
かなり実践的な内容になっているので、ここはしっかりと押さえておきたい。

#モデルの修正でやること
一度作成したモデルの精度を向上させるためにできることとして、以下のような対応が挙げられる。

* もっと多くの訓練データを集める
* 特徴量を増やして/減らしてみる
* 正則化パラメータのλを増やして/減らしてみる

がしかし、これらの方法からランダムに選ぶのは効率が悪い。
ここでは、様々なケースに対して、どういうアクションを取るのが効果的かを学ぶ。

#データセットを分けてモデルを評価する
訓練データセットでモデルを訓練しただけでは、未知のデータにどれくらい有効かが分からないので、そのモデルが過学習に陥っているのか、訓練不足なのか、等、判断が難しい。

そこで、与えられた訓練データを分割し、評価することを考える。
データ分割の考え方はいくつか考えられる。

* 訓練データ(70%)とテストデータ(30%)に分ける。
* 訓練データ(60%)、クロスバリデーションデータ(20%)、テストデータ(20%)に分ける。

例えば後者のパターンだと、

* 訓練データ(60%)を使ってモデルを訓練する。
* クロスバリデーションデータ(20%)を使って、最も損失が小さくなる$Θ$を探す。(多項式の次数とか)
* テストデータ(20%)を使って、本当の性能を評価する。

みたいにすることで、訓練データやクロスバリデーションデータへの過学習を避けつつ、モデルを評価することができる。

#過学習か学習不足か(高バリアンスと高バイアス)の評価
モデルが過学習に陥っているのか、それとも学習不足なのかを知ることは、モデルを修正していくうえでとても重要。
例えば多項式の次数を増やせば、モデルはどんどん訓練データに適応していく一方で、過学習に陥ってクロスバリデーションデータでは性能が出ない、ということが起こる。

学習不足の状態を高バイアス、過学習の状態を高バリアンスの状態と呼ぶ。

以下の図を見ると分かりやすいけど、高バイアスの状態では、訓練データに対してもクロスバリデーションデータ出たに対しても、コストが大きくなる。
一方で、高バリアンスの状態だと、訓練データのコストは小さくなるけど、クロスバリデーションデータのコストは大きくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633548/54adf422-9ec4-f9e8-9b33-ff675c9a6941.png)

つまり、

* 高バイアス時　⇒　多項式の次数が小さく学習不足

```math
J_{train}(Θ)が大きい　かつ　J_{CV}(Θ)が大きい　かつ　J_{train}(Θ) \approx J_{CV}(Θ)
```

* 高バリアンス時　⇒　多項式の次数が大きく過学習

```math
J_{train}(Θ)が小さい　かつ　J_{CV}(Θ)が大きい　かつ　J_{train}(Θ) \ll J_{CV}(Θ)
```

　
我々がやるべきことは、訓練データとクロスバリデーションデータのコストをグラフなりで可視化して、クロスバリデーションデータのコストが最小になるような点(多項式の次数)を見つけることと言える。

#正則化パラメータλとバイアス/バリアンスの関係
モデルの複雑さをコントロールする手段として、正則化を学んだ。
正則化パラメータであるλを大きくすると、モデルの複雑さが抑制される一方で、高バイアスに陥ってしまう可能性がある。
逆にλが小さすぎると、モデルの複雑さが制御できず、高バリアンスの状態となる。

グラフにするとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633548/b56fab20-b16e-e538-b0b3-531fbf64f0e6.png)

ここでも同じく、クロスバリデーションデータのコストが小さくなるようなλの値を調べて決めてあげることが大事になる。

#学習曲線
学習曲線とは、訓練データ数とコストの関係をグラフ化したもの。
普通、訓練データセットが増えるほど訓練データのコストは大きくなり、クロスバリデーションデータのコストは小さくなる。

ただし、高バイアスの状態と高バリアンスの状態では、学習曲線の少し挙動が異なる。

1. 高バイアスの場合
 * 訓練データが少ない場合     
   $$J_{train}(Θ)が小さい　かつ　J_{CV}(Θ)が大きい$$
　
 * 訓練データが多い場合
   $$J_{train}(Θ)が大きい　かつ　J_{CV}(Θ)が大きい　かつ　J_{train}(Θ) \approx J_{CV}(Θ)$$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633548/bdd214e6-e304-d073-9d36-da4fc54a2663.png)


2. 高バリアンスの場合
 * 訓練データが少ない場合     
   $$J_{train}(Θ)が小さい　かつ　J_{CV}(Θ)が大きい$$
　
 * 訓練データが多い場合

```math
\begin{align}
&J_{train}(Θ)は徐々に大きくなる　かつ　J_{CV}(Θ)が徐々に小さくなる \\
&かつ　J_{train}(Θ) < J_{CV}(Θ)
\end{align}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633548/198fccc5-bd17-8f3d-f092-a6330dce6f26.png)

#ここまでのまとめ
* 高バリアンスを是正するための手段
    * もっと多くのトレーニングデータを準備する
    * 特徴量を減らす
    * 正則化パラメータλを大きくする

* 高バイアスを是正するための手段
    * 特徴量を増やす
    * 多項式特徴量を追加する
    * 正則化パラメータλを小さくする

##ニューラルネットワークに関して
* パラメータが少ないと学習不足になりがちで、計算コストは小さい。

* パラメータが多いと過学習になりがちで、計算コストも大きい。

#スキューなデータに対する評価
分類問題において、スキューなデータ、つまり分類結果が大きく偏ったデータの場合、分類正答率だけを見ると、良いモデルが得られないことがある。

例えば、全体の0.5%だけがガン患者のデータがあり、ガンかそうでないかを予測する場合を考える。
この時、常に「ガンではない」と予測するモデルがあると、正答率は99.5%になる。
正答率だけ見るとものすごく高いけど、これは良いモデルとは言えない。

そこで、精度(Precision)と再現率(Pecall)という指標を導入する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633548/c936baae-9020-9fed-83c8-60ba73540076.png)

これまで議論してきた正答率(Accuracy)は以下計算式だった。

$$正答率(Accuracy) = \frac{True Positive + True Negative}{TotalData}$$

精度(Precision)と再現率(Recall)は以下の計算式になる。

```math
\begin{align}
精度(Precision) &= \frac{TruePositive}{TotalPredictedPositive} = \frac{TruePositive}{TruePositive+FalsePositive} \\
\\
再現率(Recall) &= \frac{TruePositive}{TotalActualPositive} = \frac{TruePositive}{TruePositive + FalseNegative}
\end{align}
```

例えばさっきのガンの例で、1000サンプル中5件がガンの場合、全てを「ガンではない」と予測したとすると、PrecisionとRecallの観点ではさっぱり使えないモデルということになる。

PrecisionとRecallはトレードオフの関係にある。
そのサンプルが1だと判断する$h_θ(x)$の閾値は大体0.5に置くことが多いけど、例えば閾値を0.7とかに上げればPrecisionは上がってRecallは下がるし、閾値を0.3とかに下げればPrecisionが下がってRecallは上がる。

PrecisionとRecallの値を評価するのに使える指標として、Fスコア、もしくはF1スコアというのがある。
Fスコアが大きいということは、PrecisionとRecallの両方が大きいということになる。

$$F_1 = 2 \frac{PrecisionRecall}{Precision + Recall}$$

実際の運用を考えてみると、目的に応じてPrecisionかRecallのどちらを大きくしたいのかが変わってきそう。
例えばガンの判定だと、見逃してしまうとその人は死んでしまう可能性があるので、AccuracyやPrecisionを下げてでも、Recallを上げて検知漏れを無くす必要があるかもしれない。

#たくさんのデータを集めるべきケース
現在持っているデータの特徴量と値をその道の専門家に見せて、有意義な予測が得られそうな場合は、たくさんのデータを集める価値がある。

十分な特徴量がある場合はこれまで学んだアルゴリズムは訓練データによくフィットするはず。
一方で、データ量が少ないと過学習してしまうかもしれないので、たくさんのデータを集めて、モデルをより汎化していくことが望ましいということだろう。

#まとめ
今回は特定のアルゴリズムではなく、様々なケースにおけるモデルの改良の仕方を勉強した。

モデルを実装するのはscikit-learnなんかを使うと一瞬でできてしまうので、実際にはこういうデータによってモデルを改良していくような作業こそが、データサイエンティストには求められているんだと思う。

実践で慣れていきたい。