[Kaggle]いろいろとTitanicしてみる：過剰適合/過学習/交差検証


# 目的
交差検証について調べたりコード化してみる

そもそもの発端としては
[前回](https://qiita.com/ryo_naka/items/5dea55f441a0055cc26a)の訓練データだと90ぐらいのスコアになったのをアップロードしてみたらちょこっとしかUPしてなかったということである。
以下のようなろくでもない検証にしかしてなかったのでダメだろうとは思っていたが
ここまで差が出るとはちょっとびっくりであった。

	evaluation_score = round(model.score(features , target) * 100, 2)

## なので、調べてみることにした。

[過剰適合]
https://ja.wikipedia.org/wiki/%E9%81%8E%E5%89%B0%E9%81%A9%E5%90%88

[交差検証]
https://ja.wikipedia.org/wiki/%E4%BA%A4%E5%B7%AE%E6%A4%9C%E8%A8%BC

ググってみた。


https://tjo.hatenablog.com/entry/2016/04/14/190000

>「モデルの説明変数は必要以上に増やせば増やすほど学習データのシグナルだけでなくノイズにまでフィットしてしまう」

訓練データに最適化しすぎると、訓練データ内のノイズについても何かしらのモデルから生成されたものなのではないかという推論モデルを構築してしまうということなわけだ。
これは仕事の世界でも割とありそうな話。

>また、これは割と嫌な話ですが「交差検証したからと言って汎化性能が確保できるとは限らない」ケースもあるということ。特に学習データと（テストデータではない本当の）新規の未知データとで性質が全く違うようなケースでは、いかな汎化性能の高いモデルでも太刀打ちできません。時々Kaggleでその手のデータセットが出てきて物議を醸すことがありますが、実務でも同様のことは少なくないです。

## そして実装へ
交差検証のロジックを調べて実装してみるかなーと思って捜索してたらびっくりした。

https://qiita.com/yhyhyhjp/items/d4b796f7658b7e5be3b6
scikit-learnのモジュールの中にあるらしい。
・・・みなが扱うのだから、それもそうか。

ちなみに上記に記載してあるとおりに実装してみると何やらワーニングが出た。


`C:\Program Files\Anaconda3\lib\site-packages\sklearn\cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
  "This module will be removed in 0.20.", DeprecationWarning)`

と思ったら、その上でcross_validationをimportしていたからっぽい。

	from sklearn import cross_validation  # ←ここでワーニング
	from sklearn.model_selection import cross_val_score
	scores = cross_val_score(model, features, target)
	# pprint.pprint(scores)
	# 各分割におけるスコア
	print('Cross-Validation scores: {}'.format(scores))
	# スコアの平均値
	# import numpy as np
	evaluation_score = np.mean(scores)
	print('Average score: {}'.format(evaluation_score))

cross_validationは使えなくなるのでmodel_selectionにしないといけないらしいのだが、そもそもまだ未使用なのでコメントアウトしておく
※参考：https://qiita.com/kasajei/items/e23929627d51aa1b09fe

### ドキュメントも見てみる
http://scikit-learn.org/stable/modules/cross_validation.html

### cvの数を変えるとどうなるのか？

	li = [i for i in range(4, 10)]
	li.append(100)
	for n in li:
	    print('Average score {}: {}'.format(n, np.mean(cross_val_score(model, features, target, cv=n))))

↓

	Average score: 0.7833894500561166
	Average score 4: 0.7991231041259068
	Average score 5: 0.8047747932733926
	Average score 6: 0.8036383699135378
	Average score 7: 0.8060033232453085
	Average score 8: 0.8071141555516557
	Average score 9: 0.8035914702581368
	Average score 100 : 0.8036111111111112

こんな感じだ。
100にしたからといってそこまで精度が上がるということでもなさそう。
というか、何をもって「精度が上がった」と言っているのかも自分ではよくわからない。
なので、とりあえず5ぐらいとして実施してみることにする。
この状態で各モデルに対して改めて検証してみる。

	                model_name     score
	0             DecisionTree  0.804775
	6            Random Forest  0.804775
	1       LogisticRegression  0.790168
	4     Gaussian Naive Bayes  0.789031
	3                k近傍法(KNN)  0.700442
	2  Support Vector Machines  0.697160
	5               Perceptron  0.627463

DecisionTreeがRandom Forestを逆転するという結果に。
また、Random Forestもsocreはよいが、前回ほどアホみたいな数値にはなっていない。
実際はこれよりも下がると考えると常識的な数値が出る検証となったと言えるかもしれない。

ただ、この検証スコアを信じるとDecisionTreeの方が高い結果になるはずなのだが、
前回アップロードした結果だとRandom Forestの方が若干高い。難しいな。

# ハイパーパラメータのチューニング
交差検証を調べていたら以下の記事に遭遇
https://qiita.com/tomov3/items/039d4271ed30490edf7b

これの後半にモデルに対するパラメータのチューニングの仕方が載っていた。
※というか、本来は体系立てて学習していくことな気もしてきたがとりあえず気にしない。

なので、TODOとしてはモデルに対するパラメータチューニングもそのうち試してみるやることにする。