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

Performance statistics for the machine learning groundwater prediction model. The model trains daily on 3,396 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.43  +  0.147 × WeightedRainSum

The intercept (-20.43) 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 39.9%, 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.

3.2%
Mean Error (MAE)
20-day backtest
3.2%
RMSE
20-day backtest
-3.2%
Bias
Over-pred
0.9997
Validation R²
3,396 samples
39.9%
Today (Actual)
2026-07-22
23
Model Runs
8,280 prediction rows

Tomorrow

+40%
40.4%
Avg
40.4%
-40%
40.3%

Actual today: 39.9%

30-Day Forecast

+40%
32.3%
Avg
31.3%
-40%
30.4%

Blue=wet, Green=avg, Orange=dry

60-Day Forecast

+40%
29.4%
Avg
25.9%
-40%
22.3%

Blue=wet, Green=avg, Orange=dry

Accuracy by Forecast Horizon

Days AheadNAvg Error %Bias %Max Error %
1220.370.240.61
2210.570.400.86
3200.680.551.26
5180.980.841.79
7161.171.032.31
10131.371.372.49
1491.951.952.66
2123.373.373.43

Backtest History Daily 20-day results

DateMAE %RMSE %Bias %Status
2026-07-213.203.24-3.20Significant bias detected
2026-07-203.163.19-3.16Significant bias detected
2026-07-193.103.14-3.10Significant bias detected
2026-07-183.023.06-3.02Significant bias detected
2026-07-172.932.97-2.93Significant bias detected
2026-07-162.842.89-2.84Significant bias detected
2026-07-152.752.81-2.75Significant bias detected
2026-07-142.652.74-2.65Significant bias detected
2026-07-132.552.66-2.55Significant bias detected
2026-07-122.462.60-2.46Significant bias detected
2026-07-112.342.54-2.34Significant bias detected
2026-07-102.242.49-2.24Significant bias detected
2026-07-092.102.40-2.10Significant bias detected
2026-07-081.972.31-1.97Within acceptable range
2026-07-071.852.23-1.85Within acceptable range
2026-07-061.732.11-1.73Within acceptable range
2026-07-051.581.94-1.58Within acceptable range
2026-07-041.431.76-1.43Within acceptable range
2026-07-031.281.59-1.28Within acceptable range
2026-07-021.121.42-1.12Within acceptable range
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-072.252.45-2.2521
2026-060.831.06-0.762

Model Training Log Daily training metrics

