Robustness and stress testing¶
A policy that looks good on the environment it was tuned for can fail once the world
shifts. stress_test
evaluates a policy across a set of perturbed environments and reports the mean return on
each, so a robust policy and a brittle one can be told apart.
from decisionrl.evaluation import stress_test
from decisionrl.envs import NonstationaryInventory
from decisionrl import baselines as B
variants = {
"nominal": NonstationaryInventory,
"demand_spike": lambda: NonstationaryInventory(demand_low=8.0, demand_high=24.0),
"volatile": lambda: NonstationaryInventory(switch_prob=0.20),
}
returns = stress_test(B.tracking_base_stock(3.0), variants, episodes=30)
Pass any (env, obs) -> action policy. To stress-test a trained agent, wrap it:
lambda env, obs: agent.predict(obs).
Example: fixed vs adaptive inventory policy¶
Mean return under three perturbations (the fixed base-stock is tuned on the nominal setting):
| Variant | Fixed base-stock | Adaptive tracking |
|---|---|---|
| nominal | 268.9 | 322.4 |
| demand spike (higher demand) | 342.6 | 476.9 |
| volatile (fast regime switching) | 238.9 | 231.4 |
The adaptive policy is far more robust to a demand-level shift, which is exactly what it is built for: it reads recent demand and follows it. Under very fast regime switching it is marginally worse, because the smoothed demand estimate lags the rapid changes. That trade-off is the point of a stress test: it surfaces where a policy holds up and where it does not, instead of reporting a single number from the setting it was tuned on.