全局敏感性分析
全局敏感性分析(global sensitivity analysis)在给定的输入范围、可行约束或概率分布下,研究各输入对模型输出变化的影响。它让输入在整个研究范围内变化,考察非线性和相互作用;局部敏感性分析则通常围绕一个指定基点作微小扰动。全局结论仍以所选模型、输入范围和输出指标为条件,并非与设定无关的普遍排名。[1]
输入范围与研究对象
先看 。若 、,将一个输入走完整个范围而固定另一个,输出变化分别是一百和十。虽然 前的系数更大,在这些范围下, 却能造成更大的全范围变化。
把两个输入归一化为 、 后,模型变成 ,二者都在零到一之间变化。范围信息进入了系数,比较才有统一基准。如果改换原始范围,排名可能改变。若还要比较输出方差的贡献,则必须另外说明输入在范围内怎样分布、是否相互依赖;范围本身不是概率分布。
同一个系统也可能有不同的输出目标。例如峰值温度与平均温度、总费用与超预算概率,可能由不同因素主导。开始计算前,应固定所分析的标量输出、单位、参数范围和约束;随机模拟还要说明重复运行或噪声处理方式。
一次改变一个输入的基本效应
考虑一个无单位的合成模型 项 表示一种相互作用:增加 的效果会随着 改变。固定 ,令 增加非零步长 ,定义基本效应 其中改变前后的点都须在允许范围内。对本模型逐项相减, 和 留下,故 。同理 。这已经说明只在一个基点计算,会漏掉背景输入变化带来的影响。
用两个短路径把计算写出来。步长取一;第一条路径先改变 ,第二条先改变 :
| 路径 | 点与输出 | 两次基本效应 |
|---|---|---|
| A | ||
| B |
每条路径每一步只改一个输入,但两条路径把其他输入放在不同背景下。四个角点足以复算全部数字。
Morris 筛选中的汇总量
Morris 方法在输入空间的多个基点安排逐项变化的轨迹,收集每个输入的基本效应,用较少模型计算筛选可能重要的因素。实际设计还包括网格、步长、随机轨迹和必要的轨迹选择。上面的两条路径只展示它的计算原理;两次效应不足以支持复杂模型的可靠排名。[2]
设某个输入取得 个基本效应 ,常用汇总量为 这里的 使用样本标准差约定。 保留方向,正负效应可能抵消; 先逐项取绝对值再平均,不能写成 。例如效应为 时, 而 。[3]
对手算模型,两输入取得的效应都是一和二。因此 较大的效应绝对值提示该输入值得保留;效应随基点变化,则提示非线性或相互作用。但 不把两者分开,也不是输出方差被某个输入“解释的百分比”。
非线性与相互作用的区分
主例的四角混合差分为 它比较了“先改变一个输入后的效果”与“未改变它时的效果”。若模型能写成 ,这四项会逐对抵消;主例留下的一正是乘积项的贡献。零混合差分只说明所选矩形上发生了抵消,不能单凭一次计算证明整个模型没有相互作用。
另一方面,一元函数 根本没有第二个输入。以 从零走到二分之一,再走到一,基本效应分别是 效应也发生变化,但来源只是单变量曲率。因而筛选图中较大的 只能提示进一步检查,不能直接宣布“发现交互”。
四角例子的 Python 实现
以下代码只实现本篇两输入、四角点的演示。输入是能接收两个实数的确定性函数,要求四角输出能转换为有限浮点数,效应与返回统计量也须能由浮点数表示。返回四角值,以及两输入的效应、均值、绝对均值和样本标准差;无法表示的中间效应或结果会报错。不改写外部输入,共调用模型四次;缓存共同端点避免两条路径重复计算。四角取样不能检出只在内部发生的变化,例如 在四角全为零。
import math
from statistics import fmean, stdev
def corner_screen(model):
values = {}
for s, t in ((0, 0), (1, 0), (0, 1), (1, 1)):
value = float(model(s, t))
if not math.isfinite(value):
raise ValueError("corner outputs must be finite")
values[s, t] = value
effects = {
"s": [values[1, 0] - values[0, 0],
values[1, 1] - values[0, 1]],
"t": [values[0, 1] - values[0, 0],
values[1, 1] - values[1, 0]],
}
summary = {}
for name, ee in effects.items():
if not all(math.isfinite(v) for v in ee):
raise ValueError("elementary effect exceeds float range")
scale = max(abs(v) for v in ee)
normalized = [v / scale for v in ee] if scale else [0.0, 0.0]
mu = scale * fmean(normalized)
mu_star = scale * fmean(abs(v) for v in normalized)
sigma = scale * stdev(normalized)
if not all(math.isfinite(v) for v in (mu, mu_star, sigma)):
raise ValueError("summary exceeds float range")
summary[name] = {
"effects": ee,
"mu": mu,
"mu_star": mu_star,
"sigma": sigma,
}
return values, summary
corners, result = corner_screen(lambda s, t: s + t + s * t)
print(corners)
print(result)
对这里固定的两维设计,除模型内部成本外,时间和额外空间均为 。更一般的 输入、 条逐项轨迹,在不复用点时需要 次模型运行,而不是 :每条轨迹还需要一个起点。模型很昂贵时,应先做适量重复和收敛检查,再决定是否精细估计。
从筛选走向概率贡献
筛选的作用是缩小后续研究范围。若需要“在给定不确定性下,某输入单独及联合贡献了多少输出方差”,可以采用索博尔指数;它需要平方可积的输出,经典方差分解还以独立输入为前提。若关心尾部风险或阈值跨越,仅看整体方差也可能不合目标。[1]
存在相关性或物理约束时,逐项改变输入可能产生不允许的组合。例如各成分占比总和为一,单独增加一项而不调整其他项就离开了可行域。此时应明确可行参数化、联合分布或分组变化规则,不能把不可实现的点当作系统预测。若模拟本身有随机噪声,还应区分输入变化的效应与重复运行的波动。
作为变式,将主例改为 ,两输入的四角基本效应都为一,故 、,混合差分也为零。这能检验程序是否把加性模型与原来的乘积相互作用区别开。
参考文献
- ↑ 1.0 1.1 European Commission, Joint Research Centre,Methods,Global Sensitivity Analysis、Screening Designs 部分。
- ↑ M. D. Morris,1991,Factorial Sampling Plans for Preliminary Computational Experiments,Technometrics,33(2):161—174,doi:10.1080/00401706.1991.10484804。方法归属与设计说明另参见 SALib 官方文档。
- ↑ SALib,SALib.analyze.morris.analyze,关于
mu、mu_star、sigma的说明及所引 Morris、Campolongo 等文献。这里采用文档方法说明中的“绝对效应的均值”定义。