DateInterceptTrain R²Val R²Tr RMSEVal RMSESamples
2026-07-21 12:15-20.431.00000.99970.0160.3723396
2026-07-20 12:15-20.441.00000.99970.0160.3843395
2026-07-19 12:15-20.441.00000.99970.0160.3883394
2026-07-18 12:15-20.451.00000.99970.0170.3853393
2026-07-17 12:15-20.451.00000.99970.0160.3843392
2026-07-16 12:15-20.461.00000.99970.0160.3843392
2026-07-15 12:15-20.471.00000.99970.0160.3823391
2026-07-14 12:15-20.481.00000.99970.0160.3883390
2026-07-13 12:15-20.481.00000.99970.0160.3823389
2026-07-12 12:15-20.491.00000.99970.0160.3763388
2026-07-11 12:15-20.501.00000.99970.0160.3763388
2026-07-10 12:15-20.511.00000.99970.0160.3763387
2026-07-09 12:15-20.521.00000.99970.0160.3733386
2026-07-08 12:15-20.531.00000.99970.0160.3793385

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-07-2140.1343.763.63222026-06-29
2026-07-2140.1343.563.43212026-06-30
2026-07-2140.1343.193.06202026-07-01
2026-07-2140.1342.892.76192026-07-02
2026-07-2140.1342.582.45182026-07-03
2026-07-2140.1342.342.21172026-07-04
2026-07-2140.1342.142.01162026-07-05
2026-07-2140.1342.382.25152026-07-06
2026-07-2140.1342.792.66142026-07-07
2026-07-2140.1342.532.40132026-07-08
2026-07-2140.1342.382.25122026-07-09
2026-07-2140.1342.912.78112026-07-10
2026-07-2140.1342.622.49102026-07-11
2026-07-2140.1342.412.2892026-07-12
2026-07-2140.1342.021.8982026-07-13
2026-07-2140.1341.761.6372026-07-14
2026-07-2140.1341.461.3362026-07-15
2026-07-2140.1341.080.9552026-07-16
2026-07-2140.1340.810.6842026-07-17
2026-07-2140.1340.580.4532026-07-18
2026-07-2140.1340.720.5922026-07-19
2026-07-2140.1340.530.4012026-07-20
2026-07-2140.1340.13-0.0002026-07-21
2026-07-2040.4243.733.30212026-06-29
2026-07-2040.4243.533.10202026-06-30
2026-07-2040.4243.162.73192026-07-01
2026-07-2040.4242.872.44182026-07-02
2026-07-2040.4242.552.13172026-07-03
2026-07-2040.4242.311.89162026-07-04
2026-07-2040.4242.111.68152026-07-05
2026-07-2040.4242.351.93142026-07-06
2026-07-2040.4242.772.35132026-07-07
2026-07-2040.4242.512.08122026-07-08
2026-07-2040.4242.361.93112026-07-09
2026-07-2040.4242.902.47102026-07-10
2026-07-2040.4242.602.1892026-07-11
2026-07-2040.4242.391.9782026-07-12
2026-07-2040.4241.991.5772026-07-13
2026-07-2040.4241.731.3162026-07-14
2026-07-2040.4241.431.0052026-07-15
2026-07-2040.4241.040.6242026-07-16
2026-07-2040.4240.760.3432026-07-17
2026-07-2040.4240.530.1122026-07-18
2026-07-2040.4240.680.2512026-07-19
2026-07-2040.4240.420.0002026-07-20
2026-07-1940.7443.863.13202026-06-29
2026-07-1940.7443.662.93192026-06-30
2026-07-1940.7443.312.57182026-07-01
2026-07-1940.7443.012.28172026-07-02
2026-07-1940.7442.701.96162026-07-03
2026-07-1940.7442.451.71152026-07-04
2026-07-1940.7442.241.51142026-07-05
2026-07-1940.7442.491.76132026-07-06
2026-07-1940.7442.922.19122026-07-07
2026-07-1940.7442.651.92112026-07-08
2026-07-1940.7442.501.76102026-07-09
2026-07-1940.7443.062.3292026-07-10
2026-07-1940.7442.762.0282026-07-11
2026-07-1940.7442.541.8072026-07-12
2026-07-1940.7442.131.4062026-07-13

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

DateAverage %+40% Rain %-40% Rain %Range %
2026-07-2240.3040.3540.250.10
2026-07-2937.1137.3336.900.44
2026-08-0534.7835.2134.360.85
2026-08-1232.4133.0831.741.34
2026-08-1931.3332.2830.381.90
2026-08-2627.7128.9526.472.49
2026-09-0226.9628.6425.283.35
2026-09-0926.0328.4423.624.82
2026-09-1625.3928.5522.246.32
2026-09-2325.2529.1621.337.83
2026-09-3024.1628.8819.449.44
2026-10-0725.7331.7319.7312.00
2026-10-1426.0633.4018.7214.68
2026-10-2126.9335.6818.1817.49
2026-10-2825.9136.2015.6120.59
2026-11-0425.3237.0913.5623.53
2026-11-1126.4039.6613.1526.51

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

