らんだむな記憶

blogというものを体験してみようか!的なー

タイタニック (1)

2019 年の夏〜冬のどっかで登録した Kaggle のアカウントに久しぶりに入ってみる。コンペがやりたいのではなく、タイタニックのデータセットが欲しいからなんだけど。決定木と勾配ブースティング木を適用して iris データセットよりはもう少しマシな結果を見てみたい。

とりあえずいつもの:

$ pip install kaggle

で、お次は API トークンを発行して、~/.kaggle/kaggle.json を配置して

$ kaggle competitions download -c titanic

でデータセットをダウンロード。楽なもんだ。

CSV の見方に慣れていないので*1『実践Data Scienceシリーズ PythonではじめるKaggleスタートブック』(石原 祥太郎,村田 秀樹)|講談社BOOK倶楽部 の pp.59-73 を眺めながら中身を見ていきたい。

import pandas as pd
import pandas_profiling

train_df = pd.read_csv('train.csv')
train_df.profile_report()

でレポートが作成される。なんという便利ツールがあるのか・・・。

for k, v in train_df.items():
    if k in ['PassengerId', 'Name', 'Ticket', 'Fare', 'Cabin']:
        continue
    print(k, set(v))

を実行してみると、

Survived {0, 1}
Pclass {1, 2, 3}
Sex {'male', 'female'}
Age {nan, nan, 2.0, nan, 4.0, nan, nan, nan, 8.0, nan, nan, nan, nan, nan, 14.0, 15.0, 3.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 16.0, 24.0, 23.0, 5.0, 26.0, 28.5, 27.0, 28.0, 29.0, nan, 31.0, nan, nan, 34.0, 35.0, nan, 7.0, 38.0, 39.0, 40.0, 42.0, 37.0, 45.0, 46.0, 47.0, 9.0, 49.0, 44.0, 51.0, 50.0, 45.5, 54.0, 55.0, 11.0, 55.5, 58.0, 59.0, 56.0, 12.0, 61.0, 62.0, 63.0, 65.0, 66.0, 60.0, 64.0, 13.0, 70.5, 71.0, 14.5, 70.0, 74.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 80.0, nan, nan, 6.0, nan, nan, 20.5, nan, nan, nan, nan, nan, nan, nan, 23.5, nan, nan, nan, 24.5, nan, nan, nan, nan, 25.0, nan, nan, nan, nan, nan, 0.42, nan, nan, nan, 30.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 32.0, 32.5, nan, nan, 33.0, 34.5, nan, nan, nan, nan, 36.5, 36.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 40.5, 41.0, 43.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 48.0, 30.5, 0.83, 0.92, 10.0, 0.67, 52.0, 53.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, 1.0, 57.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.75, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan}
SibSp {0, 1, 2, 3, 4, 5, 8}
Parch {0, 1, 2, 3, 4, 5, 6}
Embarked {'C', nan, 'S', 'Q'}

となるので、どの辺に欠損値があるのか分かりやすい・・・かもしれない。
偏るので量にもよるが

train_df['Age'].fillna(train_df['Age'].mean().round(), inplace=True)

しても良さそう。どうせ勾配ブースティング木も何か良い値を入れちゃうわけだし・・・。
年齢は平均値で、乗船した港は最頻値で欠損値を埋めると

train_df['Age'].fillna(train_df['Age'].mean().round(), inplace=True)
train_df['Embarked'].fillna(train_df['Embarked'].mode().values[0], inplace=True)
for k, v in train_df.items():
    if k in ['PassengerId', 'Name', 'Ticket', 'Fare', 'Cabin']:
        continue
    print(k, set(v))
Survived {0, 1}
Pclass {1, 2, 3}
Sex {'male', 'female'}
Age {0.75, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 28.5, 32.0, 34.0, 35.0, 33.0, 37.0, 38.0, 39.0, 40.0, 32.5, 42.0, 36.5, 40.5, 45.0, 46.0, 47.0, 44.0, 49.0, 50.0, 51.0, 45.5, 52.0, 54.0, 55.0, 55.5, 56.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 70.5, 71.0, 14.5, 70.0, 74.0, 80.0, 20.5, 23.5, 24.5, 0.42, 30.5, 34.5, 36.0, 41.0, 43.0, 48.0, 0.83, 0.92, 0.67, 53.0, 57.0}
SibSp {0, 1, 2, 3, 4, 5, 8}
Parch {0, 1, 2, 3, 4, 5, 6}
Embarked {'C', 'S', 'Q'}

というように欠損値がなくなるのでまぁまぁ嬉しいかもしれない。

*1:というか pandas かな?