「Titanic - Machine Learning from Disaster」での複数分析手法の実施

# はじめに
Kaggleのチュートリアル的なコンペである「Titanic - Machine Learning from Disaster」に
参加を行い、かつ分析手法や特徴量を変動させた場合に、スコアはどのように変動するか確認を行った。

# 対象としたKaggleの課題
「Titanic - Machine Learning from Disaster」は、実際に1912年に発生したタイタニック号の沈没事故を題材としており、本事故では乗客2,224人のうち1,502人が亡くなった※。
Kaggleでは、乗客データを用いて「どのような人の生存率が高いか」を予測するコンペとなっている。

※諸説あるが、Kaggleでは本数値をデータとして用いる

### Kaggleより抜粋
The sinking of the Titanic is one of the most infamous shipwrecks in history.

On April 15, 1912, during her maiden voyage, the widely considered “unsinkable” RMS Titanic sank after colliding with an iceberg. Unfortunately, there weren’t enough lifeboats for everyone onboard, resulting in the death of 1502 out of 2224 passengers and crew.

While there was some element of luck involved in surviving, it seems some groups of people were more likely to survive than others.

## 実行環境
パソコン：Windows10
開発環境：Kaggle Notebook
言語：Python
ライブラリ：scikit-learn, Keras, sea-born, pandas

# 分析するデータ
本コンペで取り扱うデータは以下の特徴量を持っている。
※分析データの詳細はKaggleを要確認すること。

<dl>
  <dt>test.csv</dt>
  <dd>構築した予測モデルをテストするためのデータであり、survivedを含まない（データ数：418）</dd>
  <dt>train.csv</dt>
  <dd>予測モデルを構築するためのデータであり、survivedを含む（データ数：891）</dd>
  <dt>gender_submission.csv</dt>
  <dd>提出ファイルのサンプルとして女性乗客のみが生存すると仮定した予測データ</dd>
</dl>

各データがもつ特徴量
| Variable   | Definition                               | 
|:----------:|:------------                             |
| PassengerId|ID                                        |
| Survived   |Survival                                  |
| Pclass     |Ticket class                              |
| Name       |Name                                      |
| Sex        |Sex                                       |
| Age        |Age in years                              |
|SibSp       |# of siblings / spuses aboard the Titanic |
|Parch       |# of parents / children aboard the Titanic|
|Ticket      |Ticket number                             |
|Fare        |Passenger fare                            |
|Cabin       |Cabin number                              |
|Embarked    |Port of Embarkation                       |

### Name列の存在
分析の前に注目したいのが、データにNameが含まれている点である。
本コンペは実際に起きた事故を題材にしており、データにNameが含まれている。
数人のNameについて確認したところ、タイタニック号に乗船したとされている人の名前と一致しており、生死についても一致している。
そのため、予測モデルを用いずとも実際の記録と照らし合わせることが多少は可能である。

# 分析の流れ
複数の機械学習モデルを同じデータから生成して、どのモデルが最も高いスコアか分析する。
本記事では教師あり学習として主要な以下のモデルを、簡単な前処理を用いたデータで生成を行う。
+ Logistic Regression
+ k-Nearest Neighbors
+ Support Vector Machines
+ Naive Bayes classifier
+ Decision Tree
+ Random Forrest
+ Perceptron
+ Linear SVC
+ Stochastic Gradient Descent

