Multi-horizon river flow forecasting: gradient boosting over lagged rainfall and antecedent flow.
FloodGB is lag engineering plus multi-horizon orchestration around any scikit-learn regressor, not a model of its own. You supply the estimator; it builds the lagged feature matrix, trains one model per forecast lead hour, and fills the forecast window from the last observation forward.
It is built for floods. Evaluation is weighted toward flood peaks by design, because whole-record error is dominated by baseflow that antecedent flow already tracks — and that is not the part a flood forecast exists to get right.
Quick start
from floodgb import FloodGB
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.pipeline import make_pipeline
lags = {
rain_id: (1, 48, 'sum'), # DRIVER: one column per lag in [start, end]
river_id: (72, 24, 'mean'), # TARGET: (fore_len, target_period, agg)
} # fore_len is the number of models trained
m = FloodGB()
m.set_params([rain_id, river_id], river_id, 'h', lags)
m.set_model(make_pipeline(HistGradientBoostingRegressor(
loss='squared_error', max_iter=100, learning_rate=0.05, early_stopping=False)))
m.train_models([precip, flow], break_time='2015-07-31',
variables=['precipitation', 'streamflow'])
all_results, hf_results, max_results, predictions = m.test_models()
m.export('model.blt')
# later, operationally
forecast = FloodGB('model.blt').predict([precip, flow],
variables=['precipitation', 'streamflow'])
Input is a list of xarray.Dataset with time and station_id; name the measurement with variables=. Datasets are flattened to one wide frame and merged by station id, so rainfall and flow arrive separately.
Choosing which gauges to use
floodgb.selection answers the operational question: how few rain gauges can the model depend on? Every extra gauge is another telemetry feed that can fail during the storm the model exists to forecast.
from floodgb import evaluate_subsets
res = evaluate_subsets(model, [precip, flow], river_id, candidate_ids, lags, 'h',
time_steps=[6, 24, 72], break_times=['2011-07-01', '2014-07-01'],
variables=['precipitation', 'streamflow'])
res.frontier() # best subset at each size, per lead, with ties shown
It fits a model for every subset of the candidates and scores them all on one shared evaluation set. That is deliberately more expensive than ranking gauges by importance — and necessary, because no per-gauge score can express “these three are watching the same storm”. Rank and truncate, and you reliably select near-duplicates of one signal while discarding the independent gauges carrying the rest of it.
Three things it handles that a hand-rolled sweep usually does not:
Fabricated zeros. Resampling rainfall with sum turns every gap — including a gauge’s entire pre-record span — into measured zero rainfall, not missing data. Those rows are removed.
Comparability. Every subset is scored on the same rows, asserted at runtime.
The evaluation window is computed, never hardcoded. A recorded window is only correct for the station set it was computed over, and station sets change.
Read the frontier per lead, and pass several break_times: on real records the winning subset moves with the forecast horizon, and with the train/test split.
Requirements
Python ≥ 3.11, pandas ≥ 2.2 (tested to 3.0), scikit-learn ≥ 1.3.1. Exported artifacts embed the training frame and hold pickled estimators, so pin scikit-learn in any environment that loads them.
License
Apache-2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file floodgb-0.3.0.tar.gz.
File metadata
- Download URL: floodgb-0.3.0.tar.gz
- Upload date:
- Size: 26.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
446c75b0e74f2bb02c29c4e9ead0681b81a6d50b6e9223d8b7a949c6a8c3b31b
|
|
| MD5 |
fd05fe2cd1348de9a50d9430e07ec00b
|
|
| BLAKE2b-256 |
1a976553ee29ef30aa773b68a05d1a36e85f58ebc47c27d587e52b2a6ddeefdb
|
File details
Details for the file floodgb-0.3.0-py3-none-any.whl.
File metadata
- Download URL: floodgb-0.3.0-py3-none-any.whl
- Upload date:
- Size: 28.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e655264ef2cd6e7a8acf8ac289b3f499b1e82edd6e12014cef694239a3cbe13
|
|
| MD5 |
90b4fca3c3c4eb9e5cf2ccdd2f057aab
|
|
| BLAKE2b-256 |
b3a3decbad3e3a322977f5d9f959a08211130cf596dcdfa816ce8f96d43982f4
|