Models for Olympic Medal Tables(优秀范文三:爆冷概率蒙特卡洛 + 三层次事件定义 + 杠杆实验)
2025 美赛 MCM C 题 · 优秀范文三。视角:「冷门」不该只是赛后的惊叹,而应是赛前的概率。本篇沿用范文一的 OLS 实力定律与同一合成面板,用 次全赛事蒙特卡洛模拟把爆冷拆成三个可计算层次——个体爆发(奖牌 ≥ 期望 ×1.3)、名次跳级(比期望好 ≥3 位)、格局颠覆(榜首易主 / 前三换血)——再用三个杠杆实验回答「什么会改变爆冷率」:噪声放大、主办红利(公共随机数配对实验)、经济增速。核心发现是一句可以印在海报上的话:跳级率呈 U 型——尾部高频而无新闻价值,头部被数学保护,真正值钱的爆冷是中上游跳入前五,而它最大的可控来源是主办权。正文 / 配图 / 附录 / 真源四路数字一致(固定种子 seed=20250317)。
摘要
题目第四问要求量化"爆冷概率",多数答卷止步于给预测区间——区间只回答"误差多大",不回答"谁会爆冷、爆多大、凭什么"。本文建立三层事件体系并逐层报数。L1 个体层:24 国平均爆发率 为 5%–7%,小国 C15 以 9.4% 居首——乘性同方差噪声下人人 CV 相近,小国的绝对波动小却相对波动不减。L2 名次层给出全文最反直觉的结构:跳级率呈 U 型——头部 2.8%(被与前两名 20+ 枚的断层保护)、中游 2.7%(看似胶水区,实则相邻位差 3–10 枚恰好抵消了绝对噪声)、尾部 3.6%(门槛低、随便超三人)——但尾部跳级无人报道,「有价值的爆冷」是 C08 式跳入前五()甚至领奖台。L3 格局层:2028 榜首之争中 C04(期望 100.5 枚)对 C11(93.3 枚)的优势远比点估计看起来脆弱——两者预测分布大面积重叠,;期望前三集合在 78.0% 的模拟世界里被改写。杠杆实验给出政策含义:观测噪声 从 0.12 放大到 0.30,中游跳级率翻四倍(2.7%→10.9%)、前三换血率升至 89.8%;而公共随机数配对的主办实验显示,主办红利把 C08 的期望名次从 5.2 拉到 2.7、进前五概率从 50.1% 跃至 94.0%——东道主是唯一可以被"计划"的爆冷;相比之下经济增速 +0.01 只挪动 0.3 个百分点:单届尺度上,结构因素碾压渐进增长。
一、问题重述
题目的四件事中,①预测模型(范文一)、③口径比较(范文二)已有完整交代;本篇专攻④中被处理得最潦草的部分——爆冷。要求把它从形容词变成名词:给出定义、给出概率、找出规律、评估杠杆,并对「2028 年最值得期待的冷门是谁」给出定量答案。
二、模型假设
- 实力定律沿用范文一的对数线性模型(,),即奖牌由惯性、经济、人口与主办红利解释。
- 不确定性来自两层叠加:回归残差(经验分布重抽,池 168 条、标准差 0.1167)与观测层乘性噪声 ,均在对数空间相加后取指数还原。
- 金银铜按各国历史成色(gold_frac)确定性拆分,爆冷定义在总数口径上。
- 各国扰动相互独立;同一次模拟内共享同一随机流以支持配对实验。
- 2028 主办未知时取 host=0,主办实验单独开启。
三、符号说明
| 符号 | 含义 |
|---|---|
| 国家 的期望奖牌数(2000 次模拟均值) | |
| L1 爆发概率: | |
| L2 跳级概率:名次 | |
| L3 榜首易主概率 | |
| 第 次模拟的总数榜名次表 | |
| CRN | 公共随机数:杠杆实验复用同一批抽样 |
四、建模过程
技术路线见图 1:一条 OLS 实力定律驱动 2000 次完整赛事模拟,每次模拟产出 24 国奖牌与金银铜,随后在三层次上统计事件频率,最后做三组杠杆实验。
4.1 蒙特卡洛引擎:让噪声自己长出冷门
引擎极简:对每国取特征行(末届奖牌、外推 GDP、人口、host),算线性预测 ,再叠加重抽残差与观测噪声,。没有精巧的算法——爆冷的本质就是噪声的极值行为,蒙特卡洛的价值在于用足够多的重复(,频率标准误约 ±1 个百分点)把极值事件的频率估稳。图 2 是模拟的基线画面:C04(100.5 枚)独一档,C11(93.3)紧随,C10/C23/C24 在 73–78 枚贴身缠斗,再往下是长尾——这张图已经预告了后面所有故事的位置。
4.2 三层次事件:从个体到格局
L1 只看自己:图 4 把爆发率对期望奖牌画成散点,右端头部压在 4%–5%,左端小国冲到 9.4%(C15)——相对波动人人相同,但「爆发 30%」对小国只需多拿一两枚,对霸主则是三十枚的奇迹。L2 看相对位置:图 3 的两条曲线是全文最重要的一张图。跳级率(红)并非想象中的"中游最高",而是 U 型:头部 2.8%、中游 2.7%、尾部 3.6%。解释藏在分母里——跳三位需要跨过的不是"名次"而是"奖牌差":头部之下是 20 枚级的断层(C04 与 C23 差一个量级),中游相邻位差 3–10 枚恰与绝对噪声同量级,尾部一枚之差就能连超三人。掉级率(蓝)则头部最高(2.5%):霸主身后永远站着一群只需要自己爆发的人。综合三层得到「爆冷语法」:尾部高频而无价值、中游低频而高价值、头部被数学保护但仍会塌方(掉级比跳级容易)。
4.3 有价值的爆冷:C08 的前五之路
把镜头对准中上游:C08 期望名次 5.2,跳级概率 7.0%(中游之冠),进前五概率 50.1%——它的 2028 是一枚硬币的两面。图 8 的热力图把 Top12 候选国的四种事件概率排成一张「风险说明书」:左列告诉谁能黑,右列告诉谁会凉。这类表格是蒙特卡洛独有的产品——点预测给不出「第五名的第五名概率只有一半」这种关键细节。
4.4 榜首之争:37% 不是小数
点估计说 C04 领先 C11 约 7 枚,听起来安全;分布却说不然。图 7 把两国的 2000 次 predicted 奖牌画成并列直方图:两个钟形大幅重叠,(另有 1.4% 平局)。换言之,每十届就有近三届榜首易主——把「C04 卫冕」写成定论是媒体的事,模型的责任是把 37% 放在桌上。更宏观地,期望前三集合在 78.0% 的模拟中被改写(尽管多半只是 C10 与 C23 的座次互换):奖牌榜前列的"确定论"在概率面前不堪一击。
五、杠杆实验:什么会改变爆冷率
5.1 噪声放大:σ 是混乱的总开关
若赛制扩容、禁赛风波或政治抵制使临场不确定性上升(: 0.12→0.20→0.30),图 5 显示两条曲线同步抬升:中游跳级率 2.7%→5.9%→10.9%(翻四倍),前三换血率 77.7%→84.8%→89.8%。含义有两面:对赛事组织者,降低 σ(稳定的资格体系、透明的仲裁)就是在给"确定性"定价;对博彩与保险类应用,σ 是必须显性报价的风险参数。
5.2 主办实验:可以被计划的爆冷
用公共随机数做严格配对——同一批 2000 次抽样,只把 C08 的 host 从 0 改成 1(其余一切不变),图 6 的三组柱子给出干净因果:期望名次 5.2→2.7,进前五概率 50.1%→94.0%,跳级概率 7.0%→52.0%。换个说法:东道主的历史性突破,七成半是结构红利的兑现,而非奇迹—— 的红利项在期望意义上就足以把中游强队推进领奖台竞争圈。「爆冷」与「实力」的边界,在这里被 CRN 实验划得清清楚楚。
5.3 新星杠杆:增长是十年的事
对照实验:给 C08 的经济增速加 0.01(相当于十年积累的可观提速),单届进前五概率只从 50.1% 挪到 50.4%。原因是对数尺度上的 0.004 位移在 0.17 的噪声面前近乎 invisible。这与 5.2 形成尖锐对比:单届爆冷的杠杆排序是 主办 ≫ 噪声环境 ≫ 经济增长——想要下一届出成绩,申办比发展经济立竿见影;想要持续强势,则恰恰相反。
六、灵敏度分析
- S=2000→5000:各概率变动 <±0.8 个百分点,结论排序不变;L3 事件(37.0%/78.0%)的标准误约 ±1.1pp,已够支撑定性结论。
- 爆发阈值 1.3→1.5:全表平均爆发率降至约 2%,小国占比进一步升高——阈值越苛刻,爆冷越向尾部集中。
- 跳级位数 3→5:头部跳级率跌破 0.5%,尾部仍 >1.5%——U 型更陡,"头部保护"结论加强。
- 残差池换成正态参数化:各事件概率变动 <1pp——尾部事件由乘性噪声主导,对残差分布形状不敏感。
七、模型评价与改进
优点:①把"爆冷"拆成三层可检验事件,每层都给出可复现的频率而非修辞;②CRN 配对实验在完全相同的随机环境下隔离单一杠杆,因果解释干净;③与范文一/二共用实力定律与面板,三篇构成"点估计—不确定性—极值事件"的完整链条。局限:①独立性假设忽略了国别冲击的相关(同一项目取消影响一组国家);②金银铜成色固定,未建模"金牌专项投资"的策略行为;③2028 赛制假设不变,若小项扩容应直接接入 5.1 的 σ 杠杆。改进方向:用 Copula 或项目层面模拟引入相关爆冷;把主办实验扩展为「申办决策的成本—概率」权衡分析。
八、结论
本篇把"爆冷"从形容词变成了三个带百分号的名词:个体爆发人均 5–7 个百分点且小国居首(C15,9.4%);名次跳级呈 U 型(头 2.8%/中 2.7%/尾 3.6%),有价值的版本是 C08 式的前五之争(50.1%);格局颠覆远比想象常见——榜首易主 37.0%、前三换血 78.0%。三个杠杆的强弱排序是主办(+43.9pp 进前五)≫ 噪声环境(σ 翻倍跳级率翻倍)≫ 经济增长(+0.3pp):东道主是唯一能被计划的爆冷,而增长从来不是单届的武器。一句话:冷门不是命运的恶作剧,而是噪声、结构与门槛三者共同书写的概率分布——读懂它,你就再也不需要"爆冷"这个词了。
参考文献
- COMAP. MCM Problem C: Models for Olympic Medal Tables. 2025.
- Metropolis N., Ulam S. The Monte Carlo Method. J. Am. Stat. Assoc., 1949.
- Bernard A. B., Busse M. R. Who Wins the Olympic Games: Economic Resources and Medal Totals. Rev. Econ. Stat., 2004.
- Efron B. Bootstrap Methods: Another Look at the Jackknife. Ann. Statist., 1979.
- Gelman A., Hill J. Data Analysis Using Regression and Multilevel/Hierarchical Models. Cambridge University Press, 2007.
附录:核心 Python 实现
import sys, os
_HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.abspath(os.path.join(_HERE, "..", "..", "..", "tools")))
import gen_mcm2025c as B # 范文一真源:面板与 OLS 基础件
import gen_mcm2025c_3 as U # 本篇真源:爆冷蒙特卡洛
ctys, panel = B.gen_panel()
meta = {c["id"]: c for c in ctys}
beta, r2, resid = U.resid_pool(panel)
print("实力定律 R²=%.3f β1=%.4f 残差池=%d(sd=%.4f)"
% (r2, beta[1], len(resid),
(sum(e * e for e in resid) / len(resid)) ** 0.5))
# 1) S=2000 次全赛事模拟
medals, golds, rec, mus = U.simulate(panel, beta, resid, meta,
U.S_MAIN, B.NOISE_SD, U.SEED)
ns = len(medals)
exp_m = {c: sum(m[c] for m in medals) / ns for c in medals[0]}
ranks = U.total_ranks(medals)
exp_r = {c: sum(rk[c] for rk in ranks) / ns for c in exp_m}
order = sorted(exp_m, key=lambda c: -exp_m[c])
print("期望Top5:", [(c, round(exp_m[c], 1)) for c in order[:5]])
# 2) 三层次爆冷事件
pj = {c: 100.0 * sum(rk[c] <= exp_r[c] - U.UPSET_JUMP for rk in ranks) / ns
for c in order}
pb = {c: 100.0 * sum(m[c] >= U.UPSET_MEDAL * exp_m[c] for m in medals) / ns
for c in order}
for name, grp in [("头部1-4", order[:4]), ("中游5-12", order[4:12]),
("尾部13-24", order[12:])]:
print("%s 平均跳级率=%.1f%% 爆发率=%.1f%%"
% (name, sum(pj[c] for c in grp) / len(grp),
sum(pb[c] for c in grp) / len(grp)))
p_flip = 100.0 * sum(m["C11"] > m["C04"] for m in medals) / ns
base3 = set(order[:3])
swap = 100.0 * sum(set(c for c in rk if rk[c] <= 3) != base3
for rk in ranks) / ns
print("P(C11登顶)=%.1f%% 前三换血率=%.1f%%" % (p_flip, swap))
# 3) 主办杠杆(CRN 配对)
m_h, _g, _r, _mu = U.simulate(panel, beta, resid, meta,
U.S_MAIN, B.NOISE_SD, U.SEED, host_id="C08")
rk_h = U.total_ranks(m_h)
p5 = 100.0 * sum(rk["C08"] <= 5 for rk in ranks) / ns
p5h = 100.0 * sum(rk["C08"] <= 5 for rk in rk_h) / len(rk_h)
print("C08 主办实验: P(前5) %.1f%% -> %.1f%%" % (p5, p5h))