Competition


Titanic


get_dummies train test 差分

https://qiita.com/yutowac/items/0052114affbee6fd9cb4

https://shikaolog.com/pandas-dummy-variable-categorical/


アルゴリズム

 

 参考 データ分析初心者向け!主要な予測方法を徹底解説!(前編)

 

・k近傍法

 新しいデータが既存のデータのどのクラスに属するかを、近くのデータポイントを基に決定する

 

・サポートベクターマシン

 データを分けるための最適な境界を見つける。非線形問題に対してもカーネルを使って適応できる

 

・ランダムフォレスト

 複数の決定木を使って多数決を行うことで予測を行う手法。過学習を防ぐために有効

 

・勾配ブースティング決定木

 予測の精度を上げるために、弱い予測モデルを繰り返し学習させ、最終的に強いモデルを構築する手法


1)初期処理 》 ファイル読み込み、データ確認

import pandas as pd

# ファイル読み込み
train = pd.read_csv('/kaggle/input/titanic/train.csv')  # トレーニングセット
test = pd.read_csv('/kaggle/input/titanic/test.csv')    # テストセット

# データ確認
# トレーニングセット
train.head(3)

# テストセット
test.head(3)

# 型
train.dtypes

# 欠損値(トレーニングセット)
train.isnull().sum()

#欠損値(テストセット)
test.isnull().sum()

2)欠損値のない数値のみのモデルを作成してベースラインをとる

# トレーニングセットで変数定義
x = train[['Pclass','SibSp','Parch']]  # 説明変数:最初は数値型の欠損値がないカラムを使用
y = train['Survived']                  # 目的変数

# x,yをトレーニング用とテスト用に分割
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(x, y, random_state=0)

# 【k近傍法】を使用したモデルを作成
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train, Y_train)  # トレーニング用

# scoreを使って精度を確認
"""
精度 = 予測値が「陽性」で、かつ、実際の正解値も「陽性」だった正解数 ÷「陽性」と予測した全てのデータ数
トレーニングとテストの精度の差が小さいのが理想的
一方の精度が高すぎる場合は過学習傾向にある(ex 98%)
"""
print(knn.score(X_train, Y_train))  # トレーニング用
print(knn.score(X_test, Y_test))    # テスト用

Result

0.6751497005988024

0.6502242152466368

# テストセットで変数定義
x_for_submit = test[['Pclass','SibSp','Parch']]  # 説明変数

# テストセットによる予測を行う
survived = knn.predict(x_for_submit)

# 提出用データフレームを作成
submit = pd.DataFrame({"PassengerId":test["PassengerId"], "Survived":survived})

# 提出ファイルを出力
submit.to_csv('submit01.csv', index=False)

3)特徴量設計の手法

① カテゴリ変数をダミー変数化する 》 get_dummies()

ダミー変数化前

  Pclass SibSp Parch Sex
0 3 1 0 male
1 1 1 0 female
2 3 0 0 female

 ダミー変数化後

  SibSp Parch Pclass_1 Pclass_2 Pclass_3 Sex_female Sex_male
0 1 0 0 0 1 0 1
1 1 0 1 0 0 1 0
2 0 0 0 0 1 1 0
# トレーニングセットで変数定義
"""
カテゴリ変数
 Pclass:1 = 1st, 2 = 2nd, 3 = 3rd
 sex:male, female
Sexを追加
"""
x = train[['Pclass','SibSp','Parch', 'Sex']]  # 説明変数
y = train['Survived']                         # 目的変数

# カテゴリ変数をダミー変数化する
x = pd.get_dummies(x, columns=['Pclass','Sex'], dtype=int)

# 特徴量の見直し結果

# トレーニング用とテスト用に分割
X_train, X_test, Y_train, Y_test = train_test_split(x, y, random_state=0)

# モデル作成
knn = KNeighborsClassifier()
knn.fit(X_train, Y_train) 

# 精度確認
print(knn.score(X_train, Y_train)) 
print(knn.score(X_test, Y_test))

Result

0.811377245508982

0.7982062780269058

 

② 標準化(異なるスケールの特徴量(例えば、年齢と収入)を一貫した形で扱うことができる) 》 StandardScaler()

標準化を行うことによって、特徴量の比率を揃えることが出来る。例えば100点満点のテストと50点満点のテスト

があったとして点数の比率、単位が違う場合でも標準化を利用することでそれらの影響を受けずに点数を評価でる。

 

X_train_scaler

