titanicの先へ行く入門10kernelを素人が試してみる

機械学習を始めたい一般学生ピーポーが何からやればいいのかわからないからとりあえずhttps://t.co/Eyu5zf6svs
この記事の通りに試してみて常識とされる知識を付けていこうという試みである
・kernel経由でsubmitする方法
以前書いた記事ではcsvファイルを直接アップロードしたが今回はkernel経由でアップロードする
1.kernelの右上のcommitをクリックする
2.実行が終わったらopen versionをクリックする
3.左のoutputタブを押すとこのバージョンのkernelでの予測結果がsubmisson.csvというファイルで保存されているのでsubmit to competitionを押すとこのファイルがsubmitされる

・全体像の把握
1.パッケージの読み込み
2.データの読み込み
3.特徴量エンジニアリング
4.機械学習アルゴリズムの予測
5.submit

1,パッケージの読み込み

```
%matplotlib inline
import numpy as np
import pandas as pd
```
これはいつもの

2,データの読み込み
kaggleから提供されたデータを読み込む

```
train = pd.read_csv("../input/train.csv")
test = pd.read_csv("../input/test.csv")
gender_submission = pd.read_csv("../input/gender_submission.csv")
data=pd.concat([train,test],sort=True)
```

```
data.head()
```

```
data.columns
```
欠損値の有無を確認

```
data.isnull().sum()
```
・gender_submissionはsubmitのサンプル。このファイルで提出ファイルの形式を確認する。仮の予測として女性のみが生存するという値が設定されている
・train.csvは機械学習の訓練用のデータ。これらのデータにはtitanic号の乗客の性別、年齢などの属性情報とその乗客に対応する生存したか否かの情報が格納されている
・test.csvは予測を実施するデータ。これらのデータについてはtitanic号の乗客の性別、年齢などの属性情報のみが格納されており訓練用データの情報を基に予測値を算出することになる

3,特徴量エンジニアリング
次のような処理を特徴量エンジニアリングと呼ぶ
・読み込んだデータを機械学習アルゴリズムが扱える形に変換
・既存のデータから機械学習アルゴリズムが予測する上で有用な新しい特徴量を作成

前者の例:Sexの'male','female'をそれぞれ0,1に変換する。欠損値を平均値などで穴埋めする

```
data['Sex'].replace(['male,'female'],[0,1],inplace=True)
data['Embarked'].fillna(('S'),inplace=True)
data['Embarked']=data['Embarked'].map({'S':0,'C':1,'Q':2}).astype(int)
data['Fare'].fillna(np.mean(data['Fare']),inplace=True)
age_avg=data['Age'].mean()
age_avg=data['Age'].std()
#stdは標準偏差
data['Age'].fillna(np.random.randint(age_avg-age_std,age_avg+age_std),inplace=True)
```
ここは前と埋め方が違うな。調べたら正規分布に従うとし、標準偏差の範囲内でランダムに数字を作りたい時にこんな埋め方をするらしい。

```
delete_columns=['Name','PassengerId','SibSp','Parch','Ticket','Cabin']
data.drop(delete_columns,axis=1,inplace=True)
train=data[:len(train)]
test=data[len(train):]
y_train=train['Survived']
X_train=train.drop('Survived',axis=1)
X_test=test.drop('Survived',axis=1)
X_train.head()
y_train.head()
```
4,機械学習アルゴリズムの学習、予測

```
from sklearn.linear_model import LogisticRegression
clf=LogisticRegression(penalty='12',solver="sag",random_state=0)
clf.fit(X_train,y_train)
```
ここではロジスティック回帰という機械学習アルゴリズムを利用する。

```
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(penalty='l2', solver="sag", random_state=0)
clf.fit(X_train, y_train)
```
学習を終えて予測値が未知の特徴量(X_test)を与えて予測させることができる

```
y_pred=clf.predict(X_test)
```
提出

```
sub = pd.DataFrame(pd.read_csv("../input/test.csv")['PassengerId'])
sub['Survived'] = list(map(int, y_pred))
sub.to_csv("submission.csv", index = False)
```
再現性
「再現性がある」とは何度実行しても同じ結果が現れることです。kaggleでいうと同一のスコアが得られると言い換えてもよい
再現性がないと実行ごとに異なるスコアが得られてしまう。今後特徴量エンジニアリングなどでスコアの向上を試みても予測モデルが改善されたか否かを正しく判断できなくなる問題が生じる。

実は2つ目のkernelには再現性がない。その原因はAgeという特徴量の欠損値を埋める際の乱数です。ここでは平均と標準偏差を考慮した乱数で欠損値を穴埋めしているがこの乱数は実行ごとに値が変わるようになっている。

再現性を確保するためには例えば次のような方法が考えられる。
1,そもそも乱数を用いる部分を削除する
2,乱数のseedを与えて実行結果を固定する

今回はAgeについては中央値で補完するようにコードを改変する

```
data['Age'].fillna(data['Age'].median(),inplace=True)
```
機械学習アルゴリズムの大半は乱数を利用するので再現性を担保するためにseedを設定しておかなくてはならない。

以下は全ての乱数のseedを固定する関数

```
def seed_everything(seed=1234):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.backends.cudnn.deterministic = True
```
仮説から新しい特徴量をつくる
仮説と可視化から新しい特徴量を作る過程について学ぶ。予測精度に寄与する新しい特徴量を作成するにあたっては仮説と可視化を繰り返すサイクルが大切
ドメイン知識がある場合、その仮説を検証するような可視化を実施し、本当に予測精度に寄与するかを確認する。ドメイン知識がない場合、仮説を立てるための探索的なデータ分析を実施する

ここで、ぼんやりと一緒に乗船した家族の人数が多いほうが生存率が低そうだという仮説が得られた状況を考える

可視化に移る。新しい行FamilySizeをつくりその大きさごとに生存したか否かを棒グラフにする

```
data['FamilySize']=data['Parch']+data['SibSp']+1
train['FamilySize']=data['FamilySize'][:len(train)]
test['FamilySize']=data['FamilySize'][len(train):]

import seaborn as sns
sns.countplot(x='FamilySize',data=train,hue='Survived')
#hueを第三引数に指定することで２つの条件を同時に知ることができる
```
ここでFamily_size>=5の場合、死亡率が生存を上回っており生存率が低いことがわかる。ぼんやりとした仮説が確信をもった仮説に変わった。更に今回、可視化を通してFamilySize==1の人が圧倒的に多く、かつ生存率が低いという情報を得ることができた。このFamilySize==1であるという特徴量も予測精度に寄与しそうなので下記のように新しくIsAloneという特徴量を作成した。

```
data['IsAlone']=0
data.loc[data['FamilySize']==1,'IsAlone']=1

train['IsAlone']=data['IsAlone'][:len(train)]
test['IsAlone']=data['IsAlone'][:len(train)]
test['IsAlone']=data['IsAlone'][len(train):]
```

特徴量エンジニアリングの手法https://naotaka1128.hatenadiary.jp/entry/kaggle-compe-tips

これまでは機械学習アルゴリズムとしてロジスティック回帰を採用していた。色々な機械学習アルゴリズムを使ってみる。これまではロジスティック回帰を使っていた部分を差し替えて学習、予測を行う。

```
from sklearn.linear_model import LogisiticRegression
clf=LogisticRegression(penalty='12',solver="sag",random_state=0)
```
ランダムフォレストでやってみる

```
from sklearn.ensemble import RandomForestClassifier
clf=RandomForestClassifier(n_estimators=100,max_depth=2,random_state=0)
```

```
clf.fit(X_train,y_train)
y_pred=clf.predict(X_test)
```