Kaggle何から進めると良いか！？(Kaggle攻略)

# とりあえず
KaggleのTitanicチュートリアルにおいて、精度を上げるために何をやっていけば良いのか？を上位者のアイディアを参考に前処理フローを整理する。

# 前処理フロー
### データを読み込む
 兎にも角にもデータを読み込む。やり方はPandasでDataFrameとして読み込む。
 使うコマンド:``` pd.read_csv() ```

### データを見る
- 観点1:項目名の意味を書き出す。
- 観点2:項目毎の欠損データを書き出す。
- 観点3:数値データと文字データを分類する。（把握するだけでOK）(型:objectが文字データ扱い)

ココが割と重要。欠損データは”消すでは無く”、”補完し利用する”事を優先する。
項目毎の意味を理解しないと欠損データの補完のアイディアが出ない。よって”意味”も大事。
 使うコマンド:``` pd.info() ```

### 第一欠損値補完
初めは中央値、平均、ゼロ。から適切なものを入れてみる。

### 文字データの取り扱いを決める(型:object)
 文字データの意味を考え適切な数値データを導出する。

- 観点1:文字->数値の単一変換ができそうなモノはそのまま変換する。
- 観点2:複雑なモノは、必要要素だけ抜き出し成分値を導出する。
- 観点3:わからないモノは、一旦除外する。(最終手段)

#### Titanicの場合
　[Name]・・・名前 =>観点2
　[Sex]・・・性別 =>観点1
　[Ticket]・・・チケット番号 =>観点2
　[Cabin]・・・部屋番号 =>観点2
　[Embarked]・・・乗船した港 =>観点1

<観点1>
[Sex]・・・性別
 male/femaleを数値に置き換える(0,1)
[Embarked]・・・乗船した港
 Cherbourg、Queenstown、Southamptonの頭文字C,Q,Sを数値に置き換える(0,1,2)
 
<観点2>
[Name]・・・名前
 パッと見わからない。。。敬称で分類する。（敬称もMr,Miss,Msだけじゃない・・・　英語だけじゃなく多国語における貴族敬称とかも考えたらしい。)
[Capt,Col,Countess,Don,Dr,Jonkheer,Lady,Major,Master,Miss,Mlle,Mme,Mr,Mrs,Ms,Rev,Sir]
 手順
1.まずは名前を単語に分類し、タイトルの一覧を見てみる。

``` script
def get_title(name):
    title_search = re.search(' ([A-Za-z]+)\.', name)
    if title_search:
        return title_search.group(1)
    return "" 

for row in train:
    row['honorific'] = row['Name'].apply(get_title)

print(pd.crosstab(train['honorific'], train['Sex']))
```
2.同じ意味合いのモノはまとめる。

```
train['honorific'] = train['honorific'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
train['honorific'] = train['honorific'].replace('Mlle', 'Miss')
train['honorific'] = train['honorific'].replace('Ms', 'Miss')
train['honorific'] = train['honorific'].replace('Mme', 'Mrs')
```
3.敬称を分類し数値に変える。

```
honorific_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5} 
for row in train: 
    row['honorific'] = row['honorific'].map(honorific_mapping) 
    row['honorific'] = row['honorific'].fillna(0)
```

[Ticket]・・・チケット番号
 パッと見わからない。。。チケットの頭文字で分類する。

 手順

1.頭文字を取ってきてグループ化。

```
for row in train:
    row['Ticket_Lett'] = row['Ticket'].apply(lambda x: str(x)[0])
    row['Ticket_Lett'] = row['Ticket_Lett'].apply(lambda x: str(x)) 
    row['Ticket_Lett'] = np.where((row['Ticket_Lett']).isin(['1', '2', '3', 'S', 'P', 'C', 'A']), row['Ticket_Lett'], np.where((row['Ticket_Lett']).isin(['W', '4', '7', '6', 'L', '5', '8']), '0','0')) 
    row['Ticket_Len'] = row['Ticket'].apply(lambda x: len(x))
train['Ticket_Lett']=train['Ticket_Lett'].replace("1",1).replace("2",2).replace("3",3).replace("0",0).replace("S",3).replace("P",0).replace("C",3).replace("A",3)
```


[Cabin]・・・部屋番号
 パッと見わからない。。。チケットの頭文字で分類する。

手順

1.頭文字を取ってきてグループ化。

```
for row in train: 
    row['Cabin_Lett'] = row['Cabin'].apply(lambda x: str(x)[0]) 
    row['Cabin_Lett'] = row['Cabin_Lett'].apply(lambda x: str(x)) 
    row['Cabin_Lett'] = np.where((row['Cabin_Lett']).isin([ 'F', 'E', 'D', 'C', 'B', 'A']),row['Cabin_Lett'], np.where((row['Cabin_Lett']).isin(['W', '4', '7', '6', 'L', '5', '8']), '0','0'))

train['Cabin_Lett']=train['Cabin_Lett'].replace("A",1).replace("B",2).replace("C",1).replace("0",0).replace("D",2).replace("E",2).replace("F",1)
```

### 他に関連性がありそうなデータを作る
#### Titanicの場合
　Pclass、Sibsp、Parchに注目。

  - Pclassは何等級のところに乗っていたかを表す。
  - Sibspは乗っていた夫婦と兄弟の人数を表す。
  - Parchは乗っていた親と子供の人数を表す。
  
  これを元に以下を導出する
  FamilySize（家族の人数) = Sibsp+Parch+1が
  IsAlone(一人かどうか） =  FamilySizeが１なら1

```
train["FamilySize"] = train["SibSp"] + train["Parch"] + 1
for row in train:
    row['IsAlone'] = 0
    row.loc[row['FamilySize'] == 1, 'IsAlone'] = 1
```

### モデリング
　前処理を行ったモノの内数値データのみを使う。