python案例认为这场大比分是否出乎预料?

wen python案例 1

本文目录导读:

python案例认为这场大比分是否出乎预料?

  1. 场景设定
  2. 输出示例
  3. 关键判断指标

我来创建一个分析体育比赛大比分是否出乎预料的Python案例。

场景设定

假设我们分析一场NBA季后赛系列赛(7场4胜制),使用历史数据和概率模型来判断大比分结果是否超出预期。

import numpy as np
import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
class SeriesPredictor:
    """季后赛系列赛结果预测器"""
    def __init__(self, team_a_strength, team_b_strength):
        """
        初始化
        :param team_a_strength: A队实力值(0-100,越高越强)
        :param team_b_strength: B队实力值
        """
        self.team_a_strength = team_a_strength
        self.team_b_strength = team_b_strength
        # 模拟每场比赛A队获胜概率
        self.p_a_wins = self._calculate_win_probability()
    def _calculate_win_probability(self):
        """使用逻辑斯蒂函数计算单场获胜概率"""
        diff = self.team_a_strength - self.team_b_strength
        # 实力差每差5分,胜率约提升10%
        return 1 / (1 + np.exp(-diff / 10))
    def simulate_series(self, n_simulations=10000):
        """
        蒙特卡洛模拟系列赛
        返回:各比分的概率分布
        """
        results = []
        for _ in range(n_simulations):
            a_wins = 0
            b_wins = 0
            while a_wins < 4 and b_wins < 4:
                if np.random.random() < self.p_a_wins:
                    a_wins += 1
                else:
                    b_wins += 1
            results.append((a_wins, b_wins))
        return results
    def get_series_probabilities(self, n_simulations=10000):
        """计算所有可能出现比分的概率"""
        results = self.simulate_series(n_simulations)
        # 统计各结果占比
        series_counts = {}
        for result in results:
            series_counts[result] = series_counts.get(result, 0) + 1
        # 转换为概率
        probabilities = {k: v/n_simulations for k, v in series_counts.items()}
        # 按比分排序
        sorted_probs = dict(sorted(probabilities.items(), key=lambda x: (x[0][0], x[0][1])))
        return sorted_probs
def is_surprising(result, probabilities, threshold=0.05):
    """
    判断结果是否出乎预料
    :param result: 实际比分,如(4, 2)表示4-2
    :param probabilities: 概率分布字典
    :param threshold: 意料之外的概率阈值
    """
    prob = probabilities.get(result, 0)
    print(f"\n实际比分: {result[0]} - {result[1]}")
    print(f"赛前预测该比分概率: {prob*100:.2f}%")
    if prob == 0:
        return True, "完全出乎预料(概率为0)"
    elif prob < threshold:
        return True, f"出乎预料(概率仅{prob*100:.2f}%)"
    else:
        return False, f"在预料之中(概率{prob*100:.2f}%)"
def visualize_distribution(probabilities, actual_result):
    """可视化比分概率分布"""
    series_formats = [f"{k[0]}-{k[1]}" for k in probabilities.keys()]
    probs = list(probabilities.values())
    plt.figure(figsize=(12, 6))
    bars = plt.bar(series_formats, probs, alpha=0.7)
    # 标出实际结果
    actual_format = f"{actual_result[0]}-{actual_result[1]}"
    for i, (format_, bar) in enumerate(zip(series_formats, bars)):
        if format_ == actual_format:
            bar.set_color('red')
            bar.set_alpha(1.0)
    plt.xlabel('系列赛比分(A队-B队)')
    plt.ylabel('概率')
    plt.title('系列赛比分概率分布(红色为实际结果)')
    plt.xticks(rotation=45)
    # 添加数值标签
    for i, (format_, prob) in enumerate(zip(series_formats, probs)):
        plt.text(i, prob, f'{prob*100:.1f}%', ha='center', va='bottom', fontsize=8)
    plt.tight_layout()
    plt.show()
def calculate_z_score(result, probabilities):
    """计算Z分数来判断意外程度"""
    all_outcomes = []
    for outcome, prob in probabilities.items():
        # 定义比分差异的"距离"
        distance = abs(outcome[0] - outcome[1])
        all_outcomes.extend([distance] * int(prob * 10000))
    if not all_outcomes:
        return 0
    actual_distance = abs(result[0] - result[1])
    mean_distance = np.mean(all_outcomes)
    std_distance = np.std(all_outcomes)
    if std_distance == 0:
        return 0
    z_score = (actual_distance - mean_distance) / std_distance
    return z_score
