专栏导语 :本专栏系统讲解数学建模的经典方法与 AI 智能方法,并打通两者之间的联系。上一篇我们把逻辑回归拆成了一个 sigmoid 神经元,看清了分类模型的骨架(逻辑回归与信用违约预测:从S曲线到分类器)。这一篇换一种活法:当积分算不出来、解析解根本不存在时------不再推导,而是"数" 。扔十万次骰子,取平均,答案自己就浮出来了。这就是蒙特卡洛方法,数学建模里最"暴力"、却也最万能的一招。它还有一条暗线------今天所有生成式 AI 的采样过程(MCMC、扩散模型、强化学习的轨迹采样),本质上都是它的后代。本专栏 B 线的"采样"伏笔,从这里正式埋下。
文章目录
- 一、问题引入:当公式给不出答案
- 二、问题分析:三个必须回答的问题
- 三、模型假设
- 四、符号说明
- 五、模型建立
-
- [5.1 核心思想:积分 = 期望 = 平均数](#5.1 核心思想:积分 = 期望 = 平均数)
- [5.2 误差从哪来: 1 / n 1/\sqrt{n} 1/n 与"维度无关"](#5.2 误差从哪来: 1 / n 1/\sqrt{n} 1/n 与"维度无关")
- [5.3 案例一:报童模型(有解析解,用来"校准"方法)](#5.3 案例一:报童模型(有解析解,用来"校准"方法))
- [5.4 案例二:投资组合的 VaR 与 CVaR(蒙特卡洛的主场)](#5.4 案例二:投资组合的 VaR 与 CVaR(蒙特卡洛的主场))
- [5.5 方差缩减:让同样的样本更"值钱"](#5.5 方差缩减:让同样的样本更"值钱")
- [5.6 收敛速度与样本量规划](#5.6 收敛速度与样本量规划)
- [六、Python 实现](#六、Python 实现)
-
- [6.1 报童模型:解析解 vs 蒙特卡洛](#6.1 报童模型:解析解 vs 蒙特卡洛)
- [6.2 投资组合风险:厚尾分布下的 VaR 与 CVaR](#6.2 投资组合风险:厚尾分布下的 VaR 与 CVaR)
- [6.3 方差缩减与收敛速度](#6.3 方差缩减与收敛速度)
- [6.4 结果可视化](#6.4 结果可视化)
- 七、模型评价
- [八、AI 视角:采样,是现代 AI 的通用语言](#八、AI 视角:采样,是现代 AI 的通用语言)
-
- [8.1 训练目标本身就是"蒙特卡洛估计"](#8.1 训练目标本身就是"蒙特卡洛估计")
- [8.2 MCMC:当分布本身也未知](#8.2 MCMC:当分布本身也未知)
- [8.3 扩散模型:把"加噪"倒过来放](#8.3 扩散模型:把"加噪"倒过来放)
- [8.4 强化学习与 AlphaGo:用模拟估计价值](#8.4 强化学习与 AlphaGo:用模拟估计价值)
- [8.5 不确定性量化:给预测配一个"误差棒"](#8.5 不确定性量化:给预测配一个"误差棒")
- 九、小结
个人主页 :蒲公英eric
专栏传送门 :数学建模 × AI:从经典模型到智能方法
学习方向:大数据 / 数学建模 / AI交叉领域
人生格言:建模没有终点,只有不断迭代的更优解
📌本文是专栏「数学建模 × AI:从经典模型到智能方法」的第 11 篇文章。
一、问题引入:当公式给不出答案
前面十篇,我们遇到的模型大多有一个共同点:能推出一个式子。线性回归有正规方程,逻辑回归有梯度公式,线性规划有顶点定理------至少知道"答案长什么样",剩下的是算。
但数模里有大量问题,连"答案长什么样"都写不出来:
场景 A:报童订多少份报纸?
报纸进价 6 元、售价 12 元、卖不掉只能 2 元回收。每天的需求量是个随机变量,大致服从 N ( 100 , 20 2 ) N(100, 20^2) N(100,202)。订多了砸手里,订少了少赚钱,订多少期望利润最大?
场景 B:这个投资组合明年最多可能亏多少?
60% 资金买资产 1、40% 买资产 2,两只资产的收益率都服从厚尾分布 (现实中股市暴涨暴跌远比正态频繁),且同涨同跌(相关系数 0.3)。监管部门要问:95% 置信水平下,一年最多亏多少? 如果真发生极端行情,平均会亏多少?
场景 A 有解析解(我们马上会推),场景 B 没有:两个厚尾随机变量的加权和,其分布函数写不出闭式表达式,再叠加"亏损超过本金就清零"这类非线性规则,任何公式推导都会卡死。
这正是蒙特卡洛的主场。它的逻辑简单到近乎粗暴:
既然算不出分布,那就模拟一万次,然后数一数。
| 解析解失效的典型情形 | 例子 |
|---|---|
| 高维积分 | 上百个随机因素耦合的期望值 |
| 非线性、路径依赖 | 期权定价、止损策略、破产过程 |
| 复杂约束耦合 | 供应链多级库存、排队网络 |
| 分布本身没有闭式解 | 厚尾分布之和、混合分布 |
二、问题分析:三个必须回答的问题
问题 1:怎么把"求期望"变成"数样本"?
大数定律给了理论保证:样本足够多时,样本均值依概率收敛到真实期望。所以任务拆成三步------定义输出量 → 从分布里抽样 → 取平均。听起来简单,但"输出量"设计得好不好,直接决定模拟是否有意义。
问题 2:误差有多大?要抽多少样本?
蒙特卡洛的结果永远带误差。中心极限定理告诉我们误差的尺度是 σ / n \sigma/\sqrt{n} σ/n ------样本翻 100 倍,误差只缩小到 1/10 。这个"慢"是它的软肋,但也换来了一个惊人的好处:收敛速度与维度无关。后面会详细讲。
问题 3:随机数哪来的?结果能复现吗?
计算机只能生成伪随机数 (deterministic 的算法序列)。数模论文里如果不固定随机种子,别人复现不出你的结果,这是硬伤。本文每段代码都显式写了 default_rng(...),固定种子,保证结果可复现。
三、模型假设
- 随机变量的分布已知或可设定 :需求服从正态、收益率服从 t 分布......这个假设是整个模型的地基,假设错了,模拟再精确也是错的(后文会讨论怎么检验);
- 样本独立同分布(i.i.d.):每次抽样互不影响,且来自同一个分布;
- 给定输入后,输出是确定的 :模型结构本身不含随机性,随机性全部来自输入变量。即存在确定的函数 g ( ⋅ ) g(\cdot) g(⋅),输出 = g ( X ) =g(X) =g(X);
- 结论以统计量形式报告:均值、分位数、概率,并附带误差范围,而不是声称"精确等于某个值"。
假设 3 很关键:如果模型内部还有随机决策(比如"缺货时随机调货"),那就需要把内部随机性也纳入抽样,属于随机仿真的范畴,原理相同但实现更复杂。
四、符号说明
| 符号 | 含义 | 备注 |
|---|---|---|
| n n n | 模拟次数(样本量) | 不是样本数据的条数,是我们"造"出来的次数 |
| X X X | 随机输入(向量或标量) | 如每日需求 D D D、资产收益率 r \mathbf{r} r |
| f ( x ) f(x) f(x) | X X X 的概率密度函数 | 分布假设的载体 |
| g ( X ) g(X) g(X) | 输出函数 | 如利润 π ( Q , D ) \pi(Q,D) π(Q,D)、组合收益 w T r \mathbf{w}^T\mathbf{r} wTr |
| θ \theta θ | 待求的目标量 | θ = E g ( X ) \theta=\mathbb{E}g(X) θ=Eg(X) 或某个分位数 |
| σ g \sigma_g σg | g ( X ) g(X) g(X) 的标准差 | 决定模拟误差的大小 |
| S E \mathrm{SE} SE | 标准误 | S E = σ ^ g / n \mathrm{SE}=\hat\sigma_g/\sqrt{n} SE=σ^g/n |
| 1 − α 1-\alpha 1−α | 置信水平 | 如 95%、99% |
| V a R 1 − α \mathrm{VaR}_{1-\alpha} VaR1−α | 在险价值 | 置信水平 1 − α 1-\alpha 1−α 下的最大损失( α \alpha α 分位数的相反数) |
| C V a R 1 − α \mathrm{CVaR}_{1-\alpha} CVaR1−α | 条件在险价值 | 超过 VaR 那部分的平均损失 |
| Φ , φ \Phi,\ \varphi Φ, φ | 标准正态的分布函数、密度函数 | 报童模型的解析推导要用 |
| Q ∗ Q^* Q∗ | 最优订货量 | 报童模型的决策变量 |
五、模型建立
5.1 核心思想:积分 = 期望 = 平均数
要算的量几乎都能写成一个积分:
θ = ∫ g ( x ) f ( x ) d x = E g ( X ) \theta=\int g(x)f(x)\,\mathrm{d}x=\mathbb{E}g(X) θ=∫g(x)f(x)dx=Eg(X)
这个积分可能几维、几十维,解析算不出来。蒙特卡洛的做法是把它翻译成"平均值":
θ ^ = 1 n ∑ i = 1 n g ( x i ) , x 1 , ... , x n ∼ i.i.d. f \hat\theta=\frac{1}{n}\sum_{i=1}^{n}g(x_i),\qquad x_1,\dots,x_n \overset{\text{i.i.d.}}{\sim} f θ^=n1i=1∑ng(xi),x1,...,xn∼i.i.d.f
由大数定律, θ ^ → θ \hat\theta \to \theta θ^→θ(几乎必然)。积分是"连续地加权求和",蒙特卡洛是"随机地抽样求平均"------一个是解析的路,一个是统计的路,殊途同归。
具体操作永远是这三步:
- 定义输出量 g ( ⋅ ) g(\cdot) g(⋅):把业务问题写成一个可计算的函数(利润、损失、等待时间);
- 抽样 :按 f ( x ) f(x) f(x) 生成 n n n 组输入。一维用
rng.normal;多维要先处理相关性(Cholesky 分解),厚尾要先做分布变换; - 统计 :对 n n n 个输出取平均、数分位数、算概率,并给出标准误。
第三步不只是"取平均"。同一个模拟结果可以回答很多问题:均值、中位数、5% 分位(VaR)、超过阈值的概率......一次模拟,多角度解读,这是蒙特卡洛相对解析法最实用的优势。
5.2 误差从哪来: 1 / n 1/\sqrt{n} 1/n 与"维度无关"
设 g ( X ) g(X) g(X) 的标准差为 σ g \sigma_g σg,由中心极限定理:
θ ^ ≈ N ( θ , σ g 2 n ) ⟹ S E = σ g n \hat\theta \approx N\!\left(\theta,\ \frac{\sigma_g^2}{n}\right) \quad\Longrightarrow\quad \mathrm{SE}=\frac{\sigma_g}{\sqrt{n}} θ^≈N(θ, nσg2)⟹SE=n σg
因此 95% 置信区间是 θ ^ ± 1.96 S E \hat\theta\pm1.96\,\mathrm{SE} θ^±1.96SE。两条直接推论:
(1)收敛慢,但稳定。 误差 ∝ n − 1 / 2 \propto n^{-1/2} ∝n−1/2:样本 ×100,误差 ÷10。想要精度翻倍,样本要翻 4 倍。
| 样本量 n n n | 1 万 | 10 万 | 100 万 | 1 亿 |
|---|---|---|---|---|
| 误差(相对 σ g \sigma_g σg) | 1% | 0.32% | 0.1% | 0.01% |
(2)收敛速度与维度无关------这是它碾压网格法的原因。
用网格法算 d d d 维积分,若每一维都按精度 ε \varepsilon ε 均匀布点(间隔约 ε \varepsilon ε,即每维 m ≈ 1 / ε m\approx1/\varepsilon m≈1/ε 个点),总点数就是 m d ≈ ( 1 / ε ) d m^d\approx(1/\varepsilon)^d md≈(1/ε)d------点数随维度指数爆炸 。蒙特卡洛的误差则始终是 O ( n − 1 / 2 ) O(n^{-1/2}) O(n−1/2),不含 d d d。取精度 ε = 0.01 \varepsilon=0.01 ε=0.01:
| 维度 d d d | 网格法所需点数 ≈ ( 1 / ε ) d \approx(1/\varepsilon)^d ≈(1/ε)d | 蒙特卡洛所需点数 |
|---|---|---|
| 2 | 10 4 10^4 104 | 10 4 10^4 104 |
| 5 | 10 10 10^{10} 1010 | 10 4 10^4 104 |
| 10 | 10 20 10^{20} 1020 | 10 4 10^4 104 |
d = 10 d=10 d=10 时,网格法需要 10 20 10^{20} 1020 个点------按每秒 10 亿个点的速度算,也要跑三千年;而蒙特卡洛一万个点就能给到约 1% 的误差。维度越高,蒙特卡洛越划算,这就是它在高维优化、贝叶斯推断、量子多体问题里不可替代的原因。
严谨地说,"与维度无关"指的是收敛阶 不含 d d d。常数 σ g \sigma_g σg 仍可能随维度增大,所以高维问题的绝对误差会变大------但阶数不变,这已经是决定性的优势。
5.3 案例一:报童模型(有解析解,用来"校准"方法)
模型设定 :进价 c = 6 c=6 c=6、售价 p = 12 p=12 p=12、残值 s = 2 s=2 s=2,需求 D ∼ N ( μ , σ 2 ) = N ( 100 , 20 2 ) D\sim N(\mu,\sigma^2)=N(100,20^2) D∼N(μ,σ2)=N(100,202),订货量 Q Q Q。利润为
π ( Q , D ) = p min ( Q , D ) + s ( Q − D ) + − c Q \pi(Q,D)=p\min(Q,D)+s(Q-D)^+-cQ π(Q,D)=pmin(Q,D)+s(Q−D)+−cQ
第一步:解析求解。 用 p min ( Q , D ) = p Q − p ( Q − D ) + p\min(Q,D)=pQ-p(Q-D)^+ pmin(Q,D)=pQ−p(Q−D)+ 改写:
π = ( p − c ) Q − ( p − s ) ( Q − D ) + \pi=(p-c)Q-(p-s)(Q-D)^+ π=(p−c)Q−(p−s)(Q−D)+
正态需求下有余期望公式( z = Q − μ σ z=\frac{Q-\mu}{\sigma} z=σQ−μ):
E ( Q − D ) + = σ φ ( z ) + ( Q − μ ) Φ ( z ) \mathbb{E}\left(Q-D)\^+\\right=\sigma\varphi(z)+(Q-\mu)\Phi(z) E(Q−D)+=σφ(z)+(Q−μ)Φ(z)
代入得期望利润:
E π ( Q ) = ( p − c ) Q − ( p − s ) σ φ ( z ) + ( Q − μ ) Φ ( z ) \mathbb{E}\\pi(Q)=(p-c)Q-(p-s)\Big\\sigma\\varphi(z)+(Q-\\mu)\\Phi(z)\\Big Eπ(Q)=(p−c)Q−(p−s)σφ(z)+(Q−μ)Φ(z)
对 Q Q Q 求导(注意 d d Q E ( Q − D ) + = Φ ( z ) \frac{\mathrm{d}}{\mathrm{d}Q}\mathbb{E}(Q-D)\^+=\Phi(z) dQdE(Q−D)+=Φ(z)):
d E π d Q = ( p − c ) − ( p − s ) Φ ( z ) = 0 ⟹ Φ ( z ∗ ) = p − c p − s = 12 − 6 12 − 2 = 0.6 \frac{\mathrm{d}\,\mathbb{E}\\pi}{\mathrm{d}Q}=(p-c)-(p-s)\Phi(z)=0 \;\Longrightarrow\; \Phi(z^*)=\frac{p-c}{p-s}=\frac{12-6}{12-2}=0.6 dQdEπ=(p−c)−(p−s)Φ(z)=0⟹Φ(z∗)=p−sp−c=12−212−6=0.6
这就是著名的临界分位数法则:
Q ∗ = μ + σ Φ − 1 ( 0.6 ) = 100 + 20 × 0.2533 = 105.07 Q^*=\mu+\sigma\Phi^{-1}(0.6)=100+20\times0.2533=105.07 Q∗=μ+σΦ−1(0.6)=100+20×0.2533=105.07
直觉解释:在 Q ∗ Q^* Q∗ 处再多订一件,有 1 − Φ ( z ∗ ) = 40 % 1-\Phi(z^*)=40\% 1−Φ(z∗)=40% 的概率卖掉,赚 p − c = 6 p-c=6 p−c=6 元;有 60 % 60\% 60% 的概率砸在手里,亏 c − s = 4 c-s=4 c−s=4 元。 0.4 × 6 = 2.4 0.4\times6=2.4 0.4×6=2.4 与 0.6 × 4 = 2.4 0.6\times4=2.4 0.6×4=2.4 恰好打平------再订就亏,少订就少赚。所以最优订货点满足 Φ ( z ∗ ) = p − c p − s \Phi(z^*)=\frac{p-c}{p-s} Φ(z∗)=p−sp−c,这个分位数称为临界分位数(critical fractile) ; Q ∗ Q^* Q∗ 对应的服务水平(不缺货概率)就是 60%。
把 Q ∗ Q^* Q∗ 代回,解析期望利润为 522.73 元。
第二步:蒙特卡洛验证。 抽 10 万次需求,按同一公式算利润,取平均,结果 522.91 ± 0.83 (95% 置信区间)------与解析解相差 0.18,落在误差范围内。两条路算出同一个答案,方法可信。
第三步:用模拟看整条曲线。 订货量从 90 到 120 变化时,期望利润:
| Q Q Q | 90 | 95 | 100 | 105 | 110 | 115 | 120 |
|---|---|---|---|---|---|---|---|
| E π \mathbb{E}\\pi Eπ | 500.44 | 512.73 | 520.21 | 522.73 | 520.44 | 513.77 | 503.34 |
曲线在 Q ≈ 105 Q\approx105 Q≈105 处取到峰值,两侧都下降,且左侧下降更快(缺货损失比滞销损失更贵)。这是在报童模型里非常典型的"非对称"形状。
这个案例的安排是刻意的:先有标准答案,再让蒙特卡洛去逼近。只有先证明"方法在能验证的问题上是对的",你才有底气把它用到"没法验证"的问题上。数模论文里也一样------方法验证这一节,最好找一个有解析解或已知基准的小例子。
5.4 案例二:投资组合的 VaR 与 CVaR(蒙特卡洛的主场)
数据设定 :资金 1000 万,权重 w = ( 0.6 , 0.4 ) \mathbf{w}=(0.6,0.4) w=(0.6,0.4);两只资产年收益率均值 ( 8 % , 12 % ) (8\%,12\%) (8%,12%)、波动率 ( 15 % , 25 % ) (15\%,25\%) (15%,25%)、相关系数 ρ = 0.3 \rho=0.3 ρ=0.3。但收益率不服从正态 ,而服从自由度为 5 的多元 t 分布(金融数据里常用的厚尾模型)。
厚尾数据怎么造? 不能简单地对两个正态做相关------那样尾部还是正态的。标准做法是"正态 + 共同卡方混合":
- 先造相关的标准正态: z = L ε \mathbf{z}=L\boldsymbol{\varepsilon} z=Lε, L L L 是相关矩阵的 Cholesky 分解;
- 再抽一个卡方变量 χ 5 2 \chi^2_5 χ52,令 t = z / χ 5 2 / 5 \mathbf{t}=\mathbf{z}\big/\sqrt{\chi^2_5/5} t=z/χ52/5 ;
- 最后缩放回目标波动率: r = μ + σ ⊙ t / d f d f − 2 \mathbf{r}=\boldsymbol{\mu}+\boldsymbol{\sigma}\odot\mathbf{t}\big/\sqrt{\frac{df}{df-2}} r=μ+σ⊙t/df−2df 。
第 3 步容易被漏掉:t 分布的方差是 d f d f − 2 \frac{df}{df-2} df−2df, d f = 5 df=5 df=5 时等于 5 / 3 ≈ 1.67 5/3\approx1.67 5/3≈1.67,不除掉这个因子,模拟出来的波动率会比设定的高 29%。
第 2 步的卡方因子是两只资产共享的,它代表"市场整体恐慌程度"------恐慌时两只资产一起暴跌,所以极端行情下相关性自然升高。这正是金融危机里"平时相关性 0.3,崩盘时变成 0.8"的建模方式。
待求的两个指标:
V a R 1 − α = − inf { x : F ( x ) ≥ α } , C V a R 1 − α = − E r p ∣ r p ≤ F − 1 ( α ) \mathrm{VaR}{1-\alpha}=-\inf\{x:F(x)\ge\alpha\},\qquad \mathrm{CVaR}{1-\alpha}=-\mathbb{E}\bigr_p\\ \\big\|\\ r_p\\le F\^{-1}(\\alpha)\\big VaR1−α=−inf{x:F(x)≥α},CVaR1−α=−Erp rp≤F−1(α)
用大白话:VaR 是"最惨的 5% 从哪里开始",CVaR 是"最惨的那 5% 平均有多惨" 。 V a R \mathrm{VaR} VaR 只告诉你门槛, C V a R \mathrm{CVaR} CVaR 才告诉你门槛之后的坑有多深。
模拟结果 (50 万次,并对亏损截断在 − 100 % -100\% −100%,即最多亏光本金):
| 指标 | 95% 置信 | 99% 置信 |
|---|---|---|
| VaR | 142.76 万 | 301.98 万 |
| CVaR | 245.81 万 | 428.41 万 |
另外:组合年收益均值 9.60%、波动率 15.26%(与解析的 9.60%、15.33% 吻合);亏损概率 22.76%;亏损超过 50% 的概率 0.20%;样本最坏情况亏光本金(截断生效)。
最值得玩味的一点:正态假设在 95% 下会"高估"风险,在 99% 下却"低估"风险。
| 置信水平 | 正态假设 VaR | t 分布 VaR(模拟) | 结论 |
|---|---|---|---|
| 95% | 156.15 万 | 142.76 万 | 正态高估 13 万 |
| 99% | 260.62 万 | 301.98 万 | 正态低估 41 万 |
这不是代码错了,而是厚尾分布的形状决定的:t 分布中间更尖、肩膀更薄、尾巴更厚 。5% 分位落在"肩膀"区域,因为肩膀变薄,分位数反而更靠近中心;1% 分位已经深入"尾巴",厚尾效应才暴露出来。把标准 t₅ 标准化后,它的 5% 分位是 − 1.561 -1.561 −1.561(比正态的 − 1.645 -1.645 −1.645 更靠近中心),1% 分位是 − 2.606 -2.606 −2.606(比正态的 − 2.326 -2.326 −2.326 更靠左)。
实务教训 :只报一个 95% VaR,可能得出"厚尾更安全"的荒唐结论。风险报告至少要给 99% VaR + CVaR,并且明确写出所用分布假设。这也是 Basel 委员会把压力测试和 CVaR 写进监管框架的原因。
5.5 方差缩减:让同样的样本更"值钱"
蒙特卡洛慢,所以每一点方差都值得省。三种最常用的技巧:
(1)对偶变量法(antithetic variates)。
抽样时成对使用 u u u 和 1 − u 1-u 1−u:一个需求偏高,配一个需求偏低。两者的误差方向相反,平均后相互抵消。本文报童案例的结果:
| 方案 | 样本量 | 标准误 | 相关系数 |
|---|---|---|---|
| 独立抽样 | 10 万 | 0.422 | --- |
| 对偶变量 | 5 万对(=10 万次计算) | 0.256 | − 0.633 -0.633 −0.633 |
同样的计算量,标准误降到 0.61 倍,等效于把样本量放大 2.73 倍 ( ( 0.422 / 0.256 ) 2 ≈ 2.73 (0.422/0.256)^2\approx2.73 (0.422/0.256)2≈2.73)。代价只是写一行 1-u。
(2)公共随机数(common random numbers, CRN)。
比较两个方案(比如 Q = 95 Q=95 Q=95 与 Q = 105 Q=105 Q=105)时,让它们面对同一批需求样本。这样两个估计的误差高度相关,做差时大部分误差被抵消,"谁更好"的判断会更可靠。6.1 节末尾就演示了这种写法:同一批 10 万次需求,同时评估四个订货量,得到的模拟值几乎与解析曲线逐点重合。
(3)重要性采样(importance sampling)。
估算极小概率事件(如"亏损超过 50%")时,直接抽样几乎抽不到,方差极大。做法是换一个分布去抽 (把抽样重心挪到危险区域),再用似然比 f ( x ) q ( x ) \frac{f(x)}{q(x)} q(x)f(x) 加权修正。这是稀有事件模拟的标准武器。
此外还有分层抽样和拟蒙特卡洛(Sobol 序列) ,后者把误差阶从 O ( n − 1 / 2 ) O(n^{-1/2}) O(n−1/2) 改善到接近 O ( ( log n ) d / n ) O((\log n)^d/n) O((logn)d/n),在中等维度下非常有效。
5.6 收敛速度与样本量规划
实测(报童模型, Q ∗ = 105.07 Q^*=105.07 Q∗=105.07):
| n n n | 100 | 1,000 | 10,000 | 100,000 | 1,000,000 |
|---|---|---|---|---|---|
| 估计值 | 524.535 | 523.576 | 521.966 | 522.912 | 522.706 |
| 标准误 | 12.093 | 4.340 | 1.354 | 0.422 | 0.134 |
样本每翻 10 倍,标准误降到约 1 / 3.16 1/3.16 1/3.16------与 1 / n 1/\sqrt{n} 1/n 完全吻合。100 万次时误差 0.134,相对误差 0.026%,已经远超多数数模问题的精度需求。
样本量怎么定? 不要拍脑袋,用两步法:
- 先试跑 :抽 1 万次,得到 σ ^ g \hat\sigma_g σ^g;
- 反解样本量 :要求误差不超过 ε \varepsilon ε,则
n ≈ ( 1.96 σ ^ g ε ) 2 n\approx\left(\frac{1.96\,\hat\sigma_g}{\varepsilon}\right)^2 n≈(ε1.96σ^g)2
本例 σ ^ g ≈ 133.4 \hat\sigma_g\approx133.4 σ^g≈133.4。若要期望利润的误差控制在 ±1 元以内:
n ≈ ( 1.96 × 133.4 1 ) 2 ≈ 6.8 万 n\approx\left(\frac{1.96\times133.4}{1}\right)^2\approx6.8\text{ 万} n≈(11.96×133.4)2≈6.8 万
注意分位数比均值难估。 同样跑 50 万次,均值的标准误约 0.20 万(相对 0.21%);而 95% VaR 的 bootstrap 标准误约 0.56 万(相对 0.39%),99% VaR 约 1.38 万(相对 0.46%),99% CVaR 更是达到 2.52 万(相对 0.59%)------越往尾部走,误差越大 。原因很直白:分位数只由尾部那一小撮样本决定,95% 分位背后还有 2.5 万个点,99% 分位只剩 5000 个点,有效样本量小得多。所以报告 VaR / CVaR 时,误差范围必须单独给,不能沿用均值的精度。
六、Python 实现
6.1 报童模型:解析解 vs 蒙特卡洛
python
import numpy as np
from scipy.stats import norm
rng = np.random.default_rng(2026) # 固定种子,保证结果可复现
# ---- 参数 ----
p, c, s = 12.0, 6.0, 2.0 # 售价、进价、残值
mu, sigma = 100.0, 20.0 # 需求均值、标准差
# ---- 1) 解析最优订货量 ----
cr = (p - c) / (p - s) # 临界分位数
Q_star = mu + sigma * norm.ppf(cr)
# ---- 2) 解析期望利润 ----
def expected_profit(Q):
z = (Q - mu) / sigma
return (p - c) * Q - (p - s) * ((Q - mu) * norm.cdf(z) + sigma * norm.pdf(z))
# ---- 3) 蒙特卡洛:抽 10 万次需求 ----
n = 100_000
D = rng.normal(mu, sigma, n)
profit = p * np.minimum(Q_star, D) + s * np.maximum(Q_star - D, 0) - c * Q_star
est = profit.mean()
se = profit.std(ddof=1) / np.sqrt(n)
print(f"临界分位数 = {cr:.2f}")
print(f"最优订货量 Q* = {Q_star:.2f}")
print(f"解析期望利润 = {expected_profit(Q_star):.2f}")
print(f"MC 估计 = {est:.2f} ± {1.96 * se:.2f}(95% 置信区间)")
# ---- 4) 不同订货量的期望利润(解析)----
for Q in [90, 95, 100, 105, 110, 115, 120]:
print(f"Q={Q:3d} 期望利润={expected_profit(Q):8.2f}")
# ---- 5) 公共随机数:四个订货量共用同一批需求样本 ----
for Q in [95, 100, 105, 110]:
pr = p * np.minimum(Q, D) + s * np.maximum(Q - D, 0) - c * Q
print(f"Q={Q:3d} MC={pr.mean():8.3f} ± {1.96 * pr.std(ddof=1) / np.sqrt(n):.2f}")
运行结果:
临界分位数 = 0.60
最优订货量 Q* = 105.07
解析期望利润 = 522.73
MC 估计 = 522.91 ± 0.83(95% 置信区间)
Q= 90 期望利润= 500.44
Q= 95 期望利润= 512.73
Q=100 期望利润= 520.21
Q=105 期望利润= 522.73
Q=110 期望利润= 520.44
Q=115 期望利润= 513.77
Q=120 期望利润= 503.34
Q= 95 MC= 512.823 ± 0.61
Q=100 MC= 520.352 ± 0.72
Q=105 MC= 522.911 ± 0.83
Q=110 MC= 520.645 ± 0.92
最后一段是 5.5 节(2)的代码实现:D 只生成一次,四个 Q 都在同一批 样本上评估。对比上面解析值与模拟值, Q = 105 Q=105 Q=105 的模拟误差仅 0.18,其余三点也都在 ±1 元内------模拟曲线与解析曲线的峰值位置一致,说明"订货 105 份左右最优"这个结论可靠。
6.2 投资组合风险:厚尾分布下的 VaR 与 CVaR
python
import numpy as np
from scipy.stats import norm
rng = np.random.default_rng(2026)
# ---- 参数 ----
w = np.array([0.6, 0.4]) # 权重
mu = np.array([0.08, 0.12]) # 年化收益均值
sig = np.array([0.15, 0.25]) # 年化波动率
rho, df = 0.3, 5 # 相关系数、t 分布自由度
N = 500_000
capital = 1000.0 # 本金 1000 万
# ---- 1) 造相关的厚尾收益 ----
R = np.array([[1.0, rho], [rho, 1.0]])
L = np.linalg.cholesky(R)
z = rng.standard_normal((N, 2)) @ L.T # 相关正态
chi = rng.chisquare(df, N) # 共同卡方因子(恐慌因子)
t = z / np.sqrt(chi / df)[:, None] # 多元 t
r = mu + sig * t / np.sqrt(df / (df - 2)) # 标准化到目标波动率
# ---- 2) 组合收益,亏损下限 -100%(最多亏光本金)----
rp = np.maximum(r @ w, -1.0)
pnl = capital * rp
# ---- 3) VaR 与 CVaR ----
for a in [0.05, 0.01]:
q = np.percentile(rp, a * 100)
var = -q * capital
cvar = -rp[rp <= q].mean() * capital
print(f"{1 - a:.0%} 置信:VaR = {var:.2f} 万,CVaR = {cvar:.2f} 万")
print(f"亏损概率 = {np.mean(rp <= 0):.4f}")
print(f"亏损超 50% 的概率 = {np.mean(rp <= -0.5):.4f}")
# ---- 4) 正态假设下的 VaR(用于对比)----
mup = w @ mu
sigp = np.sqrt(w @ np.diag(sig**2) @ w + 2 * w[0] * w[1] * rho * sig[0] * sig[1])
for a in [0.05, 0.01]:
print(f"{1 - a:.0%} 正态假设 VaR = {-(mup + norm.ppf(a) * sigp) * capital:.2f} 万")
运行结果:
95% 置信:VaR = 142.76 万,CVaR = 245.81 万
99% 置信:VaR = 301.98 万,CVaR = 428.41 万
亏损概率 = 0.2276
亏损超 50% 的概率 = 0.0020
95% 正态假设 VaR = 156.15 万
99% 正态假设 VaR = 260.62 万
6.3 方差缩减与收敛速度
python
import numpy as np
from scipy.stats import norm
# ---- 对偶变量法(报童模型)----
rng = np.random.default_rng(7)
p, c, s, mu, sigma = 12.0, 6.0, 2.0, 100.0, 20.0
Q = 105.07
m = 50_000
u = rng.random(m)
D1 = mu + sigma * norm.ppf(u) # 一个偏小
D2 = mu + sigma * norm.ppf(1 - u) # 一个偏大,误差反向
g1 = p * np.minimum(Q, D1) + s * np.maximum(Q - D1, 0) - c * Q
g2 = p * np.minimum(Q, D2) + s * np.maximum(Q - D2, 0) - c * Q
g = (g1 + g2) / 2
se_anti = g.std(ddof=1) / np.sqrt(m)
se_ind = np.concatenate([g1, g2]).std(ddof=1) / np.sqrt(2 * m)
print(f"对偶估计 = {g.mean():.3f},标准误 = {se_anti:.3f}")
print(f"独立 10 万样本标准误 = {se_ind:.3f}")
print(f"两半相关系数 = {np.corrcoef(g1, g2)[0, 1]:.3f}")
print(f"方差缩减倍数 = {(se_ind / se_anti) ** 2:.2f}")
# ---- 收敛速度:1/sqrt(n) ----
rng2 = np.random.default_rng(2026)
D = rng2.normal(mu, sigma, 1_000_000)
pr = p * np.minimum(Q, D) + s * np.maximum(Q - D, 0) - c * Q
for n in [100, 1000, 10000, 100000, 1000000]:
sub = pr[:n]
print(f"n={n:>7}: 估计 {sub.mean():8.3f},标准误 {sub.std(ddof=1) / np.sqrt(n):.3f}")
运行结果:
对偶估计 = 522.678,标准误 = 0.256
独立 10 万样本标准误 = 0.422
两半相关系数 = -0.633
方差缩减倍数 = 2.73
n= 100: 估计 524.535,标准误 12.093
n= 1000: 估计 523.576,标准误 4.340
n= 10000: 估计 521.966,标准误 1.354
n= 100000: 估计 522.912,标准误 0.422
n=1000000: 估计 522.706,标准误 0.134
6.4 结果可视化
python
import numpy as np
from scipy.stats import norm
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['mathtext.fontset'] = 'dejavusans'
# ================= 左图:组合损益分布 =================
rng = np.random.default_rng(2026)
w = np.array([0.6, 0.4])
mu2 = np.array([0.08, 0.12])
sig2 = np.array([0.15, 0.25])
rho, df, N = 0.3, 5, 500_000
R = np.array([[1.0, rho], [rho, 1.0]])
L = np.linalg.cholesky(R)
z = rng.standard_normal((N, 2)) @ L.T
chi = rng.chisquare(df, N)
t = z / np.sqrt(chi / df)[:, None]
r = mu2 + sig2 * t / np.sqrt(df / (df - 2))
rp = np.maximum(r @ w, -1.0)
cap = 1000.0
pnl = cap * rp
mup = w @ mu2
sigp = np.sqrt(w @ np.diag(sig2**2) @ w + 2 * w[0] * w[1] * rho * sig2[0] * sig2[1])
# ================= 右图:收敛过程 =================
rng2 = np.random.default_rng(2026)
p, c, s, Mu, Sig = 12.0, 6.0, 2.0, 100.0, 20.0
Q = 105.07
D = rng2.normal(Mu, Sig, 200_000)
g = p * np.minimum(Q, D) + s * np.maximum(Q - D, 0) - c * Q
k = np.arange(1, len(g) + 1)
run = np.cumsum(g) / k
se = g.std(ddof=1) / np.sqrt(k)
start = 20
fig, ax = plt.subplots(1, 2, figsize=(13, 5))
# ---- 左:损益直方图(对数纵轴看清尾部)----
ax[0].hist(pnl, bins=200, range=(-1000, 900), density=True,
color='#4C72B0', alpha=0.75, label='蒙特卡洛模拟')
xs = np.linspace(-1000, 900, 800)
ax[0].plot(xs, norm.pdf(xs, mup * cap, sigp * cap),
color='#DD8452', lw=2, ls='--', label='正态假设')
var95 = -np.percentile(rp, 5) * cap
cvar95 = -rp[rp <= np.percentile(rp, 5)].mean() * cap
ax[0].axvline(-var95, color='#C44E52', lw=2, label=f'VaR 95% = {var95:.0f} 万')
ax[0].axvline(-cvar95, color='#55A868', lw=2, ls=':', label=f'CVaR 95% = {cvar95:.0f} 万')
ax[0].set_yscale('log')
ax[0].set_ylim(1e-5, 6e-3)
ax[0].yaxis.set_major_formatter(FuncFormatter(lambda v, pos: f'1e{int(round(np.log10(v)))}'))
ax[0].set_xlabel('年度损益(万元)')
ax[0].set_ylabel('概率密度(对数)')
ax[0].set_title('投资组合损益分布:肥尾与 VaR / CVaR')
ax[0].legend(fontsize=9, loc='upper right')
ax[0].grid(alpha=0.3, which='both')
# ---- 右:样本均值的收敛过程 ----
ax[1].fill_between(k[start:], (run - 1.96 * se)[start:], (run + 1.96 * se)[start:],
color='#4C72B0', alpha=0.25, label='95% 置信带')
ax[1].plot(k[start:], run[start:], color='#4C72B0', lw=1.3, label='累计均值')
ax[1].axhline(522.73, color='#C44E52', lw=1.5, ls='--', label='解析解 522.73')
ax[1].set_xscale('log')
ax[1].set_xlim(start, 2e5)
ax[1].set_xlabel('样本数 n(对数轴)')
ax[1].set_ylabel('期望利润估计')
ax[1].set_title('大数定律:样本越多,估计越稳(误差 ∝ 1/√n)')
ax[1].legend(fontsize=9, loc='upper right')
ax[1].grid(alpha=0.3, which='both')
plt.tight_layout()
plt.savefig('10-蒙特卡洛结果图.png', dpi=150, bbox_inches='tight')
plt.show()

左图读法:
-
纵轴取对数 ,否则尾部会被主峰压得看不见;对数坐标下,蓝色(模拟)在两侧明显高于橙色(正态)------这就是厚尾;
-
中间的蓝色主峰比橙色更尖------"尖峰 + 薄肩 + 厚尾"是 t 分布的三件套;
-
两条竖线分别是 95% VaR(143 万)和 CVaR(246 万):VaR 只是门槛,CVaR 才是门槛之后的平均深度,两者差了 100 万,说明"越过门槛之后跌得很陡"。
右图读法:
-
累计均值从剧烈跳动逐步收敛到解析解 522.73;
-
置信带随 n n n 增大而收窄,在对数横轴上呈走廊状收束 ------宽度与 1 / n 1/\sqrt{n} 1/n 成正比,样本每 ×10,带宽缩到约 1/3;
-
这是"大数定律长什么样"最直观的一张图,可以直接放进数模论文的"算法稳定性"部分。
七、模型评价
优点:
- 几乎万能:只要能把问题写成"输入随机 → 输出确定"的函数,就能模拟;对模型形式没有解析要求;
- 误差可量化:标准误、置信区间随手可得,结果的可靠性是"算出来"的,不是"感觉";
- 无维度灾难:收敛阶与维度无关,高维问题是它相对网格法的绝对优势;
- 一次模拟、多角度解读:均值、分位数、概率、最坏情形都能从同一批样本里读出来;
- 天然可并行:样本之间互不依赖,分批跑再合并,轻松利用多核。
局限:
- 收敛慢 : O ( n − 1 / 2 ) O(n^{-1/2}) O(n−1/2),想要 10 倍精度要 100 倍样本;极端概率事件的方差更是惊人;
- 强依赖分布假设:分布错了,结果全错------而"分布假设"往往是模型里最脆弱的一环;
- 结果带随机性:不固定种子、不报误差,论文结果无法复现,这是审稿人最爱挑的毛病;
- 给不出结构:它只告诉你"答案是多少",不告诉你"为什么是这个",难以做机理分析;
- 稀有事件难估 :概率 10 − 6 10^{-6} 10−6 的事件,直接抽样要上亿次才能见到几回。
常见问题:
Q1:蒙特卡洛和数值积分(比如梯形法)有什么区别?
数值积分是确定性的 :把区间切成网格,用求积公式加权求和,没有随机性,误差是 O ( h 2 ) O(h^2) O(h2)(一维)。蒙特卡洛是随机性的 :用随机点估计积分,误差是 O ( n − 1 / 2 ) O(n^{-1/2}) O(n−1/2)。一维时数值积分碾压蒙特卡洛;但维度一高,网格点数指数爆炸,蒙特卡洛的"与维度无关"就反超了。维度是选择方法的第一判据 : d ≤ 3 d\le3 d≤3 用数值积分, d d d 高或积分区域形状怪异,用蒙特卡洛。
Q2:为什么误差是 1 / n 1/\sqrt{n} 1/n ?能不能更快?
1 / n 1/\sqrt{n} 1/n 来自中心极限定理------样本均值的方差是 σ 2 / n \sigma^2/n σ2/n,开根号就是 σ / n \sigma/\sqrt{n} σ/n 。这是"独立抽样"的极限,不能靠"多抽点"突破。要更快只有两条路:降低方差 (对偶变量、重要性采样、控制变量,相当于减小 σ \sigma σ)或改变抽样方式 (拟蒙特卡洛用低差异序列,把阶数改善到接近 O ( ( log n ) d / n ) O((\log n)^d/n) O((logn)d/n))。注意: 1 / n 1/\sqrt{n} 1/n 的普适性也是优点------它不要求被积函数光滑,函数再"丑"也是这个速度。
Q3:样本量到底取多少?
三步:先用小样本(1 万)试跑,估出 σ ^ g \hat\sigma_g σ^g;再用 n ≈ ( 1.96 σ ^ g / ε ) 2 n\approx(1.96\hat\sigma_g/\varepsilon)^2 n≈(1.96σ^g/ε)2 反解;最后跑正式模拟并核对标准误是否达到目标。不要一上来就设 100 万------先花 1 秒试跑,可能发现 5 万就够了。
Q4:每次跑结果都不一样,论文里怎么写?
三件事:固定种子 (default_rng(2026))、报告区间 ("522.91 ± 0.83"而不是"522.91")、必要时重复(换 5 个种子各跑一次,报告均值和标准差,证明结果稳定)。审稿人看到"±"和"种子",就知道你懂这个方法的脾气。
Q5:VaR 和 CVaR 有什么区别?为什么不只用 VaR?
VaR 是分位数(门槛),CVaR 是超过门槛后的条件均值(坑的深度)。VaR 有三个毛病:不满足次可加性 (两个组合合并后 VaR 可能反而变大,违背分散化直觉)、看不到尾部形状 (VaR 之后的损失可能深不见底)、不便于优化 (分位数优化是非凸的)。CVaR 满足一致性风险度量的全部公理,且是凸的、可优化,因此现代风险管理更偏好 CVaR。报告里最好两个都给:VaR 给监管口径,CVaR 给决策口径。
Q6:分布假设错了怎么办?
三个补救:(1)用经验分布 ------直接用历史数据的样本做有放回抽样(bootstrap),不假设任何参数形式;(2)做敏感性分析 ------把自由度、相关系数、波动率各扰动 ±20%,看 VaR 变化多大,变化剧烈就说明模型不稳;(3)尾部专门建模 ------对极端部分用极值理论(EVT)拟合广义帕累托分布,而不是让一个全局分布硬扛。数模论文里,敏感性分析这一节几乎必写。
八、AI 视角:采样,是现代 AI 的通用语言
蒙特卡洛看起来是"笨办法",但它恰好是现代 AI 的地基。这一节把伏笔接上。
8.1 训练目标本身就是"蒙特卡洛估计"
所有监督学习的损失函数,都是某个期望:
J ( θ ) = E ( x , y ) ∼ p data ℓ ( f θ ( x ) , y ) J(\theta)=\mathbb{E}{(x,y)\sim p{\text{data}}}\big\\ell(f_\\theta(x),y)\\big J(θ)=E(x,y)∼pdataℓ(fθ(x),y)
真实期望算不出来(不知道 p data p_{\text{data}} pdata),实践中的做法是用 mini-batch 平均去估计:
J ^ = 1 B ∑ i = 1 B ℓ ( f θ ( x i ) , y i ) \hat J=\frac{1}{B}\sum_{i=1}^{B}\ell(f_\theta(x_i),y_i) J^=B1i=1∑Bℓ(fθ(xi),yi)
这就是蒙特卡洛------每个 batch 都是一次抽样估计。随机梯度下降之所以"随机",正是因为它在用采样代替积分。本文讲的"标准误",在这里对应"batch 大小带来的梯度噪声":batch 越大,梯度越准,但每步越贵。
8.2 MCMC:当分布本身也未知
本文的蒙特卡洛是"分布已知,抽样求期望 "。但贝叶斯推断面对的是相反的问题:只知道后验的相对概率,不知道归一化常数,怎么从这个分布里抽样?
马尔可夫链蒙特卡洛(MCMC) 的答案是:构造一条马尔可夫链,让它的平稳分布恰好是目标分布。最经典的 Metropolis-Hastings 算法只有两步:
- 从当前点附近提议一个新点 x ′ x' x′;
- 以概率 min ( 1 , p ~ ( x ′ ) p ~ ( x ) ) \min\left(1,\frac{\tilde p(x')}{\tilde p(x)}\right) min(1,p~(x)p~(x′)) 接受它------新点相对概率更高就接受,更低就按比例偶尔接受(这里写的是提议分布对称时的简化形式;非对称提议还要再乘一个提议分布比值)。
跑足够多步后,链上的样本就近似服从目标分布。它不需要知道归一化常数(比值里约掉了),这正是它的威力所在。今天贝叶斯统计、主题模型(LDA)、系统发育树推断,背后都是 MCMC。
8.3 扩散模型:把"加噪"倒过来放
2020 年之后的生成式 AI 主角------扩散模型(DDPM、Stable Diffusion),本质上是蒙特卡洛思想的一次华丽升级。
前向过程把一张图逐步加噪,直到变成纯噪声:
x t = α ˉ t x 0 + 1 − α ˉ t ϵ , ϵ ∼ N ( 0 , I ) x_t=\sqrt{\bar\alpha_t}\,x_0+\sqrt{1-\bar\alpha_t}\,\epsilon,\qquad \epsilon\sim N(0,I) xt=αˉt x0+1−αˉt ϵ,ϵ∼N(0,I)
训练的目标是让网络学会"预测当初加进去的噪声":
min θ E x 0 , ϵ , t ∥ ϵ − ϵ θ ( x t , t ) ∥ 2 \min_\theta\ \mathbb{E}_{x_0,\epsilon,t}\Big\\big\\\|\\epsilon-\\epsilon_\\theta(x_t,t)\\big\\\|\^2\\Big θmin Ex0,ϵ,t ϵ−ϵθ(xt,t) 2
这个期望同样算不出来,用采样估计 ------每个训练步抽一张图、一个噪声、一个时刻,就是一次蒙特卡洛。反向生成 则是从纯噪声 x T ∼ N ( 0 , I ) x_T\sim N(0,I) xT∼N(0,I) 出发,迭代去噪:
x t − 1 = 1 α t ( x t − 1 − α t 1 − α ˉ t ϵ θ ( x t , t ) ) + σ t z x_{t-1}=\frac{1}{\sqrt{\alpha_t}}\left(x_t-\frac{1-\alpha_t}{\sqrt{1-\bar\alpha_t}}\epsilon_\theta(x_t,t)\right)+\sigma_t z xt−1=αt 1(xt−1−αˉt 1−αtϵθ(xt,t))+σtz
标准的 DDPM 采样每一步都会注入一点新噪声 z z z(DDIM 等加速采样器省掉了这一步,但"从噪声出发、逐步去噪"的骨架不变)------生成过程本身就是一条采样轨迹 。可以说:本文的"抽样求期望"是扩散模型的训练 ,本文的"从分布抽样"是扩散模型的生成。一个蒙特卡洛,撑起了整个生成式 AI。
8.4 强化学习与 AlphaGo:用模拟估计价值
强化学习里最原始的策略梯度算法 REINFORCE,梯度估计是:
∇ θ J = E τ ∼ π θ ∑ t ∇ θ log π θ ( a t ∣ s t ) ⋅ R ( τ ) \nabla_\theta J=\mathbb{E}{\tau\sim\pi\theta}\Big\\sum_t \\nabla_\\theta\\log\\pi_\\theta(a_t\|s_t)\\cdot R(\\tau)\\Big ∇θJ=Eτ∼πθt∑∇θlogπθ(at∣st)⋅R(τ)
期望里的 τ \tau τ 是一整条轨迹,只能采样估计------跑一次游戏,用这次的实际回报做估计。这就是最纯粹的蒙特卡洛。
AlphaGo 的 蒙特卡洛树搜索(MCTS) 更直接:对每个候选落子,模拟成千上万局随机对局(rollout),用胜率估计这个落子的价值,再决定往哪个分支深挖。AlphaZero 用神经网络替代了随机 rollout(相当于用"学到的先验"降低方差),但"靠模拟估计价值"的骨架没变。
8.5 不确定性量化:给预测配一个"误差棒"
本文用抽样给出 VaR 和置信区间;深度学习里有一模一样的需求:这个预测有多可靠?
-
MC Dropout:推理时保持 dropout 开启,同一张图前向 50 次,得到 50 个略有差异的预测,其分布就是不确定性的近似;
-
Deep Ensembles:训练多个模型,用预测的离散程度度量不确定性;
-
贝叶斯神经网络:对权重做后验采样,把"参数的不确定"传进预测。
它们和本文的 VaR 是同一个逻辑:从分布里抽样,再报告分位数。区别只在于"分布"是人工设定的(本文)还是网络学出来的(AI)。
| 本文的概念 | AI 里的对应 |
|---|---|
| 抽样估计期望 | mini-batch 损失、REINFORCE 回报估计 |
| 标准误 / 置信区间 | 训练曲线方差、预测区间、seed 波动 |
| 分位数(VaR) | 分位数回归、不确定性预警阈值 |
| 重要性采样 | off-policy 强化学习的重加权 |
| 方差缩减(控制变量) | REINFORCE with baseline、优势函数 |
| 样本量规划 | 数据缩放律(scaling law) |
九、小结
- 核心思想:积分 = 期望 = 平均数。三步走------定义输出量、从分布抽样、统计量汇总;
- 误差规律 : S E = σ g / n \mathrm{SE}=\sigma_g/\sqrt{n} SE=σg/n ,样本 ×100 误差 ÷10;收敛阶与维度无关,这是它相对网格法的杀手锏;
- 报童模型 :临界分位数 0.6 0.6 0.6 → 最优订货量 105.07,解析期望利润 522.73,蒙特卡洛给出 522.91 ± 0.83------先用有答案的问题验证方法;
- 投资组合:厚尾(t 分布)下 95% VaR 142.76 万、CVaR 245.81 万;99% 时 VaR 301.98 万、CVaR 428.41 万;
- 分位反转 :95% 时厚尾分布的 VaR 反而比正态小 ,99% 时才比正态大------只报一个分位会得出错误结论,风险报告要给 99% VaR + CVaR;
- 方差缩减 :对偶变量法把标准误从 0.422 降到 0.256,等效于 2.73 倍样本量,代价只是一行
1-u; - 工程规范 :固定种子、报告 ± 误差、先试跑估 σ g \sigma_g σg 再定 n n n、分位数单独给误差;
- AI 伏笔 :mini-batch 是蒙特卡洛、MCMC 是采样求分布、扩散模型是采样生成、REINFORCE/MCTS 是采样估价值、MC Dropout 是采样估不确定性------采样是现代 AI 的通用语言。
下一篇进入仿真类模型的另一半 :元胞自动机------当个体遵循极简规则,整体却涌现出复杂秩序时,如何用一格一格的局部更新,模拟森林火灾、交通流与传染病扩散。
📌 本文是专栏「数学建模 × AI:从经典模型到智能方法」的第 11 篇文章。
-
上一篇回顾 :逻辑回归与信用违约预测:从S曲线到分类器
-
下一篇预告 :元胞自动机:从森林火灾到交通流。
👉 点击订阅专栏,第一时间收到更新通知!**
如果你在阅读过程中有任何疑问,欢迎在评论区留言交流。😊