Groundwater Forecast - Model Dashboard Last run: 2026-07-01 12:15

Performance statistics for the machine learning groundwater prediction model. The model trains daily on 3,380 days of data (2003–present), using a 366-day weighted rainfall window to predict Calculated Groundwater % up to 120 days ahead across three rainfall scenarios. The intercept is auto-recalibrated each run, and a 20-day backtest runs automatically at 12:15 after EA data updates.

How the Model Works

Core Formula

Each day’s groundwater level is predicted using a linear formula applied to a weighted sum of the past 366 days of rainfall. Before being summed, every day’s rainfall is multiplied by two factors: a monthly factor (seasonal recharge variation) and a lag weight (how long ago the rain fell).

GW %  =  -20.56  +  0.147 × WeightedRainSum

The intercept (-20.56) is auto-recalibrated every daily run by linear regression against the last two years of actual groundwater readings. This corrects for seasonal drift — the aquifer behaves differently in summer vs winter — so the formula always reflects current conditions rather than requiring manual adjustment.

The slope (0.147) is currently fixed at the value derived from the original Excel hydrological model, calibrated against 20+ years of EA gauge data. Once sufficient horizon accuracy data has accumulated (from late July 2026), both slope and intercept will be tuned together against actual forecast performance at 7, 28 and 30-day horizons.

To ensure predictions start at today’s measured level, an exponentially decaying correction is added, fading to near-zero over 90 days:

correction(day) = Δ × e−0.02 × day

Day  0: 100% of correction
Day 35:  50% of correction
Day 90:   5% of correction
Monthly Rainfall Factors

Summer rain is largely lost to evapotranspiration; winter rain percolates into the chalk aquifer far more efficiently. Each month’s rainfall is multiplied by a seasonal factor before entering the model.

MonthFactorRecharge
Jan1.19High
Feb0.91Medium
Mar0.91Medium
Apr0.86Medium
May0.38Low
Jun0.38Low
Jul0.38Low
Aug0.38Low
Sep0.95Medium
Oct1.38High
Nov1.38High
Dec1.10High

Highest recharge months: Oct, Nov, Jan. Lowest recharge months: May, Jun, Jul, Aug. These factors are fixed at calibrated values from the Excel model. Automatic ML adjustment is disabled — the GBM model handles seasonality internally and was found to incorrectly push all factors toward 1.0.

Lag Weight Profile

Rain must percolate through unsaturated chalk before reaching the water table. The lag weight profile describes how much influence rainfall from different periods has on today’s groundwater level:

Days agoWeightInterpretation
0 – 190.75Recent — still percolating
20 – 391.00Reaching water table
40 – 591.20Peak influence
60 – 1790.90Sustained contribution
180 – 1990.85Fading influence
200 – 2190.77Diminishing
220 – 2590.70–0.75Background recharge
260 – 2790.50Minor residual
280 – 2990.05Negligible
300 – 3650.00No effect

The peak at 40–59 days reflects typical chalk percolation times in the upper Pang valley. These weights are fixed at calibrated values.

Dynamic Lag Shifting

When the aquifer is full, rain reaches the water table faster (less unsaturated chalk to saturate). When low, percolation takes longer. The model shifts the lag weight curve right by the appropriate number of days based on current groundwater level.

Thresholds from historical quartiles (range: 3.3%–96.6%):

GW LevelQuartileLag
< 26.61%Bottom 25%20 days
26.61–49.94%Lower mid13 days
49.94–73.26%Upper mid8 days
> 73.26%Top 25%5 days

At today’s level of 46.5%, the current lag is 13 days.

Lag values from field observation in the upper Pang chalk catchment. Applied in the 20-day backtest to correct for rain that fell recently but hasn't yet reached the water table. Not applied in forward predictions — the intercept is calibrated against historical actuals which already have percolation delay baked in, and applying the shift iteratively causes a feedback collapse. Values stored in groundwater_lag_thresholds — adjustable without code changes. Last updated: 2026-06-29.

Three rainfall scenarios: average uses historical monthly means; +40% and −40% scale future rain up or down. All scenarios start at today’s actual reading.

