从头解析 Sobol 全局敏感性分析

Jan 15, 2024

面对一个模型时,你在做什么?

调参数。翻文献。看哪个数字不确定,然后想办法让它确定一点。道理上都懂——模型是对现实的压缩,参数是对这个压缩过程的描述。一个有十个参数的模型,意味着有十个地方可能出错、十种不确定性同时存在。

问题在于:当模型跑出来的结果和你预期不符时,你该怀疑哪个参数?

拍脑袋是一种方法。文献里查是另一种。但直觉会骗人,文献也不一定靠谱——有些参数是"纸老虎",看起来重要其实无关紧要;有些参数是"幕后玩家",自己不动声色地操纵整个系统。

这就是 Sobol’ 敏感性分析要回答的问题——不是"这个参数敏感吗",而是"在参数的整个运动范围内,谁在决定输出的命运"。

从局部到全局

最直接的想法是这样的:找一个基准点,把每个参数稍微动一动,看看输出变多少。变幅大的就是"敏感"的参数,变幅小的就是"不敏感"的。实际操作中常见做法是固定所有参数在某个基准值上,然后逐个扰动——比如每个参数调高 1%,看输出变化多少。

这就是局部敏感性分析(Local Sensitivity Analysis,Local SA)。对线性模型来说,这个方法够用——导数在哪里都一样,在一点上试过就知道全局。

但现实中的模型大多是非线性的。参数 A 在基准点附近可能无关紧要,换一个区域就成了主导因素;参数 B 恰恰相反。局部 SA 给你的是一张从锁孔里拍的全景照片——理论上是全景,实际上你只看到了一条缝。

全局敏感性分析(Global Sensitivity Analysis,Global SA)的思路完全不同。它不再执着于"在这个点谁敏感"这个局部问题,而是把目光投向参数的整个运动范围——谁的波动能掀起最大的风浪?

具体来说,假设模型为

$$Y = \mathcal{M}(X_1, X_2, \ldots, X_m)$$

其中 $X_i \sim F_i$ 是相互独立的随机变量,分布 $F_i$ 反映了你对第 $i$ 个参数的不确定性认知。Sobol’ 方法要做的,是把 $\text{Var}(Y)$ 这个数字拆成一堆加起来等于它的分量,每个分量对应一组参数的贡献。

关键在于怎么拆。

ANOVA 分解:方差的乐高

Sobol’ 方法的数学基础是 ANOVA(Analysis of Variance)分解,也叫 Hoeffding–Sobol 分解。这个名字听起来吓人,直觉却很友好。

一个类比

想象你在做一道菜。最终的味道(输出 $Y$)取决于盐、糖、醋、酱油……每种调料(输入 $X_i$)。你每次做菜时各调料的用量都有一点随机波动,所以每次做出来的味道也略有不同。

现在你想知道:味道的变化,多大程度上是因为盐用量的波动?多大程度上是糖和醋的配合出了问题?

ANOVA 分解做的事情就是:把"味道的总波动"拆成"盐独自贡献的部分"、“糖独自贡献的部分”、“盐和糖交互贡献的部分”……一直拆到所有可能的组合。

数学形式

严格来说,Hoeffding–Sobol 分解说的是:任何一个平方可积函数 $f(X_1, \ldots, X_m)$ 都可以唯一地分解为

$$f(X) = f_0 + \sum_{i} f_i(X_i) + \sum_{i\lt j} f_{ij}(X_i, X_j) + \cdots + f_{1\ldots m}(X_1, \ldots, X_m)$$

其中每一项满足两个条件:

  1. 零均值:$\mathbb{E}[f_u(X_u)] = 0$ 对所有非空子集 $u \subseteq \{1,\ldots,m\}$ 成立
  2. 正交性:不同项之间相互正交,即 $\mathbb{E}[f_u \cdot f_v] = 0$ 当 $u \neq v$

$f_0 = \mathbb{E}[Y]$ 是常数项(输出的均值),$f_i(X_i)$ 是仅依赖 $X_i$ 的主效应,$f_{ij}(X_i, X_j)$ 是 $X_i$ 和 $X_j$ 的交互效应,以此类推。

正交性意味着什么?意味着方差可以直接相加:

$$\text{Var}(Y) = \sum_{i} V_i + \sum_{i\lt j} V_{ij} + \cdots + V_{12\ldots m}$$

其中 $V_u = \text{Var}(f_u(X_u))$。这就是"方差的乐高"——总方差被完美地拆成了互不重叠的方块。

各项怎么算

分解式里的每一项都有明确的构造方式。以一阶项为例:

$$f_i(X_i) = \mathbb{E}[Y \mid X_i] - \mathbb{E}[Y]$$

