Count model
How many birds might we catch?
The count forecast combines decades of ringing records with the date, moon and weather to estimate the catch on a day when ringing takes place. Here is how the model works, what we have checked, and what to expect from it in a new season.
1. Learn from past ringing days
The question is simple: given the conditions on a particular day, how many birds should we expect to capture? This is a forecast of the ringing catch, rather than the total number of birds migrating through Ngulia. It assumes ringing takes place and excludes targeted swallow and martin captures.
We use a negative-binomial generalized additive model (GAM). The GAM learns flexible curves: the relationship with rain or the time of season does not have to be a straight line. The negative-binomial distribution allows actual catches to vary widely around the expected count, as they do in the ringing records.
- Date and moon describe recurring patterns within the migration season.
- Weather adjusts the expected catch for that day's rain, wind, temperature, pressure, cloud and humidity.
- Year and bush layout account for longer-term differences in the historical records.
The saved model learns from 1,033 ringing dates across 47 seasons, from 1977 to 2023. This includes 11 documented days with no catch. Each day's inputs enter the same model together.
Model formula and training details
total_birds_ringed ~ s(season_day, k = 12) + s(moon_distance_from_new_moon,
k = 6) + s(rain_log, k = 6) + s(wind_speed_10m_mean_ms, k = 6) +
s(temperature_2m_mean_c, k = 6) + s(surface_pressure_mean_hpa,
k = 6) + total_cloud_cover_mean + relative_humidity_mean_pct +
wind_u_10m_mean_ms + wind_v_10m_mean_ms + bush_period + s(season,
bs = "cs", k = 6)
A log link combines the effects as multipliers on the expected count. Penalized smooths describe season day, distance from new moon, log(1 + morning rain), wind speed, temperature, pressure and historical year. Cloud fraction, humidity and the two wind components are linear terms; bush layout is categorical. The historical year term is a shrinkage cubic spline with basis dimension six.
Dates with unknown or mixed bush layout or missing inputs are excluded. Documented single-layout dates in the 1994–1995 transition are retained. Every fitted curve on this page comes from the saved model used by the forecast.
2. How do the date, moon and weather change the catch?
These curves show how the model adjusts its expected count when one input changes and the others stay fixed. They help us understand what the model has learned before asking whether its predictions work in a later season.
A value of 1 means the same expected catch as the reference conditions. A value of 2 means twice the expected catch; 0.5 means half. For example, a multiplier of 1.5 would turn a reference catch of 400 birds into 600, with all other inputs unchanged.
The reference uses median training inputs and front-bush layout. Each curve spans the central 90% of its input's observed values. Shading shows uncertainty in the fitted effect (pointwise 95% coefficient intervals); it is different from the range of possible catches on a future day.
Timing within the season and the moon cycle
The first curve describes the pattern through the ringing season. The second asks how the expected catch changes with distance from new moon, after accounting for the date and weather.
Weather on the ringing day
Read these curves in the same way: above 1 raises the expected catch relative to the reference, below 1 lowers it. Weather is summarised from midnight to 08:00 in Ngulia local time: rain is the total, and the other inputs are averages. The last two curves describe the east–west and north–south components of wind.
These are associations in the historical records. Weather variables are related to one another, and ringing conditions have changed over time. A curve therefore describes the model's adjustment, rather than proving that changing that one weather variable causes a change in catch.
3. Put today's forecast in its historical context
The same date and weather have not always corresponded to the same catch. The model includes a year effect to represent changes in the overall catch level, and a bush-layout term to account for the different historical ringing locations.
What happens to the year effect after 2023?
The solid curve shows the historical year effect relative to 2023, with weather and layout held fixed. A value of 2 means twice the 2023 expected catch under the same conditions. For future seasons, the forecast keeps this effect at the fitted 2023 level, shown by the dashed line.
This gives the forecast a fixed recent baseline. It avoids extending the historical curve's end slope indefinitely into the future, but assumes the 2023 level remains relevant. The model does not yet adjust that baseline using catches from the new season.
Why include bush layout?
The comparison below is relative to back-bush layout. The live forecast assumes front bush. Because layout and historical era overlap, this difference can also reflect changes in effort or bird abundance; it should not be read as an isolated effect of moving the nets.
Year and layout help describe historical variation, but do not separate changes in bird populations from changes in ringing effort. The model does not measure net-hours.
4. First check: can the model describe the records it learned from?
We add the fitted daily counts within each season and compare them with the recorded catches. This checks whether the model can describe the broad historical pattern using each day's recorded weather, year and layout.
Both lines cover exactly the same included ringing dates. A close match is useful, but the model has already seen these catches during training. To assess prediction, we need to test it on a season whose catches were left out.
These totals exclude dates outside the training data. They do not estimate catches on days when ringing did not take place.
5. The harder test: predict a season before seeing its catches
We repeat the following exercise for each season from 2014 to 2023. This mimics starting a new season with only the earlier ringing records available.
- Train on the past. For the 2014 test, use eligible seasons up to 2013; for the 2015 test, use seasons up to 2014, and so on.
- Predict the next season. Use its date, moon and historical weather, assume front bush, and keep the year effect at the last training season's level, following the live forecast rule.
- Compare with the catches. Only after making the predictions do we use that season's observed counts to score them.
Together, these tests cover 142 ringing dates across 10 seasons. No catches from a test season enter that season's fitted model.
What do the results tell us?
Average daily error
485 birdsAverage distance between the predicted and observed catch, ignoring the direction of the error.
Average predicted / observed
819 / 614Predictions average 33% above the recorded daily catch across the test dates.
Days inside the 80% range
85.9%An 80% range aims to include about 8 out of 10 catches. Here it includes slightly more.
The average error is large compared with the average observed catch. The forecast gives a broad expectation, and substantial misses remain possible. Covering more than 80% of observations does not by itself show that the ranges are precise or well calibrated.
Does it get the seasonal totals right?
The lines below sum predictions and observations over the same ringing dates in each test season. They show whether the model carries the catch level forward successfully when it has not seen that season's catches.
Predicted totals are above observed totals in 8 of the 10 test seasons. The model also misses the high catch in 2017. A new season can differ substantially from the baseline carried forward from earlier years.
Totals cover observed ringing dates only. This test does not predict how many days will be operated in a future season.
How close are the individual daily predictions?
Each dot is one test date. A dot on the dashed diagonal would be an exact match. Above the line means too many birds predicted; below it means too few. The spread shows how much day-to-day variation remains unexplained.
Detailed validation scores
| Dates | Seasons | Mean absolute error (birds) | Poisson deviance | Observed mean | Predicted mean | 80% range coverage |
|---|---|---|---|---|---|---|
| 142 | 10 | 485.43 | 523.35 | 614.43 | 819.07 | 85.9% |
Mean absolute error is the average absolute difference in birds. Poisson deviance is an additional score for error in the expected count; smaller is better. Its name does not change the model's negative-binomial fitting distribution.
We used historical ERA5 weather, rather than weather forecasts issued before each ringing day. This tests the count model with reconstructed weather inputs, so it does not measure errors introduced by the live weather forecast. The historical record also informed model selection; it is not an untouched final test.
6. What to expect from the live forecast
For each forecast date, the website uses hourly Open-Meteo ECMWF weather to calculate the same eight daily weather inputs. The date and moon follow that day; layout is fixed to front bush and the year effect stays at 2023. The saved model then produces an expected count and a range of possible catches. Mist is predicted by a separate model.
An expected count is not a promise
A forecast of 500 birds means an expected catch of 500 under those inputs. It does not mean the model expects every similar day to produce exactly 500. The example below shows the distribution of possible catches around that mean.
In this illustration, an expected count of 500 gives a central 80% range of about 31–1224 birds. The wide, asymmetric range reflects the variation in catches learned from the records.
The website's 80% range includes this fitted day-to-day count variability. It does not include uncertainty in the weather forecast, fitted coefficients or the baseline for a future season. The full-season reference curve uses median training weather, so it shows a typical-weather pattern rather than a weather forecast for every day.
The next check: follow a new season
For a new season, we need to match each archived forecast as issued with the recorded catch on days when ringing actually takes place. We can then check daily errors, whether predictions remain systematically high or low, and how often catches fall inside the published range. That will assess the weather forecast and count model together under operational conditions.
The published forecast uses historical records through 2023 and does not adjust its annual baseline from live catches. Experiments with annual updates, alternative baselines, previous-morning rain and neural networks are described in Count model alternatives and tests ; they are not used in the published forecast.
Reproduce this report
Run from the repository root:
Rscript count/scripts/train.R Rscript count/scripts/validate.R Rscript count/scripts/build_report.R
Forecast artifact: count-m2-2023-v1 · Inputs: raw-data/daily_coverage.csv · Saved model: count/model/model.rds · Validation tables: count/intermediate-data/