1.0%
Mean Error (MAE)
20-day backtest
1.3%
RMSE
20-day backtest
-1.0%
Bias
Over-pred
0.9996
Validation R²
3,380 samples
46.5%
Today (Actual)
2026-07-01
3
Model Runs
1,080 prediction rows

Tomorrow

+40%
46.7%
Avg
46.7%
-40%
46.6%

Actual today: 46.5%

30-Day Forecast

+40%
40.8%
Avg
40.0%
-40%
39.2%

Blue=wet, Green=avg, Orange=dry

60-Day Forecast

+40%
32.5%
Avg
30.4%
-40%
28.3%

Blue=wet, Green=avg, Orange=dry

Accuracy by Forecast Horizon

Days AheadNAvg Error %Bias %Max Error %
110.300.300.30

Backtest History Daily 20-day results

DateMAE %RMSE %Bias %Status
2026-07-010.991.26-0.96Within acceptable range
2026-06-300.871.13-0.81Within acceptable range
2026-06-290.780.99-0.71Within acceptable range

Monthly Averages Trend over time

MonthAvg MAE %Avg RMSE %Avg Bias %Days
2026-070.991.26-0.961
2026-060.831.06-0.762

Model Training Log Daily training metrics

DateInterceptTrain R²Val R²Tr RMSEVal RMSESamples
2026-07-01 12:15-20.561.00000.99960.0170.4313380
2026-06-30 12:15-20.571.00000.99950.0170.4733379
2026-06-29 15:11-20.571.00000.99940.0180.5113378

Historical Accuracy: Predictions Made 30 Days Ago Average scenario — comparing the 30-day forecast to what actually happened

No data available yet

Filters for predictions with a ~30-day horizon. Populates once the model has been running for at least 30 days.

Recent Predictions vs Actuals Average scenario — where actual data now exists

DateActual %Predicted %Error %Days AheadMade On
2026-06-3046.8746.870.0002026-06-30
2026-06-3046.8747.170.3012026-06-29
2026-06-2947.1947.190.0002026-06-29

Forward Predictions — All Scenarios Made on 2026-07-01

DateAverage %+40% Rain %-40% Rain %Range %
2026-07-0146.5346.5346.530.00
2026-07-0845.0145.2044.820.39
2026-07-1543.8644.2243.500.73
2026-07-2243.2843.8342.731.10
2026-07-2939.9940.7739.221.55
2026-08-0537.5938.6336.552.07
2026-08-1235.1636.5033.832.67
2026-08-1934.0335.6932.373.32
2026-08-2630.3932.3928.393.99
2026-09-0229.4731.8827.064.82
2026-09-0928.2631.3425.186.16
2026-09-1627.3731.1323.617.52
2026-09-2327.0931.5922.608.99
2026-09-3025.9431.2420.6410.60
2026-10-0727.4534.0320.8713.16
2026-10-1427.7235.6419.8015.84
2026-10-2128.5537.8819.2218.66
2026-10-2827.4938.3616.6121.75

Cron Log Last modified: 2026-07-01 11:15:20

