控除率システムの仕組みから見える競馬の数学的真実。期待値をプラスにする理論的方法とそれが現実的に不可能な理由を詳しく解説します。
動画で解説
この記事の内容を動画でも解説しています。
こんな悩みありませんか?
「前回の記事で馬券の期待値がマイナスであることは分かったけど、何とかしてプラスにする方法はないの?」「真剣に競馬を分析すれば、長期的に利益を出せるはずだ」「控除率があっても、上手くやれば勝てるでしょ?」
Web制作に携わる私たちは、データ分析やプログラミングの知識を活用して、様々な問題を解決してきました。今回は、前回の記事で全ての馬券の期待値がマイナスであることを数学的に証明した続編として、期待値をプラスにする唯一の理論的方法と、それがなぜ現実的に不可能なのかを、データサイエンスの観点から詳しく解説します。
実際に、あるクライアントの経営者から「データ分析で競馬を攻略できないか」と相談されたこともあります。その時の検証結果も交えながら、競馬の数学的構造を明らかにしていきましょう。
控除率システムの仕組み:JRAの収益構造
控除率とは何か
控除率とは、JRAが馬券の売上から事前に差し引く手数料のことです。これは法律で定められており、賭け方によって以下のように設定されています。
控除率の計算メカニズム
控除率の仕組みをPythonコードで表現すると以下のようになります:
def calculate_expected_return(betting_type, total_sales, winning_amount):
"""
馬券の期待リターンを計算
"""
control_rates = {
'tansho': 0.20, # 単勝20%
'fukusho': 0.20, # 複勝20%
'umaren': 0.225, # 馬連22.5%
'wide': 0.225, # ワイド22.5%
'umatan': 0.25, # 馬単25%
'sanrenpuku': 0.25,# 3連複25%
'sanrentan': 0.275 # 3連単27.5%
}
control_rate = control_rates.get(betting_type, 0.20)
payout_pool = total_sales * (1 - control_rate)
# 期待値 = (配当金 × 的中確率) - 投資額
win_probability = winning_amount / total_sales
expected_payout = payout_pool * win_probability
expected_return = expected_payout - 1 # 100円投資として
return expected_return, control_rate
# 例:3連単の期待値計算
total_sales = 1000000 # 100万円
winning_amount = 1000 # 1000円投資
expected, rate = calculate_expected_return('sanrentan', total_sales, winning_amount)
print(f"期待リターン: {expected:.2f}円(控除率: {rate*100}%)")
# 結果: 期待リターン: -0.28円(控除率: 27.5%)
控除率が異なる理由
控除率が馬券種類によって異なる理由は、予想の難易度とJRAの収益戦略にあります:
flowchart TD
A[馬券販売] --> B[総売上]
B --> C{馬券種類}
C -->|単勝・複勝| D[20%控除]
C -->|馬連・ワイド| E[22.5%控除]
C -->|馬単・3連複| F[25%控除]
C -->|3連単| G[27.5%控除]
D --> H[配当原資80%]
E --> I[配当原資77.5%]
F --> J[配当原資75%]
G --> K[配当原資72.5%]単純な予想(単勝)ほど控除率が低く、複雑な予想(3連単)ほど控除率が高く設定されています。これは、難しい予想に挑戦する購入者からより多くの手数料を徴収する仕組みです。
期待値をプラスにする唯一の理論的方法
オッズと真の勝率のズレを利用する方法
期待値をプラスにする唯一の理論的方法は、オッズが示す勝率と真の勝率にズレがある馬券を見つけ出すことです。
数学的には以下の条件を満たす必要があります:
import numpy as np
def calculate_true_expected_value(odds, true_win_probability, bet_amount=100):
"""
真の勝率を使った期待値計算
"""
expected_return = (odds * true_win_probability * bet_amount) - bet_amount
return expected_return
def find_profitable_bet(odds_list, market_probabilities, true_probabilities):
"""
利益が出る可能性のある馬券を探す
"""
profitable_bets = []
for i, (odds, market_prob, true_prob) in enumerate(
zip(odds_list, market_probabilities, true_probabilities)
):
expected_value = calculate_true_expected_value(odds, true_prob)
if expected_value > 0:
profitable_bets.append({
'horse': i + 1,
'odds': odds,
'market_probability': market_prob,
'true_probability': true_prob,
'expected_value': expected_value
})
return profitable_bets
# 例:10頭立てレースのシミュレーション
odds = [2.5, 4.0, 6.0, 8.0, 12.0, 15.0, 20.0, 30.0, 50.0, 80.0]
market_probs = [1/o for o in odds] # オッズから逆算した市場確率
true_probs = [0.45, 0.22, 0.15, 0.10, 0.04, 0.02, 0.01, 0.008, 0.005, 0.002]
profitable = find_profitable_bet(odds, market_probs, true_probs)
for bet in profitable:
print(f"馬{bet['horse']}: オッズ{bet['odds']}倍, "
f"期待値+{bet['expected_value']:.2f}円")
期待値プラスの条件式
期待値がプラスになるための数学的条件は以下の通りです:
期待値 = (オッズ × 真の勝率) - 1 > 0
つまり:
オッズ × 真の勝率 > 1
さらに控除率を考慮すると:
真の勝率 > (1 + 控除率) ÷ オッズ
具体例:控除率を上回る精度が必要
3連単(控除率27.5%)で100倍のオッズの馬券を購入する場合:
def required_accuracy_for_profit(odds, control_rate):
"""
利益を出すために必要な予想精度を計算
"""
market_probability = 1 / odds
required_probability = (1 + control_rate) / odds
accuracy_improvement = (required_probability / market_probability - 1) * 100
return required_probability, accuracy_improvement
# 3連単100倍の例
odds = 100
control_rate = 0.275
required_prob, improvement = required_accuracy_for_profit(odds, control_rate)
print(f"オッズ: {odds}倍")
print(f"市場予想確率: {1/odds*100:.3f}%")
print(f"必要な真の勝率: {required_prob*100:.3f}%")
print(f"必要な精度向上: {improvement:.1f}%")
# 結果:
# オッズ: 100倍
# 市場予想確率: 1.000%
# 必要な真の勝率: 1.275%
# 必要な精度向上: 27.5%
現実的に不可能な理由:情報の非対称性と市場効率性
理由1:情報の質と量の限界
実際のクライアント案件で、競馬予想AIの開発を検討したことがありました。その際に直面した根本的な問題がこれです。
class HorseRacingAnalyzer:
def __init__(self):
self.available_data = {
'past_performance': '過去の成績',
'jockey_stats': '騎手統計',
'weather': '天候情報',
'track_condition': '馬場状態',
'odds_fluctuation': 'オッズ変動'
}
self.unavailable_data = {
'horse_health': '馬の健康状態',
'training_details': '調教の詳細',
'jockey_condition': '騎手のコンディション',
'strategy': 'レース戦略',
'insider_info': '内部情報'
}
def analyze_information_gap(self):
"""
一般投資家と関係者の情報格差を分析
"""
public_info_weight = 0.3 # 公開情報の影響度
private_info_weight = 0.7 # 非公開情報の影響度
return {
'public_access': public_info_weight,
'insider_advantage': private_info_weight,
'prediction_ceiling': public_info_weight * 100 # 予想精度の上限
}
理由2:市場の効率性
競馬のオッズは、数十万人の投資家の予想を集約した「集合知」です。個人がこれを上回る精度で予想することの困難さを示すデータがこちらです:
理由3:統計的な証拠
長期間のデータ分析結果も、個人投資家の勝利の困難さを裏付けています:
def simulate_long_term_betting(initial_capital=100000, bet_per_race=1000,
races_per_year=3000, years=10):
"""
長期投資シミュレーション
"""
results = {
'perfect_strategy': [], # 完璧な予想(市場を25%上回る)
'good_strategy': [], # 良い予想(市場を10%上回る)
'average_strategy': [] # 平均的予想(市場レベル)
}
strategies = {
'perfect_strategy': 0.25, # 25%向上
'good_strategy': 0.10, # 10%向上
'average_strategy': 0.00 # 向上なし
}
for strategy, improvement in strategies.items():
capital = initial_capital
yearly_capitals = [capital]
for year in range(years):
for race in range(races_per_year):
# 3連単平均的中率 1/1000 を向上させる
base_win_rate = 1/1000
improved_win_rate = base_win_rate * (1 + improvement)
# 平均オッズ500倍、控除率27.5%
if np.random.random() < improved_win_rate:
capital += bet_per_race * 500 * 0.725 - bet_per_race
else:
capital -= bet_per_race
if capital <= 0:
break
yearly_capitals.append(capital)
if capital <= 0:
break
results[strategy] = yearly_capitals
return results
# シミュレーション実行
simulation = simulate_long_term_betting()
for strategy, capitals in simulation.items():
final_capital = capitals[-1]
print(f"{strategy}: 最終資産 {final_capital:,.0f}円")
よくある失敗パターンと対処法
失敗パターン1:「必勝法」への過信
あるクライアントが「統計分析で必勝法を見つけた」と相談に来たことがありました。詳しく調べると、以下の問題がありました:
- サンプルバイアス: 好調な期間のデータのみを使用
- 過学習: 過去のデータに最適化しすぎた予想モデル
- 控除率の軽視: 手数料を考慮しない期待値計算
def detect_common_mistakes(betting_data):
"""
よくある分析ミスを検出
"""
mistakes = []
# サンプルバイアスのチェック
if len(betting_data) < 1000:
mistakes.append("サンプル数不足: 統計的に有意な結果を得るには最低1000レース必要")
# 期間バイアスのチェック
date_range = max(betting_data['date']) - min(betting_data['date'])
if date_range.days < 365:
mistakes.append("期間不足: 季節性を考慮するため最低1年間のデータが必要")
# 控除率考慮のチェック
if 'control_rate' not in betting_data.columns:
mistakes.append("控除率未考慮: 期待値計算に控除率を含めていない")
return mistakes
失敗パターン2:感情的な判断
数学的分析を始めても、結局は感情に流される例も多く見てきました:
失敗パターン3:システムの過信
「AIやプログラムなら勝てる」という過信も危険です。実際の検証結果をご覧ください:
プログラマー視点での現実的な対処法
1. データ分析スキルの他分野活用
競馬分析で身につけたスキルは、より収益性の高い分野で活用できます:
def transfer_skills_to_business():
"""
競馬分析スキルのビジネス転用例
"""
transferable_skills = {
'statistical_analysis': {
'skill': '統計分析',
'business_application': 'マーケティング効果測定',
'expected_roi': '300-500%' # 競馬の-20%より圧倒的に良い
},
'data_visualization': {
'skill': 'データ可視化',
'business_application': 'BIダッシュボード開発',
'expected_roi': '200-400%'
},
'machine_learning': {
'skill': '機械学習',
'business_application': '需要予測・在庫最適化',
'expected_roi': '150-300%'
}
}
return transferable_skills
2. エンターテイメントとしての適切な楽しみ方
もし競馬を楽しむなら、以下のガイドラインを推奨します:
| 項目 | 推奨アプローチ | 危険なアプローチ |
|---|---|---|
| 予算 | 月収の1%以下 | 生活費を圧迫 |
| 目的 | 娯楽・学習 | 利益追求 |
| 期間 | 短期イベント | 継続投資 |
| 分析 | 趣味レベル | 本格システム開発 |
3. 真に利益を生む投資への転換
数学的思考力があるなら、期待値が正の投資に向かうべきです:
まとめと次のステップ
今回の分析で明らかになったのは、競馬で期待値をプラスにする唯一の方法は「市場を上回る予想精度」ですが、これは以下の理由で現実的に不可能だということです:
- 控除率の壁: 20-27.5%の手数料を上回る精度が必要
- 情報の非対称性: 一般投資家は重要な情報にアクセスできない
- 市場効率性: 数十万人の集合知を個人が上回ることの困難さ
- 統計的証拠: 長期的な勝者がほぼ存在しない事実
Web制作会社として20年間、多くのデータ分析プロジェクトに携わってきましたが、競馬ほど数学的に勝利が困難なシステムは他にありません。
むしろ、データ分析スキルを身につけたなら、期待値が正の分野で活用することを強く推奨します。Webマーケティングの効果測定、顧客行動分析、業務効率化など、確実にリターンが見込める領域は数多く存在します。
次に取るべきアクション
数学とプログラミングの力は、正しい方向で使えば必ず成果につながります。競馬の魅力的な数字に惑わされず、真に価値を生む分野でその能力を発揮していきましょう。
もしデータ分析を活用したWeb戦略や業務効率化にご興味があれば、ぜひご相談ください。20年の実績を持つFivenine Designが、確実にプラスのリターンをお約束いたします。