You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python手动计算Sobol一阶敏感性指数遇异常,求指导

正确计算一阶Sobol敏感性指数的方法

你的计算出现结果大于1的问题,核心原因是采样设计不符合Sobol指数的要求,直接用普通分组均值计算的方式不适用,以下是正确的实现逻辑和代码:

问题根源

一阶Sobol指数的公式是 $S_i = \frac{Var(E[Y|X_i])}{Var(Y)}$,但这个公式的前提是样本是通过Sobol方法特有的正交采样生成的——需要两组独立的采样矩阵,而非任意分组的样本。普通分组采样会因为参数间的相关性、采样重叠等问题,导致$Var(E[Y|X_i])$超过$Var(Y)$,最终指数大于1。

正确计算步骤

Sobol指数的标准计算依赖三组输出:

  1. $Y_A$:基于采样矩阵$A$的模型输出
  2. $Y_B$:基于与$A$独立的采样矩阵$B$的模型输出
  3. $Y_{AB_i}$:将$A$的第$i$列替换为$B$的第$i$列后,得到的矩阵$AB_i$对应的模型输出

一阶指数的实用计算公式为:
$$S_i = \frac{E[Y_A \cdot Y_{AB_i}] - (E[Y])^2}{Var(Y)}$$

Python实现示例

1. 生成符合要求的采样矩阵

使用scipy.stats.qmc生成Sobol采样:

import numpy as np
from scipy.stats import qmc

# 参数维度D,样本量N(建议取2的幂次)
D = 3
N = 1024

# 生成两组独立的采样矩阵A和B(归一化到[0,1]区间)
sampler = qmc.Sobol(d=D, scramble=True)
A = sampler.random(n=N)
B = sampler.random(n=N)

# 生成每个参数对应的ABi矩阵
AB_list = []
for i in range(D):
    ABi = A.copy()
    ABi[:, i] = B[:, i]
    AB_list.append(ABi)

2. 运行模型获取输出

替换为你的实际模型调用:

# 模拟模型输出(示例:简单线性模型)
def run_model(params):
    return params[:,0] + 2*params[:,1] + 3*params[:,2] + np.random.normal(0, 0.1, size=params.shape[0])

Y_A = run_model(A)
Y_AB = [run_model(abi) for abi in AB_list]

3. 计算一阶Sobol指数

mu = np.mean(Y_A)
var_y = np.var(Y_A, ddof=1)  # 使用样本方差(自由度为1)

S1 = []
for y_ab in Y_AB:
    cov_term = np.mean(Y_A * y_ab) - mu**2
    s_i = cov_term / var_y
    S1.append(s_i)

print("一阶Sobol指数:", S1)

关键注意事项

  • 样本量必须取2的幂次(如1024、2048),保证Sobol采样的正交性。
  • 必须通过独立的A、B矩阵生成ABi,不能用普通分组采样替代。
  • 计算方差时用ddof=1的样本方差,避免总体方差带来的偏差。

内容的提问来源于stack exchange,提问作者safa bousbih

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:37:23