### 前処理
本分析での前処理は以下を実施した。
<dl>
  <dt>欠損値を別の値に置換</dt>
  <dd>AgeやFareの欠損値を中央値に置換</dd>
  <dt>非数値データを数字へ置換</dt>
  <dd>Sexの「male」、「female」をそれぞれ[「0」、「1」に置換</dd>
</dl>

### 分析の過程（モデルの生成）
予測モデル生成とモデルのテストには、前述の前処理を行ったデータから'Pclass', 'Sex', 'Age', 'Fare'を使用する。
```データの代入
X_train = train[['Pclass', 'Sex', 'Age', 'Fare']].values
Y_train = train['Survived'].values
X_test  = test[['Pclass', 'Sex', 'Age', 'Fare']].values
```

+ Logistic Regression
```モデル生成とスコア値
logreg = LogisticRegression(random_state=0)
logreg.fit(X_train, Y_train)
Y_pred = logreg.predict(X_test)
acc_log = round(logreg.score(X_train, Y_train) * 100, 2)
acc_log
```

+ k-Nearest Neighbors
```モデル生成とスコア値
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train, Y_train)
Y_pred = knn.predict(X_test)
acc_knn = round(knn.score(X_train, Y_train) * 100, 2)
acc_knn
```

+ Support Vector Machines
```モデル生成とスコア値
svc = SVC(random_state=0)
svc.fit(X_train, Y_train)
Y_pred = svc.predict(X_test)
acc_svc = round(svc.score(X_train, Y_train) * 100, 2)
acc_svc
```

+ Naive Bayes classifier
```モデル生成とスコア値
gaussian = GaussianNB()
gaussian.fit(X_train, Y_train)
Y_pred = gaussian.predict(X_test)
acc_gaussian = round(gaussian.score(X_train, Y_train) * 100, 2)
acc_gaussian
```

+ Decision Tree
```モデル生成とスコア値
decision_tree = DecisionTreeClassifier()
decision_tree.fit(X_train, Y_train)
Y_pred = decision_tree.predict(X_test)
acc_decision_tree = round(decision_tree.score(X_train, Y_train) * 100, 2)
acc_decision_tree
```

+ Random Forrest
```モデル生成とスコア値
random_forest = RandomForestClassifier(n_estimators=100)
random_forest.fit(X_train, Y_train)
Y_pred = random_forest.predict(X_test)
random_forest.score(X_train, Y_train)
acc_random_forest = round(random_forest.score(X_train, Y_train) * 100, 2)
acc_random_forest
```

+ Perceptron
```モデル生成とスコア値
perceptron = Perceptron(random_state=0)
perceptron.fit(X_train, Y_train)
Y_pred = perceptron.predict(X_test)
acc_perceptron = round(perceptron.score(X_train, Y_train) * 100, 2)
acc_perceptron
```

+ Linear SVC
```モデル生成とスコア値
linear_svc = LinearSVC()
linear_svc.fit(X_train, Y_train)
Y_pred = linear_svc.predict(X_test)
acc_linear_svc = round(linear_svc.score(X_train, Y_train) * 100, 2)
acc_linear_svc
```

+ Stochastic Gradient Descent
```モデル生成とスコア値
sgd = SGDClassifier()
sgd.fit(X_train, Y_train)
Y_pred = sgd.predict(X_test)
acc_sgd = round(sgd.score(X_train, Y_train) * 100, 2)
acc_sgd
```

### 分析したデータから得られた情報
生成した予測モデルの精度を訓練データで計測すると以下となった。

| model                     | Score | 
|:----------                |:-----:|
|Logistic Regression        | 79.91 |
|k-Nearest Neighbors        | 84.18 |
|Support Vector Machines    | 68.01 |
|Naive Bayes classifier     | 77.78 |
|Decision Tree              | 97.76 |
|Random Forrest             | 97.76 |
|Perceptron                 | 62.07 |
|Linear SVC                 | 78.45 |
|Stochastic Gradient Descent| 64.09 |


### 考察
訓練データを用いたスコアが最も高いモデルは「Decision Tree」と「Random Forrest」で、スコアは「97.76」であった。
スコアはあくまで訓練データに対する値であるため、試しに「Decision Tree」でテストデータに対する予測を算出し、Kaggleに提出したところ、Kaggleのスコアは「0.73684」であった。
訓練データに対するスコアとは大きな乖離があった。
そのため、訓練データに過学習している可能性を感じた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083784/d0bf3ea0-a804-4186-a660-7810c8ddadd8.png)

## まとめ
本記事では、複数の機械学習モデルを生成して、どのモデルが課題に対し、有効か確認を行った。
本記事を記載するにあたって以下の記事を参考とした。
>https://www.kaggle.com/code/aryelbezerra/titanic-competition-ml-models#Submission-to-Kaggle

参考記事では本記事と同様に複数のモデルを生成していたが、データに対する前処理には大きな違いがある。
前処理では不要データの削除や相関関係のあるデータを1つのデータにまとめる等の処理を実施している。
参考記事での訓練データに対する各モデルのスコアは以下のようになっている。

| model                     | Score | 
|:----------                |:-----:|
|Logistic Regression        | 80.36 |
|k-Nearest Neighbors        | 83.84 |
|Support Vector Machines    | 78.23 |
|Naive Bayes classifier     | 72.28 |
|Decision Tree              | 86.76 |
|Random Forrest             | 86.76 |
|Perceptron                 | 78.34 |
|Linear SVC                 | 78.90 |
|Stochastic Gradient Descent| 79.12 |

最もスコアが高いモデルは本記事と同様に「Decision Tree」と「Random Forrest」であり、「Decision Tree」でテストデータに対する予測を算出し、Kaggleに提出したところ、Kaggleのスコアは「0.76794」であった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083784/5c29b5ce-2300-447d-a7b0-d91a963cb67b.png)



モデルとしては「Decision Tree」と「Random Forrest」のスコアが高い値となったが、参考記事やKaggleのスコアを確認すると、訓練データに対して過学習している可能性がある。
Kaggleのスコアとしては、参考記事のほうが良い結果となったため、データに対する前処理が重要になっていると感じた。