Skip to main content

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.

Metadata

Release files for floodgb 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for floodgb 0.3.0
File Size Uploaded
floodgb-0.3.0.tar.gz 26.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for floodgb 0.3.0
File Interpreter ABI Platform
floodgb-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 54.9 kB

Release files / floodgb-0.3.0.tar.gz

Download URL floodgb-0.3.0.tar.gz
Size 26.5 kB
Tags Source
SHA-256 checksum
How to use checksums
446c75b0e74f2bb02c29c4e9ead0681b81a6d50b6e9223d8b7a949c6a8c3b31b
BLAKE2b-256 checksum
How to use checksums
1a976553ee29ef30aa773b68a05d1a36e85f58ebc47c27d587e52b2a6ddeefdb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.7

Release files / floodgb-0.3.0-py3-none-any.whl

Download URL floodgb-0.3.0-py3-none-any.whl
Size 28.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e655264ef2cd6e7a8acf8ac289b3f499b1e82edd6e12014cef694239a3cbe13
BLAKE2b-256 checksum
How to use checksums
b3a3decbad3e3a322977f5d9f959a08211130cf596dcdfa816ce8f96d43982f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.7

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page