Master Sensitivity Analysis: Theory, Methods, and Python SALib Walkthrough
This article introduces sensitivity analysis, explains its key concepts, indices, and selection criteria, then details various methods—including OAT, derivative‑based, regression, variance‑based, FAST, Morris, and Sobol—followed by practical Python examples using the SALib library with code and visualizations.
Sensitivity Analysis Overview
Sensitivity analysis (also called sensitivity analysis) quantifies how changes in one or more inputs affect the output. It evaluates the impact of each input on the output to support decision‑making. If a small change in an input causes a large change in the output, the output is said to be sensitive to that input; the opposite indicates insensitivity.
Each input’s sensitivity is usually expressed by a numerical sensitivity index. Common forms include:
First‑order index: measures the contribution of a single input to the output variance.
Second‑order index: measures the contribution of the interaction between two inputs to the output variance.
Total‑order index: measures the overall contribution of an input, including its first‑order effect and all higher‑order interactions.
Choosing a Sensitivity‑Analysis Method
Factors influencing the choice of method typically include:
Computational cost
Relationships among inputs
Non‑linear effects
Model interactions
Sensitivity‑Analysis Process
Quantify input uncertainties (e.g., ranges, probability distributions).
Identify the model output(s) to be analysed.
Run the model multiple times using a designed set of experiments.
Compute sensitivity metrics from the model outputs.
Common Sensitivity‑Analysis Methods
One‑at‑a‑time (OAT) analysis: change one factor at a time while keeping others fixed; simple but cannot capture input coupling.
Derivative‑based local methods: require partial derivatives of the output with respect to inputs; explore only small perturbations, usually one variable at a time.
Regression analysis: fit a linear regression to model responses and use standardized regression coefficients as sensitivity measures; works best for linear models.
Variance‑based methods: decompose output variance into contributions from individual inputs and their combinations; handle non‑linearity and interactions, often using Monte‑Carlo sampling.
Screening methods: identify which inputs have a significant impact on high‑dimensional models with low computational cost.
Scatter‑plot visualisation: plot model outputs against individual inputs after random sampling to obtain an intuitive sense of sensitivity.
Advanced Methods Implemented in SALib
Fourier Amplitude Sensitivity Test (FAST): assigns a characteristic frequency to each input and analyses the frequency spectrum of the model output.
Morris method: uses elementary effects (EE) sampled across the input space; the mean of EE indicates overall influence, while the standard deviation reflects interaction strength.
Sobol method: a variance‑decomposition technique that provides first‑order, second‑order, and total‑order sensitivity indices.
SALib Library for Sensitivity Analysis
Introduction to SALib
SALib is an open‑source Python library that provides a decoupled workflow for sensitivity analysis. It generates model inputs via sampling functions and computes sensitivity indices via analysis functions.
Define model inputs (parameters) and their sampling ranges.
Generate samples using a sampling function (e.g., saltelli.sample ).
Evaluate the model with the generated inputs and collect outputs.
Run an analysis function (e.g., sobol.analyze ) to obtain sensitivity indices.
Case Study 1 – Single Parameter
Consider the simple function f1(x) = (7‑500*x)/(25*x) . With only one input, the first‑order sensitivity equals the total sensitivity.
<code>import numpy as np
import matplotlib.pyplot as plt
from SALib.sample import saltelli # sampling
from SALib.analyze import sobol # analysis
def f1(x):
return (7-500*x)/(25*x)
problem = {
'num_vars': 1,
'names': ['x'],
'bounds': [[0, 0.02]]
}
param_values = saltelli.sample(problem, 2**6)
Y = np.array([f1(param) for param in param_values])
Si = sobol.analyze(problem, Y.reshape((-1,)))
</code>The resulting sensitivity dictionary contains:
<code>{'S1': array([1.05021531]),
'S1_conf': array([1.0443136]),
'ST': array([1.05021531]),
'ST_conf': array([0.06995809]),
'S2': array([[nan]]),
'S2_conf': array([[nan]])}
</code>'S1': first‑order sensitivity
'S1_conf': half‑width of the 95% confidence interval for S1
'ST': total sensitivity (identical to S1 for a single parameter)
'ST_conf': half‑width of the 95% confidence interval for ST
'S2' and 'S2_conf': second‑order sensitivities (not applicable here)
Case Study 2 – Three Parameters (Full Analysis)
We analyse the influence of three inputs x1, x2, x3 on the model sin(x1) + x2 * cos(2*x3) :
<code>from SALib.sample import saltelli
from SALib.analyze import sobol
import numpy as np
import math
problem = {
'num_vars': 3,
'names': ['x1', 'x2', 'x3'],
'bounds': [[-3.14159265359, 3.14159265359],
[-3.14159265359, 3.14159265359],
[-3.14159265359, 3.14159265359]]
}
def evaluate(x1, x2, x3):
return math.sin(x1) + x2 * math.cos(2 * x3)
param_values = saltelli.sample(problem, 2**6)
Y = np.array([evaluate(*x) for x in param_values]).T
Si = sobol.analyze(problem, Y, print_to_console=True)
</code>Key results (selected values):
<code> ST ST_conf
x1 0.214994 0.085113
x2 0.766964 0.287282
x3 0.743665 0.297265
S1 S1_conf
x1 0.214994 0.133399
x2 -0.269421 0.313660
x3 -0.270951 0.289135
S2 S2_conf
(x1, x2) 0.012031 0.215911
(x1, x3) 0.004933 0.233270
(x2, x3) 1.041531 0.502472
</code>The term x1‑x2 denotes the interaction effect between x1 and x2 .
Bar plots of total, first‑order, and second‑order sensitivities are shown below:
Case Study 3 – Three Parameters (Two‑Parameter Analysis)
Fixing one parameter and analysing the remaining two ( r and g ) for the function (0.65‑r*t)*(200+g*t)‑0.45*t :
<code>from SALib.sample import saltelli
from SALib.analyze import sobol, delta
import numpy as np
def evaluate(t, r, g):
return (0.65 - r*t)*(200 + g*t) - 0.45*t
problem = {
'num_vars': 2,
'names': ['r', 'g'],
'bounds': [[0.005, 0.015], [0.3, 0.6]]
}
x0 = 100
param_values = saltelli.sample(problem, 2**8)
Y = np.array([evaluate(x0, *param) for param in param_values])
Si = sobol.analyze(problem, Y, print_to_console=True)
</code>Result excerpt:
<code> ST ST_conf
r 0.997954 0.122747
g 0.003082 0.000695
S1 S1_conf
r 0.993931 0.131148
g 0.004666 0.009740
S2 S2_conf
(r, g) -0.001779 0.152896
</code>Bar plots for total, first‑order, and second‑order sensitivities are displayed:
Feel free to share your experiences and questions in the comments.
Follow the "Model Perspective" public account for more modeling insights.
References
SALib documentation: https://salib.readthedocs.io/en/latest/basics.html#what-is-sensitivity-analysis
浅析敏感性分析: https://zhuanlan.zhihu.com/p/48233393
【参数不确定】敏感性分析(sensitivity analysis): https://blog.csdn.net/weixin_38094405/article/details/105492403
蒋立志等, 基于 FAST 方法的核动力装置非能动系统全局参数敏感性分析
胡国标等, 基于Morris方法的车轴结构参数灵敏度分析
常晓栋等, 基于 Sobol方法的 SWMM 模型参数敏感性分析
Model Perspective
Insights, knowledge, and enjoyment from a mathematical modeling researcher and educator. Hosted by Haihua Wang, a modeling instructor and author of "Clever Use of Chat for Mathematical Modeling", "Modeling: The Mathematics of Thinking", "Mathematical Modeling Practice: A Hands‑On Guide to Competitions", and co‑author of "Mathematical Modeling: Teaching Design and Cases".
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.