Using calibrated parameters: intercept=-20.5629, slope=0.147000
Today's actual: 46.533, formula predicts: 49.391, adjustment: -2.859
Day 0: GW=46.5%, lag_shift=+0, weighted_sum=475.9, adj=-2.86, pred=46.533
Day 10: GW=43.9%, lag_shift=+0, weighted_sum=454.2, adj=-2.34, pred=43.867
Day 20: GW=43.2%, lag_shift=+0, weighted_sum=446.7, adj=-1.92, pred=43.190
Day 30: GW=39.7%, lag_shift=+0, weighted_sum=417.5, adj=-1.57, pred=39.240
Day 40: GW=35.3%, lag_shift=+0, weighted_sum=387.6, adj=-1.28, pred=35.135
Day 50: GW=34.0%, lag_shift=+0, weighted_sum=374.3, adj=-1.05, pred=33.414
Day 60: GW=29.9%, lag_shift=+0, weighted_sum=348.2, adj=-0.86, pred=29.758
Day 70: GW=28.2%, lag_shift=+0, weighted_sum=336.9, adj=-0.70, pred=28.262
Day 80: GW=27.5%, lag_shift=+0, weighted_sum=331.2, adj=-0.58, pred=27.545
Day 90: GW=25.7%, lag_shift=+0, weighted_sum=318.9, adj=-0.47, pred=25.845
Day 100: GW=27.3%, lag_shift=+0, weighted_sum=328.1, adj=-0.39, pred=27.274
Day 110: GW=28.0%, lag_shift=+0, weighted_sum=335.0, adj=-0.32, pred=28.362
Predicted range: 25.364 to 46.696
Generating predictions for scenario: +40%
Predicting calc_gw from 2026-07-01 00:00:00 (level: 46.533)
Using calibrated parameters: intercept=-20.5629, slope=0.147000
Today's actual: 46.533, formula predicts: 49.391, adjustment: -2.859
Day 0: GW=46.5%, lag_shift=+0, weighted_sum=475.9, adj=-2.86, pred=46.533
Day 10: GW=44.1%, lag_shift=+0, weighted_sum=456.0, adj=-2.34, pred=44.133
Day 20: GW=43.6%, lag_shift=+0, weighted_sum=450.2, adj=-1.92, pred=43.706
Day 30: GW=40.5%, lag_shift=+0, weighted_sum=423.2, adj=-1.57, pred=40.079
Day 40: GW=36.5%, lag_shift=+0, weighted_sum=396.1, adj=-1.28, pred=36.378
Day 50: GW=35.7%, lag_shift=+0, weighted_sum=385.9, adj=-1.05, pred=35.119
Day 60: GW=32.0%, lag_shift=+0, weighted_sum=363.0, adj=-0.86, pred=31.940
Day 70: GW=31.2%, lag_shift=+0, weighted_sum=357.9, adj=-0.70, pred=31.340
Day 80: GW=31.4%, lag_shift=+0, weighted_sum=358.7, adj=-0.58, pred=31.595
Day 90: GW=30.7%, lag_shift=+0, weighted_sum=354.2, adj=-0.47, pred=31.034
Day 100: GW=34.1%, lag_shift=+0, weighted_sum=375.3, adj=-0.39, pred=34.221
Day 110: GW=36.7%, lag_shift=+0, weighted_sum=395.6, adj=-0.32, pred=37.271
Predicted range: 30.090 to 46.768
Generating predictions for scenario: -40%
Predicting calc_gw from 2026-07-01 00:00:00 (level: 46.533)
Using calibrated parameters: intercept=-20.5629, slope=0.147000
Today's actual: 46.533, formula predicts: 49.391, adjustment: -2.859
Day 0: GW=46.5%, lag_shift=+0, weighted_sum=475.9, adj=-2.86, pred=46.533
Day 10: GW=43.6%, lag_shift=+0, weighted_sum=452.4, adj=-2.34, pred=43.601
Day 20: GW=42.7%, lag_shift=+0, weighted_sum=443.2, adj=-1.92, pred=42.674
Day 30: GW=38.9%, lag_shift=+0, weighted_sum=411.8, adj=-1.57, pred=38.401
Day 40: GW=34.1%, lag_shift=+0, weighted_sum=379.2, adj=-1.28, pred=33.892
Day 50: GW=32.4%, lag_shift=+0, weighted_sum=362.7, adj=-1.05, pred=31.709
Day 60: GW=27.7%, lag_shift=+0, weighted_sum=333.3, adj=-0.86, pred=27.575
Day 70: GW=25.2%, lag_shift=+0, weighted_sum=316.0, adj=-0.70, pred=25.184
Day 80: GW=23.5%, lag_shift=+0, weighted_sum=303.6, adj=-0.58, pred=23.496
Day 90: GW=20.6%, lag_shift=+0, weighted_sum=283.6, adj=-0.47, pred=20.656
Day 100: GW=20.5%, lag_shift=+0, weighted_sum=280.8, adj=-0.39, pred=20.327
Day 110: GW=19.3%, lag_shift=+0, weighted_sum=274.4, adj=-0.32, pred=19.453
Predicted range: 16.613 to 46.623
✓ Saved calc_gw predictions to database
============================================================
SUCCESS: Daily update completed
============================================================
============================================================
PREDICTION SUMMARY
============================================================
CALC_GW:
average: 46.533 (day 1) → 29.876 (day 60)
+40%: 46.533 (day 1) → 32.020 (day 60)
-40%: 46.533 (day 1) → 27.733 (day 60)