python案例如何应对突发伤病的变数?

wen python案例 5

Python案例:如何应对突发伤病的变数

这是一个很有意思的问题,在体育赛事预测、保险精算、健康管理等领域,"突发伤病"是典型的低概率高影响事件,我用一个可运行的 Python 案例来演示几种应对思路。

python案例如何应对突发伤病的变数?


场景设定

假设你在做一个体育比赛胜负概率预测系统,需要应对球员突发伤病带来的不确定性。


贝叶斯动态更新(核心思路)

当伤病消息传来时,用贝叶斯定理实时修正概率。

import numpy as np
class BayesianTeamStrength:
    """用贝叶斯更新球队实力评分"""
    def __init__(self, prior_mean=1500, prior_std=100):
        self.mean = prior_mean
        self.std = prior_std  # 不确定性
    def apply_injury(self, impact=-150, uncertainty=80):
        """
        impact: 伤病对实力的影响(负值=削弱)
        uncertainty: 突发性带来的额外不确定性
        """
        self.mean += impact
        # 关键:不确定性叠加(方差相加)
        self.std = np.sqrt(self.std**2 + uncertainty**2)
        print(f"伤病后:实力 {self.mean:.0f} ± {self.std:.0f}")
    def win_probability(self, opponent_mean=1500, opponent_std=100):
        """用正态分布近似的胜率(简化的 Bradley-Terry)"""
        diff = self.mean - opponent_mean
        combined_std = np.sqrt(self.std**2 + opponent_std**2)
        return 1 / (1 + np.exp(-diff / combined_std * 1.7))
# 演示
team = BayesianTeamStrength()
print(f"赛前胜率: {team.win_probability():.1%}")
# 核心球员赛前受伤
team.apply_injury(impact=-180, uncertainty=120)
print(f"伤后胜率: {team.win_probability():.1%}")

要点:伤病不仅改变均值(实力),更关键的是放大方差(不确定性),这比单纯打折更符合现实。


蒙特卡洛模拟(量化极端情景)

伤病有"可能发生也可能不发生"的概率性,用模拟覆盖尾部风险。

import numpy as np
def simulate_season(n_players=11, injury_prob=0.08, n_sims=10000):
    """
    模拟一个赛季:每个球员有 injury_prob 概率受伤
    受伤后贡献减半
    """
    base_contribution = 100  # 每人基础贡献
    outcomes = []
    for _ in range(n_sims):
        injured = np.random.random(n_players) < injury_prob
        total = np.sum(np.where(injured, base_contribution * 0.5, base_contribution))
        outcomes.append(total)
    outcomes = np.array(outcomes)
    return {
        "均值": outcomes.mean(),
        "P5(悲观)": np.percentile(outcomes, 5),
        "P50(中位)": np.percentile(outcomes, 50),
        "P95(乐观)": np.percentile(outcomes, 95),
        "最差情景": outcomes.min(),
    }
result = simulate_season()
for k, v in result.items():
    print(f"{k}: {v:.0f}")

要点:不要只看期望值,要看 P5 分位数——这才是"伤病变数"的真实杀伤力。


鲁棒性指标(压力测试)

主动评估系统在极端伤病下的表现,而不是被动等待。

def stress_test(roster_contributions, scenarios):
    """
    roster_contributions: 各球员的贡献值列表
    scenarios: 要模拟的伤病情景
    """
    total = sum(roster_contributions)
    print(f"全员健康:{total}\n")
    for name, lost_indices in scenarios.items():
        lost = sum(roster_contributions[i] for i in lost_indices)
        remaining = total - lost
        drop = lost / total
        print(f"{name}: 剩余 {remaining} (下降 {drop:.1%})")
        # 关键判断:是否有冗余
        if drop > 0.3:
            print(f"  ⚠️  风险预警:单一情景损失超过30%,阵容缺乏冗余")
        print()
# 演示
roster = [180, 150, 140, 120, 100, 90, 80, 70, 60, 50, 40]  # 从核心到替补
scenarios = {
    "核心1人伤": [0],
    "核心2人伤": [0, 1],
    "双核+第三得分手": [0, 1, 2],
    "最坏:前4人全伤": [0, 1, 2, 3],
}
stress_test(roster, scenarios)

要点:识别单点故障(concentration risk)——如果一个人受伤就让整体崩盘,说明系统本身脆弱。


决策层——成本-收益权衡

是否要为伤病"买保险"(例如签替补、买保险、调整投注)?

def insurance_decision(loss_if_injured, injury_prob, premium, max_loss):
    """
    经典保险决策:期望效用 vs 风险规避
    loss_if_injured: 受伤时的损失
    injury_prob: 受伤概率
    premium: 保费(保险成本)
    max_loss: 你能承受的最大损失(风险承受阈值)
    """
    expected_loss = loss_if_injured * injury_prob
    print(f"期望损失: {expected_loss:.0f}")
    print(f"保险成本: {premium}")
    print(f"风险承受上限: {max_loss}")
    print(f"不保险的最坏损失: {loss_if_injured}")
    if loss_if_injured > max_loss:
        print("→ 建议保险:最坏情景超出承受能力")
    elif expected_loss < premium:
        print("→ 不建议保险:期望损失低于保费(精算上不划算)")
    else:
        print("→ 建议保险:虽然略贵,但能控制尾部风险")
# 演示:核心球员受伤导致赛季失败
insurance_decision(
    loss_if_injured=5000,  # 赛季失败的直接损失
    injury_prob=0.15,
    premium=1200,          # 签替补的额外成本
    max_loss=3000          # 俱乐部能承受的最大损失
)

应对伤病变数的四个层次

层次 方法 解决的问题
预测层 贝叶斯更新 消息来了如何实时修正判断
量化层 蒙特卡洛 伤病概率化后的整体分布与尾部
诊断层 压力测试 阵容/系统的冗余度与单点故障
决策层 成本-收益 要不要为不确定性付费(保险/替补)

核心心法:

  1. 不要只调均值,要放大方差——突发性的本质是不确定性上升;
  2. 看尾部,别只看期望——伤病是肥尾事件,P5 比均值更重要;
  3. 冗余 > 预测——你无法预测谁受伤,但可以设计"谁都伤得起"的系统。

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