Lesson14: Validationまとめ Intro to Machine learning@Udacity 

#Lesson14の概要
ここまでのlessonで交差検証等は使ってきたが、このlessonではもっと、包括的に解説してくれるみたい。ホールドアウト検証・交差検証について

#データをトレーニングデータとテストデータの分割の仕方：train/test split in sklearn
もし、そのことで悩んだらこちらを参照にすること。
[3.1. Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)
分割の仕方には大まかに2種類ある。ホールドアウトと交差。
講義の前半・Mini-projectではホールドアウトやる。途中に交差が入る。

<PCAが入る場合の処理の流れ>
train/test split（ホールドアウトor交差）
↓
◆トレーニング段階
pca.fit(training_features)：トレーニングデータに対して主成分の統計分析
pca.transform(training_features)：fit結果を使って実際にトレーニングデータ変換
↓
svc.fit(training_feaures):分類器に主成分分析したトレーニングデータを入力
↓
◆テスト段階
pca.transform(test_features)：テストデータに対して主成分の統計分析
svc.predict(test_feaures)：トレーニング段階で学習した分類器に主成分分析後のテストデータ入力

fitとtransformの違いは@makopoさんの[scikit-learn の fit() / transform() / fit_transform()](https://qiita.com/makopo/items/35c103e2df2e282f839a)が大変わかりやすい。統計値を計算するのがfit、それを使って実際にデータを変換するのがtransformなのね。

◆pcaのトレーニング(fit)段階では
pca.fit(training_features),  **pca.transform(training_feaures)**
としてSVMに入力する。

◆テスト段階では
**pca.transform(test_features)**
のみ行う。fitをテストデータに対して行ってしまうと、トレーニング段階で計算した統計量が変わってしまうので。
PCAについては[Lesson13: PCA 主成分分析まとめ　Intro to Machine learning@Udacity](https://qiita.com/Allovertom/items/84087cd2bd502116b1bc)を参照。


##交差検証：Cross Validation
トレーニングデータとテストデータの数を一番効果のある最大の数にしたいが、これらは明らかにトレードオフの関係。ただ、すべてのデータをトレーニングデータ＆テストデータとして使用する方法がある。
それがk-fold cross validation：K分割交差検証らしい。
[wikipedia:交差検証](https://ja.wikipedia.org/wiki/%E4%BA%A4%E5%B7%AE%E6%A4%9C%E8%A8%BC#K-%E5%88%86%E5%89%B2%E4%BA%A4%E5%B7%AE%E6%A4%9C%E8%A8%BC)より引用
>英名では"K-fold cross-validation"。K-分割交差検証では、標本群をK個に分割する。そして、そのうちの1つをテスト事例とし、残る K − 1 個を訓練事例とするのが一般的である。交差検証は、K 個に分割された標本群それぞれをテスト事例として k 回検証を行う。そうやって得られた k 回の結果を平均して1つの推定を得る。

ここで注意。
きれいに並べてあるデータをデフォルトのk-foldでテストデータとトレーニングデータに分けてしまうと、正しく学習＆予測できない。
例えばテストデータのラベルが：[1,1,1,1,1]、トレーニングデータのラベル：[0,0,0,0,1]と[0,1,0,1,0]（K=3）。各foldでラベルがかたよらないようにシャッフルしたい。

◆ランダマイズ
[sklearn.model_selection.KFold](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html#sklearn.model_selection.KFold)に書いてある、shuffle=trueにすれば、ランダマイズしてくれる。からこれを使うようにとのこと。各foldの中身をランダムでバラバラにしてくれるようだ。

◆各foldの、ラベルの比率を一定にする分け方
[sklearn.model_selection.StratifiedKFold](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html)も使おうと書いてある。これはどうやら、ラベルが2つ(0,1)なら、各foldの中の0,1の比率がだいたい同じになるように各foldの中身を選択してくれるみたい。

[scikit learn の Kfold, StratifiedKFold, ShuffleSplit の違い](http://nakano-tomofumi.hatenablog.com/entry/2018/01/15/172427)を参考にさせていただきました。

###Cross Validation for Parameter Tuning
SVMや決定木などのアルゴリズムで、精度の高い結果を得るために、私たち人が推測して、パラメーターチューニングをしてきたが、骨が折れた。[sklearn.model_selection.GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)を使えば、それが自動になる！←ほんとか！

例）
[sklearn.model_selection.GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)のドキュメンテーションの中にあるExampleを例に。

```python

parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
svr = svm.SVC()
clf = grid_search.GridSearchCV(svr, parameters)
clf.fit(iris.data, iris.target)
```

```parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
```

ディクショナリのパラメータを設定。それぞれがとることが可能なものをすべて入れ込んでいる。この場合はカーネルがliner or rbf, Cが1 or 10。
このパラメータができたら、下記のようにGrid(格子)を作ってくれる。
(rbf, 1)   (rbf, 10)
(linear, 1) (linear,10)
それぞれがSVMをトレーニングするのに使ってくれ、性能がCross Validationを使って評価してくれる。

```svr = svm.SVC()
```

ここでclassifierを作っているわけではなく、ここで「どのアルゴルズムを使うか」だけを宣言している。classifier = altorithm + parameter value.

```clf = grid_search.GridSearchCV(svr, parameters)```


Classifierを作成。アルゴリズムとディクショナリのパラメーターを入力すると、パラメーター格子を生成してくれる。

```clf.fit(iris.data, iris.target)
```

このコードで、すべてのパラメーターの組み合わせにて学習し、最も性能のよかった、Classifierを返す。
```clf.best_params_```
によって、そのパラメーターにアクセスできる。

#Mini-project
Enronデータセットを使ってPOI-identifierを作る。
ただ、ここで使うのは交差検証ではなく、ホールドアウト検証。
ちなみに[wikipedia:交差検証](https://ja.wikipedia.org/wiki/%E4%BA%A4%E5%B7%AE%E6%A4%9C%E8%A8%BC#K-%E5%88%86%E5%89%B2%E4%BA%A4%E5%B7%AE%E6%A4%9C%E8%A8%BC)によると
>ホールドアウト検証
>初期標本群から事例を無作為に選択してテスト事例を形成し、残る事例を訓練事例とする。テスト事例に使われるのは初期の標本群の3分の1以下の場合が多い[5]。ただし一般にホールドアウト検証は交差検証には分類されない。なぜなら、データを交差させることがないためである。

みたい。
◆1st part：全部のfeatures, labelsを使ってclfをトレーニング。スコア出す。
◆2nd part：30%hold outでrandom_state = 42とする。再現性があるようにするには42を指定するらしい。

```python

### it's all yours from here forward!  
from sklearn import tree
from sklearn.model_selection import train_test_split
#1st part
clf = tree.DecisionTreeClassifier()
clf = clf.fit(features, labels)
score = clf.score(features, labels)
print score #Quiz17


#2nd part
X_train, X_test, y_train, y_test = train_test_split(\
	features, labels, test_size=0.3, random_state=42)


clf2 = tree.DecisionTreeClassifier()
clf2 = clf2.fit(X_train, y_train)
score2 = clf2.score(X_test, y_test)
print score2 #Quiz18

```

#感想
今回はホールドアウト検証と交差検証を学んだ。
交差検証で、データを全部使ってフルにできるのは賢いなー！！


#調べた英単語
validation・・・n, 批准、確認
assess・・・v, (…と)評価する、査定する、(…と)査定する、性質を評価する、値踏みする、課する
explicitly・・・adv, (言葉に出して)はっきりと、明白に
inherent・・・adj, 固有の、本来の、生来の、(…に)内在して、つきもので、固有で
indices・・n, indexの複数形
stratify・・・v, (…に)層を形成させる、(…を)層状にする、階層化する、階級に分ける
grid・・・n, (鉄)格子、(肉・魚を焼く)焼き網、(自動車の屋根の)格子状荷台、(電線・水道・ガスなどの)敷設網、送電網、(街路の)碁盤目、(地図の上に引かれた検索用の)碁盤目、グリッド
viable・・・n, 存立できる、実行可能な、生存できる