機械学習初心者が『Pythonではじめる機械学習』についてまとめてみた。 【5章 モデルの評価と改良】　

#はじめに
　モデルの汎化性能を評価する上で、より頑健な手法である**交差検証**を導入する。また、クラス分類性能と回帰性能を評価する上で、`score`でのデフォルトの*R^2*よりも良い手法について議論されてます。
　教師あり学習で汎化性能を最大にするように効率的にパラメータを調整する**グリッドサーチ**にも触れます。

#交差検証
　**交差検証**では、データの分割を何度も繰り返して行うことで、これまでのただの分割よりも安定した評価を実現する。最もよく用いられるのは、**k分割交差検証**である。例えば、k=5の場合は、分割0から分割4の5つに分割され、分割0から順番にテストセットに、残りの分割を訓練セットにして学習を行い、性能の平均をとる。

##（層化）k分割交差検証
```python
from sklearn.model_selection import cross_val_score
```
　データをk個に分割する際に、先頭から1/k個取る方法はうまくいくとは限らない。なぜなら、データがクラス0から順番に保存されているデータセットもあるためだ。そのため、scikit-learnでは各分割内でのクラスの比率が全体の比率と同じになるように、層化交差検証を行っている。

`cross_val_score`では、デフォルトで3分割交差検証を行い、3つの精度を返す。
`cv`　分割数

##1つ抜き交差検証
```python
from sklearn.model_selection import LeaveOneOut
```
　k分割交差検証の個々の分割が1サンプルしかないと考え、毎回、テストセットの中の1サンプルだけをテストセットとして検証する。大規模なデータセットでは非常に時間がかかるが、小さいデータセットではよりよい推定ができる。

##シャッフル分割交差検証
```python
from sklearn.model_selection import ShuffleSplit
```
　データセットの中から指定した数・割合の訓練セットとテストセットを選び、指定した回数の検証を行う。**サブサンプリング**と呼ばれる、データの一部だけを用いるようにすることもでき、データセットが大きい場合に有用である。
`train_size`　訓練セットの数・割合
`test_size`　テストセットの数・割合
`n_iter`　繰り返しの回数

##グループ付き交差検証
```python
from sklearn.model_selection import GroupKFold
```
　汎化性能を高めるためには、データとしては異なるものの、訓練セットとテストセットに分かれることが好ましくないことがある。例えば、表情から感情を予測する際に、同じ人のデータが分かれることである。なぜならば、学習済の人の表情の予測は容易になるはずであり、未知の人の表情から感情を予測する汎化性能を計るには適切でないためである。
　そのため、配列を用意し、同じグループに属するデータには同じ番号を振ることで、それらのデータをグループ化し、個々のグループはまとまって訓練セットもしくはテストセットに入るように出来る。
`groups`　グループ分けを行うための配列

#グリッドサーチ
　**グリッドサーチ**とは、基本的にはパラメータのすべての組み合わせに対して試して見る方法である。ただし、それぞれのパラメータに対する評価に対してテストセットを使っていては、汎化性能を適切に評価できているとは言い難い。そのため、訓練セット・検証セット・テストセットとデータセットを3つに分割する。

###交差検証を用いたグリッドサーチ
```python
from sklearn.model_selection import GridSearchCV
```
　グリッドサーチは一般に用いられているが、データの実際の分割のされ方によって大きく性能が変わる。そのため、それぞれのパラメータの組み合わせに対して交差検証を行うとよい。ただし、パラメータ2つをそれぞれ6つの値で、交差検証を5回行うとすると、6×6×5=180通りのモデルを訓練する必要がある。これには非常に時間がかかることが大きな問題点である。

###ネストした交差検証
　上記のグリッドサーチでは、データセットを訓練セットとテストセットに一度だけ分け、訓練セット上で交差検証を行い、訓練セットと検証セットに分けた。訓練セットとテストセットの分割が一度だけの場合、その分割の仕方に結果が依存する場合がある。そのため、訓練セットとテストにも交差検証による分割を適用する。この手法を**ネストした交差検証**と呼ぶ。
　ネストした交差検証をscikit-learnで行うのは容易で、`cross_val_score`を`GridSearchCV`のインスタンスをモデルとして呼び出せば良い。

