1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[ふわっと機械学習] 1.Titanicの生存者予測

Last updated at Posted at 2024-06-01

はじめに

ようやく重い腰を上げて手を動かす気になったので分野を問わず気の向くままふわっと機械学習に触れてみようと思います。記念すべき第一回はKaggle(データ分析の問題を解くコンテスト)の有名なチュートリアルTitanic - Machine Learning from Disasterを取り上げます。有名な問題なのでちょっとググればたくさん解き方が出てきます。先人の知恵を拝借しつつゆるゆる取り組んでみましょう。Pythonを使います。

下記シリーズを参考にしています。とても丁寧です!
Kaggle入門「タイタニックの生存予測」メダリストと一緒に解説!

出来上がるコードはこんな感じ。

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# トレーニングデータの読み込みと前処理
train = pd.read_csv('train.csv')
X = train[['Pclass', 'SibSp', 'Parch', 'Sex', 'Fare']]
Y = train['Survived']
X = pd.get_dummies(X, columns=['Pclass', 'Sex'])
X['Fare'] = X['Fare'].fillna(X['Fare'].mean())

# トレーニングデータを訓練セットと検証セットに分割
X_train, X_val, Y_train, Y_val = train_test_split(X, Y, test_size=0.2, random_state=0)

# スケーリング
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_val_scaled = scaler.transform(X_val)

# モデルのトレーニング
knn = KNeighborsClassifier()
knn.fit(X_train_scaled, Y_train)

# 検証セットでのモデル評価
Y_val_pred = knn.predict(X_val_scaled)
val_accuracy = accuracy_score(Y_val, Y_val_pred)
print(f"Validation Accuracy: {val_accuracy}")

# テストデータの読み込みと前処理
test = pd.read_csv('test.csv')
X_test = test[['Pclass', 'SibSp', 'Parch', 'Sex', 'Fare']]
submit = test[['PassengerId']]
X_test = pd.get_dummies(X_test, columns=['Pclass', 'Sex'])
X_test['Fare'] = X_test['Fare'].fillna(X_test['Fare'].mean())

# トレーニングデータと同じダミー変数列を持つように調整
X_test = X_test.reindex(columns=X_train.columns, fill_value=0)

# スケーリング
X_test_scaled = scaler.transform(X_test)

# 全トレーニングデータで最終モデルをトレーニング
knn_final = KNeighborsClassifier()
X_train_full_scaled = scaler.fit_transform(X)
knn_final.fit(X_train_full_scaled, Y)

# テストデータでの予測
submit['Survived'] = knn_final.predict(X_test_scaled)

print(submit)

コメントを付した通りですが、ひとつひとつ見ていきましょう。

基本情報チェック(※完成コードにはありません)

基本情報を確認します。とりあえずデータを読み込みましょう。

# pandas入れる -> データ読み込む
import pandas as pd
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

中身をチェックして、nullがあるかを見ます。

# trainの中身をチェック -> nullの数をカウント
train.dtypes
train.isnull().sum()
# testの中身をチェック -> nullの数をカウント
train.dtypes
train.isnull().sum()

たとえばtrainのデータはこんな感じでした。

データ名 意味 データ型 null数
PassengerId 乗客番号 int64 0
Survived 生存 int64 0
Pclass チケットクラス int64 0
Name 名前 object 0
Sex 性別 object 0
Age 年齢 float64 177
SibSp 乗船した配偶者・兄弟の数 int64 0
Parch 乗船した親・子の数 int64 0
Ticket チケット番号 object 0
Fare 運賃 float64 0
Cabin 客室番号 object 687
Embarked 乗船港 object 2

データ加工

上の表を見て、数値じゃない項目やnullがあることがわかります。これらの項目を捨てるのはもったいないのでなんとか数値にして使いたい。データ分析をしていると数値で表せる量的データ(身長とか体重とか)と分類を表す質的(カテゴリカル)データ(性別とか職業とか)に出くわしますが、質的データを処理する方法としてワンホットエンコーディングなるものがあります。

ワンホットエンコーディング

たとえば性別は数値ではないですが次のようにすれば数値として扱うことができます。
男, 女 -> (男である, 女である) = (1,0) or (0,1)
つまり、カテゴリの数のサイズで、該当の要素のみ1ほかが0になるようなベクトルのイメージです。

