Kaggle(34) - タイタニックをRandom Forestで予測 - 連続変数のビニング

ビニングまたは離散化は、連続変数または数値変数をカテゴリカル特徴に変換するための処理です。

運賃(Fare)に関してビニング処理を行ってみます。

運賃データのチェック

運賃(Fare)に着目してみますと、データのばらつきが大きく外れ値が予測に悪い影響を与えている可能性があります。

運賃データのばらつきを確認するために、箱ひげ図で表示します。

[ソース]

1
2
3
4
5
6
7
8
9
import pandas as pd

df_train = pd.read_csv('/kaggle/input/titanic/train.csv')

import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style='darkgrid')
plt.figure(figsize=(12, 8))
sns.boxplot(data=df_train, y='Fare')

[出力]

データのばらつきは一目瞭然で、とくに500以上のデータは外れ値の最たるものかと思われます。

運賃をqcut関数を使って、ビニングします。qcut関数は各ビン(データ範囲)に含まれる個数(要素数)が等しくなるようにビニング処理(ビン分割)する関数です。

今回はビンの数が10個になるように指定します。(10分割)

[ソース]

1
2
df2 = pd.qcut(df_train['Fare'], 10)
df2.value_counts()

[出力]

データが10分割され、データ数もだいたい同じであることが分かります。

データの読み込みとデータクレンジング改善3

Kaggleに準備されているタイタニックの訓練データを読み込みます。

データの前処理(不要列の削除・欠損処理・カテゴリ変数の変換)と、正解ラベルとそれ以外にデータを分けます。

データクレンジングの改善3として、運賃データをqcut関数を使ってビニング処理を行っています。(17行目)

[ソース]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import pandas as pd

df_train = pd.read_csv('/kaggle/input/titanic/train.csv')

# データ前処理
def preprocessing(df):
df['Deck'] = df['Cabin'].apply(lambda s:s[0] if pd.notnull(s) else 'M') # 改善2

# 不要な列の削除
df.drop(['Name', 'Ticket', 'Cabin'], axis=1, inplace=True)

# 欠損値処理
df['Age'] = df.groupby(['Pclass', 'Sex'])['Age'].apply(lambda x: x.fillna(x.median())) # 改善1
df['Fare'] = df['Fare'].fillna(df['Fare'].median())
df['Embarked'] = df['Embarked'].fillna('S')

df['Fare'] = pd.qcut(df['Fare'], 10, labels=False) # 改善3

# カテゴリ変数の変換
df = pd.get_dummies(df, columns=['Sex', 'Embarked', 'Deck']) # 改善2

return df

x_titanic = preprocessing(df_train.drop(['Survived'], axis=1))
y_titanic = df_train['Survived']

x_titanic

[出力]

運賃(Fare)が金額ではなく、0~9の数字に変換されていることが確認できます。


Random Forest分割交差検証

Random Forestのインスタンスを作成し、cross_val_score関数で分割交差検証を行い、どのくらいの正解率になるか調べてみます。

[ソース]

1
2
3
4
5
6
7
from sklearn import ensemble, model_selection

clf = ensemble.RandomForestClassifier()

score = model_selection.cross_val_score(clf, x_titanic, y_titanic, cv=4) # cv=4は4分割の意
print('各正解率', score)
print('正解率', score.mean())

[出力]

正解率は81.82%となりそこそこの結果ではありますが、これまでの結果と比較して改善したかどうかは微妙なところです。

Kaggleに提出

訓練データ全体で学習を行います。

その後、検証データを読み込み、推論・提出用のCSVの出力を行い、Kaggleに提出します。

[ソース]

1
2
3
4
5
6
7
8
9
10
11
12
13
# 学習
clf.fit(x_titanic, y_titanic)

# 検証データの読み込み
df_test = pd.read_csv('/kaggle/input/titanic/test.csv')
df_test = preprocessing(df_test)
df_test['Deck_T'] = 0

pre = clf.predict(df_test)

result = pd.DataFrame(df_test['PassengerId'])
result['Survived'] = pre
result.to_csv('result0312.csv', index=False)

[提出結果]

正解率75.59%となりました。

・・・7割台での足踏みがなかなかにしんどいです。