ワンクリックで
sensitivity-analysis
灵敏度分析:参数扰动、单因素/多因素分析、Monte Carlo 模拟、龙卷风图/蛛网图。触发词: 灵敏度分析、参数敏感性、sensitivity analysis、Monte Carlo、鲁棒性测试、参数扰动。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
灵敏度分析:参数扰动、单因素/多因素分析、Monte Carlo 模拟、龙卷风图/蛛网图。触发词: 灵敏度分析、参数敏感性、sensitivity analysis、Monte Carlo、鲁棒性测试、参数扰动。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
数据清洗、EDA、缺失值处理、异常值检测、相关性分析。触发词: 数据预处理、数据清洗、EDA、缺失值、异常值、data preprocessing、数据探索。
模型验证:交叉验证、留出法、残差分析、与已知解对比、假设检验。触发词: 模型验证、交叉验证、残差分析、model validation、留出法、误差分析、假设检验。
多子问题拆解与依赖分析。触发词: 子问题拆解、拆题、problem decomposition、依赖关系、求解顺序、时间分配、并行安排。
自动多轮评审优化循环。通过 Codex MCP 反复评审→修改→重新评审,直到达标或达到最大轮数。当用户说'自动优化循环'、'auto optimize'、'评审到通过'时使用。
Autonomously improve a generated paper via GPT-5.4 xhigh review → implement fixes → recompile, for 2 rounds. Use when user says "改论文", "improve paper", "论文润色循环", "auto improve", or wants to iteratively polish a generated paper.
数模竞赛全流程流水线:赛题分析 → 建模方案 → 代码求解 → 自动优化 → 论文撰写。当用户说'全流程'、'full pipeline'、'从赛题到论文'、'一键建模'时使用。
| name | sensitivity-analysis |
| description | 灵敏度分析:参数扰动、单因素/多因素分析、Monte Carlo 模拟、龙卷风图/蛛网图。触发词: 灵敏度分析、参数敏感性、sensitivity analysis、Monte Carlo、鲁棒性测试、参数扰动。 |
| argument-hint | ["model-file-or-parameter-list"] |
| allowed-tools | Bash(*), Read, Write, Edit, Grep, Glob, Agent, mcp__codex__codex, mcp__codex__codex-reply |
执行描述: $ARGUMENTS
SENSITIVITY_ANALYSIS_REPORT.md — 主输出文件,供 paper-write、model-review 使用。figures/sensitivity/ — 灵敏度图表存放目录。artifacts/ — 中间结构化文件存放目录。0.20 — 默认参数扰动幅度为基准值的 +/-20%。11 — 单因素分析默认取 11 个等距点(含基准值)。15 — 超过 15 个参数时先做初筛(Morris 方法或相关性排序)。10000 — Monte Carlo 模拟默认采样次数。1000 — 采样次数不得低于 1000。0.95 — 置信区间默认 95%。0.05 — 灵敏度指数超过 0.05 才视为"敏感参数"。gpt-5.4 — Codex MCP 交叉验证模型。high — 灵敏度分析验证使用高推理强度。30 — 单次灵敏度分析的计算时间上限。Input: $ARGUMENTS、已有模型文件和求解结果。
Output: artifacts/sensitivity_scope.json(参数列表与基准值)。
$ARGUMENTS 是文件路径,读取模型代码或参数文件。MODEL_REPORT.md、SOLVE_PLAN.md、FINAL_PROPOSAL.mdscripts/、src/ 目录中的模型实现代码results/ 目录中的求解结果MAX_PARAMETERS),使用 Morris 筛选法或专家判断先缩减范围。import json
from pathlib import Path
import re
def extract_parameters_from_code(code_path: str) -> list:
"""Extract tunable parameters from Python model code."""
code = Path(code_path).read_text(encoding="utf-8")
params = []
# Match common parameter assignment patterns
patterns = [
r"(\w+)\s*=\s*([\d.eE+-]+)\s*#\s*(.+)", # x = 0.5 # description
r"(\w+)\s*=\s*([\d.eE+-]+)\s*$", # x = 0.5
r"params\[.(\w+).\]\s*=\s*([\d.eE+-]+)", # params["x"] = 0.5
]
for pattern in patterns:
for match in re.finditer(pattern, code, re.MULTILINE):
groups = match.groups()
name = groups[0]
value = float(groups[1])
desc = groups[2] if len(groups) > 2 else ""
params.append({
"name": name,
"baseline": value,
"description": desc.strip(),
"range_low": value * 0.8,
"range_high": value * 1.2,
})
return params
# Save scope
Path("artifacts").mkdir(exist_ok=True)
# params = extract_parameters_from_code("scripts/model.py")
# Path("artifacts/sensitivity_scope.json").write_text(
# json.dumps(params, ensure_ascii=False, indent=2), encoding="utf-8"
# )
Input: 参数列表、基准值、模型求解函数。
Output: artifacts/oat_results.json、龙卷风图。
[基准值 * (1 - PERTURBATION_RANGE), 基准值 * (1 + PERTURBATION_RANGE)] 范围内取 PERTURBATION_STEPS 个等距点。S_i = (max(Y) - min(Y)) / Y_baseline。SIGNIFICANCE_THRESHOLD 的参数标记为"敏感参数"。import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def one_at_a_time(model_func, params: list, perturbation: float = 0.20, steps: int = 11):
"""Run OAT sensitivity analysis."""
baseline_values = {p["name"]: p["baseline"] for p in params}
y_baseline = model_func(**baseline_values)
results = {}
for p in params:
name = p["name"]
low = p["baseline"] * (1 - perturbation)
high = p["baseline"] * (1 + perturbation)
test_values = np.linspace(low, high, steps)
y_values = []
for v in test_values:
trial = baseline_values.copy()
trial[name] = v
y_values.append(model_func(**trial))
y_arr = np.array(y_values)
sensitivity_index = (y_arr.max() - y_arr.min()) / abs(y_baseline) if y_baseline != 0 else float("inf")
results[name] = {
"test_values": test_values.tolist(),
"y_values": [float(y) for y in y_arr],
"sensitivity_index": round(float(sensitivity_index), 6),
"y_baseline": float(y_baseline),
"monotonic": bool(np.all(np.diff(y_arr) >= 0) or np.all(np.diff(y_arr) <= 0)),
}
return results
def plot_tornado(oat_results: dict, fig_path: str = "figures/sensitivity/tornado.png"):
"""Generate tornado chart from OAT results."""
sorted_params = sorted(oat_results.items(), key=lambda x: x[1]["sensitivity_index"])
names = [k for k, _ in sorted_params]
low_deltas = []
high_deltas = []
baseline = list(oat_results.values())[0]["y_baseline"]
for name, res in sorted_params:
y_vals = res["y_values"]
low_deltas.append(min(y_vals) - baseline)
high_deltas.append(max(y_vals) - baseline)
fig, ax = plt.subplots(figsize=(10, max(4, len(names) * 0.5)))
y_pos = range(len(names))
ax.barh(y_pos, high_deltas, left=0, color="#2196F3", alpha=0.8, label="Increase")
ax.barh(y_pos, low_deltas, left=0, color="#FF5722", alpha=0.8, label="Decrease")
ax.set_yticks(y_pos)
ax.set_yticklabels(names)
ax.axvline(x=0, color="black", linewidth=0.8)
ax.set_xlabel("Change in Objective Function")
ax.set_title("Tornado Chart — Parameter Sensitivity")
ax.legend()
fig.tight_layout()
Path(fig_path).parent.mkdir(parents=True, exist_ok=True)
fig.savefig(fig_path, dpi=150)
plt.close(fig)
Input: Phase 2 识别出的敏感参数、模型求解函数。
Output: artifacts/multi_factor_results.json、交互效应热力图。
MAX_COMPUTE_MINUTES),降低采样数或减少参数。from scipy.stats import qmc
def latin_hypercube_sample(params: list, n_samples: int = 1000) -> np.ndarray:
"""Generate LHS samples for multi-factor analysis."""
n_params = len(params)
sampler = qmc.LatinHypercube(d=n_params)
samples_unit = sampler.random(n=n_samples)
lower = np.array([p["range_low"] for p in params])
upper = np.array([p["range_high"] for p in params])
samples = qmc.scale(samples_unit, lower, upper)
return samples
def compute_sobol_indices(model_func, params: list, n_samples: int = 1024):
"""Compute first-order and total Sobol indices using Saltelli scheme."""
from SALib.sample import saltelli
from SALib.analyze import sobol as sobol_analyze
problem = {
"num_vars": len(params),
"names": [p["name"] for p in params],
"bounds": [[p["range_low"], p["range_high"]] for p in params],
}
X = saltelli.sample(problem, n_samples)
Y = np.array([model_func(**dict(zip(problem["names"], x))) for x in X])
Si = sobol_analyze.analyze(problem, Y)
return {
"S1": dict(zip(problem["names"], Si["S1"].tolist())),
"ST": dict(zip(problem["names"], Si["ST"].tolist())),
"S2": Si.get("S2", None),
}
Input: 参数分布假设、模型求解函数。
Output: artifacts/monte_carlo_results.json、目标函数分布图。
MONTE_CARLO_SAMPLES 次随机采样。CONFIDENCE_LEVEL 置信区间的上下界。def monte_carlo_simulation(
model_func,
param_distributions: dict,
n_samples: int = 10000,
confidence: float = 0.95,
) -> dict:
"""
Run Monte Carlo simulation.
param_distributions: {"param_name": {"dist": "normal", "mean": 5.0, "std": 0.5}, ...}
"""
samples = {}
for name, dist_info in param_distributions.items():
dist_type = dist_info["dist"]
if dist_type == "normal":
samples[name] = np.random.normal(dist_info["mean"], dist_info["std"], n_samples)
elif dist_type == "uniform":
samples[name] = np.random.uniform(dist_info["low"], dist_info["high"], n_samples)
elif dist_type == "triangular":
samples[name] = np.random.triangular(dist_info["left"], dist_info["mode"], dist_info["right"], n_samples)
elif dist_type == "lognormal":
samples[name] = np.random.lognormal(dist_info["mean"], dist_info["sigma"], n_samples)
results = []
for i in range(n_samples):
kwargs = {name: float(samples[name][i]) for name in samples}
results.append(model_func(**kwargs))
results = np.array(results)
alpha = 1 - confidence
ci_low = np.percentile(results, 100 * alpha / 2)
ci_high = np.percentile(results, 100 * (1 - alpha / 2))
return {
"n_samples": n_samples,
"mean": float(np.mean(results)),
"std": float(np.std(results)),
"median": float(np.median(results)),
"ci_low": float(ci_low),
"ci_high": float(ci_high),
"ci_level": confidence,
"min": float(np.min(results)),
"max": float(np.max(results)),
"cv": float(np.std(results) / np.mean(results)) if np.mean(results) != 0 else float("inf"),
}
def plot_mc_distribution(results: np.ndarray, fig_path: str = "figures/sensitivity/mc_distribution.png"):
"""Plot Monte Carlo result distribution."""
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Histogram + KDE
axes[0].hist(results, bins=50, density=True, alpha=0.7, color="#2196F3", edgecolor="white")
from scipy.stats import gaussian_kde
kde = gaussian_kde(results)
x_range = np.linspace(results.min(), results.max(), 200)
axes[0].plot(x_range, kde(x_range), color="#FF5722", linewidth=2)
axes[0].set_title("Monte Carlo Distribution (PDF)")
axes[0].set_xlabel("Objective Function Value")
axes[0].set_ylabel("Density")
# CDF
sorted_results = np.sort(results)
cdf = np.arange(1, len(sorted_results) + 1) / len(sorted_results)
axes[1].plot(sorted_results, cdf, color="#4CAF50", linewidth=2)
axes[1].set_title("Cumulative Distribution (CDF)")
axes[1].set_xlabel("Objective Function Value")
axes[1].set_ylabel("Cumulative Probability")
axes[1].axhline(y=0.025, color="red", linestyle="--", alpha=0.5, label="2.5%/97.5%")
axes[1].axhline(y=0.975, color="red", linestyle="--", alpha=0.5)
axes[1].legend()
fig.tight_layout()
Path(fig_path).parent.mkdir(parents=True, exist_ok=True)
fig.savefig(fig_path, dpi=150)
plt.close(fig)
Input: OAT 结果、Monte Carlo 结果、模型上下文。 Output: 修订建议。
gpt-5.4 与 high 推理强度做独立审查。threadId,后续可追问具体参数的灵敏度解释。mcp__codex__codex:
model: gpt-5.4
config: {"model_reasoning_effort": "high"}
prompt: |
你是数学建模竞赛灵敏度分析专家,请审查以下分析结果。
模型概述:
[粘贴模型描述和目标函数]
参数灵敏度排名 (OAT):
[粘贴龙卷风图数据表]
Monte Carlo 结果:
[粘贴统计摘要:均值、标准差、置信区间]
请逐项回答:
1. 敏感参数排序是否符合物理/数学直觉?有无反常排序需要解释?
2. 参数扰动范围(+/-20%)是否合适?哪些参数应该用更大或更小的范围?
3. Monte Carlo 中的分布假设是否合理?有无更好的分布选择?
4. 置信区间宽度是否可接受?模型结论是否足够鲁棒?
5. 对论文写作有什么建议?哪些图表最能说明问题?
将最终结果写入 SENSITIVITY_ANALYSIS_REPORT.md。
Output files:
| 路径 | 必需 | 内容 | 说明 |
|---|---|---|---|
SENSITIVITY_ANALYSIS_REPORT.md | Yes | 主报告 | 提供给 paper-write 和 model-review |
figures/sensitivity/tornado.png | Yes | 龙卷风图 | 可直接用于论文 |
figures/sensitivity/spider.png | Recommended | 蛛网图 | 展示参数-输出关系 |
figures/sensitivity/mc_distribution.png | Recommended | MC 分布图 | 展示结果不确定性 |
figures/sensitivity/mc_cdf.png | Recommended | MC 累积分布 | 展示置信区间 |
figures/sensitivity/sobol_heatmap.png | Optional | Sobol 交互热力图 | 多因素分析时生成 |
artifacts/sensitivity_scope.json | Recommended | 参数范围定义 | 机器可读 |
artifacts/oat_results.json | Recommended | OAT 分析结果 | 支持复查 |
artifacts/monte_carlo_results.json | Recommended | MC 模拟结果 | 支持复查 |
artifacts/multi_factor_results.json | Optional | 多因素分析结果 | Sobol 指数 |
cat << 'EOF' > file) to write in chunks. Do NOT ask the user for permission — just do it silently.MONTE_CARLO_MIN_SAMPLES (1000)。Open Questions,暴露灵敏度分析的局限性。model-creator
-> solve-plan
-> run-solver
-> analyze-results
-> sensitivity-analysis
-> model-validation
-> paper-write
sensitivity-analysis
-> paper-figure (提供灵敏度图表)
-> paper-write (提供灵敏度分析章节素材)
-> model-review (评委常问灵敏度)