也就是说,先对除 $X_i$ 以外的所有变量取条件期望,得到 $X_i$ 的一个函数,再减去均值。这个操作的本质是:把 $Y$ 中与 $X_i$ 相关的信息提取出来。

二阶项类似:

$$f_{ij}(X_i, X_j) = \mathbb{E}[Y \mid X_i, X_j] - \mathbb{E}[Y \mid X_i] - \mathbb{E}[Y \mid X_j] + \mathbb{E}[Y]$$

先取联合条件期望,再把已经算过的一阶项减掉,剩下的就是纯粹的交互效应。高阶项依此类推,规律是:包含奇数个下标的项前面加负号,偶数个加正号。(这其实就是 Möbius 反演。)

对应的方差分量为:

$$V_i = \text{Var}\left(\mathbb{E}[Y \mid X_i]\right)$$$$V_{ij} = \text{Var}\left(\mathbb{E}[Y \mid X_i, X_j]\right) - V_i - V_j$$

Sobol’ 指数:归一化的贡献度

有了各方差分量,定义 Sobol’ 指数就是一件自然的事情——把每个分量除以总方差:

一阶 Sobol’ 指数(First-order index):

$$S_i = \frac{V_i}{\text{Var}(Y)} = \frac{\text{Var}\left(\mathbb{E}[Y \mid X_i]\right)}{\text{Var}(Y)}$$

$S_i$ 衡量的是 $X_i$ 单独对输出方差的贡献比例。如果 $S_i = 0.6$,意味着 $X_i$ 自己就能解释 60% 的输出波动。

二阶 Sobol’ 指数:

$$S_{ij} = \frac{V_{ij}}{\text{Var}(Y)}$$

衡量 $X_i$ 和 $X_j$ 的纯交互贡献——扣除各自的主效应之后,两者协同作用产生的额外方差。

总阶 Sobol’ 指数(Total-order index):

$$S_{Ti} = \frac{\mathbb{E}\left[\text{Var}(Y \mid X_{\sim i})\right]}{\text{Var}(Y)} = 1 - \frac{\text{Var}\left(\mathbb{E}[Y \mid X_{\sim i}]\right)}{\text{Var}(Y)}$$

这里 $X_{\sim i}$ 表示除 $X_i$ 以外的所有参数。$S_{Ti}$ 衡量的是 $X_i$ 的总贡献——包括它自己,加上它和所有其他参数的二阶交互、三阶交互、……一直到 $m$ 阶交互。

这三个指数之间的关系值得仔细品味:

指数 含义 包含的内容
$S_i$ 主效应 仅 $X_i$ 独自的贡献
$S_{Ti}$ 总效应 $X_i$ 的全部贡献(主效应 + 所有涉及 $X_i$ 的交互)
$S_{Ti} - S_i$ 交互效应 $X_i$ 与其他参数的交互贡献

三种典型情况:

最后一种情况尤其有价值——它告诉你什么不需要做,这在科研经费有限的世界里和知道什么需要做一样重要。

怎么算:Monte Carlo 与 Saltelli 采样器

理论漂亮,但 $f_i(X_i) = \mathbb{E}[Y \mid X_i] - \mathbb{E}[Y]$ 里面的条件期望怎么求?

如果模型 $\mathcal{M}$ 有解析表达式,某些简单情况下可以手算。但现实中 $\mathcal{M}$ 往往是一个 ODE 求解器、一个有限元模拟、或者一个 agent-based model——黑箱一个,给输入返回输出,别的一概不知。(跑一次半小时起步的那种。)

这时只能用 Monte Carlo(MC)估计。

一阶指数的估计量

先看 $S_i$ 的估计。我们需要估计两个量:$\text{Var}(\mathbb{E}[Y \mid X_i])$ 和 $\text{Var}(Y)$。

构造两组样本矩阵:

$$A = \begin{pmatrix} X_1^{(1)} & X_2^{(1)} & \cdots & X_m^{(1)} \\ X_1^{(2)} & X_2^{(2)} & \cdots & X_m^{(2)} \\ \vdots & \vdots & \ddots & \vdots \\ X_1^{(N)} & X_2^{(N)} & \cdots & X_m^{(N)} \end{pmatrix}, \quad B = \begin{pmatrix} X_1^{(N+1)} & X_2^{(N+1)} & \cdots & X_m^{(N+1)} \\ \vdots & \vdots & \ddots & \vdots \\ X_1^{(2N)} & X_2^{(2N)} & \cdots & X_m^{(2N)} \end{pmatrix}$$

$A$ 和 $B$ 的每一行都是从参数的联合分布中独立采样的。然后构造第 $i$ 个混合矩阵 $A_B^{(i)}$:取 $B$ 的第 $i$ 列替换 $A$ 的第 $i$ 列,其余不变。

