【Kaggle初心者】タイタニックコンペを決定木&ランダムフォレストで試行錯誤してみた

絶賛機械学習お勉強中につき、初心者向けでデータが扱いやすいタイタニックコンペで訓練しています。

今回は決定木とランダムフォレストのお勉強をしたので、Kaggleで実践してみて試行錯誤した経過を記録しようと思います。

おおまかな流れとしては

前処理

→決定木モデルを作成

→RFのfeature_importances_で有効な特徴量を絞り込み

→絞り込んだ特徴量のみで決定木

です。

そのあとのハイパーパラメータチューニングについてはその2として、続きを別記事に書こうと思います。

では、EDAはすっ飛ばして、データの前処理からやっていこうと思います。

 

ライブラリのインポート

今回使うライブラリを最初にまとめてインポートしておきます。

データも読み込みます。

 

 

前処理

データの前処理は最低限の2つ、欠損値埋めと、カテゴリ変数変換だけやっておきます。

の前に、[PassengerId , Name , Ticket , Cabin]については予測に必要なさそう&扱いが難しそうということで不要なカラムとみなすことにします。

欠損値の処理

まず欠損値についてですが、isnull().sum()を用いて、各特徴量ごとにいくつ欠損があるかどうかを確認します。

trainデータセットではAgeとEmbarked

testデータセットではAgeとFareに欠損があることが確認できました。

これらを埋めていきます。

Embarkedの欠損を埋める

欠損値埋めにはpandasのfillna()メソッドを用います。

今回は最頻値で埋めることにするので、fillna().mode()とします。

mode()メソッドは、pandas.DataFrameを返すので、ilocで先頭行をpandas.Seriesとして取得する必要があります。

Ageの欠損を埋める

Ageは中央値で埋めてみました。

中央値はmedian()です。

Fareの欠損を埋める

FareもAgeと同様です。

 

カテゴリ変数の処理

お次はカテゴリ変数を処理します。

全部数値型にしてあげないとモデルに入れたときにエラーが吐き出されて悲しい気持ちになります。

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

カテゴリ変数はSexとEmbarkedの2つですね。

Sexを変換

まずは性別から。

map関数を用いて変換を行います。

性別間に順序はないので、置き換える数字を1,2とかにしないように注意です。

Embarkedを変換

Embarkedについては、値の種類が3つですので、one-hotエンコーディングを行います。

もしmap関数で適当な数値に置き換えてしまうと、実際には順序の関係性がないのに、そこに順序の関係性をコンピュータが勝手に見出してしまいます。

(S=1、C=2、Q=3と置き換えたら、Q=S+Cみたいな謎な関係性を機会が見出してしまいます。)

pd.get_dummies() で簡単に行えます。

 

訓練データを分割

モデルの作成のために訓練データを訓練セットとテストセットに分割します。

 

いったん全部の特徴量を使って決定木モデルを作ってみる

とりあえず1個モデルをつくってみて、精度を見ます。

それを基準に、のちの改善後スコアが向上しているかどうか見たいと思います。

タイタニックは評価指標がaccuracyですので、accuracyで評価をします。

正解率は、、、0.79888でした。

ちなみにですが、今回どれだけあってたか、というのは混同行列で可視化するとわかりやすいです。

こんな表ができます。

さらにseabornを用いてヒートマップにしてみます。

混同行列ですが、見方としては

・列は予測における正誤(タイタニックなので生き残ったか、亡くなったか)

・行は本当の正誤

を示しています。ですので、

・左上=diedと予測して、本当にdiedだった数

・左下=diedと予測して実際はsurivivedだった数

・右上=survivedと予測して実際はdiedだった数

・右下=survivrdと予測して本当にsurvivedだった数

を意味します。

つまり、左上から右下へと対角線にあたるセルに数字が集中するほど、予測精度が高い、といえることになります。

ちなみに、正解率のaccuracyはこの4象限を足したもの(左上+左下+右上+右下)を分母に、予測と本当の正誤が一致した数(左上+右下)を分子とした計算で求められます。

また、モデルの評価にはaccuracy以外にも、適合率(precision)や再現率(recall)、F1値などがあり、みなこの混同行列から算出することができます。

 

ランダムフォレストで特徴量の重要度を求めてみる

ランダムフォレストではfeature_importances_というとても便利なものが使えて、これは何かというと使った特徴量の重要度を数値化してくれるのです!

これで、この特徴量はめっちゃ貢献しているから入れておこう、逆にこれはいらない、と特徴量の選別を行うことができます。

というわけで、ランダムフォレスト分類器をつくります。

使用した特徴量と、それらの重要度を表にまとめます。

はい、このようになりました!

どうやら大きく予測に貢献しているのは”Sex”,”Fare”,”Age”のよう。

逆にダミー変数化したEmbarkedについては予測の役に立っていないようですね。

 

重要度の高い特徴量のみで決定木

では、先ほどの結果を踏まえ、重要度の高い上位5つのみを特徴量として決定木にかけたらどうなるかやってみます。

流れは先ほどと一緒です。

気になる正解率はというと、、、0.79888!! まさかの変わらないという結果に、、そんな、、。

まったく変わっていないということはないはずなので、混同行列を作って比較してみます。

▼Before(左)・After(右)

うん、確かにちょこっと変わってはいるものの、左上と右下足した数は変わらないので、正解率に変化がなかったようです。

きっとこうやって特徴量を絞り込むのは、今回みたいに特徴量が少ないデータセットではなく、多いデータセットの時に有効なのでしょう。

 

最初にランダムフォレストやったんだから、ランダムフォレストで予測すればよいじゃん、という自分突っ込みをいれてみたのですが、それでも決定木を使ったのは、dtreevizでの可視化をやってみたかったからです。

このコードを打ち込むとこんな感じで決定木の分類を可視化してくれます。

ちょっとキャプチャがはしっこちょん切れてしまっているのですが、とてもきれいで分かりやすい。

1人でもくもくとやる分には良いですが、人に説明したりするときにこんな風に可視化できるのは大きなメリットですよね。

 

ちなみにランダムフォレストの精度ですが、先ほど作ったランダムフォレスト分類器では、決定木とスコアは変わりませんでした。

 

 

 

というわけで、今回は少ない特徴量に対して、こうやって全体から特徴量を減らしていくアプローチは有効ではない、ということを学びました。

とはいえスコアは改善したいので、次はハイパーパラメータのチューニングをやっていきたいなと思います。

長くなったので、それは次に書こうと思います。

最後まで読んでいただきありがとうございました。