競馬AI予測システム設計:データ収集から機械学習モデルまで完全ガイド
はじめに:競馬予測の課題と可能性
競馬は多くの変数が絡み合う複雑な予測問題です。単純なオッズ追従では長期的な収益は見込めません。本記事では、機械学習を活用した競馬予測システムの設計を段階的に解説します。
競馬予測の難しさ
graph TD
A[競馬予測の難しさ] --> B[変数の多さ]
A --> C[データの不確実性]
A --> D[市場の効率性]
A --> E[時系列の複雑さ]
B --> B1[馬の能力]
B --> B2[騎手の技術]
B --> B3[馬場状態]
B --> B4[展開・ペース]
C --> C1[馬のコンディション]
C --> C2[調教の質]
C --> C3[当日の気性]
D --> D1[オッズに情報が織り込み済み]
D --> D2[大量の参加者]
E --> E1[馬の成長曲線]
E --> E2[距離適性の変化]
E --> E3[季節要因]
本システムの目標
| 指標 | 目標値 | 説明 |
|---|---|---|
| 単勝的中率 | 25%以上 | 人気馬に偏らない予測 |
| 回収率 | 80%以上 | 長期的な損失を抑制 |
| 複勝的中率 | 50%以上 | 安定した予測精度 |
| 期待値馬券 | 100%以上 | 期待値がプラスの馬券を特定 |
システム全体アーキテクチャ
6層アーキテクチャ
graph TB
subgraph "Layer 1: データ収集層"
A1[JRA公式データ]
A2[netkeiba API]
A3[地方競馬データ]
A4[オッズデータ]
A5[天候・馬場データ]
end
subgraph "Layer 2: データストア層"
B1[(PostgreSQL
マスタデータ)] B2[(TimescaleDB
時系列データ)] B3[(Redis
キャッシュ)] B4[S3/MinIO
生データ] end subgraph "Layer 3: データ処理層" C1[ETLパイプライン] C2[特徴量エンジニアリング] C3[データ品質チェック] end subgraph "Layer 4: モデル層" D1[LightGBM
着順予測] D2[XGBoost
勝率予測] D3[Neural Network
複合予測] D4[アンサンブル
統合モデル] end subgraph "Layer 5: 推論・配信層" E1[リアルタイム推論API] E2[バッチ予測] E3[通知サービス] end subgraph "Layer 6: フロントエンド層" F1[Web Dashboard] F2[モバイルアプリ] F3[LINE Bot] end A1 & A2 & A3 & A4 & A5 --> B4 B4 --> C1 C1 --> B1 & B2 B1 & B2 --> C2 C2 --> C3 C3 --> D1 & D2 & D3 D1 & D2 & D3 --> D4 D4 --> E1 & E2 E1 --> F1 & F2 & F3 E2 --> E3 B3 -.キャッシュ.-> E1
マスタデータ)] B2[(TimescaleDB
時系列データ)] B3[(Redis
キャッシュ)] B4[S3/MinIO
生データ] end subgraph "Layer 3: データ処理層" C1[ETLパイプライン] C2[特徴量エンジニアリング] C3[データ品質チェック] end subgraph "Layer 4: モデル層" D1[LightGBM
着順予測] D2[XGBoost
勝率予測] D3[Neural Network
複合予測] D4[アンサンブル
統合モデル] end subgraph "Layer 5: 推論・配信層" E1[リアルタイム推論API] E2[バッチ予測] E3[通知サービス] end subgraph "Layer 6: フロントエンド層" F1[Web Dashboard] F2[モバイルアプリ] F3[LINE Bot] end A1 & A2 & A3 & A4 & A5 --> B4 B4 --> C1 C1 --> B1 & B2 B1 & B2 --> C2 C2 --> C3 C3 --> D1 & D2 & D3 D1 & D2 & D3 --> D4 D4 --> E1 & E2 E1 --> F1 & F2 & F3 E2 --> E3 B3 -.キャッシュ.-> E1
技術スタック
| レイヤー | 技術 | 選定理由 |
|---|---|---|
| データ収集 | Python (Scrapy, requests) | 柔軟なスクレイピング |
| データストア | PostgreSQL + TimescaleDB | 時系列データに最適 |
| データ処理 | Apache Airflow + dbt | 堅牢なETLパイプライン |
| 機械学習 | LightGBM, XGBoost, PyTorch | 高精度モデル |
| 推論API | FastAPI + Redis | 低レイテンシ |
| フロントエンド | Next.js | モダンなUI |
| インフラ | Docker + Kubernetes | スケーラブル |
データモデル設計
エンティティ関連図(ER図)
erDiagram
HORSE ||--o{ RACE_RESULT : "出走"
JOCKEY ||--o{ RACE_RESULT : "騎乗"
TRAINER ||--o{ HORSE : "管理"
RACE ||--o{ RACE_RESULT : "含む"
RACECOURSE ||--o{ RACE : "開催"
HORSE ||--o{ TRAINING : "調教"
HORSE }|--|| BLOODLINE : "血統"
HORSE {
int horse_id PK
string name
date birth_date
string gender
int trainer_id FK
int bloodline_id FK
string color
string origin
}
JOCKEY {
int jockey_id PK
string name
date birth_date
string belonging
float career_win_rate
float career_place_rate
}
TRAINER {
int trainer_id PK
string name
string stable_location
float career_win_rate
}
RACE {
int race_id PK
int racecourse_id FK
date race_date
int race_number
string grade
int distance
string surface
string condition
int prize_money
}
RACE_RESULT {
int result_id PK
int race_id FK
int horse_id FK
int jockey_id FK
int post_position
int finish_position
float finish_time
float last_3f_time
float weight
float weight_diff
float odds
int popularity
}
BLOODLINE {
int bloodline_id PK
string sire
string dam
string broodmare_sire
string sire_line
}
TRAINING {
int training_id PK
int horse_id FK
date training_date
string course
float time
string evaluation
}
RACECOURSE {
int racecourse_id PK
string name
string location
int turf_distance_min
int turf_distance_max
int dirt_distance_min
int dirt_distance_max
}
主要テーブル定義
| |
特徴量エンジニアリング
特徴量カテゴリ
graph LR
A[特徴量] --> B[馬の基本情報]
A --> C[過去成績]
A --> D[血統]
A --> E[騎手・調教師]
A --> F[レース条件]
A --> G[オッズ・人気]
A --> H[調教]
B --> B1[年齢]
B --> B2[性別]
B --> B3[馬体重]
B --> B4[体重増減]
C --> C1[過去N走の着順]
C --> C2[勝率・連対率]
C --> C3[距離別成績]
C --> C4[馬場別成績]
C --> C5[コース別成績]
D --> D1[父系スコア]
D --> D2[母父系スコア]
D --> D3[距離適性遺伝]
D --> D4[馬場適性遺伝]
E --> E1[騎手勝率]
E --> E2[調教師勝率]
E --> E3[騎手×馬相性]
F --> F1[距離]
F --> F2[馬場状態]
F --> F3[コース形態]
F --> F4[グレード]
G --> G1[単勝オッズ]
G --> G2[人気順位]
G --> G3[オッズ変動]
H --> H1[調教タイム]
H --> H2[調教評価]
H --> H3[調教パターン]
特徴量生成コード
| |
特徴量の重要度分析
graph TB
A[特徴量重要度 Top 15] --> B[1. 過去5走平均着順 0.15]
A --> C[2. 騎手勝率 0.12]
A --> D[3. オッズ 0.11]
A --> E[4. 距離適性スコア 0.09]
A --> F[5. 前走着順 0.08]
A --> G[6. 調教タイム 0.07]
A --> H[7. 馬場適性スコア 0.06]
A --> I[8. 枠順有利スコア 0.05]
A --> J[9. 馬体重変動 0.05]
A --> K[10. 父系スコア 0.04]
A --> L[11. 騎手乗り替わり 0.04]
A --> M[12. 上がり3F平均 0.04]
A --> N[13. 人気順 0.03]
A --> O[14. 年齢 0.03]
A --> P[15. コース別成績 0.03]
機械学習モデル設計
モデルアーキテクチャ
graph TB
subgraph "入力層"
A[特徴量
約100次元] end subgraph "モデル層" B1[LightGBM
着順予測] B2[XGBoost
勝率予測] B3[CatBoost
複勝予測] B4[Neural Network
深層学習] end subgraph "アンサンブル層" C1[スタッキング] C2[ブレンディング] end subgraph "出力層" D1[予測着順] D2[勝利確率] D3[複勝確率] D4[期待値スコア] end A --> B1 & B2 & B3 & B4 B1 & B2 & B3 & B4 --> C1 C1 --> C2 C2 --> D1 & D2 & D3 & D4
約100次元] end subgraph "モデル層" B1[LightGBM
着順予測] B2[XGBoost
勝率予測] B3[CatBoost
複勝予測] B4[Neural Network
深層学習] end subgraph "アンサンブル層" C1[スタッキング] C2[ブレンディング] end subgraph "出力層" D1[予測着順] D2[勝利確率] D3[複勝確率] D4[期待値スコア] end A --> B1 & B2 & B3 & B4 B1 & B2 & B3 & B4 --> C1 C1 --> C2 C2 --> D1 & D2 & D3 & D4
LightGBMモデル実装
| |
アンサンブルモデル
| |
モデル評価指標
| |
リアルタイム推論パイプライン
推論フロー
sequenceDiagram
participant User as ユーザー
participant API as FastAPI
participant Cache as Redis Cache
participant DB as PostgreSQL
participant Model as MLモデル
participant Notify as 通知サービス
User->>API: レース予測リクエスト
API->>Cache: キャッシュ確認
alt キャッシュあり
Cache-->>API: キャッシュ済み予測
else キャッシュなし
API->>DB: レースデータ取得
DB-->>API: 出走馬情報
API->>API: 特徴量生成
API->>Model: 予測リクエスト
Model-->>API: 予測結果
API->>Cache: 結果をキャッシュ
end
API-->>User: 予測結果
Note over API,Notify: オッズ更新時
API->>Model: 再予測
Model-->>API: 更新された予測
API->>Notify: 大きな変動を通知
Notify-->>User: プッシュ通知
FastAPI実装
| |
モニタリングと継続的改善
モニタリングダッシュボード
graph TB
subgraph "リアルタイムモニタリング"
A1[予測API応答時間]
A2[予測件数/分]
A3[キャッシュヒット率]
A4[エラー率]
end
subgraph "予測精度モニタリング"
B1[日次的中率]
B2[週次回収率]
B3[モデル別AUC]
B4[特徴量ドリフト]
end
subgraph "ビジネスモニタリング"
C1[ユーザー数]
C2[アクティブ率]
C3[推奨採用率]
C4[ユーザー回収率]
end
subgraph "アラート"
D1[精度低下アラート]
D2[システム異常アラート]
D3[データ異常アラート]
end
A1 & A2 & A3 & A4 --> D2
B1 & B2 & B3 & B4 --> D1
B4 --> D3
精度モニタリング実装
| |
モデル再学習パイプライン
| |
費用対効果の試算
システム運用コスト
| 項目 | 月額コスト | 備考 |
|---|---|---|
| クラウドインフラ | ¥50,000 | AWS/GCP 中規模構成 |
| データソース | ¥10,000 | API利用料 |
| MLプラットフォーム | ¥20,000 | MLflow, モデル管理 |
| モニタリング | ¥5,000 | Datadog等 |
| 合計 | ¥85,000/月 |
期待リターン
前提条件:
- 月間予測レース数: 300レース
- 1レースあたり投資額: ¥1,000
- 月間投資総額: ¥300,000
シナリオ別回収率:
┌─────────────────┬──────────┬──────────┬──────────┐
│ シナリオ │ 回収率 │ 月間収支 │ 年間収支 │
├─────────────────┼──────────┼──────────┼──────────┤
│ 悲観的 │ 75% │ -¥75,000 │ -¥900,000│
│ 標準的 │ 85% │ -¥45,000 │ -¥540,000│
│ 楽観的 │ 100% │ ¥0 │ ¥0 │
│ 理想的 │ 110% │ +¥30,000 │ +¥360,000│
└─────────────────┴──────────┴──────────┴──────────┘
※ システム運用コスト ¥85,000/月 を考慮すると、
回収率110%以上が損益分岐点
投資対効果の考え方
graph TB
A[競馬AI予測システム] --> B[定量的効果]
A --> C[定性的効果]
B --> B1[回収率向上
目標: 85%→100%] B --> B2[時間削減
分析時間 80%減] B --> B3[的中率向上
目標: 20%→25%] C --> C1[データドリブンな
意思決定] C --> C2[感情に左右されない
投資判断] C --> C3[学習と改善の
サイクル確立] B1 --> D[ROI計算] B2 --> D B3 --> D
目標: 85%→100%] B --> B2[時間削減
分析時間 80%減] B --> B3[的中率向上
目標: 20%→25%] C --> C1[データドリブンな
意思決定] C --> C2[感情に左右されない
投資判断] C --> C3[学習と改善の
サイクル確立] B1 --> D[ROI計算] B2 --> D B3 --> D
段階的な導入ロードマップ
フェーズ別実装計画
gantt
title 競馬AI予測システム導入計画
dateFormat YYYY-MM-DD
section Phase 1: MVP
データ収集基盤構築 :a1, 2026-02-01, 14d
基本特徴量実装 :a2, after a1, 14d
LightGBMモデル構築 :a3, after a2, 14d
簡易予測API開発 :a4, after a3, 7d
section Phase 2: 精度向上
特徴量拡充 :b1, after a4, 21d
アンサンブルモデル :b2, after b1, 14d
バックテスト基盤 :b3, after b2, 7d
section Phase 3: 本格運用
リアルタイム推論 :c1, after b3, 14d
モニタリング基盤 :c2, after c1, 7d
フロントエンド開発 :c3, after c2, 21d
section Phase 4: 高度化
ニューラルネット統合 :d1, after c3, 21d
自動再学習パイプライン :d2, after d1, 14d
A/Bテスト基盤 :d3, after d2, 14d
各フェーズの目標
| フェーズ | 期間 | 目標回収率 | 主要成果物 |
|---|---|---|---|
| Phase 1: MVP | 2ヶ月 | 75% | 基本予測モデル、API |
| Phase 2: 精度向上 | 1.5ヶ月 | 85% | アンサンブルモデル |
| Phase 3: 本格運用 | 1.5ヶ月 | 90% | 完全なシステム |
| Phase 4: 高度化 | 2ヶ月 | 95%+ | 自動化・高度化 |
まとめ
設計のポイント
段階的なアプローチ
- 単純なモデルから始めて徐々に複雑化
- 各段階で効果を検証
データ品質の重視
- 特徴量エンジニアリングが精度の鍵
- データパイプラインの堅牢性
継続的な改善サイクル
- モニタリングと再学習の自動化
- A/Bテストによる検証
現実的な期待値
- 競馬は不確実性が高い
- 長期的な視点での評価
今後の発展可能性
- LLMによる分析: レース展望の自動生成
- 画像解析: パドック映像からのコンディション判定
- リアルタイムオッズ分析: オッズ変動からの情報抽出
- 地方競馬への展開: データソースの拡充
参考資料
更新履歴:
- 2026-01-25: 初版作成