How the expected-score model works
Context Trained on 7,332 surveys at 1,162 sites, it explains 39% of the variation at sites it never saw.
For every usable biological survey, the model predicts what it should find given its season, survey form, watershed (paved and urban share, forest, farmland, soils, elevation, climate), rain and air temperature in the week before, water temperature, flow and team. It never sees the year, so change over time stays in the gap between observed and expected.
Every expected value comes from a version of the model that never saw any survey from that site (five folds grouped by site), which is how a site is judged by what the rest of the country predicts for it.
| Predicts | Surveys | Sites | Held-out R² | Season and form only | Typical error |
|---|---|---|---|---|---|
| Share of groups found that are pollution-sensitive | 7,332 | 1,162 | 0.39 | 0.02 | 8 pts |
| Score percentile within its survey form | 7,294 | 1,147 | 0.38 | 0.00 | 18 percentile pts |
Rainfall in the week before each survey is included. Volunteer data is noisy, so an R² near 0.4 at unseen sites is useful: enough to set an expected range for each survey and to tell a change in the stream from a change in the season or team.
How this was worked out
scikit-learn HistGradientBoostingRegressor (500 iterations, learning rate 0.04, 15 leaves, at least 40 surveys per leaf); importance by scrambling each input group on held-out folds.