MotoJapan's Tech-Memo

技術めも

【kaggle②】初心者がタイタニック号の生存予測モデル(Titanic: Machine Learning from Disaster)をやってみる(データ分析、整形、欠損データ補完)

これの続きです。

【kaggle①】初心者が Titanic: Machine Learning from Disasterをやってみる(Titanic概要 ~ データ確認) - MotoJapan's Tech-Memo


(ここからはpythonのpandasが便利すぎるというポジティブキャンペーンになります)
ちなみに「ここでわかってきたことは」を読めば記事の重要ポイントは大体把握できます。 

2.4.データ整形

前回の記事の続きですが、データを整形します。
男女(Sex)情報は文字列であるため、バイナリ(0/1)変換。

#男女を01で表現
df_train = df_train.replace("male",0).replace("female",1)

2.4.データ傾向確認

pandasのDataFrameで全体的なデータの傾向を可視化(便利!)

#各特徴量の大枠の分布を表示
df_train.describe()
#欠損データの集計を表示
df_train.isnull().sum()

f:id:motojapan:20170613223519p:plain
f:id:motojapan:20170613223627p:plain

ここでわかってきたことは

  • [Age]が一部欠損
  • [Cabin]は2/3以上欠損

今回は、欠損が多き過ぎるものは、学習させる特徴量としては一旦除外しておきます。  
あと、[PassengerId]は便宜上ついているだけの通し番号ですのでこれも除外します。

次で簡単に除外できます。(ありがとう、pandas様)

#学習に不要なデータを排除
df_train_dropna = df_train.dropna()
df_train_dropna = df_train_dropna.drop('Cabin', axis = 1)
df_train_dropna = df_train_dropna.drop('PassengerId', axis = 1)

2.5.データ相関分析

つぎにもう少し踏み込んで分析したいと思います。が、pandasでは既に簡単な分析ができる関数が準備されています(ありがとう!)

#一次相関のconfusion matrixを表示
df_train_dropna.corr()

f:id:motojapan:20170613225537p:plain

ここでわかってきたことは

  • [Sex][Age]は[Servived]に対して相関が高い
  • 逆に[Fare][Pclass]は相関が低い

乗船料金や旅客席クラスの高い人が優先的に救助されたというわけではなさそうですね。
年齢は一部欠損していますが、相関が高いことからここをいかにうまく補完できるかが鍵のようです。

2.6.欠損データ補完

[Age]は部分欠損を起こしてるため、補完処理を実施
2パターンを検証

  • 2.6.0 [Age]平均値で補完 #今回は割愛
  • 2.6.1 [Pclass]毎の[Age]平均値で補完 ([Age_1])
  • 2.6.2 [Name]の敬称毎の[Age]平均値で補完 ([Age_2])

2.6.0の[Age]平均値で補完は、初期検討ではいいですが、割と乱暴な手法なので今回は割愛させて頂きます。

2.6.1.[Pclass]毎の[Age]平均値で補完 [Age_1]

べたべたなやり方で、confusion matrixの[Age]と最も相関が高い[Pclass]で補完する方法です。

ap = pd.concat([df_train['Age'],df_train['Pclass']],axis=1)
ap = ap.dropna()
ap.plot(x='Age',y='Pclass',kind='scatter')
plt.xlabel('Age')
plt.ylabel('Pclass')
plt.show()

f:id:motojapan:20170617173754p:plain
ヒストグラム版はこんな感じ
f:id:motojapan:20170617174650p:plain

if Pclass == 1, Average Age == 38.2
if Pclass == 2, Average Age == 29.9
if Pclass == 3, Average Age == 25.1

ここでわかってきたことは

  • [Pclass]客室階級は高い程、平均年齢が高い傾向は見れる
  • 一方で、子供(例えば12歳以下)等の考慮ができない補完方法
    • 子供はどの[Pclass]にも存在するし、そもそも子供に妥当な年齢を与えられない

2.6.2 [Name]の敬称毎の[Age]平均値で補完 [Age_2]

結果を先に書くと、[Age_1]に比べて、精度は2%程向上しました。(記憶が正しければ)
※1のアプローチを参考にさせて頂きました。
これは、[Name]という一見扱いずらそうな文字列を特徴量にします。

手法

  • 名前から敬称[Honorific]を探す
  • 下記でラベリングする
    • mr->0, mrs->1, miss->2, master->3, ms.->4, dr.->5, else->6
  • [Honorific]毎の平均年齢を確認
  • 傾向が高いもので年齢補完する
    • elseとかは全体平均などで補う

ソースコード等は割愛しまする (GitHubにコードあり)
f:id:motojapan:20170617182137p:plain


ここでわかってきたことは

  • [Age_1]に比べて、敬称毎の年齢はばらつきが少なく、優秀そう(優秀でした)
  • ms.->4, dr.->5, else->6は数も少ないため、全体平均で代替でよさそう

以上、今回はここまでです。
次は特徴量生成と可視化。