一から始める機械学習（Kaggleで学ぶ機械学習）

## このページの対象読者、目的
### 対象読者
・機械学習の概要がわかっている方　
・もしくは[一から始める機械学習(機械学習概要)](http://qiita.com/taki_tflare/items/42a40119d3d8e622edd2)を読んだ方が対象です

### 目的
　・Kaggleについて理解する
　・機械学習について実際の流れを理解する
　・Kaggleのチュートリアルを用いて実践を行う
　・scikit-learnを用いて実践を行う
## アジェンダ
1.  Kaggleとは
2.  なぜKaggle？
3.  Kaggleチュートリアル（Titanic: Machine Learning from Disaster）
4.  データの中でどれを使う？
5.  データ前処理
6.  使用データ
7.  使用する学習手法
8.  学習実行と交差検証
9.  最適化
10.  機械学習の流れ
11. 企業のコンテストを一部紹介

このページはプレゼンテーションを再編集したものです。
オリジナルであるプレゼンテーションをみたい方はこちらをどうぞ
https://www.edocr.com/v/vlzyelxe/tflare/Kaggle_-Machine-learning-to-learn-at-Kaggle

## 1.  Kaggleとは
誤解を恐れずにまとめれば
「Kaggleは企業や研究家が、データサイエンス、機械学習関連のお題をだしてそれを解くサイトです。賞金がつくものもあり（さらにそれを解くためのコードを公開しかつ説明する。その説明についてコメント等でコミュニケーションを行う機能もあり）

## 2.  なぜKaggle？
・本などの説明では、説明のためのデータセットが使われていることが多く、実感が湧きにくい。
・本などの説明では端折られる箇所も、実施する必要があるため機械学習の実際の流れが理解できる。
・順位が出るためやる気が出る。（全世界のデータ分析家と勝負できますし、協力もできます）
・賞金がでます（150万ドルの賞金が出るものもあり）

## 3.  Kaggleチュートリアル（Titanic: Machine Learning from Disaster）
・乗客がタイタニックの沈没を生き延びたかどうかを予測
・訓練用データ（891行 × 12列のcsv）　データに一部欠損あり
・テストデータ（418行 × 11列のcsv）　データに一部欠損あり
・訓練用データで学習し、テストデータに対して、生き延びたかどうかを予測する。

## 4.  データの中でどれを使う？
・PassengerId：データにシーケンシャルでついている番号
・Survived：生存（0 = No, 1 = Yes）　訓練用データにのみ存在
・Pclass：チケットのクラス（1 = 1st, 2 = 2nd, 3 = 3rd）
・Name：名前
・Sex：性別
・Age：年齢
・SibSp：タイタニック号に乗っていた兄弟と配偶者の数
・Parch：タイタニック号に乗っていた両親と子どもの数
・Ticket：チケット番号
・Fare：旅客運賃
・Cabin：船室番号
・Embarked：乗船場（C = Cherbourg, Q = Queenstown, S = Southampton）

```Python:実行コード
import numpy as np
import pandas as pd
train = pd.read_csv("train.csv", dtype={"Age": np.float64}, )
test  = pd.read_csv("test.csv", dtype={"Age": np.float64}, )
train.head(10)
```
![kaggle_titanic1.png](https://qiita-image-store.s3.amazonaws.com/0/118618/5fa4fa1b-9107-783d-a2a6-cc6956200b71.png "kaggle_titanic1.png")



```Python:実行コード
train_corr = train.corr()
train_corr
```

![kaggle_titanic3.png](https://qiita-image-store.s3.amazonaws.com/0/118618/2f68aedc-fb4a-0db4-e774-4ba828c8f64d.png "kaggle_titanic3.png")



## 5.  データ前処理
PassengerId以外は使えそうです。
現在解析に使えていないデータがあるので使えるデータ（数値）に変換します。
また欠損データがあるので補正します。

```Python:実行コード
def correct_data(titanic_data):
    
    titanic_data.Age = titanic_data.Age.fillna(titanic_data.Age.median())
    
    titanic_data.Sex = titanic_data.Sex.replace(['male', 'female'], [0, 1])
    
    titanic_data.Embarked = titanic_data.Embarked.fillna("S")
    titanic_data.Embarked = titanic_data.Embarked.replace(['C', 'S', 'Q'], [0, 1, 2])

    titanic_data.Fare = titanic_data.Fare.fillna(titanic_data.Fare.median())
   
    return titanic_data

train_data = correct_data(train)
test_data  = correct_data(test)
```

```Python:実行コード
train_corr = train.corr()
train_corr
```
![kaggle_titanic.png](https://qiita-image-store.s3.amazonaws.com/0/118618/5d0c716f-de59-40d9-dc90-fb83109db26f.png "kaggle_titanic.png")

## 6.  使用データ
今回は以下項目を使用します。
・チケットのクラス
・性別
・年齢
・タイタニック号に乗っていた兄弟と配偶者の数
・タイタニック号に乗っていた両親と子どもの数
・旅客運賃
・乗船場

## 7.  使用する学習手法
・ロジスティック回帰
・サポートベクターマシン
・k-最近傍法
・決定木
・ランダムフォレスト
・ニューラルネットワーク

参考文献
学習手法の詳細は以下を参照ください。
Pythonではじめる機械学習 scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
https://www.oreilly.co.jp/books/9784873117980/

## 8. 学習実行と交差検証
### データと学習手法を指定します。

```Python:実行コード
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC, LinearSVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier

from sklearn.model_selection import cross_val_score

predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]

models = []

models.append(("LogisticRegression",LogisticRegression()))
models.append(("SVC",SVC()))
models.append(("LinearSVC",LinearSVC()))
models.append(("KNeighbors",KNeighborsClassifier()))
models.append(("DecisionTree",DecisionTreeClassifier()))
models.append(("RandomForest",RandomForestClassifier()))
models.append(("MLPClassifier",MLPClassifier(solver='lbfgs', random_state=0)))
```


### 交差検証を実施します。
交差検証ではデータセットを訓練データとテストデータに分割し（ここでは3分割）、
それぞれで評価することで精度を安定させる方法です

![一から始める機械学習（Kaggleで学ぶ機械学習）__Machine_learning_to_learn_at_Kaggle_key.png](https://qiita-image-store.s3.amazonaws.com/0/118618/72c5415d-f0eb-2b26-ac18-a7a40694e0bb.png "一から始める機械学習（Kaggleで学ぶ機械学習）__Machine_learning_to_learn_at_Kaggle_key.png")

```Python:実行コード
results = []
names = []
for name,model in models:
    result = cross_val_score(model, train_data[predictors], train_data["Survived"],  cv=3)
    names.append(name)
    results.append(result)
    
```

3分割されている結果を平均し、評価を出します。
ランダムフォレストが良い結果を出しました。

```Python:実行コード
for i in range(len(names)):
    print(names[i],results[i].mean())
    
```

```
LogisticRegression 0.785634118967
SVC 0.687991021324
LinearSVC 0.58810325477
KNeighbors 0.701459034792
DecisionTree 0.766554433221
RandomForest 0.796857463524
MLPClassifier 0.785634118967
```

ランダムフォレストで学習したものを元に、
テストデータで予想をし、その結果をcsvにして送ります。

```Python:実行コード
alg = RandomForestClassifier()
alg.fit(train_data[predictors], train_data["Survived"])

predictions = alg.predict(test_data[predictors])

submission = pd.DataFrame({
        "PassengerId": test_data["PassengerId"],
        "Survived": predictions
    })

submission.to_csv('submission.csv', index=False)
    
```



## 9. 最適化
### 正解率
正解率0.74163
7922人中7043位でした。ちょっと悔しいので最適化します。

### 最適化
grid searchを使用すればハイパーパラメータを自動的に最適化してくれます。
ただし実行時間がかかることに注意して下さい。

```Python:実行コード
parameters = {
        'n_estimators'      : [5, 10, 20, 30, 50, 100, 300],
        'max_depth'         : [3, 5, 10, 15, 20, 25, 30, 40, 50, 100]
        'random_state'      : [0],
}
gsc = GridSearchCV(RandomForestClassifier(), parameters,cv=3)
gsc.fit(train_data[predictors], train_data["Survived"])
```

上記等で最適化した結果を適応してみます。



正解率0.77990
7922人中4129位まで行きました。


![Titanic__Machine_Learning_from_Disaster___Kaggle.png](https://qiita-image-store.s3.amazonaws.com/0/118618/a88af6a9-765e-7dfa-5eec-a45ea16f03eb.png "Titanic__Machine_Learning_from_Disaster___Kaggle.png")



### データ前処理変更による最適化

先程のコードをKaggleに公開するとコメントがつきました。
欠損値を訓練用データからではなくテストデータから求めるようにしたほうが良いとのことでした。やってみました。
修正後のコードを以下に記載します。

```Python:実行コード
def correct_data(train_data, test_data):
    
    # Make missing values ​​for training data from test data as well
    train_data.Age = train_data.Age.fillna(test_data.Age.median())
    train_data.Fare = train_data.Fare.fillna(test_data.Fare.median())
    
    test_data.Age = test_data.Age.fillna(test_data.Age.median())
    test_data.Fare = test_data.Fare.fillna(test_data.Fare.median())    
    
    train_data = correct_data_common(train_data)
    test_data = correct_data_common(test_data)    

    return train_data,  test_data

def correct_data_common(titanic_data):
    titanic_data.Sex = titanic_data.Sex.replace(['male', 'female'], [0, 1])
    titanic_data.Embarked = titanic_data.Embarked.fillna("S")
    titanic_data.Embarked = titanic_data.Embarked.replace(['C', 'S', 'Q'], [0, 1, 2])
    
    return titanic_data

train_data,  test_data = correct_data(train, test)
```

**正解率0.79426**
**7922人中2189位まで行きました。**

![Titanic__Machine_Learning_from_Disaster___Kaggle2.png](https://qiita-image-store.s3.amazonaws.com/0/118618/0c73b0a3-3629-eb97-7f85-9e1eeb1643c5.png "Titanic__Machine_Learning_from_Disaster___Kaggle2.png")


### さらなる最適化の案
・名前の解析をする。（Mr. Mrs. Miss等があるためここから推測できないか等）

![kaggle_titanic1.png](https://qiita-image-store.s3.amazonaws.com/0/118618/2bc5dc8b-9786-db62-7a49-2fafd33ae936.png "kaggle_titanic1.png")

・別の学習手法を使用する（例えばXGBoost、LightGBM）を使用する

## 10. 機械学習の流れ
![一から始める機械学習（Kaggleで学ぶ機械学習）__Machine_learning_to_learn_at_Kaggle_key2.png](https://qiita-image-store.s3.amazonaws.com/0/118618/1f5a9db9-c2ce-322f-c0e8-3019c8420a6d.png "一から始める機械学習（Kaggleで学ぶ機械学習）__Machine_learning_to_learn_at_Kaggle_key2.png")

### 手法選択はアルゴリズム　チートシート
![Choosing_the_right_estimator_—_scikit-learn_0_19_0_documentation.png](https://qiita-image-store.s3.amazonaws.com/0/118618/a7ae626f-9398-308b-b969-08fd363783a5.png "Choosing_the_right_estimator_—_scikit-learn_0_19_0_documentation.png")

### ハイパーパラメータ選択
**grid search**

### モデルの評価
**交差検証**


## 11. 企業のコンテストを一部紹介
### Prudential Life Insurance Assessment
・Can you make buying life insurance easier?
・生命保険申請者の属性からリスクレベルを算出する
・賞金3万ドル
・既に終了済み（コードが参照できる）
・https://www.kaggle.com/c/prudential-life-insurance-assessment

### Zillow Prize: Zillow’s Home Value Prediction (Zestimate)
・Can you improve the algorithm that changed the world of real estate?
・自宅のすべての機能を考慮して、Zestimateと実際の販売価格との間の誤差を予測する
・賞金120万ドル
・4ヶ月後に終了
・https://www.kaggle.com/c/zillow-prize-1