#評価基準とスコア
　機械学習の基準を選ぶときには、そのアプリケーションによって最終的な目的を考える必要がある。横軸を予測ラベル、縦軸を新ラベルとし、あてはまるデータの数を成分とした行列を**混同行列**と呼ぶ。

##2クラス分類
　2クラス分類では、2つのクラスを**陽性**と**陰性**と呼ぶ。予測・実際の値がともに陽性のときを**真陽性（TP）**、予測・実際の値がともに陰性のときを**真陰性（TN)**と呼ぶ。また、陽性と予測したが実際は陰性のときを**偽陽性（FP）**、この逆のときを**偽陰性（FN）**と呼ぶ。

```python
from sklearn.metrics import classification_report
```
　以下の3つの評価基準をクラスごとにそのクラスを陽性とした場合に値を出力してくれる。同時に**支持度**と呼ばれる、陽性のデータの数も出力してくれる。

###適合率
```math
適合率=\frac{TP}{TP+FP}
```
　適合率は、陽性であると予測されたものがどれだけ実際に陽性であったかを表す。偽陽性の数を制限したい場合に基準として用いられる。

###再現率
```math
再現率=\frac{TP}{TP+FN}
```
　再現率は、実際に陽性のデータのうち、陽性と予測されたものの割合を示す。偽陰性を避けることが重要な場合に基準として用いられる。例えば、ガンの診断。

###f-値
```math
F=2×\frac{適合率×再現率}{適合率+再現率}
```
　適合率と再現率がトレードオフである。すべてを陽性と判定すれば再現率は100%となるが、適合率は非常に小さくなる。一方、最も真である可能性が高いもの1つだけを真とすれば、適合率は100%となるが、再現率は非常に小さくなる。
　適合率と再現率はそれぞれ非常に重要な基準であるが、一方だけでは全体像がつかめない。そのため、これら2つを包括的に評価するf-値という基準がある。これは、適合率と再現率の調和平均によって求められる。（f-値の変種の1つであり、他にもあるらしい）

###適合率・再現率カーブ
```python
from sklearn.metrics import precision_recall_curve, average_precision_score
```
　カーブが右上に近いほど、適合率と再現率が同時に高いため、良いクラス分類器であることがわかる。カーブを要約する方法の1つとして、カーブ下の領域（AUC）を積分することがあり、これは**平均適合率**とも呼ばれる。

###受信者動作特性カーブ（ROCカーブ）
```python
from sklearn.metrics import roc_curve, roc_auc_score
```
　横軸に**偽陽性率**、縦軸に**真陽性率（再現率）**をとる。低い偽陽性率を保ちながら、高い再現率を達成したいので、左上に近いほどよいクラス分類器と言える。同様にして、ROCカーブのAUCを積分することで要約することができる。

###

###予測の不確実性
　ほとんどのクラス分類器には、予測の不確実性を評価するための`decision_function`メソッドもしくは`predict_proba`メソッドがある。予測の閾値は、デフォルトでは前者が0、後者が0.5となっている。例えば、偽陽性が増えてもよいからより多くの真陽性を得たい場合は、閾値を小さくすることで再現率を上げることができる。

##他クラス分類
　他クラス分類においても、`classification_report`によって適合率・再現率・f-値を求めることができる。クラスごとのf-値を平均する方法は以下の3つがある。

`macro`　重みをつけずにクラスごとのf-値を平均する。個々の**クラス**を同じように重視している。
`weighted`　各クラスの支持度に応じて重みをつけてクラスごとのf-値を平均する。
`micro`　すべてのクラスの偽陽性・偽陰性・真陽性の総数を計算し、その値を用いて計算する。個々の**サンプル**を同じように重視している。

##回帰
　R^2スコアが最も直観的。

#参考文献
Pythonではじめる機械学習
――scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
Andreas C. Muller、Sarah Guido　著、中田 秀基　訳