性別 Sex_female Sex_male
1 0 1
2 1 0
3 1 0
4 1 0

get_dummies関数をつかうと一撃でワンホットコーディングしてくれます。
ということでこんな感じ。

# トレーニングデータの読み込みと前処理
train = pd.read_csv('train.csv')
X = train[['Pclass', 'SibSp', 'Parch', 'Sex', 'Fare']]
Y = train['Survived']
X = pd.get_dummies(X, columns=['Pclass', 'Sex'])

欠損値の補完

つぎはnullまみれのFareをなんとかします。
fillna関数を使って埋めましょう。平均値で埋めます。

X['Fare'] = X['Fare'].fillna(X['Fare'].mean())

訓練データをさらに訓練データと検証データに分割

モデルの性能を評価するために、トレーニングデータをさらに分割して検証データセットを作成します。
今回は初めから訓練データ(train.csv)と検証データ(test.csv)に分けてくれているのでこの作業は別に要らない気もしますが、まあ練習ということで。random_stateは固定値を与えればなんでもいいです。与えないと訓練用と検証用の振り分け方が毎回変わり、再現性に影響します。

# トレーニングデータを訓練セットと検証セットに分割
X_train, X_val, Y_train, Y_val = train_test_split(X, Y, test_size=0.2, random_state=0)

スケーリング

特徴量のスケール(値の範囲)が大きく異なる場合、スケールの大きい特徴量が機械学習モデルに与える影響が大きくなり、スケールの小さい特徴量が無視されてしまうことがあります。速度や精度上昇に寄与します。

# スケーリング
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_val_scaled = scaler.transform(X_val)

fit_transform関数は、訓練データに対して初めてフィッティングと変換を行うために使用し、transform関数は、すでにフィッティングされたスケーラーを用いて新しいデータを変換するときに使用します。これにより、訓練データとテストデータが同じ基準で標準化されます。

トレーニング

今回はシンプルなK-近傍法を用います。
ざっくりいえば、ご近所さんを調べて参加チームを決めるイメージです。
引っ越し先のご近所さんに犬好きが多ければあなたも犬好きになります。

# モデルのトレーニング
knn = KNeighborsClassifier()
knn.fit(X_train_scaled, Y_train)

コードばかりで何が起きているのかわからなくなってきたのでいったん整理。
x_train_scaledは各乗客の特徴量が入った行列(つまり生死を知る手がかりのデータ)です。Y_trainは各乗客の生死を示すベクトル(つまり答え)です。
knn.fitによって、「手がかり」から「答え」を推論するようなハッピーなデータを生成します。(これがいわゆる機械学習の「モデル」)
ハッピーなデータを手に入れたので、予想->答え合わせをしてみましょう。

# 検証セットでのモデル評価
Y_val_pred = knn.predict(X_val_scaled)
val_accuracy = accuracy_score(Y_val, Y_val_pred)
print(f"Validation Accuracy: {val_accuracy}")

テストデータを使って提出用の予想を作る

モデルができたので、あとはこれを使って提出用のデータを作るだけです。

# テストデータの読み込みと前処理
test = pd.read_csv('test.csv')
X_test = test[['Pclass', 'SibSp', 'Parch', 'Sex', 'Fare']]
submit = test[['PassengerId']]
X_test = pd.get_dummies(X_test, columns=['Pclass', 'Sex'])
X_test['Fare'] = X_test['Fare'].fillna(X_test['Fare'].mean())

# トレーニングデータと同じダミー変数列を持つように調整
X_test = X_test.reindex(columns=X_train.columns, fill_value=0)

# スケーリング
X_test_scaled = scaler.transform(X_test)

# 全トレーニングデータで最終モデルをトレーニング
knn_final = KNeighborsClassifier()
X_train_full_scaled = scaler.fit_transform(X)
knn_final.fit(X_train_full_scaled, Y)

# テストデータでの予測
submit['Survived'] = knn_final.predict(X_test_scaled)
submit.to_csv('submit.csv', index=False)
print(submit)

submit.csvをKaggleに提出して完了です!
Scoreは0.763くらいでした。
今回はK近傍法でモデルを構築しましたが、参考動画ではランダムフォレストだったりいろいろなアルゴリズムを試していました。
まだまだ奥深そうですが雰囲気はつかめた気がします。
では。
※!記事に嘘が混じってたらコメントお願いします!※

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?