1. このデモが何をしているか
気象衛星画像と数理モデル(数値天気予報, NWP)出力 を組み合わせて、 線形回帰ベースの災害危険度マップを 10 段階のカラーで衛星画像に重畳する 研究兼可視化デモです。 「画像モデルと数理モデルが等価か」という議論の入口を、実データと最小限のコードで触れるようにしてあります。
2. 全体パイプライン
[衛星画像] [数値モデル / 再解析]
Himawari B13 IR OpenMeteo (= GFS / ICON)
または ERA5 合成画像 または ERA5 archive
| |
+--------+--------+---------+
| |
[共通格子へ整列]
|
[画像分析で特徴量抽出 Tier 1-2]
[NWP変数をそのまま特徴量に追加]
|
[Ridge 回帰: y = β·x + β₀]
(目的変数 = precipitation mm/h)
|
[予測値を JMA 雨量階級 10 区分に離散化]
|
[リスクレベル毎の RGBA (α 制御) で
衛星画像に半透明オーバーレイ]
|
[cartopy で海岸線・国境を上から重畳]
|
[matplotlib で PNG → ffmpeg で MP4/GIF]
|
[vanilla JS で時系列スクラブ UI]
3. データソース
| レイヤ | 取得先 | 用途 |
|---|---|---|
| Himawari B13 IR タイル | JMA bosai 公式タイルサーバ | 2026 直近の実衛星画像 |
| OpenMeteo Forecast API | open-meteo.com | 直近〜数日のNWP変数 |
| ERA5 archive | open-meteo.com archive | 2022 Nanmadol の再解析 |
| 海岸線・国境 | Natural Earth 10m | cartopy 経由 |
取得した変数:
precipitation(目的変数)cloud_cover,cloud_cover_low/mid/highwind_speed_10m,pressure_mslrelative_humidity_2m,temperature_2m
4. 画像分析で抽出した特徴量
雲量バンド cloud_cover_high を入力画像 I とみなして、線形回帰の前に次の派生特徴を計算しています。
Tier 1 (ピクセルレベル)
- 生バンド輝度
- 他バンドとの差分 (cloud_mid / low / total)
Tier 2 (局所近傍オペレータ)
- 勾配 ∇I(Sobel x/y)
- ラプラシアン ∇²I — 対流コアの形状
- 局所平均・標準偏差(3×3, 7×7 窓)
- テクスチャ(分散)
これは数式的には 1×1 conv 層に手設計のフィルタバンクを連結したもの と等価です。 CNN の最低次の構成要素を、解釈可能な手書き版で実装している、という位置づけ。
5. 線形回帰の中身
各ピクセル (i, j) で:
risk(i,j) = β₀ + Σ_c β_c · φ_c(I)(i,j) + ε
- φ_c は上記の Tier 1-2 特徴量(13ch 程度)
- 正則化に Ridge(α=1.0)— 多重共線性対策
- 目的変数は 同時刻の precipitation
- R² は時刻 / 事例によって 0.30〜0.53
線形モデルの既知の限界:
Ridge は平均回帰の性質を持つので、強雨域(Lv7 以上)の極値を打てません。
実測で Lv7「激しい雨」が出ても予測は Lv4-5 で頭打ちになります。
解法は分位点回帰 / Tweedie GLM / 残差を CNN で学習する hybrid。
研究的にはここがベースライン→深層学習への跳躍点になります。
6. 10 段階離散化 (JMA 雨量階級準拠)
| Lv | 表示色 | 表現 | mm/h 区分 |
|---|---|---|---|
| 0 | no risk | < 0.5 | |
| 1 | trace | 0.5 – 1 | |
| 2 | light | 1 – 2 | |
| 3 | moderate | 2 – 4 | |
| 4 | fairly strong | 4 – 8 | |
| 5 | strong | 8 – 15 | |
| 6 | very strong | 15 – 25 | |
| 7 | intense | 25 – 40 | |
| 8 | very intense | 40 – 60 | |
| 9 | extreme | ≥ 60 |
7. 衛星画像 × リスクのオーバーレイ手法
- 下層:Himawari B13 IR(あるいは ERA5 合成 IR)をグレースケールで描画
- 上層:10 段階リスクを RGBA で重畳。α を level に応じて 0 → 0.86 までランプ させ、低リスクは透過、高リスクほど不透明に
- 最上層:Natural Earth 10m 解像度の海岸線・国境を黄色で重ねて、位置参照を可能に
ERA5 合成 IR (Nanmadol 用)
2022 のひまわり生画像が無料で取れないので、再解析から擬似衛星を合成しています。
synth_IR = 0.55 · (1 − normalized_pressure)
+ 0.30 · cloud_cover_high / 100
+ 0.15 · cloud_cover / 100
↓ ガンマ 0.85 ↓ 14倍 cubic 拡大 ↓ ガウシアン σ=1.6
低気圧(台風中心)が明るく、雲量が陰影を作るので、見た目は実IRに近い渦構造になります。
8. 時系列とビューワ
- 1 時間刻みで複数フレームを生成(June 2026: 13fr、Nanmadol: 24fr)
- ffmpeg で MP4 / GIF 化(palette 最適化 GIF)
- 単一 HTML(
viewer.html)+ vanilla JS の SPA:プリロード・スクラブ・キーボード操作対応 - 2 イベント切替対応(右上のスイッチ)
9. リポジトリ構成
typhoon_risk_demo/
├── demo.py # ベース実装(3 過去台風)
├── risk10.py # 10 段階離散化、色定義
├── risk10_overlay.py # 旧オーバーレイ(cloud-based)
├── risk_on_real_satellite.py # 実 Himawari 単発、CLI 引数で時刻指定
├── animate.py # 時系列アニメ生成(JMA tiles, ERA5 forecast)
├── nanmadol_demo.py # ERA5 archive 合成衛星 + 24h アニメ
├── cache/ # 衛星 PNG, OpenMeteo .npz キャッシュ
└── outputs/
├── viewer.html # 時系列ビューワ(本ページの親)
├── about.html # 本ページ
├── frames/ # June 2026 PNG(13枚)
├── frames_nanmadol/ # Nanmadol PNG(24枚)
├── typhoon_animation.* # MP4 / GIF
└── nanmadol_animation.* # MP4 / GIF
10. 既知の制限 / 次にできること
- 線形モデルの極値抑制:Lv7 以上が出ない。分位点回帰 / Tweedie / 残差CNN で改善
- 視差補正未実施:ひまわりは静止軌道なので雲頂の高い領域は地上座標から数 km ずれる。本格運用なら parallax correction が必要
- OpenMeteo / ERA5 のグリッドは粗い(0.25°)。XRAIN 250m と組み合わせれば対流コアの位置決めが上がる
- ハザード ≠ リスク:今回は降水量の予測。本来の災害リスクは人口・建物・流域などの曝露を掛けて初めて成立
- 2022 衛星画像:JAXA P-Tree(要登録)から本物を引っ張ってくれば合成 IR を置き換え可能