$$A_B^{(i)} = \begin{pmatrix} X_1^{(1)} & \cdots & X_i^{(N+1)} & \cdots & X_m^{(1)} \\ X_1^{(2)} & \cdots & X_i^{(N+2)} & \cdots & X_m^{(2)} \\ \vdots & \ddots & \vdots & \ddots & \vdots \\ X_1^{(N)} & \cdots & X_i^{(2N)} & \cdots & X_m^{(N)} \end{pmatrix}$$

直观理解:$A_B^{(i)}$ 的第 $j$ 行和 $A$ 的第 $j$ 行只在第 $i$ 列不同。这意味着两行的差异完全来自 $X_i$ 的变化。

Saltelli 等人给出的估计量为:

一阶指数:

$$\hat{S}_i = \frac{\frac{1}{N}\sum_{j=1}^N Y^B_j \left(Y^i_j - Y^A_j\right)}{\frac{1}{N}\sum_{j=1}^N \left(Y^A_j\right)^2 - \left(\frac{1}{N}\sum_{j=1}^N Y^A_j\right)^2}$$

总阶指数:

$$\hat{S}_{Ti} = \frac{\frac{1}{N}\sum_{j=1}^N Y^A_j \left(Y^A_j - Y^i_j\right)}{\frac{1}{N}\sum_{j=1}^N \left(Y^A_j\right)^2 - \left(\frac{1}{N}\sum_{j=1}^N Y^A_j\right)^2}$$

其中 $Y^A_j = \mathcal{M}(A_j)$,$Y^B_j = \mathcal{M}(B_j)$,$Y^i_j = \mathcal{M}\!\left((A_B^{(i)})_j\right)$。

分子为什么是这个形式?关键在于两组矩阵之间"哪些列相同"。$B$ 和 $A_B^{(i)}$ 只在第 $i$ 列相同,其余都不同——这意味着它们的"差异中的协方差"恰好提取出 $\text{Var}(\mathbb{E}[Y \mid X_i])$,即一阶方差分量 $V_i$。同理,$A$ 和 $A_B^{(i)}$ 只在第 $i$ 列不同,它们的协方差对应 $\text{Var}(\mathbb{E}[Y \mid X_{\sim i}])$,由此可得总阶指数。

计算成本

标准的 Saltelli 方案使用 $(N, 2N)$ 设计:生成两组各 $N$ 个样本(共 $2N$ 个),然后对每个参数 $i$ 构造混合矩阵并评估模型。总的模型评估次数是 $N(m+2)$。

这就是为什么 Sobol’ 分析虽然理论上完美,实际应用中常常让人头疼。后面会提到一些缓解策略。

几何直觉:$L^2$ 空间中的投影

ANOVA 分解不只是代数操作,它有漂亮的几何解释。这有助于真正理解 Sobol’ 指数在做什么。

把所有平方可积函数 $f(X_1, \ldots, X_m)$ 看作一个希尔伯特空间 $L^2$,内积定义为 $\langle f, g \rangle = \mathbb{E}[fg]$。在这个空间里,条件期望 $\mathbb{E}[Y \mid X_i]$ 不是别的,正是 $Y$ 到"仅依赖于 $X_i$ 的函数子空间"上的正交投影

换句话说,在所有只含 $X_i$ 的函数中,$\mathbb{E}[Y \mid X_i]$ 是 $Y$ 的最优均方逼近:

$$\mathbb{E}[Y \mid X_i] = \arg\min_{g(X_i)} \mathbb{E}\left[(Y - g(X_i))^2\right]$$

残差 $Y - \mathbb{E}[Y \mid X_i]$ 与所有仅依赖 $X_i$ 的函数正交。这就是为什么 ANOVA 分解的各项之间两两正交——每一步投影都在找一个互补的方向。

从这个角度看,$S_i = \text{Var}(\mathbb{E}[Y \mid X_i]) / \text{Var}(Y)$ 就是投影能量的占比。你把 $Y$ 投影到 “$X_i$ 的方向” 上,投影的长度占总长度的比例就是 $X_i$ 的重要性。

高阶项同理。$\mathbb{E}[Y \mid X_i, X_j]$ 是 $Y$ 到"仅依赖于 $X_i, X_j$ 的函数子空间"的投影,减去两个一阶投影后,剩下的部分就是纯粹的交互方向。

这种几何视角不仅优雅,还直接催生了基于多项式混沌展开(Polynomial Chaos Expansion, PCE)的高效计算方法——PCE 本质上就是在特定的正交多项式基下做同样的投影展开,一旦系数确定了,Sobol’ 指数的计算只是系数平方和的比值,不需要额外的 MC 采样。

