はじめてのKaggle② タイタニックコンペのデータ確認～モデル作成（決定木）

## 概要

はじめてKaggleに取り組む人へ向けた記事②として、タイタニックコンペで簡単にデータ確認後、決定木モデルを作成して提出します。

## 前提
以下は対応済みとます。
- [環境作成](https://qiita.com/udata/items/44ec3293ce8b6f97588b)
- [Kaggle登録](https://qiita.com/udata/items/0fe7a72fddd7018b6052)


## 1. 準備
データダウンロードと集計するための準備をします。

### 1-1.コンペデータのダウンロード
タイタニックのコンペぺージでDataタブ（[■](https://www.kaggle.com/competitions/titanic/data)）を開き、"Download All"を押下する

⇒"titanic.zip"がダウンロードされるので、所定の位置へ設置して展開します。
　※今回はこのコンペ用にtinanicフォルダ（`C:/Users/u-data/kaggle/titanic/`）を用意し、その下の`data`フォルダに設置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/227fc89c-10e2-ab23-1e79-f0a9fae9e6ca.png)


### 1-2. JupyterLabの起動
ターミナルまたはコマンドプロンプトを開いて、以下コマンドを実行する

```
jupyter lab　
```

⇒自動的にブラウザが開き、JupyterLabのホーム画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/75f28136-c734-3be4-7234-c26fb1734c15.png)


### 1-3. ノートブック作成

JupyterLabでtitanicフォルダへ移動する
　※`C:/Users/u-data/kaggle/titanic/`

titanicフォルダに移動したら、NotebookのPython3（ipkernel）を選択して、ノートブックを開く

⇒`C:/Users/u-data/kaggle/titanic/`に"Untitled.ipynb"が作成されるので、適当に"decision_tree.ipynb"と名前を付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/f06ed145-9255-c079-2b4c-d80c831ab539.png)


## 2. データ確認+前処理
ノートブックを準備できたので、読み込んで簡単にデータ確認を行います。

### 2-1. データ読み込み
ノートブックで以下セルを実行して、データを読み込む

```python:decision_tree.ipynb
# pandasを"pd"としてインポート
import pandas as pd

# ノートブックと同じフォルダ（.）内にある、data/train.csvの読み込んでデータフレームに入れる
train_data = pd.read_csv('./data/train.csv')

# 最初の5行を表示
train_data.head(5)
```
※`No module named 'pandas'`エラーが出たら、pipインストールしてください（[■](https://qiita.com/udata/items/e164189028f4fa0fc50b)）

⇒Pandasライブラリを使って`train.csv`を読み込み、最初の5行が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/7e0c62fa-2fdf-a152-5fb7-e35513607e6c.png)

### 2-2. 要約統計量の計算

ノートブックで以下セルを実行して、データの要約統計量を計算する

```python:decision_tree.ipynb
# 要約統計量の計算
train_data.describe()
```
⇒各列の平均や標準偏差・最大値・最小値・最頻値などの要約統計量を出力できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/259a9d37-9ed2-1b7b-36f3-23b6615d2676.png)

## 3. 前処理

ノートブックで以下セルを実行して、数値項目に変換する（モデル作成のため）

### 3-1. Object型の2項目を数値型に変換
```python:decision_tree.ipynb
# Sex を数値型に
train_data['Sex'] = train_data['Sex'].map({'male':0, 'female':1})
# Embarked を数値型に
train_data['Embarked'] = train_data['Embarked'].map({'S':0, 'C':1, 'Q':2})
```
### 3-2. 要約統計量の計算(再確認）

ノートブックで以下セルを実行して、要約統計量を出力する

```python:decision_tree.ipynb
# 要約統計量を再出力
train_data.describe()
```
⇒SexとEmbarked項目も要約統計量を出力できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/3135fb44-4e72-0c74-5f70-c18b72dba8be.png)



## 4. データの可視化

次に、MatplotlibとSeabornを使ってデータを可視化してみます。

### 4-1. 可視化用ライブラリのインポート
```python:decision_tree.ipynb
# 可視化用ライブラリのimport
import matplotlib.pyplot as plt
import seaborn as sns
```
### 4-2. ヒストグラムを描画（乗客の年齢）
ノートブックで以下セルを実行して、ヒストグラムを描画する

