Titanicに再チャレンジ

前回kaggleのトレーニングコンペティション"Titanic"にエントリーしましたが、別のモデルで精度を検証したくなり、再チャレンジしました。

色んな書式のコードを参考にしたのですが、今回は実装力の強化を目標にできるだけ自身でデータクレンジングやモデルの構成を考えてコーディングしています。

まだ機械学習を始めてから２ヶ月しか経っていないため、色々と至らないコードの記述があると思いますがそこはご容赦ください。



#ランダムフォレストで生存確率の予測を実装

```python
#ライブラリのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib 
%matplotlib inline
from sklearn.ensemble import RandomForestClassifier
```


```python
#学習データのcsvファイルを読み込み
train = pd.read_csv("/kaggle/input/titanic/train.csv")
#学習データの先頭５行でデータ内容の確認
train.head()
```
![スクリーンショット 2023-02-08 22.20.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/f882031b-3b01-7705-78ea-4895ae21ffdd.png)

```python
#テストデータのcsvファイルを読み込み
test = pd.read_csv("/kaggle/input/titanic/test.csv")
#テストデータの先頭５行でデータ内容を確認
test.head()
```
![スクリーンショット 2023-02-08 22.22.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/91c15619-9623-060e-7b2c-22089392906a.png)

```python
#学習データとテストデータのshape数を確認（いつも念のため行なっています）
print(train.shape)
print(test.shape)
```
![スクリーンショット 2023-02-08 22.25.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/d4472bbb-a051-9f6c-d47c-148bc8f142a1.png)

```python
#学習データの要約を確認
train.info()
```
![スクリーンショット 2023-02-08 22.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/5c1f0dcb-35cd-6c9f-0b2a-1fa9e5e67b82.png)
型が違うデータの有無などを確認できました。


```python
#テストデータの要約を確認
test.info()
```
![スクリーンショット 2023-02-08 22.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/04f91e62-6e5c-e541-8372-e54d458cda50.png)

カラムに”Survived”が無いのが確認できました、
下記の統計情報取得については情報を把握したくて念の為に出力しました。

```python
train.describe()
```

```python
test.describe()
```

```python
#学習データ"Survived"の割合を円グラフで可視化
plt.pie(train["Survived"].value_counts(), labels=["dead", "Survived"], autopct="%.1f%%")
plt.show()
```
![スクリーンショット 2023-02-08 22.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/ee947eb7-3d2a-9963-f0d9-4e55f1216c20.png)

```python
#学習データ"Survived"の１と０を集計（１→生存、０→それ以外）
train["Survived"].value_counts()
```

```python
#分析に不要な可能性がある列を削除
train = train.drop(['PassengerId','Name','Ticket','Cabin','Embarked'], axis=1)
test = test.drop(['Name','Ticket','Cabin','Embarked'], axis=1)
train.head()
```
![スクリーンショット 2023-02-08 22.39.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/a1c7a614-94b2-9cad-aa1b-64b4a488e09f.png)

```python
#学習データを「生存したか」「それ以外か」で分割
train_x = train.drop("Survived", axis=1)
train_y = train["Survived"]
train_x.head()
```
![スクリーンショット 2023-02-08 22.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/e78d983f-23ab-e7cc-6c7a-0114f2ec409b.png)

```python
#テストデータの"PassengerId"を削除しtest_xへ代入
test_x = test.drop("PassengerId", axis=1)
```
```python
#学習データの欠損値を確認
train_x.isnull().sum()
```
![スクリーンショット 2023-02-08 22.45.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/a68abe2c-30a2-c993-400f-083b82b98ddc.png)


```python
#テストデータの欠損値を確認
test_x.isnull().sum()
```
![スクリーンショット 2023-02-08 22.45.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/c7839afb-4ba0-4f09-65fe-84c922bb7155.png)

学習データの"Age"の列とテストデータの"Age"と"Fare"に欠損値が存在することが確認できました

```python
#学習データ、テストデータの欠損値を別の値の平均を使用して補完
train_x["Age"].fillna(train_x["Age"].mean(), inplace=True)
test_x["Age"].fillna(test_x["Age"].mean(), inplace=True)
test_x["Fare"].fillna(test_x["Fare"].mean(), inplace=True)
train_x.isnull().sum()
```
![スクリーンショット 2023-02-08 22.48.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/249c39c3-c8c3-6e42-98ff-404e45ce2f49.png)

```python
test_x.isnull().sum()
```
![スクリーンショット 2023-02-08 22.50.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/bbb30da3-0d31-c230-6a09-ae20887ac306.png)

これで学習データ、テストデータの欠損値が全て補完されました。
ただ、両データともに「性別」の列がオブジェクトオブジェクト型のままになっており、このままだと分析に使えません。
そこでone-hot-エンコーディングを使ってオブジェクト型の文字列をダミーの数値型に変換しました。

```python
#"Sex"列の文字（オブジェクト型）をダミー数値に変換
train_x = pd.get_dummies(train_x, columns=["Sex"])
```
![スクリーンショット 2023-02-08 22.57.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/d98c9442-1e5b-9c35-b0b3-7fd93016672a.png)
これで性別欄も数値化できました。
テストデータも同様の処理をします。

```python
#上記と同じ処理
test_x = pd.get_dummies(test_x, columns=["Sex"])
```

```python
#モデルの構築（今回はハイパーパラメータはデフォルトで構築しました）
model = RandomForestClassifier()
```

```python
#モデルの学習
model.fit(train_x,train_y)
```
```python
#テストデータの予測値を確率で出力
pred = model.predict_proba(test_x)[:,1]
#テストデータの予測値を二値に変換
pred_y = np.where(pred > 0.5, 1, 0)
```


この予測値を提出したところ、、、
![スクリーンショット 2023-02-08 23.03.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124100/f9ad4626-80e6-079f-abaf-8eedc6fedf81.png)

７４%でした。
前回の文献を参考にしながら作成したモデルは７６%であったため
少し精度が落ちてしまいましたが、ほぼ自力でモデル作成ができた
ため満足しています。


次の目標はハイパーパラメータの与え方とデータ内容に合わせたモデル選定
の精度を上げることを目標にスキルを磨いていきたいと思います。

長くなって申し訳ありません。
ここまで読んでくださってありがとうございました。

また次回。