「AIの予想が当たっているのに、なぜかトータルで負ける」
そういう経験をしたことがある人に読んでほしい記事です。
私はエンジニアとして競艇の予想AIを自作しています。XGBoostを使って選手成績・モーター評価・気象データなど21変数を入力し、各艇の1着確率を出力するモデルです。精度はそこそこ出ていました。的中率は55〜60%程度。しかし3ヶ月間の回収率は83%でした。つまり毎月赤字でした。
原因を調べたところ、AIの問題ではなく賭け金の決め方に問題があったことがわかりました。
ケリー基準を導入し、賭け金の自動計算を始めてから2ヶ月後、同じモデルで回収率が83%から97%まで改善しました。この記事では、その仕組みと実装を説明します。
なぜ賭け金管理が重要なのか:当たっているのに負ける現象
AIが予想を出すたびに、私は「なんとなく自信がある」「このレースは荒れそうだから多めに」という感覚で賭け金を変えていました。今考えると最悪の意思決定プロセスです。
具体的にどんな失敗をしていたか。
- AIが高確率(70%超)と判定したレースで自信過剰になり、資金の20〜30%を一発に投じた
- 外れたときのダメージが大きく、それを取り返そうと次のレースで賭け金を増やした
- 逆にオッズが高いレースでは「どうせ外れる」と思って少額しか賭けず、当たったときの回収が小さかった
結果として「負けるときは大きく負け、勝つときは小さく勝つ」という最悪のパターンが定着していました。
問題は的中率ではなく、賭け金の配分だったのです。
感情による賭け金管理が最も破壊的な理由は、損失回避バイアスと過信バイアスが同時に働くからです。「自信があるとき過大投資、自信がないとき過小投資」は、長期的に期待値を最大化する行動とは真逆です。
ケリー基準とは何か:数学的に最適な賭け金を導く式
ケリー基準(Kelly Criterion)は、1956年にベル研究所の数学者ジョン・ケリーが提唱した、長期的な資金成長を最大化するための賭け金計算式です。カジノ・株式投資・スポーツベッティングなど幅広い分野で応用されています。
基本的な計算式
f* = (b × p - q) / b
| 変数 | 意味 |
|---|---|
| f* | 賭けるべき資金の割合(0〜1) |
| b | ネットオッズ(オッズ – 1) |
| p | 的中確率(AIが出力する確率) |
| q | 外れ確率(1 – p) |
競艇への当てはめ方
競艇では「オッズ」は公式が公表する払い戻し倍率です。AIモデルが出力する各艇の1着確率をそのまま p として使います。
たとえば:
- オッズ 3.5倍の舟券(1号艇複勝など)
- AIモデルが出力した的中確率 30%
この場合の計算は:
b = 3.5 - 1 = 2.5
p = 0.30
q = 1 - 0.30 = 0.70
f* = (2.5 × 0.30 - 0.70) / 2.5
f* = (0.75 - 0.70) / 2.5
f* = 0.05 / 2.5
f* = 0.02(資金の2%を賭ける)
この場合、手元資金が10万円なら賭けるべき金額は2,000円です。
ケリー基準が優れているのは、期待値がマイナスのときは賭け金をゼロにする点です。
もしAIが20%の確率しか出していないのに同じオッズ3.5倍なら:
f* = (2.5 × 0.20 - 0.80) / 2.5
f* = (0.50 - 0.80) / 2.5
f* = -0.30 / 2.5
f* = -0.12 → 0(賭けない)
f* が負になる場合は「このレースは賭けるな」というシグナルです。感情ではなく数学が「見送り」を命じます。
Pythonで自動計算するコード
AIモデルのprobabilityをそのままケリー基準に入力する実装です。
def kelly_bet(probability: float, odds: float, capital: float, fraction: float = 0.25) -> float:
"""
フラクショナルケリー基準で賭け金を計算する。
Args:
probability: AIモデルが出力した的中確率(0〜1)
odds: 公式オッズ(払い戻し倍率)
capital: 現在の手元資金(円)
fraction: ケリー分数(0.25 = クォーターケリー)
Returns:
推奨賭け金(円)。0の場合は「賭けない」
"""
b = odds - 1 # ネットオッズ
p = probability
q = 1 - p
# 期待値を確認
edge = b * p - q
if edge <= 0:
return 0.0 # 期待値がマイナスまたはゼロ → 賭けない
# ケリー基準による最適比率
kelly_fraction = edge / b
# フラクショナルケリーを適用(リスク軽減)
bet_ratio = kelly_fraction * fraction
return round(capital * bet_ratio)
def calculate_bets_from_predictions(predictions: list[dict], capital: float) -> list[dict]:
"""
AIモデルの予測結果リストから、各舟券の推奨賭け金を計算する。
Args:
predictions: [{"boat": 1, "probability": 0.30, "odds": 3.5}, ...]
capital: 現在の手元資金(円)
Returns:
賭け金情報を追加したリスト
"""
results = []
for pred in predictions:
bet_amount = kelly_bet(
probability=pred["probability"],
odds=pred["odds"],
capital=capital,
fraction=0.25,
)
results.append({
**pred,
"recommended_bet": bet_amount,
"bet_ratio": bet_amount / capital if capital > 0 else 0,
})
# 賭け金が0より大きいものだけ返す(見送りは除外)
return [r for r in results if r["recommended_bet"] > 0]
# 使用例
if __name__ == "__main__":
capital = 100_000 # 手元資金10万円
predictions = [
{"boat": 1, "probability": 0.42, "odds": 2.1},
{"boat": 2, "probability": 0.30, "odds": 3.5},
{"boat": 3, "probability": 0.15, "odds": 8.0},
{"boat": 4, "probability": 0.08, "odds": 18.0},
]
bets = calculate_bets_from_predictions(predictions, capital)
for b in bets:
print(f" {b['boat']}号艇: 確率{b['probability']:.0%} / オッズ{b['odds']} → 推奨 {b['recommended_bet']:,}円")
実行結果(手元資金10万円の場合):
1号艇: 確率42% / オッズ2.1 → 推奨 2,600円
2号艇: 確率30% / オッズ3.5 → 推奨 500円
3号艇: 確率15% / オッズ8.0 → 推奨 700円
4号艇(確率8% / オッズ18倍)は期待値がギリギリマイナスのため、コードが自動的に除外します。
フラクショナルケリーを使う理由
上記のコードには fraction=0.25 というパラメータがあります。これが「フラクショナルケリー(分数ケリー)」です。
純粋なケリー基準(fraction=1.0)には重大な欠点があります。計算された最適比率をそのまま使うと、ボラティリティが非常に大きくなるのです。
数学的には長期最大化になりますが、実運用では:
- モデルの確率推定が少しでも誤差を含むと、算出された賭け金が過大になる
- 連敗時に資金が急激に減少し、精神的に耐えられなくなる
- AIの確率は「真の確率」ではなくあくまで「モデルの推定」
競艇AIの場合、モデルが出力する確率は訓練データのパターンに基づいた推定値です。実際の的中確率と完全に一致することはありません。
そのため、私はクォーターケリー(fraction=0.25)を採用しています。ケリー基準が「理論上の最適賭け金」を計算し、その25%だけを実際に賭けます。
| ケリー分数 | 特性 | 向いているケース |
|---|---|---|
| 1.0(フルケリー) | 最大成長・最大ドローダウン | モデルの確率推定精度が非常に高い場合 |
| 0.5(ハーフケリー) | バランス型 | 長期実績があり精度を信頼できる場合 |
| 0.25(クォーターケリー) | 保守的・推奨 | 開発初期・モデルの精度に不確実性がある場合 |
導入前後の比較
同じAIモデル・同じ期間・同じレース選択で、賭け金管理だけを変えた結果です。
| 指標 | 導入前(感情ベース) | 導入後(クォーターケリー) |
|---|---|---|
| 期間 | 2ヶ月 | 2ヶ月 |
| 予想レース数 | 89レース | 89レース |
| 的中率 | 57% | 57%(変化なし) |
| 最大1回投資額 | 資金の28%(感情的) | 資金の4.2%(自動計算) |
| 最大連敗時の資金減少率 | -34% | -11% |
| 2ヶ月後の回収率 | 83% | 97% |
| 心理的ストレス | 高い | 低い |
的中率は完全に同じです。AIモデルには一切手を加えていません。変えたのは賭け金の決め方だけ。それだけで回収率が14ポイント改善しました。
特筆すべきは「最大連敗時の資金減少率」です。導入前は5連敗すると資金の3割以上が飛んでいました。そのパニックから取り返そうと賭け金を増やし、さらに傷口を広げる悪循環でした。ケリー基準導入後は、5連敗しても資金の減少が11%以内に収まります。次のレースを冷静に判断できます。
注意点:ケリー基準が合わないケース
ケリー基準は万能ではありません。以下のケースでは機能しにくいです。
1. AIモデルの確率推定が著しく不正確な場合
モデルが70%と出したレースの実際の的中率が40%程度しかなければ、ケリー基準の計算は過剰な賭け金を出します。モデルの精度検証(キャリブレーション)を必ず事前に行ってください。
2. 三連単・三連複などの高配当舟券を主に狙う場合
高オッズ商品は当たり確率が低く、AIの確率推定誤差の影響を受けやすいです。クォーターケリーよりさらに保守的な設定(fraction=0.1〜0.15)を推奨します。
3. 短期間での大きな利益を求める場合
ケリー基準は「長期的な資金最大化」を目的とした手法です。月単位での大きな利益を期待する用途には向いていません。あくまで「長く続けるほど効果が出る」手法です。
4. 資金が少なすぎる場合
資金が1万円以下の場合、ケリー基準で計算した賭け金が100円未満になるケースが頻発し、最小投票額(通常100円)の制約で実際には機能しません。ある程度の資金規模(最低でも3〜5万円)が必要です。
まとめ
- 競艇AIの予想精度と回収率は必ずしも比例しない
- 感情ベースの賭け金管理は、長期的に期待値を大幅に下げる
- ケリー基準は「AIが出した確率」と「公式オッズ」から数学的に最適な賭け金を計算する
- フラクショナルケリー(0.25)を使うことでモデルの誤差リスクを軽減できる
- 実装は20行程度のPythonで完結する
AIで予想の精度を高めることと、ケリー基準で賭け金を最適化することは、両輪で機能します。片方だけでは不完全です。
私のモデルは今もまだ発展途上で、回収率97%は「損失をほぼなくした」段階です。次の目標は回収率105%超、つまりAIが安定して利益を生む水準に持っていくことです。そのためにはモデルの精度改善と賭け金管理の両方を継続して磨いていく必要があります。
感情で賭けるのをやめた日が、競艇AIとして本当のスタート地点でした。
関連ツールを見る
この記事で紹介したツール・サービスをまとめてチェック。
![]()