实际应用中的几个陷阱

样本量不够

MC 估计的方差收敛速度是 $O(N^{-1/2})$。要把估计精度提高一倍,样本量需要翻四倍。对于昂贵的模型,这很快就会触及预算上限。

经验法则:$N$ 至少应该取几百到几千。太少的话,估计出的 Sobol’ 指数本身就不稳定——你可能在两次运行中得到截然不同的排名。

负指数问题

理论上 $S_i \in [0, 1]$,但 MC 估计有时会产生负值或大于 1 的值。这是因为有限样本下的估计误差,尤其是当真实的 $S_i$ 接近 0 时——噪声很容易把它推到负区间。

看到负的 Sobol’ 指数不要慌。它的正确解读是:这个参数的贡献在统计上不显著异于零。不是数学错了,是样本不够。

参数独立性假设

整个推导建立在一个前提之上:$X_1, \ldots, X_m$ 相互独立

如果参数之间存在相关性(这在实际问题中很常见——比如两个物理参数共享同一个底层测量误差源),标准 Sobol’ 分解就不再成立。此时需要用推广的方法,如基于协方差分解的 Shapley 效应或基于独立变换的技巧。这些方法的计算复杂度和理论保证都不如标准 Sobol’ 干净利落。

计算成本的缓解

几种常见的策略:

  1. 多项式混沌展开(PCE):用少量样本训练一个 surrogate model,然后在 surrogate 上精确计算 Sobol’ 指数。适用于光滑模型。
  2. 随机梯度 / 导数辅助方法:如果模型可微,可以用梯度信息加速收敛。
  3. 分组(Grouping):如果某些参数天然属于同一类(比如同一批实验测得的),可以把它们当作一个超参数处理,减少维度。
  4. 稀疏网格积分(Sparse Grids):在某些正则性条件下比标准 MC 收敛更快。

没有银弹。选择哪种策略取决于模型的特性——是否光滑、是否可微、维度的诅咒有多严重。

我的观察

写到这里,想谈几个不一定正确但确实困扰过我的问题。(反正博客又不是 journal review,说错了大不了以后删掉。)

第一个问题是关于"重要性"这个词本身的模糊性。

Sobol’ 指数度量的是方差贡献。但方差真的是你关心的东西吗?如果你的 QoI(Quantity of Interest)是某种阈值行为——比如"感染人数是否超过医院容量"——那么方差可能是一个糟糕的代理指标。一个参数可能对方差的贡献很小,但它决定了系统是否跨越临界点。这时候 Sobol’ 指数可能会给你一种虚假的安全感。

这不是说 Sobol’ 方法不好。而是说任何工具都有其适用边界,把工具的输出等同于"真相"本身就是一种危险。

第二个问题关于模型校准和敏感性分析的顺序。

很多人习惯先校准模型(拟合参数),再做敏感性分析。但这两者的逻辑关系其实很微妙:敏感性分析告诉你哪些参数值得花力气去校准;而校准的结果又会改变参数的后验分布,进而改变敏感性分析的结论。这是一个鸡生蛋蛋生鸡的问题。

更诚实的做法可能是迭代:先用宽先验做一轮粗略的 SA → 根据结果确定校准优先级 → 校准后更新参数分布 → 再做一轮 SA。当然,时间和经费允许的话。

第三个问题——也是我觉得最有意思的一个——Sobol’ 指数揭示的"隐形参数"。

前面提到 $S_i$ 小但 $S_{Ti}$ 大的情况。这类参数在生物学模型中尤其常见。信号通路里的反馈回路、生态学里的种间相互作用、流行病学里的隐性传播链——很多关键的调控机制恰恰藏在高阶交互里。如果你只看一阶指数(很多人确实只看一阶,因为它最好解释),你会系统性地遗漏这些机制。

这让我想起统计里常说的"主效应不显著但交互效应显著"。在充满反馈和耦合的系统里,这可能不是例外,而是常态。

结尾

Sobol’ 方法本质上在做一件事:在一个由多个不确定来源驱动的系统中,追问每个来源到底该为结果的不可预测性承担多少责任。

它不会替你做决策,也不会告诉你哪个参数"真正重要"——那取决于你的科学问题和价值判断。它能做的是提供一个不依赖直觉的、可复现的、数学上干净的分解框架。在这个框架内,争论可以从"我觉得 A 重要"变成"$S_A = 0.62$ 而 $S_B = 0.03$,所以有限的实验资源应该优先分配给 A"。

后者至少是可以证伪的。

至于那些 $S_i$ 很小但 $S_{TI}$ 很大的参数——它们安静地待在交互的阴影里,等待被发现。或者继续被忽略。

这取决于你看不看得到。