skills/relsa-severity-assessment/references/forecasting.md
scripts/forecast_relsa.py ports the foRcast tool of Lutscher et al. (2026),
Front. Physiol. 17:1869563 — an ARIMA model fitted per animal to its own RELSA trajectory,
forecasting the score at the next time point (or at the humane endpoint) with a 95%
prediction interval.
The purpose is triage, not automation: identify the individuals at risk of reaching a humane endpoint so handling personnel give them attention, while avoiding euthanising animals that would have recovered. It is a proof of concept on 13 animals across seven models, not a validated clinical tool.
ARIMA(p, d, q) combines an autoregressive part (p lags of the series), differencing (d, to remove trend and reach stationarity), and a moving-average part (q lags of the forecast errors). It needs nothing but the animal's own history, which suits single-animal severity assessment where each individual is its own control.
Model selection follows Hyndman & Khandakar (2008), i.e. forecast::auto.arima:
d by successive KPSS tests (null = stationary; difference while it is rejected).(p, q) and the drift term until AICc
stops improving.auto_arima(..., stepwise=False) searches the full p × q grid instead. Both are bounded by
max_p, max_q, max_d; the paper notes that the globally best model could lie outside that
range, which is a limitation of the approach rather than of one implementation.
Animal experiments typically produce one measurement per animal per day. ARIMA is conventionally said to want ~50 observations (Box et al., 2016), a number recently challenged (Hassouna & Al-Sahili, 2020) but still far above what a 7-day study yields. The paper's workaround is to interpolate linearly between observed values at 0.1-day increments and fit the model to that denser series, and it is explicit that this is an alteration of the method, not a free improvement:
interpolate_step=None / --interpolate-step 0 fits the observed series directly. Prefer it
whenever measurement frequency allows — with automated home-cage or telemetry monitoring the
interpolation step becomes unnecessary, which is the paper's own outlook.
Two routes to a predicted RELSA score:
forecast_animal(), predict_endpoint().forecast_indirect().The paper compared them in the sepsis model and direct won clearly: median deviation from the actual score −0.002 (direct) versus −0.240 (indirect), a large effect (d = 1.42, 95% CI [1.03, 1.81]). The reason is error propagation — each variable's forecast error accumulates through the score, whereas the direct forecast carries only its own error.
Use direct. forecast_indirect() exists to reproduce the comparison and to inspect which
variable is driving a forecast.
Reported together, because each hides a failure the others catch
(_common.forecast_metrics):
| Metric | Meaning | Failure mode it exposes |
|---|---|---|
| RMSE | root mean square deviation of predictions from actual RELSA scores | point-forecast accuracy |
| PICP | % of actual values falling inside the prediction interval | interval calibration |
| MPIW | mean prediction interval width, in RELSA units | a model that buys 100% PICP by making the interval useless |
MPIW is read against the RELSA scale, which normally spans about 0–1: the paper's overall MPIW of 1.69 means the average interval covered 169% of the RELSA range, and the pancreatic cancer model's 7.35 means 735% — a technically perfect PICP with almost no information in it. Always report MPIW next to PICP.
Predicting the RELSA score at the (pre-)humane endpoint from all measurements up to the time point immediately before it:
| Model / intervention | Animals | RMSE | PICP [%] | MPIW |
|---|---|---|---|---|
| Sepsis | 2 | 0.009 | 100 | 0.30 |
| 1.5% DSS + restraint stress | 2 | 0.007 | 100 | 0.66 |
| 1% DSS + blood sampling | 4 | 0.046 | 75 | 0.53 |
| 1.5% DSS + blood sampling | 2 | 0.065 | 100 | 0.84 |
| 1.5% DSS | 1 | 0.095 | 100 | 1.64 |
| Pancreatic cancer | 1 | 0.177 | 100 | 7.35 |
| Neurosurgery | 1 | 0.082 | 100 | 0.54 |
| Overall | 13 | 0.069 | 96 | 1.69 |
Five of the seven rows rest on one or two animals. The overall PICP of 96% comes from 13 endpoint predictions.
Using the public sepsis data (tm_sepsis.txt, 7 mice) with the paper's four telemetry
variables, no turned variables, and the CLP animals as reference set:
arima), so treat MPIW comparisons across
implementations as approximate.The paper's exact reference set and baseline window per model are in its Supplementary Table S2, which is not bundled here; small differences in those choices shift every score slightly.
forecast_animal() records a warning below four observed points.