論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
訓練・テスト分割
Train/Test Split
ML基礎
別称: データ分割

🔖 キーワード索引

train-test split ホールドアウト shuffle stratify random_state 再現性 時系列分割 TimeSeriesSplit GroupKFold k分割CV リーケージ 層化抽出 比率 再現可能性

💡 30秒で分かる結論

訓練・テスト分割(Train/Test Split):データを訓練用と評価用に分けること。 ML プロジェクトの最も基本的な作法

📍 あなたが今見ているもの

このページは「訓練・テスト分割(Train/Test Split)」の用語解説です。 機械学習の基礎カテゴリにおける重要概念で、 機械学習の基礎 グループ教材の中で繰り返し登場します。 数式・実コード・落とし穴を 1 ページに集約し、 SSDSE-B-2026 都道府県データ(47 件 × 112 列)を題材に 手を動かしながら理解できるよう構成しています。

別称:ホールドアウト法。 まず 💡 30秒結論 で全体像を、 次に 🎨 直感📐 数式🧮 実値🐍 Python の順で読むのがおすすめ。

🎨 直感で掴む

訓練・テスト分割は、 「学習に使ったデータでは性能を測らない」という原則を守るための最も簡単な方法です。 全データを 70/30 や 80/20 で 2 つに割り、 前者でモデル学習、 後者で評価のみ。

落とし穴は (1) シャッフルなしで偏る、 (2) 時系列を無視、 (3) 同じグループ(同じ顧客・同じ県)が訓練と評価に跨ると 事実上のリーケージ。 用途に応じて train_test_split / KFold / StratifiedKFold / TimeSeriesSplit / GroupKFold を選びます。

📐 数式または定義

本概念は次のように記述されます(KaTeX で描画)。

$$\mathcal{D} = \mathcal{D}_{\text{train}} \sqcup \mathcal{D}_{\text{test}},\qquad |\mathcal{D}_{\text{train}}|:|\mathcal{D}_{\text{test}}| = (1-\alpha) : \alpha,\quad \alpha\in\{0.2,0.25,0.3\}$$

英語名 Train/Test Split。 別称:ホールドアウト法。

🔬 数式を言葉で読み解く

記号と意味を逐一突き合わせて読みます。 慣れないうちは式を「日本語で読む」ことが理解の近道です。

🧮 SSDSE-B 実値で計算してみる

SSDSE-B で ランダム分割 / 層化分割 / 時系列分割 / グループ分割 の 4 通りを比較します。

データ出典:SSDSE-B-2026(独立行政法人統計センター)。 47 都道府県 × 複数年(最新 2023)の社会統計データ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pandas as pd
import numpy as np
from sklearn.model_selection import (train_test_split, StratifiedKFold,
                                     TimeSeriesSplit, GroupKFold)

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df = df[df['年度'] == 2023].reset_index(drop=True)
df['ラベル'] = (df['15歳未満人口'] / df['総人口']
              >= (df['15歳未満人口']/df['総人口']).median()).astype(int)

X = df[['総人口','65歳以上人口']].values
y = df['ラベル'].values

# (1) ランダム 70/30
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=0)
print('(1) random ', y_tr.mean(), y_te.mean())

# (2) 層化(クラス比率を保つ)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=0,
                                          stratify=y)
print('(2) stratify', y_tr.mean(), y_te.mean())

# (3) 時系列分割(複数年データ前提:年度列で時系列扱い)
df_ts = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
tss = TimeSeriesSplit(n_splits=4)
for tr_idx, te_idx in tss.split(df_ts):
    print('(3) TS  train_yrs=', sorted(df_ts.iloc[tr_idx]['年度'].unique())[-3:],
          ' test_yrs=', sorted(df_ts.iloc[te_idx]['年度'].unique()))
    break

# (4) グループ分割(都道府県をグループに)
gkf = GroupKFold(n_splits=5)
for tr_idx, te_idx in gkf.split(df_ts, groups=df_ts['都道府県']):
    print('(4) Group test 県=', df_ts.iloc[te_idx]['都道府県'].unique()[:5])
    break

実行結果の要約(出力は環境依存。 概算値):

項目
(1) ランダム y平均 訓練/テスト0.53 / 0.40
(2) 層化 y平均 訓練/テスト0.50 / 0.50
(3) TimeSeriesSplit古い年で訓練 → 新しい年で評価
(4) GroupKFold1 県は訓練か検証どちらか片方
47 県データの推奨5-fold StratifiedKFold
時系列データの推奨TimeSeriesSplit

🐍 Python 実装

scikit-learn / pandas を使った最小実装パターン。 上の SSDSE-B 計算と同じスタイルですが、 ここでは「読み込み→前処理→学習→評価」のテンプレを 4 つのスニペットに分けます。

① データ読み込み & 概観

1
2
3
4
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df = df[df['年度'] == 2023].reset_index(drop=True)
print(df.shape, df.columns.tolist()[:8])

② 特徴量と目的変数

1
2
3
X = df[['総人口','65歳以上人口']].values
y = df['15歳未満人口'].values
print('X shape =', X.shape, ',  y shape =', y.shape)

③ 訓練/テスト分割 + モデル学習

1
2
3
4
5
6
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor

X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=0)
model = RandomForestRegressor(n_estimators=300, random_state=0).fit(X_tr, y_tr)
print('R^2 (test) =', model.score(X_te, y_te))

④ 評価と可視化

1
2
3
4
5
6
import matplotlib.pyplot as plt
pred = model.predict(X_te)
plt.scatter(y_te, pred)
plt.plot([y_te.min(), y_te.max()], [y_te.min(), y_te.max()], 'r--')
plt.xlabel('実測'); plt.ylabel('予測'); plt.title('「訓練・テスト分割」関連モデルの予測精度')
plt.tight_layout(); plt.savefig('out.png', dpi=150)

※ 「訓練・テスト分割」固有の本格コードは上の 🧮 SSDSE-B 実値計算 節を参照。

⚠️ よくある落とし穴(5 つ)

❌ random_state を指定しない
実行のたびに分割が変わる → 結果が再現しない。 必ず固定。
❌ クラス不均衡で stratify=None
陽性 1% の問題でテストに陽性が 0 件 → 精度測定不能。 stratify=y。
❌ 時系列を普通の split で割る
未来の情報で過去を予測 → 当たって当然。 必ず時間順 split。
❌ 顧客 ID をまたいで分割
同じユーザの行動を訓練・テストに分けると事実上の漏洩。 GroupKFold を使う。
❌ テストが小さすぎる
n_test < 30 では精度のばらつきが大きすぎ。 サンプル数が少ないなら k-fold で安定化。

✅ 学習チェックリスト