タイタニック号の乗客の生存予測〜80%以上の予測精度を超える方法(モデル構築&推論編)

タイタニック号の乗客の生存予測〜80%以上の予測精度を超える方法(モデル構築&推論編)

本当に今更なテーマなのですが、以下の記事の後編を書きました。


1年以上も前のお話です笑
submitした結果が良くて満足してしまい、記事にするのを忘れていたようです。
コメントいただいた方、ありがとうございました。

さて、本編では前編での探索的データ解析をもとにモデルを構築し、推論します。

環境準備

以下のディレクトリ構造で進めていきます。

前編と同様にDockerコンテナ上で分析環境を構築しています。
notebookだけを観たいという方はコードをGitHubにあげていますので、こちらをご覧ください。

前処理

まずはデータを読み込みます。
train(学習データ)とtest(テストデータ)で共通の前処理をしていくため、いったん統合します。
(trainとtestを統合したDataFrameがalldataとなります。)
input:

output:

欠損値補完

まず、どの特徴量に欠損値が存在しているのかを確認します。

欠損値が存在している特徴量は、Age、Fare、Cabin、Enbarkedです。
ここで、FareとEnbarkedは中央値で欠損値を補完してあげます。
一方、AgeやCabinはFareとEnbarkedとは異なり全体からみても欠損値の割合が大きいです。
恣意的な補完は返ってノイズになると考えたため、AgeやCabinには欠損値補完をしません。

Fare、Embarkedの欠損値が補完できました。

特徴量別加工

特徴量ごとに集計・変換処理を行い、新しいカラムを追加していきます。

Parch/Sibsp

ParchとSibspからFamilySize(家族数)を算出します。
さらに、FamilySizeをビニングします。

Ticket

同じTicketを持っている乗客数(alldataにおけるTicketの出現頻度)を特徴量とします。

Name

Nameの敬称を特徴量とします。
EDAでみたように、出現頻度の低い敬称はRareに統合します。

Fare

EDAでみたように、Fareには外れ値がいくつか存在しています。
外れ値に対してロバストなモデルを構築したいのでビニングします。
分割数を14にしているのはなんとなくです笑
もっと他にいい分割数があると思います。

Cabin

Cabinの頭文字を特徴量とします。

Encoding

まず、特徴量のデータ型を確認します。

カテゴリカル変数のPclassが整数型になっているので、文字列に変換しておきます。

次に、SexとFare_binにLabel Encodingしておきます。
(Fare_binはpandas.qcut()関数で生成された”(“や”[“が含まれる文字列となっているため、One-Hot Encodingの前にLabel EncodingをしないとXGBoostでerrorが発生します。)

カテゴリカル変数をOne-Hot Encodingします。

特徴量を確認します。

特徴量加工できました。

モデル構築

上で加工した特徴量をもとにモデルを構築します。
まず、trainを学習データとテストデータに分割します。

ベースライン

機械学習モデルを構築する前に、学習データにおける単純な生存率を確認しておきます。
input:

output:

これより、学習データにおいて、全員Survived:0(死亡)とするだけで、Accuracyが62%になることがわかりました。
なので、機械学習モデルによる予測では、少なくともこのAccuracy62%を超えていないと話になりません。
さて、以下ではRandamForest、XGBoost、LightGBM、LogisticRegression、SVCの5つの機械学習モデルで学習データへの当てはめとテストデータへの汎化性能を確認します。
input:

output:

5つの機械学習モデル全てでベースラインのAccuracyを超えているようです。
次にRandamForestの重要度(importance)を確認します。


重要度Top3は、Sex(性別)、honorific_Mr(男性)、Ticket_freq(チケットの出現頻度)となっています。
honorific_Mr(男性)はSex(性別)に包含されるので、Sexが重要度が高いならhonorific_Mrも高くなります。(逆も然り)
ただ、Ticket_freqが高くでているのが気になります。本当に効いているのか、それとも連続値だから重要度が高く出ているのか…。
ちなみに、決定木アルゴリズムの重要度の算出方法関して以下の記事でまとめています。

パラメータチューニング

RandamForest、XGBoost、LightGBM、LogisticRegression、SVCの5つの機械学習モデルそれぞれにおいて、最適なパラメータを求めます。
今回はscikit-learnのGridSearchCVではなく、Preferred Networks社が出しているハイパーパラメータ自動化ツールOptunaを使用します。


input:

RandomForest

input:

output:

XGBoost

input:

output:

LightGBM

input:

output:

LogisticRegression

input:

output:

SVC

input:

output:

汎化性能検証

Optunaで最適なパラメータを求めたので、次は学習データ全体を使って汎化性能を検証します。
学習データ全体を5分割し、層化k分割交差検証(Stratified K-Fold CV)を行います。
input:

5つの機械学習モデルの中でRandomForestがAccuracyの平均値が最も高く、分散も小さくなりました。
一応、多数決モデル(VotingClassifer)も試してみます。
input:

output:

VotingClassifierよりもRandomForestの方が汎化性能が高くなりました。

推論

5つの機械学習モデルで学習データ全てを入力し、推論を実施します。
一応、5つ推論結果を出力していますが、RandomForestの汎化性能が最もよかったので、RandomForestの推論結果をsubmitします。
自分がsubmitしたときは、leader boardでのスコアが0.80382となっていました。