NeuralHydrologyで始める降雨流出解析入門:CudaLSTM→EA-LSTM→MTS-LSTM→MC-LSTM
1. はじめに
降雨流出解析では、現在の河川流量は「今の雨」だけでは決まりません。
数日前から数か月前までの降雨、気温、蒸発散、積雪、土壌水分、流域の地形・土地利用などが複雑に影響します。
従来は、タンクモデル、貯留関数法、キネマティックウェーブ法、分布型流出モデルなど、物理・経験式に基づくモデルが多く使われてきました。
一方で近年は、LSTMをはじめとする深層学習モデルを使った降雨流出解析も研究・実務プロトタイプとして注目されています。
その中で、水文分野向けに整備された代表的なPythonライブラリが NeuralHydrology です。
本記事では、NeuralHydrologyを使って水文LSTMを段階的に試す流れとして、次の4ステップで整理します。
Step 1: CudaLSTM + 日単位 + GenericDataset
Step 2: EA-LSTM + 静的流域属性
Step 3: MTS-LSTM + 多時間スケール
Step 4: MC-LSTM + 水収支を意識したモデル
本記事は、まずプロトタイプとしてNeuralHydrologyの考え方と進め方を整理するものです。
最初から高度なモデルを実務運用に使うのではなく、使用するデータ作成を行い、Step 1で確実に動く最小構成を作り、その後段階的に拡張する 方針とします。
2. NeuralHydrologyとは
NeuralHydrology は、水文分野、とくに降雨流出解析・河川流量予測を対象とした深層学習ライブラリです。
主な特徴は以下です。
NeuralHydrologyの特徴
- PyTorchベース
- YAML設定ファイルで学習・評価を制御
- CudaLSTM、EA-LSTM、MTS-LSTM、MC-LSTMなどを利用可能
- CAMELS系データセットだけでなく、独自データも扱える
- NSE、RMSE、KGEなど、水文でよく使われる評価指標を扱いやすい
- 研究・プロトタイプ開発に向いている
- 新しいモデル、データセット、損失関数、評価指標を追加しやすい
公式GitHubでは、NeuralHydrologyは「水文アプリケーションに強く焦点を当てたニューラルネットワーク学習用Pythonライブラリ」と説明されています。
3. なぜ水文でLSTMを使うのか
水文現象には過去の履歴である「記憶」があります。
たとえば、同じ10mmの雨でも、流域が乾いている場合と、数日前から雨が続いて湿っている場合では、流出量は大きく異なります。
過去の雨
↓
土壌水分・地下水・流域貯留
↓
現在の流量
LSTMは、時系列の過去情報を内部状態として保持できるモデルです。
そのため、降雨履歴や流域の湿潤状態をデータから学習するモデルとして、水文解析と相性が良いと考えられます。
ただし、LSTMは万能ではありません。
学習データにない規模の豪雨や、ダム操作、取水、河道改修などがある場合には、予測が不安定になることがあります。
そのため、LSTMを使うNeuralHydrologyを使う場合も、プロトタイプとして位置づけ、物理モデルや既存の水文モデルと比較しながら進めることが重要です。
4. 全体の進め方
本記事では、いきなり複雑なモデルを使うのではなく、次の順番で段階的に進めます。
Step 1
CudaLSTM + 日単位 + GenericDataset
まずは1流域または少数流域で、日雨量から日流量を予測する
Step 2
EA-LSTM
流域面積、標高、勾配、土地利用などの静的流域属性を加える
Step 3
MTS-LSTM
日単位と時間単位など、異なる時間スケールのデータを扱う
Step 4
MC-LSTM
雨量などの入力した量を保存する構造(水収支)を持つモデルに進む
実務プロトタイプとしては、まず Step 1で確実に動かすこと が重要です。
その後、複数流域化、短時間予測、物理整合性の順に拡張していくのが自然です。
5. 各ステップの目的
| Step | モデル | 主な目的 | 入力 | 難易度 |
|---|---|---|---|---|
| Step 1 | CudaLSTM | まず動かす | 日雨量、気温、蒸発散 | 低 |
| Step 2 | EA-LSTM | 流域属性を使う | Step 1 + 静的流域属性 | 中 |
| Step 3 | MTS-LSTM | 多時間スケールを扱う | 日単位 + 時間単位 | 高 |
| Step 4 | MC-LSTM | 水収支を意識する | 雨量をmass inputとして扱う | 高 |
6. Step 1:CudaLSTM + 日単位 + GenericDataset
Step 1の目的
Step 1では、NeuralHydrologyの基本操作に慣れることを目的にします。
ここでは、以下のような単純な降雨流出モデルを作ります。
入力:
- 日雨量
- 日平均気温
- 可能蒸発散量
出力:
- 日流量
モデルは、NeuralHydrologyの基本的なLSTMである CudaLSTM を使います。
CudaLSTMは、単一時間スケールの予測を対象とするLSTMモデルです。
まずは日単位の降雨流出解析に使い、NeuralHydrologyの基本的なデータ形式、設定ファイル、学習、評価の流れを確認します。
GenericDatasetとは
独自データでNeuralHydrologyを使う場合、まず検討したいのが GenericDataset です。
GenericDatasetは、NeuralHydrologyで用意されている汎用データセット形式です。
決められたフォルダ構成とNetCDF形式に合わせることで、独自の水文データを読み込めます。
基本的なフォルダ構成は次のようになります。
data/
├─ time_series/
│ ├─ basin_001.nc
│ ├─ basin_002.nc
│ └─ basin_003.nc
│
└─ attributes/
└─ attributes.csv
Step 1では、まず静的属性なしでも構いません。
最初は time_series のみで、日雨量・気温・蒸発散・流量を入れて試します。
入力データの例
各流域のNetCDFには、次のような日単位データを入れるイメージです。
| 変数名 | 内容 | 単位例 |
|---|---|---|
precipitation |
日雨量 | mm/day |
temperature |
日平均気温 | ℃ |
pet |
可能蒸発散量 | mm/day |
discharge |
日流量または流出高 | m3/s または mm/day |
NeuralHydrologyでは、設定ファイル内の dynamic_inputs と target_variables に書いた名前が、データ内の変数名と一致している必要があります。
basin listの例
学習・検証・テストに使う流域IDをテキストファイルで分けます。
basins_train.txt
basin_001
basin_002
basins_validation.txt
basin_003
basins_test.txt
basin_004
CudaLSTM用config例
以下は、日単位の降雨流出解析を行う最小構成に近い設定例です。
experiment_name: step1_cudalstm_daily_generic
run_dir: runs/
dataset: generic
data_dir: data/
train_basin_file: basins_train.txt
validation_basin_file: basins_validation.txt
test_basin_file: basins_test.txt
train_start_date: "01/01/2010"
train_end_date: "31/12/2018"
validation_start_date: "01/01/2019"
validation_end_date: "31/12/2020"
test_start_date: "01/01/2021"
test_end_date: "31/12/2023"
model: cudalstm
head: regression
dynamic_inputs:
- precipitation
- temperature
- pet
target_variables:
- discharge
seq_length: 365
predict_last_n: 1
hidden_size: 64
initial_forget_bias: 3
output_dropout: 0.2
optimizer: Adam
loss: NSE
learning_rate:
0: 0.001
10: 0.0005
20: 0.0001
batch_size: 64
epochs: 30
clip_gradient_norm: 1
metrics:
- NSE
- RMSE
- KGE
device: cuda:0
seq_length は入力系列長、predict_last_n は損失計算に使う末尾ステップ数です。
たとえば seq_length: 365、predict_last_n: 1 の場合、過去365日分の入力から最後の1日の流量を予測する形になります。
学習と評価
インストールは、通常は次のように行います。
pip install neuralhydrology
学習は次のように実行します。
nh-run train --config-file config_step1_cudalstm.yml
評価は次のように実行します。
nh-run evaluate --run-dir runs/step1_cudalstm_daily_generic_XXXXXX/
公式ドキュメントでは、コマンドラインから実行する方法と、PythonやJupyter NotebookからAPIを使う方法が紹介されています。
Step 1で確認すること
Step 1では、モデル精度そのものよりも、まず以下を確認します。
- データ形式が正しいか
- 欠測値や異常値がないか
- configの変数名がデータと一致しているか
- 学習が最後まで動くか
- 評価結果が出力されるか
- ハイドログラフが大きく破綻していないか
最初から高精度を狙うのではなく、NeuralHydrologyで独自水文データを読み、学習・評価する一連の流れを確認する段階 と考えるのが良いです。
7. Step 2:EA-LSTM + 静的流域属性
Step 2の目的
Step 2では、複数流域を対象にし、流域ごとの違いをモデルに学習させます。
Step 1のCudaLSTMでは、主に時系列入力を使います。
Step 2の EA-LSTM では、時系列入力に加えて、流域面積、標高、勾配、土地利用、地質などの 静的流域属性 を使います。
EA-LSTMは、標準LSTMの変種として提案されたモデルです。
静的入力によって入力ゲートを調整し、流域ごとの特徴を学習しやすくする点が特徴です。
流域属性の例
data/attributes/attributes.csv に、流域ごとの属性を整理します。
basin_id,area,mean_elevation,mean_slope,forest_ratio,urban_ratio
basin_001,120.5,430.2,0.18,0.72,0.05
basin_002,85.1,250.7,0.12,0.48,0.18
basin_003,210.4,680.1,0.25,0.81,0.02
属性の例です。
| 属性 | 内容 |
|---|---|
area |
流域面積 |
mean_elevation |
平均標高 |
mean_slope |
平均勾配 |
forest_ratio |
森林率 |
urban_ratio |
市街地率 |
geology_code |
地質区分 |
river_length |
河道長 |
basin_shape |
流域形状指標 |
EA-LSTM用configの変更点
Step 1からの主な変更点は、model: ealstm と static_attributes です。
model: ealstm
head: regression
dynamic_inputs:
- precipitation
- temperature
- pet
static_attributes:
- area
- mean_elevation
- mean_slope
- forest_ratio
- urban_ratio
target_variables:
- discharge
Step 2で期待する効果
EA-LSTMでは、流域ごとの特性を静的属性として与えることで、単一流域ではなく、複数流域をまとめて学習しやすくなります。
たとえば、同じ雨量でも、次のような流域差があります。
急勾配・森林多い流域
→ 反応が速い可能性
平坦・市街地が多い流域
→ 流出特性が異なる可能性
大きな流域
→ 流出の遅れが大きい可能性
EA-LSTMは、こうした流域の個性を静的属性として学習し、複数流域にまたがるモデルを作るための重要なステップになります。
Step 2で確認すること
Step 2では、以下を確認します。
- 静的属性CSVが正しく読まれているか
- 流域IDがNetCDFファイル名・basin list・attributes.csvで一致しているか
- 単一流域モデルより複数流域モデルの性能が改善するか
- 流域ごとのNSE、RMSE、KGEに偏りがないか
- 山地流域、都市流域、大流域、小流域で誤差傾向が異なるか
Step 2の目的は、流域属性を使って、複数流域に対応できる水文LSTMへ拡張すること です。
8. Step 3:MTS-LSTM + 多時間スケール
Step 3の目的
Step 3では、日単位だけでなく、時間単位の入力も扱います。
洪水予測では、長期的な流域湿潤状態と、直近の短時間強雨の両方が重要です。
長期の状態:
過去数か月の日雨量、気温、蒸発散
短期の反応:
直近数時間の時間雨量、水位、流量
このような場合に使う候補が MTS-LSTM です。
MTS-LSTMは、日単位・時間単位などの多時間スケールの予測を1つのモデルで扱うLSTMアーキテクチャです。
低い時間スケールの入力で長期的な状態を処理し、その後、対象時間スケールごとに分岐して予測を行う考え方です。
考えられる入力データ
たとえば、次のような構成が考えられます。
| 時間スケール | 入力 | 目的 |
|---|---|---|
| 日単位 | 日雨量、日平均気温、日蒸発散 | 流域の長期的な湿潤状態を表現 |
| 時間単位 | 時間雨量、時間水位、時間流量 | 洪水時の短時間応答を表現 |
MTS-LSTM用configのイメージ
MTS-LSTMでは、use_frequencies を使って複数の時間スケールを指定します。
また、seq_length と predict_last_n は時間スケールごとの辞書形式で指定します。
model: mtslstm
head: regression
use_frequencies:
- 1D
- 1h
dynamic_inputs:
1D:
- precipitation_daily
- temperature_daily
- pet_daily
1h:
- precipitation_hourly
- water_level_hourly
target_variables:
- discharge
seq_length:
1D: 365
1h: 72
predict_last_n:
1D: 1
1h: 24
hidden_size:
1D: 64
1h: 64
shared_mtslstm: False
この設定はあくまで概念例です。
実データに合わせて、変数名、時間スケール、対象期間を調整します。
Step 3で注意すること
MTS-LSTMは強力ですが、Step 1やStep 2よりデータ整備が難しくなります。
特に注意する点は以下です。
- 日単位データと時間単位データの時刻整合
- 欠測の扱い
- 時間雨量の累積・単位
- 水位と流量の関係
- 洪水イベントの偏り
- 学習データ量の不足
Step 3ではまず、日単位と時間単位を同時に扱う実験モデル として位置づけ、運用予測に使う前に十分な検証を行うことが重要です。
Step 3で確認すること
Step 3では、日単位と時間単位などの多時間スケールデータを同時に扱うため、Step 1・Step 2よりも確認項目が増えます。
特に以下を確認します。
- 日単位データと時間単位データの時刻が正しく対応しているか
- 雨量、流量、水位の単位が時間スケールごとに整理されているか
-
use_frequencies、dynamic_inputs、seq_length、predict_last_nの設定が整合しているか - 日単位入力が長期的な湿潤状態の表現に役立っているか
- 時間単位入力が洪水時の短時間応答を表現できているか
- 洪水ピークの時刻と大きさを再現できているか
- 洪水の立ち上がり部と逓減部が不自然になっていないか
- 時間単位だけのモデルと比べて、多時間スケール化による改善があるか
- 欠測値や時刻ずれが予測結果に悪影響を与えていないか
- 学習期間に含まれない大雨イベントで極端に不安定な予測にならないか
Step 3の目的は、単に時間単位データを追加することではありません。
日単位データで流域の長期的な湿潤状態を捉え、時間単位データで洪水時の短時間応答を捉えること が重要です。
そのため、評価ではNSEやRMSEだけでなく、洪水ピークの再現性、ピーク時刻のずれ、立ち上がりの再現性も確認する必要があります。
9. Step 4:MC-LSTM + 水収支を意識したモデル
Step 4の目的
Step 4では、通常のLSTMよりも物理整合性を意識したモデルに進みます。
通常のLSTMは、必ずしも水収支を守るわけではありません。
入力された雨量に対して、どれだけが流出し、どれだけが貯留され、どれだけが失われるかは、明示的には制約されません。
そこで候補になるのが MC-LSTM です。
MC-LSTMは、Mass-Conserving LSTMの略で、直訳すると「質量保存型LSTM」です。水文分野では、降雨などの入力水量を内部で保存・配分しながら流出を予測する、水収支を意識したLSTMモデル と考えると分かりやすいです。
水文では、降雨を入力水量として扱い、内部の貯留・再配分・流出を表現する考え方と相性があります。
水文での水収支の考え方
水文で水収支を考える場合、もっとも自然な入力は雨量です。
入力:
降雨 P(t)
内部:
流域貯留 S(t)
出力:
流出 Q(t)
通常のLSTMでは、P(t)からQ(t)を直接学習します。
MC-LSTMでは、P(t)という入力水量を内部セルに分配・再配分し、出力として流出を出すイメージになります。
降雨 P(t)
↓
MC-LSTM内部セルに分配
↓
貯留・再配分
↓
流出 Q(t)
MC-LSTM用configのイメージ
MC-LSTMでは、mass_inputs を指定します。
ここでは、雨量を水収支上の入力水量として扱う例にします。
model: mclstm
head: regression
dynamic_inputs:
- precipitation
- temperature
- pet
mass_inputs:
- precipitation
target_variables:
- discharge
seq_length: 365
predict_last_n: 1
hidden_size: 64
initial_forget_bias: -3
MC-LSTMでは、雨量を単なる説明変数ではなく、水収支上の入力水量として扱う点が重要です。
Step 4で確認すること
MC-LSTMでは、精度だけでなく、以下を確認します。
- ピーク流量の再現性
- 洪水立ち上がりの再現性
- 低水時の安定性
- 水収支の違和感が小さいか
- 内部状態が水文的に解釈可能か
- 通常のCudaLSTMやEA-LSTMと比べて改善があるか
Step 4は、実務プロトタイプというより、物理整合性を意識した研究・検証段階 と考えるのが良いです。
10. 実装ロードマップ
実装としては、次の順番で進め行きます。
1. サンプルデータを作る
- basin_001.nc
- basin_002.nc
- basin_003.nc
2. GenericDataset形式で読み込む
- time_seriesフォルダ
- attributesフォルダ
3. Step 1のCudaLSTMを動かす
- 日単位
- 1流域または少数流域
4. 評価指標を確認する
- NSE
- RMSE
- KGE
- ハイドログラフ
5. Step 2でEA-LSTMにする
- 静的流域属性を追加
- 複数流域で学習
6. Step 3でMTS-LSTMにする
- 日単位 + 時間単位
- 短時間洪水予測へ拡張
7. Step 4でMC-LSTMにする
- 雨量をmass inputとして扱う
- 水収支・物理整合性を確認
11. 評価指標
水文モデルでは、単純なMSEやRMSEだけでなく、NSEやKGEもよく使われます。
| 指標 | 内容 |
|---|---|
| NSE | Nash-Sutcliffe Efficiency。流量再現性の代表的指標 |
| RMSE | 二乗平均平方根誤差 |
| KGE | Kling-Gupta Efficiency。相関、バイアス、変動性を総合評価 |
| MAE | 平均絶対誤差 |
| Peak error | 洪水ピークの誤差 |
NeuralHydrologyでは、設定ファイルの metrics に評価指標を指定できます。
12. 注意点
12.1. データ品質が最重要
LSTMは、入力データの癖をそのまま学習します。
雨量・流量・水位に欠測、異常値、単位ミス、時刻ずれがあると、簡単におかしなモデルになります。
特に以下は必ず確認します。
- 雨量の単位
- 流量の単位
- 時刻のタイムゾーン
- 欠測値
- 異常なピーク
- ダム操作や取水の影響
- 流域改変の履歴
12.2. 単一流域だけで過信しない
Step 1では単一流域でも構いませんが、LSTMの強みは大量データ・複数流域学習で発揮されやすいです。
単一流域だけで高精度に見えても、別期間や別流域で性能が落ちる可能性があります。
12.3. 未経験豪雨には注意
学習期間に存在しない規模の豪雨や洪水に対して、深層学習モデルは不安定になる可能性があります。
そのため、実務利用では以下の確認が必要です。
- 極端降雨時の挙動
- ピーク流量の過小評価
- 外挿時の安定性
- 物理的にあり得ない予測値が出ないか
12.4. 物理モデルとのハイブリッドも検討する
NeuralHydrologyは、LSTMだけでなく、概念的水文モデルとの組み合わせも研究されています。
将来的には、次のような方向も考えられます。
LSTMで状態量やパラメータを推定
↓
タンクモデル・貯留関数モデル・分布型モデルへ入力
↓
物理整合性を保ちながら予測
このため、NeuralHydrologyは「既存の水文モデルを完全に置き換えるもの」ではなく、データ駆動型モデルと物理モデルを組み合わせるための実験基盤 として捉えるとよいです。
13. まとめ
NeuralHydrologyは、水文分野でLSTM系モデルを試すための非常に有力なライブラリです。
ただし、最初から高度なモデルを使うよりも、以下のように段階的に進めるのが現実的です。
まずは対象とする流域を決めてデータを集めましょう。
Step 1: CudaLSTM + 日単位 + GenericDataset
→ まず独自データで学習・評価を動かす
Step 2: EA-LSTM
→ 流域面積、標高、土地利用などの静的属性を使う
Step 3: MTS-LSTM
→ 日単位と時間単位を組み合わせ、短時間予測へ進む
Step 4: MC-LSTM
→ 雨量などの入力水量を考慮し、水収支の観点から物理整合性を高める
実務プロトタイプとしては、まず Step 1のCudaLSTM + 日単位 + GenericDataset を確実に動かすことが重要です。
その後、EA-LSTMで複数流域化し、MTS-LSTMで時間雨量や短時間洪水予測へ拡張し、最終的にMC-LSTMやハイブリッドモデルで物理整合性を高めていく流れが良いと考えます。
14. 参考リンク
公式・ドキュメント
- NeuralHydrology GitHub
- NeuralHydrology Documentation
- Quick Start
- Configuration Arguments
- Modelzoo
- GenericDataset Documentation
- Adding a New Dataset
モデル別ドキュメント
論文・解説
- NeuralHydrology JOSS Paper
- NeuralHydrology — A Python library for Deep Learning research in hydrology
- Rainfall–runoff modelling using Long Short-Term Memory networks
- NeuralHydrology — Interpreting LSTMs in Hydrology
- Towards Learning Universal, Regional, and Local Hydrological Behaviors
- Rainfall-Runoff Prediction at Multiple Timescales with a Single LSTM Network
- MC-LSTM: Mass-Conserving LSTM
- Multi-Timescale LSTM for Rainfall–Runoff Forecasting

