🎯 STEP 14: 予測モデルの構築と評価
過学習を防ぎ、実用的な予測モデルを作ろう
📋 このステップで学ぶこと
- 学習データとテストデータの分割方法
- 過学習(Overfitting)とその防止策
- 予測精度の評価指標(MAE、RMSE、MAPE)
- 交差検証(Cross-Validation)の実践
- 実務で使える予測モデルの構築
学習時間の目安:3.5時間
🎯 1. なぜデータを分割するのか
過学習の問題
モデルが過去のデータに合いすぎて、未来の予測が悪くなること
例:
・過去のデータ:R² = 0.99(ほぼ完璧!)
・新しいデータ:予測が全然当たらない…
→ これが過学習
原因:
・説明変数が多すぎる
・サンプルサイズが小さい
・ノイズ(たまたまの変動)まで学習してしまう
学習データとテストデータ
学習データ(Training Data):
モデルを作るためのデータ
例:過去のデータの70%
テストデータ(Test Data):
モデルの予測精度を確認するためのデータ
例:過去のデータの30%
重要:
テストデータは、モデル作成時には一切使わない
→ 「未来のデータ」として扱う
なぜ分割が必要か
学習データだけで評価する問題:
- モデルは学習データに「最適化」されている
- 学習データでのR²は高くなりやすい
- でも、新しいデータでの予測は悪いかもしれない
テストデータで評価する利点:
- 本当の予測精度がわかる
- 過学習を検出できる
- 実務での性能を推定できる
✂️ 2. データの分割方法
分割比率の決め方
| 分割比率 | 適用ケース |
|---|---|
| 70:30 | 最も一般的。中規模データ(100〜1000件) |
| 80:20 | データが少ない場合(〜100件) |
| 60:20:20 | 学習:検証:テスト(高度なモデル選択) |
| 90:10 | データが非常に多い場合(10000件〜) |
ランダム分割の重要性
データをランダムに分割することが重要です。
NG例:最初の70%を学習、残り30%をテスト
→ 時系列データの場合、季節性などが偏る
OK例:ランダムにシャッフルしてから分割
→ 学習データとテストデータに偏りがない
ただし、時系列データの場合は例外(後述)
Pythonでの分割
時系列データの分割
時系列データ:時間順に並んだデータ(売上、株価など)
重要:
時系列データはランダム分割しない
→ 過去のデータで学習、未来のデータでテスト
例:
・1月〜8月:学習データ
・9月〜12月:テストデータ
理由:未来は過去を見てから予測するため
📊 3. 予測精度の評価指標
R²だけでは不十分
R²は相対的な指標
→ 「どれくらい説明できるか」はわかるが、「予測誤差が何円か」はわからない
例:R² = 0.9でも、予測誤差が100万円なら実務で使えない
解決:絶対的な誤差を測る指標を使う
主要な評価指標
1. MAE(Mean Absolute Error、平均絶対誤差)
計算式:
MAE = (|誤差1| + |誤差2| + … + |誤差n|) / n
意味:平均して、予測がどれくらい外れているか
例:MAE = 50万円 → 平均して、予測は50万円ズレている
特徴:解釈しやすい(同じ単位)、外れ値の影響を受けにくい
2. RMSE(Root Mean Squared Error、平均二乗誤差の平方根)
計算式:
RMSE = √[(誤差1² + 誤差2² + … + 誤差n²) / n]
意味:誤差の二乗の平均の平方根
特徴:大きな誤差をより重視、外れ値の影響を受けやすい、MAEより値が大きくなる
3. MAPE(Mean Absolute Percentage Error、平均絶対パーセント誤差)
計算式:
MAPE = (|誤差1/実際の値1| + … + |誤差n/実際の値n|) / n × 100%
意味:パーセントでの平均誤差
例:MAPE = 5% → 平均して、予測は実際の値の5%ズレている
特徴:異なるスケールのデータを比較できる、実際の値が0に近いと計算できない
どの指標を使うべきか
| 状況 | 推奨指標 | 理由 |
|---|---|---|
| わかりやすさ重視 | MAE | 同じ単位で解釈しやすい |
| 大きな誤差を重視 | RMSE | 大きな誤差にペナルティ |
| パーセントで評価 | MAPE | 相対的な誤差がわかる |
| 異なるモデルの比較 | RMSE / MAPE | 標準的な比較指標 |
・MAE:経営層への報告に適している(「平均20万円のズレ」)
・RMSE:技術的な評価・モデル比較に適している
・MAPE:異なる規模のデータを比較する場合に便利
💻 4. Pythonでの実践
モデルの学習と評価
結果の解釈
| 指標 | 学習データ | テストデータ | 判定 |
|---|---|---|---|
| R² | 0.9823 | 0.9645 | ✓ 良好 |
| MAE | 8.45万円 | 12.34万円 | ✓ 許容範囲 |
| RMSE | 10.23万円 | 15.67万円 | ✓ 許容範囲 |
判断:
・テストデータの性能が学習データよりやや低いが、これは正常
・差が大きすぎない(過学習していない)
・テストデータでも高い精度 → 実務で使えるモデル!
過学習の検出
学習データとテストデータの性能差が大きい
例:
・学習データ:R² = 0.99、MAE = 5万円
・テストデータ:R² = 0.60、MAE = 50万円
→ 過学習!
対処:
・説明変数を減らす
・正則化(Ridge、Lasso回帰)
・サンプルサイズを増やす
・交差検証で確認
結果の可視化
🔄 5. 交差検証(Cross-Validation)
交差検証とは
データをk個のグループに分けて、
順番に1つをテストデータ、残りを学習データとして評価を繰り返す
例:5分割交差検証
1回目:グループ1をテスト、2-5で学習
2回目:グループ2をテスト、1,3-5で学習
3回目:グループ3をテスト、1-2,4-5で学習
4回目:グループ4をテスト、1-3,5で学習
5回目:グループ5をテスト、1-4で学習
→ 5回の平均を取る
利点:
・すべてのデータを学習にもテストにも使える
・評価が安定する
・過学習を検出しやすい
Pythonでの実装
結果の解釈
1. 平均スコア
モデルの平均的な性能を示す
2. 標準偏差
スコアのバラつき
・標準偏差が小さい → 安定したモデル ✓
・標準偏差が大きい → 不安定(データに依存しすぎ)✗
判断:
上記の例では、R²の標準偏差が0.0063と非常に小さい
→ 安定した高性能なモデル!
総合的な評価関数
📝 STEP 14 のまとめ
1. データ分割の基本
- 学習データ(70%)とテストデータ(30%)に分割
- テストデータは「未来のデータ」として扱う
- 時系列データは時間順に分割
2. 過学習(Overfitting)
- 学習データに合いすぎて、テストデータで性能が悪化
- 学習とテストの性能差で検出
3. 評価指標
- MAE:わかりやすい(同じ単位)
- RMSE:大きな誤差を重視
- MAPE:パーセントで評価
4. 交差検証
- データを分割して複数回評価
- 平均と標準偏差でモデルの安定性を評価
予測モデルの本当の性能は、テストデータで評価します。学習データでのR²が高くても、安心してはいけません!
実務での推奨フロー:
- データを学習(70%)とテスト(30%)に分割
- 学習データでモデルを作成
- テストデータで性能を評価
- MAE、RMSE、MAPEを計算
- 過学習していないか確認
- 交差検証で安定性を確認
- 問題なければ、全データでモデルを再学習
- 実運用開始
次のSTEP 15では、多重共線性の対処を学びます!
STEP 15では、「多重共線性の対処」を学びます。VIF(分散拡大要因)の計算と、変数選択の方法を習得します!
📝 練習問題
なぜデータを学習データとテストデータに分割する必要があるのですか?
理由:
モデルの本当の予測精度を確認するため
詳細:
- 学習データだけで評価すると:
モデルは学習データに「最適化」されているので、性能が高く出やすい
でも、新しいデータでの予測は悪いかもしれない(過学習) - テストデータで評価すると:
モデルが「見たことのない」データでの性能がわかる
実務での予測精度を推定できる
過学習を検出できる
MAE、RMSE、MAPEの違いを説明し、それぞれどのような場面で使うのが適切か答えてください。
MAE(平均絶対誤差):
- 予測誤差の絶対値の平均
- 同じ単位で解釈しやすい
- 適切な場面:経営層への報告、直感的な理解が必要な場合
RMSE(平均二乗誤差の平方根):
- 誤差の二乗の平均の平方根
- 大きな誤差をより重視
- 適切な場面:技術的な評価、モデル比較、大きな誤差が問題になる場合
MAPE(平均絶対パーセント誤差):
- パーセントでの平均誤差
- 異なるスケールのデータを比較できる
- 適切な場面:異なる規模のデータを比較する場合、相対的な精度を知りたい場合
以下の2つのモデルがあります。どちらが良いモデルですか?理由も説明してください。
モデルA:
学習データ:R² = 0.85、MAE = 15万円
テストデータ:R² = 0.82、MAE = 18万円
モデルB:
学習データ:R² = 0.95、MAE = 8万円
テストデータ:R² = 0.60、MAE = 50万円
比較表:
| 項目 | モデルA | モデルB |
|---|---|---|
| 学習データのR² | 0.85 | 0.95(高い) |
| テストデータのR² | 0.82 | 0.60(低い) |
| 性能差(R²) | 0.03(小さい) | 0.35(大きい) |
| 判定 | ✓ 安定 | ✗ 過学習 |
理由:
モデルBは学習データでは性能が高いが、テストデータで大きく悪化しています。これは過学習のサインであり、実務では使えません。
モデルAは学習データとテストデータの性能差が小さく、安定した予測ができます。実務で使える!
交差検証の結果、R²の平均が0.85、標準偏差が0.15でした。この結果をどう解釈しますか?
解釈:
平均R²は0.85と良好ですが、標準偏差が0.15と大きいため、不安定なモデルと判断できます。
問題点:
- 分割によってR²が0.70〜1.00と大きくバラつく
- データに依存しすぎている
- 実務での予測精度が安定しない可能性
対処法:
・説明変数を見直す
・外れ値の影響を確認
・サンプルサイズを増やす
・正則化(Ridge、Lasso)を検討
あなたは売上予測モデルを作成しました。MAE = 20万円、MAPE = 5%という結果でした。平均売上400万円と仮定して、このモデルはビジネス的に使えますか?判断基準を示しながら説明してください。
分析:
- MAE = 20万円:平均して、予測は20万円ズレる。平均売上400万円に対して5%のズレ。
- MAPE = 5%:パーセントで見ても5%のズレ。一般的に、MAPEが10%以下なら「良い精度」とされる。
ビジネス判断:
- 在庫計画:5%の誤差は許容範囲 → 使える
- 予算計画:20万円のズレは許容範囲 → 使える
- 戦略的意思決定:十分な精度 → 使える
注意:
許容できる精度は、ビジネスの目的によって異なります。
・在庫最適化:5%でOK
・金融取引:1%未満が必要
・大まかな予算:10%でもOK
目的に応じて、必要な精度を設定しましょう。
❓ よくある質問
理由:
テストデータを何度も見てモデルを調整すると、テストデータに「最適化」されてしまい、本来の目的を失います。
推奨フロー:
1. データを学習(70%)、検証(15%)、テスト(15%)に3分割
2. 学習データでモデル作成
3. 検証データでモデル選択・調整(何度でもOK)
4. 最後に、テストデータで最終評価(一度だけ)
実務では:
小規模データなら、学習(70%)とテスト(30%)の2分割でOK。交差検証を使えば、検証データは不要です。
例:
・2020年1月〜2023年8月:学習データ
・2023年9月〜2023年12月:テストデータ
重要:
・ランダム分割しない(時間順を保つ)
・未来は過去を見てから予測するため
交差検証も特殊:
時系列交差検証(TimeSeriesSplit)を使う → Pythonのsklearnで実装可能
使い分け:
MAE(平均絶対誤差):
・わかりやすい(同じ単位)
・経営層への報告に最適
・例:「平均して20万円ズレます」
RMSE(平均二乗誤差の平方根):
・大きな誤差をより重視
・技術的な評価に適している
・モデル比較に使いやすい
MAPE(平均絶対パーセント誤差):
・パーセントで表現
・異なるスケールのデータを比較できる
・実際の値が0に近いと使えない
推奨:MAE(報告用)+ RMSE(技術評価用)
交差検証が特に重要な場合:
・データ数が少ない(100件未満)
・モデルの安定性を確認したい
・複数のモデルを比較したい
・過学習を防ぎたい
省略してもOKな場合:
・データ数が非常に多い(10000件以上)
・シンプルなモデル(説明変数が1〜2個)
・時間的制約が厳しい
推奨:
時間があれば、必ず交差検証を実施しましょう。モデルの信頼性が大きく向上します!
1. 過学習の確認
学習データとテストデータの性能差が大きい
→ 説明変数を減らす、正則化を使う
2. モデルの見直し
・線形回帰が適切か?(非線形の関係はないか)
・重要な変数が抜けていないか
・変数変換(対数、平方根など)が必要か
3. データの質を確認
・外れ値がないか
・データ入力ミスがないか
・サンプルサイズは十分か
4. 別の手法を検討
・決定木、ランダムフォレスト
・勾配ブースティング(XGBoost、LightGBM)
・ニューラルネットワーク
5. ビジネス的判断
完璧な予測は不可能。許容できる精度なら使う。
説明:
データ分割はランダムに行われますが、random_stateを指定すると、毎回同じ分割結果になります。
なぜ必要か:
・結果を再現できる(同じ分析を再度実行可能)
・チームで結果を共有できる
・デバッグがしやすい
値の選び方:
・任意の整数(42、123、0など)
・値自体に意味はない
・一度決めたら変えない
例:
random_state=42 → 何度実行しても同じ分割になる
random_state=None → 毎回異なる分割になる
学習メモ
ビジネスデータ分析・意思決定 - Step 14