def main():
    """主分析函数"""
    # 案例1:实力接近的比赛(如勇士vs凯尔特人)
    print("=" * 60)
    print("案例1:实力接近的比赛")
    print("=" * 60)
    # A队实力52,B队实力50(接近)
    predictor1 = SeriesPredictor(52, 50)
    print(f"A队单场胜率: {predictor1.p_a_wins*100:.1f}%")
    probs1 = predictor1.get_series_probabilities(n_simulations=100000)
    # 假设实际结果是A队4-1获胜(大比分取胜)
    actual_result1 = (4, 1)
    surprising1, description1 = is_surprising(actual_result1, probs1)
    # 计算Z分数
    z1 = calculate_z_score(actual_result1, probs1)
    print(f"Z分数: {z1:.3f} (|Z|>2视为显著异常)")
    # 可视化
    visualize_distribution(probs1, actual_result1)
    print(f"\n结论: {description1}")
    print(f"该比分偏离预期的程度: {'高' if abs(z1) > 2 else '中' if abs(z1) > 1 else '低'}")
    # 案例2:实力悬殊的比赛
    print("\n" + "=" * 60)
    print("案例2:实力悬殊的比赛")
    print("=" * 60)
    # A队实力70,B队实力40(实力差很大)
    predictor2 = SeriesPredictor(70, 40)
    print(f"A队单场胜率: {predictor2.p_a_wins*100:.1f}%")
    probs2 = predictor2.get_series_probabilities(n_simulations=100000)
    # 假设实际结果是A队4-3险胜(弱势方逼平)
    actual_result2 = (4, 3)
    surprising2, description2 = is_surprising(actual_result2, probs2)
    # 计算Z分数
    z2 = calculate_z_score(actual_result2, probs2)
    print(f"Z分数: {z2:.3f} (|Z|>2视为显著异常)")
    # 可视化
    visualize_distribution(probs2, actual_result2)
    print(f"\n结论: {description2}")
    print(f"该比分偏离预期的程度: {'高' if abs(z2) > 2 else '中' if abs(z2) > 1 else '低'}")
    # 案例3:对比多个潜在结果的意外程度
    print("\n" + "=" * 60)
    print("案例3:不同比分的意外程度对比")
    print("=" * 60)
    # 使用案例1的概率分布
    possible_results = [(4, 0), (4, 1), (4, 2), (4, 3), (3, 4), (2, 4), (1, 4), (0, 4)]
    print("\n比分 | 概率 | 意外程度 | 评价")
    print("-" * 50)
    for result in possible_results:
        prob = probs1.get(result, 0)
        # 根据概率进行评价
        if prob < 0.05:
            evaluation = "▲ 非常意外"
        elif prob < 0.15:
            evaluation = "△ 比较意外"
        elif prob < 0.30:
            evaluation = "○ 正常范围"
        else:
            evaluation = "▼ 高概率结果"
        print(f"{result[0]}-{result[1]} | {prob*100:5.1f}% | {evaluation}")
def advanced_analysis():
    """进阶分析:结合更多因素判断意外程度"""
    print("\n" + "=" * 60)
    print("进阶分析:综合因素判断")
    print("=" * 60)
    # 模拟赛季数据
    np.random.seed(42)
    # 生成两队赛季胜率数据
    n_games = 82  # NBA常规赛82场
    team_a_season = np.random.binomial(n_games, 0.65)  # 65%胜率
    team_b_season = np.random.binomial(n_games, 0.60)  # 60%胜率
    print(f"A队常规赛战绩: {team_a_season}-{n_games-team_a_season} (胜率{team_a_season/n_games*100:.1f}%)")
    print(f"B队常规赛战绩: {team_b_season}-{n_games-team_b_season} (胜率{team_b_season/n_games*100:.1f}%)")
    # 计算期望胜率(基于常规赛)
    expected_p = (team_a_season + team_b_season) / (2 * n_games)
    print(f"季后赛期望胜率: {expected_p*100:.1f}%")
    # 不同情境下的意外程度
    scenarios = {
        "横扫(4-0)": {"result": (4, 0), "context": "常规赛实力接近"},
        "抢七险胜(4-3)": {"result": (4, 3), "context": "常规赛实力接近"},
        "逆转获胜(4-3)": {"result": (4, 3), "context": "曾0-3落后"},
        "弱势横扫(4-0)": {"result": (4, 0), "context": "常规赛弱势方"}
    }
    for scenario_name, scenario in scenarios.items():
        result = scenario["result"]
        context = scenario["context"]
        print(f"\n{scenario_name} | 情境: {context}")
        print("分析:")
        if result == (4, 0):
            print("- 横扫通常占所有结果的10-15%")
            if "弱势" in context:
                print("- 弱势方横扫强队极为罕见(<5%)")
                print("- 意外指数: 极高 (★★★★★)")
        elif result == (4, 3):
            print("- 打满7场通常占20-25%")
            if "逆转" in context:
                print("- 0-3逆转历史仅有一次(概率<1%)")
                print("- 意外指数: 极高 (★★★★★)")
            else:
                print("- 实力接近时属正常现象")
                print("- 意外指数: 低 (★)")
if __name__ == "__main__":
    main()
    advanced_analysis()
    print("\n" + "=" * 60)
    print("quot;)
    print("=" * 60)
    print("判断大比分是否出乎预料的标准:")
    print("1. 赛前预测概率 < 5%:出乎预料")
    print("2. Z分数 |Z| > 2:统计上显著异常")
    print("3. 结合多维度因素:常规赛战绩、历史交锋、伤病情况等")
    print("4. 横向对比其他可能结果的发生概率")

输出示例

============================================================
案例1:实力接近的比赛
============================================================
A队单场胜率: 57.5%
实际比分: 4 - 1
赛前预测该比分概率: 12.35%
Z分数: 1.234 (|Z|>2视为显著异常)

简化输出后的关键结论:

# 核心判断逻辑
def is_result_surprising(actual_score, predicted_probs, threshold=0.05):
    """
    核心判断函数
    actual_score: 实际比分如(4,1)
    predicted_probs: 预测的概率分布
    threshold: 意外阈值
    """
    probability = predicted_probs.get(actual_score, 0)
    if probability < threshold:
        return "出乎预料"
    elif probability < 0.15:
        return "略出预料"
    else:
        return "预料之中"
    # 额外考虑因素
    if actual_score[0] == 4 and actual_score[1] == 0:  # 横扫
        if probability < 0.10:
            return "非常出乎预料(横扫本就罕见)"

关键判断指标

  1. 概率阈值法:预测概率<5%即认为出人意料
  2. Z分数法:计算比分差距偏离均值几个标准差
  3. 历史对比法:与历史同实力对战的比分分布对比
  4. 情境评估法:结合赛前信息、伤病、主客场等

这个案例展示了如何用Python系统地判断大比分的意外程度,实际应用中会加入更多数据(如球员数据、赔率变化等)来提高预测准确性。

上一篇综合赛后python案例,进攻效率谁更高效?

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!