Scikit-learnで機械学習モデル構築 (実践)
いよいよ、これまでの知識を総動員して、機械学習モデルを構築します。Pythonで機械学習を行う際の標準的なライブラリであるScikit-learn (サイキット・ラーン) を使って、タイタニック号の乗客の生存を予測するモデルを作成しましょう。
このページでは、以下の流れで進めていきます。
- データの前処理: モデルが学習できるようにデータを整える。
- 学習データと検証データの分割: モデルの性能を正しく評価するためにデータを分ける。
- モデルの学習: データを学習させ、予測モデルを作る。
- モデルの評価: モデルの性能を確かめる。
- 未知のデータで予測:
test.csvのデータを使って予測を体験する。
0. 準備
まずは、必要なライブラリのインポートとデータの読み込みを行います。
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# データを読み込む
train_df = pd.read_csv('train.csv')
test_df = pd.read_csv('test.csv')
1. データの前処理 (Preprocessing)
機械学習モデルは、生のデータをそのまま学習することはできません。特に、欠損値や文字列データを、モデルが理解できる数値形式に変換する必要があります。これを前処理と呼びます。
ここでは、簡単のため、使用する特徴量をPclass, Sex, Age, Fareに絞り、最小限の前処理を行います。
def preprocess(df):
# Sex(性別)を数値に変換: male -> 0, female -> 1
df['Sex'] = df['Sex'].map({'male': 0, 'female': 1})
# Age(年齢)の欠損値を、全体の平均年齢で埋める
df['Age'].fillna(df['Age'].mean(), inplace=True)
# Fare(運賃)の欠損値を、全体の平均運賃で埋める(テストデータに1件欠損があるため)
df['Fare'].fillna(df['Fare'].mean(), inplace=True)
# 今回使う特徴量を選択
features = df[['Pclass', 'Sex', 'Age', 'Fare']]
return features
# 学習データとテストデータの両方に前処理を適用
train_features_full = preprocess(train_df.copy()) # 元のDataFrameを壊さないようにコピー
test_features_full = preprocess(test_df.copy())
# 正解ラベル(目的変数)を準備
train_labels = train_df['Survived']
print("--- 前処理後の学習データ ---")
print(train_features_full.head())
2. 学習データと検証データの分割
モデルの性能を正しく評価するためには、学習に使ったデータとは別のデータで評価する必要があります。なぜなら、モデルは学習データを「暗記」してしまい、そのデータに対しては非常に高い性能を発揮しますが、未知のデータには全く対応できない「過学習(Overfitting)」という状態に陥りやすいからです。
そこで、train.csvのデータをさらに「学習用データ」と「検証用データ」に分割します。Scikit-learnのtrain_test_splitがこの役割を果たします。
# train_features_full と train_labels を、学習用と検証用に分割する
# test_size=0.2 は、全体の20%を検証用データとして使うという意味
# random_state=42 は、毎回同じように分割するためのシード値
X_train, X_val, y_train, y_val = train_test_split(
train_features_full, train_labels, test_size=0.2, random_state=42)
print("元の学習データのサイズ:", train_features_full.shape)
print("学習用データ(特徴量)のサイズ:", X_train.shape)
print("検証用データ(特徴量)のサイズ:", X_val.shape)
3. モデルの学習 (Training)
分割した学習用データ (X_train, y_train) を使って、モデルを学習させます。今回は、多くのコンペで高い性能を発揮するランダムフォレストというアルゴリズムを使います。
# ランダムフォレスト分類器のモデルを作成
model = RandomForestClassifier(n_estimators=100, random_state=42)
# モデルに「学習用」データを渡して学習させる
model.fit(X_train, y_train)
print("モデルの学習が完了しました。")
4. モデルの評価 (Evaluation)
学習が完了したモデルが、未知のデータに対してどれくらいの性能を持つかを検証用データ (X_val, y_val) を使って評価します。これがモデルの真の実力に近い値となります。
# 「検証用」データに対する予測を行う
val_predictions = model.predict(X_val)
# 正解ラベル(y_val)と予測結果を比較し、正解率を計算する
accuracy = accuracy_score(y_val, val_predictions)
print(f"検証データに対する正解率: {accuracy:.4f}")
# -> おおよそ 0.8156 のようなスコアが表示されるはず
この正解率が、あなたのモデルが「初見のデータ」に対してどれくらい正しく予測できるかの指標となります。
5. 未知のデータで予測 (Prediction)
モデルの性能に納得したら、いよいよKaggleのtest.csv(答えがわからない、全く新しいデータ)の乗客たちの生存を予測してみましょう。これは、あなたが実際にKaggleに挑戦する際の最終ステップの練習です。
# test.csvから作った前処理済みのデータに対して予測を実行
test_predictions = model.predict(test_features_full)
# 予測結果をDataFrameにして、わかりやすく表示
prediction_df = pd.DataFrame({
'PassengerId': test_df['PassengerId'],
'Predicted_Survived': test_predictions
})
print("--- test.csvに対する予測結果 ---")
print(prediction_df.head())
この結果が、あなたのモデルが出した最終的な答えです。Kaggleに挑戦する際は、この結果を所定のフォーマットのCSVファイルにして提出することになります。
お疲れ様でした!これで、データの前処理、学習と検証の分割、モデルの学習、評価、そして未知のデータへの予測という、機械学習の基本的なワークフロー全体を体験できました。
もちろん、今回は非常にシンプルな前処理とモデルでした。より良いモデルを作るためには、
- 特徴量エンジニアリング(
NameやCabinから新しい特徴を作るなど) - ハイパーパラメータチューニング(
RandomForestClassifierのn_estimatorsなどを調整する) - 別のモデルを試す(勾配ブースティングなど) といった、より高度なテクニックに挑戦していくことになります。このドキュメントが、その第一歩となれば幸いです。