Using calibrated parameters: intercept=-20.4327, slope=0.147000
Today's actual: 40.130, formula predicts: 43.949, adjustment: -3.819
Day 0: GW=40.1%, lag_shift=+0, weighted_sum=438.0, adj=-3.82, pred=40.130
Day 10: GW=36.9%, lag_shift=+0, weighted_sum=407.8, adj=-3.13, pred=36.385
Day 20: GW=32.5%, lag_shift=+0, weighted_sum=376.6, adj=-2.56, pred=32.364
Day 30: GW=31.3%, lag_shift=+0, weighted_sum=362.2, adj=-2.10, pred=30.714
Day 40: GW=27.2%, lag_shift=+0, weighted_sum=335.2, adj=-1.72, pred=27.126
Day 50: GW=25.9%, lag_shift=+0, weighted_sum=325.6, adj=-1.40, pred=26.026
Day 60: GW=25.6%, lag_shift=+0, weighted_sum=321.3, adj=-1.15, pred=25.654
Day 70: GW=23.9%, lag_shift=+0, weighted_sum=309.1, adj=-0.94, pred=24.057
Day 80: GW=25.6%, lag_shift=+0, weighted_sum=318.2, adj=-0.77, pred=25.571
Day 90: GW=26.4%, lag_shift=+0, weighted_sum=325.1, adj=-0.63, pred=26.729
Day 100: GW=25.9%, lag_shift=+0, weighted_sum=317.0, adj=-0.52, pred=25.648
Day 110: GW=25.6%, lag_shift=+0, weighted_sum=317.1, adj=-0.42, pred=25.764
Predicted range: 23.538 to 40.464
Generating predictions for scenario: +40%
Predicting calc_gw from 2026-07-21 00:00:00 (level: 40.130)
Using calibrated parameters: intercept=-20.4327, slope=0.147000
Today's actual: 40.130, formula predicts: 43.949, adjustment: -3.819
Day 0: GW=40.1%, lag_shift=+0, weighted_sum=438.0, adj=-3.82, pred=40.130
Day 10: GW=37.1%, lag_shift=+0, weighted_sum=409.6, adj=-3.13, pred=36.651
Day 20: GW=33.1%, lag_shift=+0, weighted_sum=380.6, adj=-2.56, pred=32.956
Day 30: GW=32.3%, lag_shift=+0, weighted_sum=368.9, adj=-2.10, pred=31.703
Day 40: GW=28.6%, lag_shift=+0, weighted_sum=344.8, adj=-1.72, pred=28.544
Day 50: GW=28.2%, lag_shift=+0, weighted_sum=342.0, adj=-1.40, pred=28.437
Day 60: GW=28.9%, lag_shift=+0, weighted_sum=344.9, adj=-1.15, pred=29.123
Day 70: GW=28.4%, lag_shift=+0, weighted_sum=340.4, adj=-0.94, pred=28.666
Day 80: GW=31.8%, lag_shift=+0, weighted_sum=361.5, adj=-0.77, pred=31.938
Day 90: GW=34.5%, lag_shift=+0, weighted_sum=381.8, adj=-0.63, pred=35.058
Day 100: GW=36.2%, lag_shift=+0, weighted_sum=388.5, adj=-0.52, pred=36.164
Day 110: GW=37.9%, lag_shift=+0, weighted_sum=402.8, adj=-0.42, pred=38.359
Predicted range: 27.683 to 41.407
Generating predictions for scenario: -40%
Predicting calc_gw from 2026-07-21 00:00:00 (level: 40.130)
Using calibrated parameters: intercept=-20.4327, slope=0.147000
Today's actual: 40.130, formula predicts: 43.949, adjustment: -3.819
Day 0: GW=40.1%, lag_shift=+0, weighted_sum=438.0, adj=-3.82, pred=40.130
Day 10: GW=36.6%, lag_shift=+0, weighted_sum=406.0, adj=-3.13, pred=36.118
Day 20: GW=32.0%, lag_shift=+0, weighted_sum=372.6, adj=-2.56, pred=31.773
Day 30: GW=30.4%, lag_shift=+0, weighted_sum=355.5, adj=-2.10, pred=29.725
Day 40: GW=25.8%, lag_shift=+0, weighted_sum=325.6, adj=-1.72, pred=25.708
Day 50: GW=23.6%, lag_shift=+0, weighted_sum=309.2, adj=-1.40, pred=23.616
Day 60: GW=22.2%, lag_shift=+0, weighted_sum=297.7, adj=-1.15, pred=22.185
Day 70: GW=19.4%, lag_shift=+0, weighted_sum=277.7, adj=-0.94, pred=19.449
Day 80: GW=19.4%, lag_shift=+0, weighted_sum=274.9, adj=-0.77, pred=19.205
Day 90: GW=18.2%, lag_shift=+0, weighted_sum=268.5, adj=-0.63, pred=18.401
Day 100: GW=15.6%, lag_shift=+0, weighted_sum=245.5, adj=-0.52, pred=15.133
Day 110: GW=13.2%, lag_shift=+0, weighted_sum=231.5, adj=-0.42, pred=13.170
Predicted range: 12.185 to 40.343
✓ Saved calc_gw predictions to database
============================================================
SUCCESS: Daily update completed
============================================================
============================================================
PREDICTION SUMMARY
============================================================
CALC_GW:
average: 40.130 (day 1) → 25.560 (day 60)
+40%: 40.130 (day 1) → 28.932 (day 60)
-40%: 40.130 (day 1) → 22.188 (day 60)