5. Morris Sensitivity Analysis
Now that we know how much stochasticity contributes to output variability, we can apply
the first sensitivity analysis method: Morris. This method screens parameters by
their influence on nb_recovered and is the recommended starting point before the more
expensive Sobol analysis — it gives qualitative rankings at a fraction of the cost.
In particular, this step presents:
- The principle of the Morris method and its three indices μ, μ* and σ
- How to declare
method morrisand configure its key facets - How to read and interpret the report file produced by GAMA
- The computational cost of the method and how to tune it
The model file for this step can be found in:
msi.gama.models/models/Tutorials/SIR Analysis/models/SIR Model 05.gaml
How Morris works​
Morris is a One-At-a-Time (OAT) screening method. It samples r random starting
points (trajectories) in the parameter space and, from each, changes one parameter at a
time while holding all others fixed. The change in output caused by each step is called
an elementary effect. After r trajectories, three summary statistics are computed
for each parameter:
| Index | Meaning |
|---|---|
| μ (mu) | Mean of elementary effects — signed average influence. Can cancel if effects are of opposite sign across the space. |
| μ* (mu_star) | Mean of absolute elementary effects — the main ranking index, robust to non-monotonic models. |
| σ (sigma) | Standard deviation of elementary effects — captures non-linearity and interactions with other parameters. |
The μ* vs σ plane is the standard diagnostic plot for Morris results:
| μ* | σ | Interpretation |
|---|---|---|
| High | Low | Strong, approximately linear effect |
| High | High | Strong effect with interactions or non-linearities |
| Low | Low | Negligible parameter — can be fixed |
| Low | High | Influential only through interactions |
Total run count​
For r trajectories and k parameters, Morris requires exactly r × (k + 1)
simulation runs. With sample: 10 and k = 5 parameters:
10 × (5 + 1) = 60 runs
Increasing sample improves the robustness of the indices but scales linearly with
cost. A value of 10–20 trajectories is standard for a first screening.
The method morris statement​
The facets are:
outputs:— list of global variables to use as sensitivity targets. Mandatory.report:— path to the output file. Use.txtfor a human-readable report. Mandatory.results:— path to the raw CSV with one row per run. Optional but recommended.levels:— number of grid levels for the OAT design. The default value of 4 is appropriate for most models. Must be even.sample:— number of trajectories r. More trajectories give more stable estimates.
Reading the report​
After the run, morris_report.txt contains one block per output variable listing μ,
μ* and σ for each parameter. Here is an example obtained on our SIR model:
Reading by μ* rank: nb_agents and infection_distance dominate, followed at a
distance by nb_infected_init and infection_rate. recovery_time has negligible
direct influence. The high σ of infection_rate relative to its μ* suggests it acts
mainly through interactions rather than as a direct driver.
The morris_rax.csv contains the sampling strategy used by the experiment.
Complete model​
model SIR
global {
int nb_agents <- 200 min: 50 max: 500;
int nb_infected_init <- 5 min: 1 max: 50;
float infection_rate <- 0.5 min: 0.0 max: 1.0;
int infection_distance <- 5 min: 1 max: 20;
int recovery_time <- 50 min: 10 max: 200;
int max_steps <- 1000;
int nb_susceptible <- 0;
int nb_infected <- 0;
int nb_recovered <- 0;
init {
create person number: nb_agents;
ask nb_infected_init among (person as list) {
status <- "infected";
infection_timer <- recovery_time;
}
}
reflex update_counts {
nb_susceptible <- person count (each.status = "susceptible");
nb_infected <- person count (each.status = "infected");
nb_recovered <- person count (each.status = "recovered");
}
reflex stop when: cycle >= max_steps or nb_infected = 0 {
do halt;
}
}
species person skills: [moving] {
string status <- "susceptible";
int infection_timer <- 0;
float speed <- 1.0;
reflex move {
do wander();
}
reflex infect when: status = "infected" {
ask (person at_distance infection_distance) where (each.status = "susceptible") {
if flip(infection_rate) {
status <- "infected";
infection_timer <- recovery_time;
}
}
infection_timer <- infection_timer - 1;
if infection_timer <= 0 {
status <- "recovered";
}
}
aspect base {
aspect base {
draw circle(1) at: location color:
(status = "infected") ? #red : ((status = "recovered") ? #blue : #green);
}
}
experiment SIR_gui type: gui {
parameter "Number of agents" var: nb_agents;
parameter "Initially infected" var: nb_infected_init;
parameter "Infection rate" var: infection_rate;
parameter "Infection distance" var: infection_distance;
parameter "Recovery time" var: recovery_time;
output {
display "Population" type: java2D {
species person aspect: base;
}
display "SIR Chart" type: java2D {
chart "SIR dynamics" type: series {
data "Susceptible" value: nb_susceptible color: #green;
data "Infected" value: nb_infected color: #red;
data "Recovered" value: nb_recovered color: #blue;
}
}
monitor "Susceptible" value: nb_susceptible;
monitor "Infected" value: nb_infected;
monitor "Recovered" value: nb_recovered;
monitor "Cycle" value: cycle;
}
}
// Total runs = sample × (k + 1) = 10 × 6 = 60 runs
experiment SIR_Morris type: batch
repeat: 1
keep_seed: false
until: (cycle >= max_steps or nb_infected = 0) {
parameter "Number of agents" var: nb_agents min: 50 max: 500;
parameter "Initially infected" var: nb_infected_init min: 1 max: 50;
parameter "Infection rate" var: infection_rate min: 0.0 max: 1.0;
parameter "Infection distance" var: infection_distance min: 1 max: 20;
parameter "Recovery time" var: recovery_time min: 10 max: 200;
method morris
outputs: ["nb_recovered"]
report: "../results/morris_report.txt"
results: "../results/morris_raw.csv"
levels: 4
sample: 10;
}
What's next?​
Morris gives qualitative rankings. Step 6 introduces Sobol, which goes further by quantifying exactly how much of the output variance each parameter explains — both directly (S1) and through interactions (ST).