```python:decision_tree.ipynb
# ヒストグラムを描画（乗客の年齢）
sns.histplot(train_data['Age'], bins=20, kde=True)
plt.title('Age Distribution')
plt.xlabel('Age')
plt.ylabel('Frequency')
plt.show()
```
⇒乗客は20代～30代ぐらいの年齢が多いようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/c0ef281b-3c02-953d-6dda-0c9e63755204.png)


### 4-3. 散布図の描画（乗客の年齢・運賃と生存結果）

ノートブックで以下セルを実行して、散布図を描画する

```python:decision_tree.ipynb
# 散布図の描画（乗客の年齢・運賃と生存結果）
sns.scatterplot(data=train_data, x='Age', y='Fare', hue='Survived')
plt.title('Age vs Fare')
    plt.show()
```
⇒運賃が高い人・15歳以下の子供で生存率が高そうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/12e666f1-21fa-809f-b674-bd2485fa3fcc.png)




### 5. 決定木モデルを作成

ノートブックで以下セルを実行して、モデルを作成する

```python:decision_tree.ipynb
#ライブラリのインポート
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 特徴量（数値項目のみ）と目的変数を分割してX, yに入れる
X = train_data.select_dtypes(include='number').drop(['Survived'], axis=1)
y = train_data['Survived']

# Xとyをそれぞれ、訓練データと検証データに分割する
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

# 決定木モデルを作成して、訓練データで学習を行う
model = DecisionTreeClassifier(max_depth=3, random_state=42)
model.fit(X_train, y_train)

# 訓練データで学習したmodelを使用して、検証データの予測を行う
y_pred = model.predict(X_val)
print('Validation Accuracy:', accuracy_score(y_val, y_pred))
```

ノートブックで以下セルを実行して、モデルの結果を可視化する

```python:decision_tree.ipynb
# 決定木の結果を可視化

from sklearn.tree import plot_tree
import matplotlib.pyplot as plt

plt.figure(figsize=(15,8))
plot_tree(model, filled=True, feature_names=X.columns)
plt.show()
```
⇒「性別が男性か女性か」「年齢が6.5歳以下かどうか」など分岐して結果を予測しています。
※結果の読み方についてはもっと分かりやすい解説記事があったので、最下部に参考として挙げています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/c0508ab0-dda9-a2a7-2c92-e038169e69f3.png)


### 6. 予測と提出
最後にノートブックで以下セルを実行して、テストデータを用いて予測を行って、結果をKaggleに提出します。

```python:decision_tree.ipynb
# テストデータの読み込み
test_data = pd.read_csv('./data/test.csv')


# テストデータも同様に前処理
# Sex を数値化
test_data['Sex'] = test_data['Sex'].map({'male':0, 'female':1})
# Embarked を数値化
test_data['Embarked'] = test_data['Embarked'].map({'S':0, 'C':1, 'Q':2})

# テストデータでの予測
X_test = test_data.select_dtypes(include='number')
predictions = model.predict(X_test)

# 提出用ファイルの作成
submission = pd.DataFrame({
    'PassengerId': test_data['PassengerId'],
    'Survived': predictions
})

submission.to_csv('submission_decision_tree.csv', index=False)

```

[提出ページ](https://www.kaggle.com/competitions/titanic/submissions)の、「Submit Prediction」から、submission_decision_tree.csvをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/cfed1d17-d784-1b7e-52a7-e8748e28b860.png)

⇒精度は0.77511で、性別のみで予測したサンプルファイル（0.76555）よりも僅かに精度が向上していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357979/110d4cd1-9ead-64cb-db51-aa85f9c10a1d.png)


## 7. 結論
これで、決定木モデルを用いてタイタニックの生存者予測を行い、その結果をKaggleに提出することができました。決定木は過学習しやすい点には注意が必要ですが、条件分岐が直感的に解釈しやすいモデルでした。

今回は簡単なモデルを作成できたので、次回以降は他のモデルやアンサンブル手法を試して、更に精度を向上させてみたいと思います。


## 参考

決定木を可視化した結果の見方は以下ページがとても分かりやすかったので、参考に挙げさせていただきます。
https://smart-hint.com/ml/tree/#%E6%B1%BA%E5%AE%9A%E6%9C%A8%E3%81%AE%E5%8F%AF%E8%A6%96%E5%8C%96%EF%BC%88plot_tree%EF%BC%89