python案例如何量化主力缺阵损失值?

wen python案例 9

如何量化"主力缺阵"损失值 — 完整案例

"主力缺阵"常见于体育竞技(球员伤停)和电商/零售(核心SKU缺货)两类场景,下面以体育赛事为主线,给出可复用的Python量化框架,最后附电商场景变体。

python案例如何量化主力缺阵损失值?


量化思路总览

主力缺阵损失 = 反事实推断:预测"如果主力在场会怎样",对比"实际结果",差值即为损失。

损失 = 反事实预期收益 − 实际收益

三种主流建模路径:

方法 适用场景 数据要求
① 历史胜率/贡献法 数据少、快速估算 中等
② 回归/泊松模型 有大量比赛数据 较高
③ 因果推断(DID/PSM) 需要严谨因果证据 高

方法①:历史贡献法(快速上手)

核心思想:用球员在场/缺阵时的球队表现差估算其边际贡献。

import pandas as pd
import numpy as np
# 模拟数据:每场比赛球队得分、该主力是否出战
np.random.seed(42)
df = pd.DataFrame({
    "game_id": range(1, 101),
    "star_played": np.random.choice([0, 1], 100, p=[0.25, 0.75]),
})
# 主力在场时球队平均得分更高
df["team_score"] = np.where(df["star_played"] == 1,
                            np.random.normal(108, 8, 100),
                            np.random.normal(98, 8, 100))
# --- 量化 ---
played    = df.loc[df.star_played == 1, "team_score"]
not_played= df.loc[df.star_played == 0, "team_score"]
loss_per_game = played.mean() - not_played.mean()
# 单场胜率损失(粗略:得分→胜率经验换算,假设每+1分≈+0.03胜率)
win_rate_delta = loss_per_game * 0.03
print(f"主力在场均得分: {played.mean():.1f}")
print(f"主力缺阵均得分: {not_played.mean():.1f}")
print(f"单场得分损失:  {loss_per_game:.1f}")
print(f"单场胜率损失:  {win_rate_delta:.3f}")

局限:忽略对手强度、主客场、样本选择偏差(主力往往对阵强队时轮休)。


方法②:泊松回归 + 反事实预测(推荐)

对足球/篮球得分建模,把"主力是否出战"作为特征,反事实预测缺阵时的预期得分。

import pandas as pd, numpy as np
import statsmodels.api as sm
from statsmodels.formula.api import glm
np.random.seed(0)
n = 200
df = pd.DataFrame({
    "home":        np.random.choice([0,1], n),
    "opp_strength":np.random.normal(0, 1, n),       # 对手强度(标准化)
    "star_played": np.random.choice([0,1], n, p=[0.8,0.2]),
})
# 真实生成过程:主场+3, 对手强度每+1约-2, 主力+8, 泊松噪声
mu = np.exp(4.6 + 0.03*df.home - 0.02*df.opp_strength + 0.08*df.star_played)
df["goals"] = np.random.poisson(mu)
# --- 泊松回归 ---
model = glm("goals ~ home + opp_strength + star_played",
            data=df, family=sm.families.Poisson()).fit()
print(model.summary())
# --- 反事实:假设所有样本主力都出战 vs 都不出战 ---
df_on  = df.assign(star_played=1)
df_off = df.assign(star_played=0)
pred_on  = model.predict(df_on)
pred_off = model.predict(df_off)
loss_per_game = (pred_on - pred_off).mean()
print(f"\n主力单场边际贡献(预期得分): {loss_per_game:.2f}")
# 折算成赛季/胜率损失
season_games = 38
star_out_games = 8
season_loss = loss_per_game * star_out_games
print(f"缺阵 {star_out_games} 场累计期望得分损失: {season_loss:.1f}")

优势:控制对手强度、主客场等混杂因素;给出置信区间(model.conf_int())。


方法③:双重差分(DID)— 因果更稳健

对比"主力缺阵组 vs 对照组"在缺阵前后的表现变化,剔除组间固有差异。

import pandas as pd, numpy as np
import statsmodels.formula.api as smf
# 构造面板:treatment=1 表示该场主力缺阵,post=1 表示缺阵后时期
np.random.seed(1)
rows = []
for game in range(200):
    treat = np.random.choice([0,1])
    for post in [0,1]:
        base = 100 + np.random.normal(0,5)
        # DID效应:缺阵导致约-6分
        score = base - 6*treat*post + np.random.normal(0,3)
        rows.append(dict(game=game, treat=treat, post=post, score=score))
df = pd.DataFrame(rows)
did = smf.ols("score ~ treat + post + treat:post", data=df).fit()
print(did.summary().tables[1])
print(f"\nDID估计的主力缺阵损失: {did.params['treat:post']:.2f} 分/场")

treat:post 系数即"缺阵造成的净损失",是因果推断中较可信的估计。


进阶:把"损失"折算成业务价值

# 假设:每分 ≈ 0.03 胜率,每胜 ≈ 门票+转播+商业 200 万元
point_to_winrate = 0.03
winrate_to_revenue = 200  # 万元/胜场
loss_points_per_game = loss_per_game          # 来自方法②
loss_winrate = loss_points_per_game * point_to_winrate
loss_revenue = loss_winrate * winrate_to_revenue
print(f"每场缺阵损失胜率: {loss_winrate:.3f}")
print(f"每场缺阵经济损失: {loss_revenue:.1f} 万元")
print(f"赛季10场缺阵损失: {loss_revenue*10:.1f} 万元")

电商/零售场景变体(主力SKU缺货)

import pandas as pd, numpy as np
# 核心SKU缺货期间,用同期同类目其他SKU做反事实代理
df = pd.DataFrame({
    "date": pd.date_range("2024-01-01", periods=60),
    "core_in_stock": [1]*40 + [0]*20,          # 后20天缺货
    "core_sales":    np.r_[np.random.normal(1000,50,40), [0]*20],
    "category_sales":np.random.normal(5000,200,60),  # 类目整体趋势
})
# 用类目趋势做反事实基线(缺货前拟合)
fit_df = df[df.core_in_stock == 1]
coef = np.polyfit(fit_df.category_sales, fit_df.core_sales, 1)
pred = np.polyval(coef, df[df.core_in_stock == 0].category_sales)
loss = pred.sum()  # 缺货期间本应实现的销售额
print(f"缺货期预期销售: {loss:.0f} 元")
print(f"实际销售: {df[df.core_in_stock==0].core_sales.sum():.0f} 元")
print(f"缺货损失: {loss - df[df.core_in_stock==0].core_sales.sum():.0f} 元")

关键注意事项

  1. 样本偏差:主力常在"垃圾时间/背靠背"轮休,需控制比赛情境变量。
  2. 对手强度调整:用 opp_strength 或 Elo 评级做协变量,否则高估损失。
  3. 替补替代效应:损失 ≠ 主力全部贡献,替补会顶上一部分(用"净损失"而非"绝对贡献")。
  4. 置信区间:报告点估计同时给出 bootstrap 或模型 CI,避免"看起来精确"。
  5. 因果 vs 相关:DID/PSM 优于简单均值差;样本充足时优先方法②③。

一句话总结:先用历史均值差快速估算,再用泊松回归反事实预测控制混杂,重要决策用 DID 做因果验证,最后折算成胜率/金额的业务语言。

需要我针对具体场景(NBA/英超/某品类SKU)给出可运行的完整脚本或数据模板吗?

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

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