array([[-0.46037161, -0.47720996, -0.48380773, ..., 0.90562878,

     -0.72705166, 0.72705166],

   [ 2.98532288, 1.95619654, -0.48323058, ..., 0.90562878,

     1.37541808, -1.37541808],

   [ 0.40105202, -0.47720996, -0.32165051, ..., 0.90562878,

     -0.72705166, 0.72705166],

     ...,

# トレーニングセットで変数定義
"""
桁数の大きいFare(運賃)を追加 例 7.2500
"""
x = train[['Pclass','SibSp','Parch', 'Sex','Fare']]  # 説明変数
y = train['Survived']                                # 目的変数

# ダミー変数化
x = pd.get_dummies(x, columns=['Pclass','Sex'], dtype=int)

# トレーニング用とテスト用に分割
X_train, X_test, Y_train, Y_test = train_test_split(x, y, random_state=0)

# 標準化
from sklearn.preprocessing import StandardScaler
# インスタンス生成
scaler = StandardScaler()
# データの平均と標準偏差を計算
scaler.fit(X_train)                         
# データを標準化
X_train_scaler = scaler.transform(X_train)
X_test_scaler = scaler.transform(X_test)

# モデル作成
knn = KNeighborsClassifier()
knn.fit(X_train_scaler, Y_train) 

# 精度確認
print(knn.score(X_train_scaler, Y_train)) 
print(knn.score(X_test_scaler, Y_test))

Result

0.8458083832335329

0.8161434977578476

 

③ NULLに平均値をセット 》 fillna()

# テストセットで変数定義
x_for_submit = test[['Pclass','SibSp','Parch', 'Sex','Fare']]  # 説明変数

# 欠損値を平均値に置換(穴埋め)
x_for_submit['Fare'] = x_for_submit['Fare'].fillna(x_for_submit['Fare'].mean())

# ダミー変数化
x_for_submit = pd.get_dummies(x_for_submit, columns=['Pclass','Sex'], dtype=int)

# 標準化
"""
テストセットに対しては、インスタンス生成やfitを行わず、transformのみ実施する
"""
x_for_submit_scaler = scaler.transform(x_for_submit)

# テストセットによる予測
"""
predictのINPUTに欠損値が含まれていると以下の例外が発生する。当処理を実施する前にfillna等で置換が必要
ValueError: Input X contains NaN.
"""
survived = knn.predict(x_for_submit_scaler)

# 提出用Dataframe作成
submit = pd.DataFrame({"PassengerId":test["PassengerId"], "Survived":survived})

submit.head(3)

# 提出ファイル(csv)出力
submit.to_csv('submit02.csv', index=False)

4)他のモデルを試して精度を確認

・モデル作成までの一連作業

# トレーニングセットで変数定義
x = train[['Pclass','SibSp','Parch', 'Sex','Fare']]  # 説明変数
y = train['Survived']                                # 目的変数

# ダミー変数化
x = pd.get_dummies(x, columns=['Pclass','Sex'], dtype=int)

# トレーニング用とテスト用に分割
X_train, X_test, Y_train, Y_test = train_test_split(x, y, random_state=0)

# 標準化
scaler = StandardScaler()
scaler.fit(X_train)                         
X_train_scaler = scaler.transform(X_train)
X_test_scaler = scaler.transform(X_test)

》サポートベクターマシン

from sklearn.svm import LinearSVC

# モデル作成 svc = LinearSVC() svc.fit(X_train_scaler, Y_train) # 精度確認 print(knn.score(X_train_scaler, Y_train)) print(knn.score(X_test_scaler, Y_test))

Result

0.8458083832335329

0.8161434977578476

 

》ランダムフォレスト

from sklearn.ensemble import RandomForestClassifier

# モデル作成 rf = RandomForestClassifier() rf.fit(X_train_scaler, Y_train) # 精度確認 print(rf.score(X_train_scaler, Y_train)) print(rf.score(X_test_scaler, Y_test))

Result

0.9221556886227545

0.8251121076233184

 

》勾配ブースティング決定木 - Scikit-Learn

from sklearn.ensemble import GradientBoostingClassifier

# モデル作成 gr = GradientBoostingClassifier() gr.fit(X_train_scaler, Y_train) # 精度確認 print(gr.score(X_train_scaler, Y_train)) print(gr.score(X_test_scaler, Y_test))

Result

0.8712574850299402

0.8026905829596412

》勾配ブースティング決定木 - XGBoost

from xgboost import XGBClassifier

# モデル作成 xg = XGBClassifier() xg.fit(X_train_scaler, Y_train) # 精度確認 print(xg.score(X_train_scaler, Y_train)) print(xg.score(X_test_scaler, Y_test))

Result

0.9041916167664671

0.820627802690583

 

》一番精度の高かったランダムフォレストのモデルで提出する作業

# テストセットで変数定義
x_for_submit = test[['Pclass','SibSp','Parch', 'Sex','Fare']]  # 説明変数

# 欠損値を平均値に置換(穴埋め)
x_for_submit['Fare'] = x_for_submit['Fare'].fillna(x_for_submit['Fare'].mean())

# ダミー変数化
x_for_submit = pd.get_dummies(x_for_submit, columns=['Pclass','Sex'], dtype=int)

# 標準化
x_for_submit_scaler = scaler.transform(x_for_submit)

# テストセットによる予測
survived = rf.predict(x_for_submit_scaler)

# 提出用Dataframe作成
submit = pd.DataFrame({"PassengerId":test["PassengerId"], "Survived":survived})

# 提出ファイル(csv)出力
submit.to_csv('submit03.csv', index=False)

5)説明変数の重要度を確認

df = pd.DataFrame({"feature_names":x_for_submit.columns, "coefficiet":rf.feature_importances_})
df.sort_values("coefficiet", ascending=False)
  feature_names coefficiet
2 Fare 0.424016
6 Sex_female 0.180267
7 Sex_male 0.172370
0 SibSp 0.063386
1 Parch 0.062222
5 Pclass_3 0.044798
3 Pclass_1 0.031634
4 Pclass_2 0.021308