Initial FireWx-FM artifact release
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitignore +6 -0
- LICENSE +9 -0
- README.md +146 -0
- artifacts/manifests/paper_outputs.sha256 +20 -0
- artifacts/manifests/paper_outputs.yml +60 -0
- artifacts/results/fireprone_contract_progression_summary.json +0 -0
- artifacts/results/fireprone_contract_progression_table.generated.tex +69 -0
- artifacts/results/selection_regret_all_backbones_20260504.csv +25 -0
- artifacts/results/selection_regret_all_backbones_20260504.json +0 -0
- artifacts/results/selection_regret_full_head_table.generated.tex +2 -0
- artifacts/results/selection_regret_head_metrics.csv +241 -0
- artifacts/results/selection_regret_main_table.generated.tex +24 -0
- artifacts/results/selection_regret_per_seed.csv +121 -0
- artifacts/results/selection_regret_rq2_figure_values.csv +12 -0
- artifacts/results/selection_regret_scope_sweep_20260505.csv +45 -0
- artifacts/results/selection_regret_scope_sweep_20260505.generated.tex +24 -0
- artifacts/results/selection_regret_scope_sweep_20260505.json +0 -0
- artifacts/results/selection_regret_summary.csv +25 -0
- artifacts/results/selection_regret_tolerance_family_table.generated.tex +2 -0
- data_sources/DATA_SOURCES.md +27 -0
- docs/artifact_map.md +56 -0
- docs/huggingface_release_design.md +16 -0
- experiments/README.md +25 -0
- experiments/raw_reference/run_selection_regret_scope_sweep_20260505.py +335 -0
- experiments/raw_reference/task_scripts/run_all_backbone_selection_regret_20260504.py +656 -0
- experiments/raw_reference/task_scripts/run_analog_extended_retrieval_sweep_seeded.py +333 -0
- experiments/raw_reference/task_scripts/run_event_analog_taskmodel_seeded.py +350 -0
- experiments/raw_reference/task_scripts/run_extreme_heat_alphaearth_suite_seeded.py +344 -0
- experiments/raw_reference/task_scripts/run_final_area_taskmodel_seeded.py +353 -0
- experiments/raw_reference/task_scripts/run_smoke_pm25_alphaearth_suite_seeded.py +306 -0
- experiments/raw_reference/task_scripts/run_smoke_pm25_attached_fm_suite_seeded.py +231 -0
- experiments/raw_reference/task_scripts/summarize_forced_meanstd_20260429.py +232 -0
- experiments/slurm/submit_template.sbatch +13 -0
- paper_outputs/figures/fig_fireprone_contract_progression_compact.pdf +262 -0
- paper_outputs/figures/fig_selection_regret_rq2.tikz +120 -0
- paper_outputs/figures/fig_task_contract_tiles.pdf +0 -0
- paper_outputs/figures/fig_task_rank_map.pdf +348 -0
- paper_outputs/figures/matching.pdf +0 -0
- paper_outputs/tables/tab_app_analog_rank_depth.tex +24 -0
- paper_outputs/tables/tab_app_burned_area_median_acre.tex +24 -0
- paper_outputs/tables/tab_app_contract_params_full.tex +22 -0
- paper_outputs/tables/tab_app_head_architectures.tex +36 -0
- paper_outputs/tables/tab_app_heat_event_pr.tex +24 -0
- paper_outputs/tables/tab_app_matching_rule_params.tex +17 -0
- paper_outputs/tables/tab_app_occupancy_ppr_scope.tex +27 -0
- paper_outputs/tables/tab_app_scope_params.tex +19 -0
- paper_outputs/tables/tab_app_seed_robustness.tex +36 -0
- paper_outputs/tables/tab_app_smoke_high_event.tex +24 -0
- paper_outputs/tables/tab_app_spread_ap_by_scope.tex +24 -0
- paper_outputs/tables/tab_appendix_selection_regret_tolerance.tex +37 -0
.gitignore
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
*.py[cod]
|
| 3 |
+
.DS_Store
|
| 4 |
+
.ipynb_checkpoints/
|
| 5 |
+
*.log
|
| 6 |
+
tmp/
|
LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
This release is provided for scholarly reproducibility of the associated paper.
|
| 2 |
+
|
| 3 |
+
Code files are released under the MIT License.
|
| 4 |
+
Paper-output tables, figures, and bundled summary artifacts are released for
|
| 5 |
+
non-commercial research and review use with attribution.
|
| 6 |
+
|
| 7 |
+
Raw data from NOAA, NASA, LANDFIRE, Wildfire Risk to Communities, LandScan,
|
| 8 |
+
WFIGS, MTBS, and model providers are not redistributed here. Users must obtain
|
| 9 |
+
those data from the original providers and comply with their terms.
|
README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
tags:
|
| 4 |
+
- wildfire
|
| 5 |
+
- geospatial
|
| 6 |
+
- earth-observation
|
| 7 |
+
- foundation-models
|
| 8 |
+
- evaluation
|
| 9 |
+
- reproducibility
|
| 10 |
+
- paper-artifact
|
| 11 |
+
pretty_name: FireWx-FM and Wildfire Evaluation Contracts
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# FireWx-FM and Wildfire Evaluation Contracts
|
| 15 |
+
|
| 16 |
+
This repository contains the public code and lightweight artifacts for the
|
| 17 |
+
paper *Does Your Wildfire Prediction Model Actually Work, or Just Score Well?*
|
| 18 |
+
|
| 19 |
+
The release has two parts:
|
| 20 |
+
|
| 21 |
+
- **FireWx-FM reference backbone artifacts.** FireWx-FM is a wildfire-specialized
|
| 22 |
+
reference model used as an in-domain comparator in the paper.
|
| 23 |
+
- **Fixed-contract evaluation artifacts.** The paper evaluates wildfire transfer
|
| 24 |
+
under fixed task, metric, matching-rule, scope, and head-family choices.
|
| 25 |
+
|
| 26 |
+
This is a paper-artifact repository. It includes scripts, compact summary files,
|
| 27 |
+
paper tables, and paper figures needed to inspect and reproduce reported
|
| 28 |
+
outputs. It does **not** redistribute raw weather, fire, fuel, exposure,
|
| 29 |
+
incident, perimeter, feature-cache, or private model files.
|
| 30 |
+
|
| 31 |
+
## Key Results in the Release
|
| 32 |
+
|
| 33 |
+
The bundled paper outputs reproduce the main results reported in the manuscript.
|
| 34 |
+
|
| 35 |
+
| Check | Paper artifact | What it shows |
|
| 36 |
+
|---|---|---|
|
| 37 |
+
| Matching-rule sensitivity (RQ1) | `paper_outputs/figures/fig_fireprone_contract_progression_compact.pdf` | The same occupancy outputs can move sharply from exact to tolerated to union \(F_1\), especially under fire-prone scopes. |
|
| 38 |
+
| Fixed-feature head selection (RQ2) | `paper_outputs/figures/fig_selection_regret_rq2.tikz` | Selecting a head by ranking evidence can lose decision performance relative to direct decision selection. |
|
| 39 |
+
| Same-contract transfer matrix (RQ3) | `paper_outputs/tables/tab_primary_results.tex` | FireWx-FM, Prithvi-WxC, Aurora, ClimaX, StormCast, DLWP, FCN, FengWu, FuXi, Pangu-Weather, and AlphaEarth are compared under fixed occupancy and spread contracts. |
|
| 40 |
+
| Supporting task forms (RQ4) | `paper_outputs/tables/tab_supporting_results.tex` and `paper_outputs/figures/fig_task_rank_map.pdf` | Backbone ranking changes across burned area, analog retrieval, smoke PM2.5, and extreme heat task forms. |
|
| 41 |
+
|
| 42 |
+
Selected displayed values from the paper:
|
| 43 |
+
|
| 44 |
+
- FireWx-FM reference occupancy union \(F_1\): `59.0656 ± 2.7372`.
|
| 45 |
+
- ClimaX occupancy union \(F_1\): `60.1506 ± 7.5865`.
|
| 46 |
+
- FireWx-FM fire-spread AP: `30.0900 ± 1.2500`.
|
| 47 |
+
- FireWx-FM smoke PM2.5 RMSE: `4.4646 ± 0.0060`.
|
| 48 |
+
- AlphaEarth smoke PM2.5 RMSE: `4.4403 ± 0.0488`.
|
| 49 |
+
|
| 50 |
+
Values are stored as TeX table cells under `paper_outputs/tables/`. The
|
| 51 |
+
corresponding compact CSV/JSON summaries are under `artifacts/results/`.
|
| 52 |
+
|
| 53 |
+
## Repository Layout
|
| 54 |
+
|
| 55 |
+
```text
|
| 56 |
+
artifacts/
|
| 57 |
+
manifests/ table/figure provenance metadata and SHA-256 hashes
|
| 58 |
+
results/ compact CSV/JSON summaries used by paper outputs
|
| 59 |
+
data_sources/ source list and download notes for raw data
|
| 60 |
+
docs/ artifact map and Hugging Face release notes
|
| 61 |
+
experiments/ sanitized raw-rerun scripts and Slurm templates
|
| 62 |
+
paper_outputs/
|
| 63 |
+
figures/ PDF/TikZ figures used by the manuscript
|
| 64 |
+
tables/ TeX table blocks used by the manuscript
|
| 65 |
+
scripts/ release rebuild and audit scripts
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
## Quick Reproduction
|
| 69 |
+
|
| 70 |
+
The paper-output path uses only the Python standard library.
|
| 71 |
+
|
| 72 |
+
```bash
|
| 73 |
+
python3 scripts/reproduce_paper_outputs.py
|
| 74 |
+
```
|
| 75 |
+
|
| 76 |
+
This command:
|
| 77 |
+
|
| 78 |
+
- rebuilds the RQ1 fire-prone progression figure from summary JSON;
|
| 79 |
+
- rebuilds the RQ2 selection-regret TikZ figure from CSV;
|
| 80 |
+
- rebuilds the RQ4 rank-map PDF from the released main tables;
|
| 81 |
+
- checks SHA-256 hashes for all final paper outputs;
|
| 82 |
+
- audits that stale labels, local paths, and incomplete placeholders are absent.
|
| 83 |
+
|
| 84 |
+
Expected terminal tail:
|
| 85 |
+
|
| 86 |
+
```text
|
| 87 |
+
Paper-output checksum check passed.
|
| 88 |
+
Release audit passed.
|
| 89 |
+
Rebuilt reproducible outputs and passed release audit.
|
| 90 |
+
```
|
| 91 |
+
|
| 92 |
+
## What Is Included
|
| 93 |
+
|
| 94 |
+
- Final paper table TeX files under `paper_outputs/tables/`.
|
| 95 |
+
- Final paper figures under `paper_outputs/figures/`.
|
| 96 |
+
- Small released CSV/JSON summary artifacts under `artifacts/results/`.
|
| 97 |
+
- Builder scripts for reproducible paper-output figures under `scripts/`.
|
| 98 |
+
- Sanitized raw-rerun reference scripts under `experiments/raw_reference/`.
|
| 99 |
+
- Data-source documentation under `data_sources/DATA_SOURCES.md`.
|
| 100 |
+
- A table/figure provenance map under `docs/artifact_map.md`.
|
| 101 |
+
|
| 102 |
+
## What Is Not Included
|
| 103 |
+
|
| 104 |
+
Raw data are not bundled. The paper uses public or provider-hosted resources,
|
| 105 |
+
including NOAA HRRR, NASA FIRMS, LANDFIRE, Wildfire Risk to Communities,
|
| 106 |
+
LandScan, WFIGS, MTBS, and external Earth-FM/backbone sources.
|
| 107 |
+
|
| 108 |
+
See `data_sources/DATA_SOURCES.md` for the role of each source and public access
|
| 109 |
+
entry points. Full raw-data reruns require users to obtain those sources
|
| 110 |
+
independently and rebuild local feature caches.
|
| 111 |
+
|
| 112 |
+
## Reproducibility Scope
|
| 113 |
+
|
| 114 |
+
There are two levels of reproducibility:
|
| 115 |
+
|
| 116 |
+
1. **Paper-output reproduction from bundled artifacts.** This is lightweight and
|
| 117 |
+
does not require raw data, GPUs, or Slurm. It verifies the exact files used by
|
| 118 |
+
the manuscript.
|
| 119 |
+
2. **Raw-data reruns.** These require separately downloaded source data, local
|
| 120 |
+
preprocessing, model dependencies, and compute resources. The repository
|
| 121 |
+
provides sanitized scripts and Slurm templates, but not the raw inputs.
|
| 122 |
+
|
| 123 |
+
## Intended Use
|
| 124 |
+
|
| 125 |
+
Use this repository to inspect paper values, reproduce released figures from
|
| 126 |
+
summary artifacts, audit table/figure provenance, or adapt the fixed-contract
|
| 127 |
+
evaluation workflow for wildfire transfer studies.
|
| 128 |
+
|
| 129 |
+
Do not use this repository as a raw dataset mirror. Do not treat the included
|
| 130 |
+
summary artifacts as a substitute for the original data sources.
|
| 131 |
+
|
| 132 |
+
## Citation
|
| 133 |
+
|
| 134 |
+
If you use this release, please cite:
|
| 135 |
+
|
| 136 |
+
```bibtex
|
| 137 |
+
@misc{wildfire_fm_evaluation_contracts_2026,
|
| 138 |
+
title = {Does Your Wildfire Prediction Model Actually Work, or Just Score Well?},
|
| 139 |
+
author = {Anonymous},
|
| 140 |
+
year = {2026},
|
| 141 |
+
note = {FireWx-FM and fixed-contract wildfire evaluation code and artifacts}
|
| 142 |
+
}
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
The BibTeX entry will be updated with arXiv metadata after the preprint is
|
| 146 |
+
public.
|
artifacts/manifests/paper_outputs.sha256
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
b369d13e0419fa8272ccdc994b6642f3b141248a879c030218e387c583537eb2 paper_outputs/figures/fig_fireprone_contract_progression_compact.pdf
|
| 2 |
+
b2e56403e2774c457dd12c4685e2dc7492e22e32df46fcc5c37b3087110f2439 paper_outputs/figures/fig_selection_regret_rq2.tikz
|
| 3 |
+
bc4d35ad9cb4c1f9ba8f31c7c340d9684c9dd2d55f5a2e60604a2b58b90cbe40 paper_outputs/figures/fig_task_contract_tiles.pdf
|
| 4 |
+
c382f5d69f25cc2f5db174601a33d0fd0928b44910a2a4b1c131954bd42113d9 paper_outputs/figures/fig_task_rank_map.pdf
|
| 5 |
+
015ab951b0af5c130e4894092a5dd0bb0fd62e710467163a9df8246d8cf369f4 paper_outputs/figures/matching.pdf
|
| 6 |
+
e8abbd2668517f5cae14933ed943fe103e74132886b0ff48ecd1685978549504 paper_outputs/tables/tab_app_analog_rank_depth.tex
|
| 7 |
+
81db28aace3366625f1cfd5935892eb5af672d5ecd8327e6dcba00b7b04e2b3c paper_outputs/tables/tab_app_burned_area_median_acre.tex
|
| 8 |
+
4a93401ef355c02eb0cc6b2e9a1506f9ed9d912301ec6829581247e40991bdfb paper_outputs/tables/tab_app_contract_params_full.tex
|
| 9 |
+
3c5398c28e6243b1784b27d2e9eab1a5c60e6e6d2cfd14a79aa6fd1e0499b871 paper_outputs/tables/tab_app_head_architectures.tex
|
| 10 |
+
f740b8f076490e852efa88fa8180ca08bb6b12901ff3ec3687c7e5c0b236da4e paper_outputs/tables/tab_app_heat_event_pr.tex
|
| 11 |
+
86e97a394ceae8cc6eafd6d1021b44d13a117378ead87bfee662cc90a1e0e54b paper_outputs/tables/tab_app_matching_rule_params.tex
|
| 12 |
+
0b1ad4587dd440fdabf771000b1c971daa9222e946a3404c9beae10dd7ea67c6 paper_outputs/tables/tab_app_occupancy_ppr_scope.tex
|
| 13 |
+
4e79672c28a938cd9ba1bc0e423e7169eca389251a22357aff6fe84d3cbfa889 paper_outputs/tables/tab_app_scope_params.tex
|
| 14 |
+
6850ee131e203f66392c79f17f59214672b362274f42285b252b83ac0ede1eb3 paper_outputs/tables/tab_app_seed_robustness.tex
|
| 15 |
+
1ca91ca451f846e59cb62ea64a616780c698b9dee80918a05467bd6c40df2dd5 paper_outputs/tables/tab_app_smoke_high_event.tex
|
| 16 |
+
cd65372622e8dd388adb1122a3e93b22d2090fba836405b08a078d5159b182de paper_outputs/tables/tab_app_spread_ap_by_scope.tex
|
| 17 |
+
a31d4a4e0f2f1c7f90a5610acea77aef5a48e63c754ab2159a42473dce2c3b94 paper_outputs/tables/tab_appendix_selection_regret_tolerance.tex
|
| 18 |
+
22614e90568cc562c023c540bdfdec14c0923ecf55d432fffa2619625b856092 paper_outputs/tables/tab_fireprone_contract_progression.tex
|
| 19 |
+
6672c62a150d83a351f4fa23ac04537d9aaae01af6056f689437d9b7d8bcee40 paper_outputs/tables/tab_primary_results.tex
|
| 20 |
+
717555b2584658c936aa8fc27b63f1068dc5f796a297bcef0576cf020b3ddaf8 paper_outputs/tables/tab_supporting_results.tex
|
artifacts/manifests/paper_outputs.yml
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
figures:
|
| 2 |
+
fig:toy_occupancy_contract:
|
| 3 |
+
output: paper_outputs/figures/matching.pdf
|
| 4 |
+
type: static_vector
|
| 5 |
+
fig:task_contract_tiles:
|
| 6 |
+
output: paper_outputs/figures/fig_task_contract_tiles.pdf
|
| 7 |
+
type: static_vector
|
| 8 |
+
fig:selection_regret_diagnostic:
|
| 9 |
+
output: paper_outputs/figures/fig_selection_regret_rq2.tikz
|
| 10 |
+
builder: scripts/build_selection_regret_rq2_figure.py
|
| 11 |
+
inputs:
|
| 12 |
+
- artifacts/results/selection_regret_scope_sweep_20260505.csv
|
| 13 |
+
fig:fireprone_contract_progression:
|
| 14 |
+
output: paper_outputs/figures/fig_fireprone_contract_progression_compact.pdf
|
| 15 |
+
builder: scripts/build_fireprone_contract_progression_figure.py
|
| 16 |
+
inputs:
|
| 17 |
+
- artifacts/results/fireprone_contract_progression_summary.json
|
| 18 |
+
fig:task_comparator_normalized_map:
|
| 19 |
+
output: paper_outputs/figures/fig_task_rank_map.pdf
|
| 20 |
+
builder: scripts/build_task_rank_map.py
|
| 21 |
+
inputs:
|
| 22 |
+
- paper_outputs/tables/tab_primary_results.tex
|
| 23 |
+
- paper_outputs/tables/tab_supporting_results.tex
|
| 24 |
+
tables:
|
| 25 |
+
tab:primary_results:
|
| 26 |
+
output: paper_outputs/tables/tab_primary_results.tex
|
| 27 |
+
tab:supporting_results:
|
| 28 |
+
output: paper_outputs/tables/tab_supporting_results.tex
|
| 29 |
+
tab:app_matching_rule_params:
|
| 30 |
+
output: paper_outputs/tables/tab_app_matching_rule_params.tex
|
| 31 |
+
tab:app_contract_params_full:
|
| 32 |
+
output: paper_outputs/tables/tab_app_contract_params_full.tex
|
| 33 |
+
tab:app_scope_params:
|
| 34 |
+
output: paper_outputs/tables/tab_app_scope_params.tex
|
| 35 |
+
tab:fireprone_contract_progression:
|
| 36 |
+
output: paper_outputs/tables/tab_fireprone_contract_progression.tex
|
| 37 |
+
inputs:
|
| 38 |
+
- artifacts/results/fireprone_contract_progression_summary.json
|
| 39 |
+
tab:appendix_selection_regret_tolerance:
|
| 40 |
+
output: paper_outputs/tables/tab_appendix_selection_regret_tolerance.tex
|
| 41 |
+
inputs:
|
| 42 |
+
- artifacts/results/selection_regret_all_backbones_20260504.csv
|
| 43 |
+
tab:app_occupancy_ppr_scope:
|
| 44 |
+
output: paper_outputs/tables/tab_app_occupancy_ppr_scope.tex
|
| 45 |
+
inputs:
|
| 46 |
+
- artifacts/results/fireprone_contract_progression_summary.json
|
| 47 |
+
tab:app_spread_ap_by_scope:
|
| 48 |
+
output: paper_outputs/tables/tab_app_spread_ap_by_scope.tex
|
| 49 |
+
tab:app_burned_area_median_acre:
|
| 50 |
+
output: paper_outputs/tables/tab_app_burned_area_median_acre.tex
|
| 51 |
+
tab:app_analog_rank_depth:
|
| 52 |
+
output: paper_outputs/tables/tab_app_analog_rank_depth.tex
|
| 53 |
+
tab:app_smoke_high_event:
|
| 54 |
+
output: paper_outputs/tables/tab_app_smoke_high_event.tex
|
| 55 |
+
tab:app_heat_event_pr:
|
| 56 |
+
output: paper_outputs/tables/tab_app_heat_event_pr.tex
|
| 57 |
+
tab:app_seed_robustness:
|
| 58 |
+
output: paper_outputs/tables/tab_app_seed_robustness.tex
|
| 59 |
+
tab:app_head_architectures:
|
| 60 |
+
output: paper_outputs/tables/tab_app_head_architectures.tex
|
artifacts/results/fireprone_contract_progression_summary.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
artifacts/results/fireprone_contract_progression_table.generated.tex
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{4pt}
|
| 5 |
+
\caption{Occupancy scores across global and fire-prone scopes. Global uses the full validation/test domain; top-\(k\) rows use train-defined fire-prone masks from historical fire frequency. Values are \(F_1\) percentages from the same validation-selected strict threshold. Tolerance is spatial-only; union adds temporal and spatial matching. Difference is union minus strict. Rows report five-seed mean with small std. Values use four decimals.}
|
| 6 |
+
\label{tab:fireprone_contract_progression}
|
| 7 |
+
\begin{adjustbox}{max width=\textwidth}
|
| 8 |
+
\begin{tabular}{@{}llcccc@{}}
|
| 9 |
+
\toprule
|
| 10 |
+
Backbone & Scope & Strict \(F_1\uparrow\) & Tolerance \(F_1\uparrow\) & Union \(F_1\uparrow\) & Difference \(\uparrow\) \\
|
| 11 |
+
\midrule
|
| 12 |
+
\textcolor{blue}{FireWx-FM ref.} & global & \ms{0.4550}{0.1410} & \ms{29.7480}{1.2870} & \ms{59.0660}{2.7370} & \ms{58.6110}{2.6950} \\
|
| 13 |
+
& top 5\% & \ms{3.5600}{0.8810} & \ms{39.2620}{1.4010} & \ms{72.8280}{2.5780} & \ms{69.2680}{1.9960} \\
|
| 14 |
+
& top 10\% & \ms{3.5580}{0.8800} & \ms{39.1660}{1.3910} & \ms{72.5200}{2.5670} & \ms{68.9630}{1.9890} \\
|
| 15 |
+
& top 20\% & \ms{3.5300}{0.8700} & \ms{38.2850}{1.2950} & \ms{69.7230}{2.4660} & \ms{66.1930}{1.9270} \\
|
| 16 |
+
\addlinespace[1pt]
|
| 17 |
+
Prithvi-WxC & global & \ms{0.0550}{0.0040} & \ms{7.1600}{0.6600} & \ms{20.1900}{1.8300} & \ms{20.1300}{1.8300} \\
|
| 18 |
+
& top 5\% & \ms{1.4100}{1.1600} & \ms{19.2600}{4.5000} & \ms{42.5800}{4.5500} & \ms{41.1700}{3.4800} \\
|
| 19 |
+
& top 10\% & \ms{1.2400}{1.3200} & \ms{14.8800}{8.4400} & \ms{32.6900}{13.2100} & \ms{31.4500}{11.9100} \\
|
| 20 |
+
& top 20\% & \ms{1.1500}{1.3800} & \ms{13.1500}{9.4600} & \ms{28.1300}{15.2900} & \ms{26.9800}{13.9200} \\
|
| 21 |
+
\addlinespace[1pt]
|
| 22 |
+
Aurora & global & \ms{0.0700}{0.0100} & \ms{8.5000}{1.9600} & \ms{23.1000}{4.9400} & \ms{23.0400}{4.9300} \\
|
| 23 |
+
& top 5\% & \ms{0.9900}{0.9300} & \ms{15.1300}{6.0800} & \ms{35.4800}{11.0200} & \ms{34.5000}{10.3700} \\
|
| 24 |
+
& top 10\% & \ms{0.7800}{1.0500} & \ms{12.7400}{6.5600} & \ms{30.5300}{10.8800} & \ms{29.7500}{9.8700} \\
|
| 25 |
+
& top 20\% & \ms{0.6700}{1.1000} & \ms{10.5300}{7.4300} & \ms{24.9400}{12.5800} & \ms{24.2800}{11.4900} \\
|
| 26 |
+
\addlinespace[1pt]
|
| 27 |
+
ClimaX & global & \ms{0.3500}{0.0800} & \ms{29.7500}{3.6100} & \ms{60.1500}{7.5900} & \ms{59.8000}{7.5500} \\
|
| 28 |
+
& top 5\% & \ms{1.2900}{0.1100} & \ms{34.5800}{2.3800} & \ms{69.2200}{5.7200} & \ms{67.9200}{5.7300} \\
|
| 29 |
+
& top 10\% & \ms{1.2500}{0.1600} & \ms{34.3300}{2.2900} & \ms{68.5700}{5.5400} & \ms{67.3200}{5.5500} \\
|
| 30 |
+
& top 20\% & \ms{1.0300}{0.2700} & \ms{30.2100}{4.2900} & \ms{60.0600}{7.5700} & \ms{59.0400}{7.5900} \\
|
| 31 |
+
\addlinespace[1pt]
|
| 32 |
+
StormCast & global & \ms{0.0560}{0.0110} & \ms{8.2000}{2.1900} & \ms{22.3800}{5.4300} & \ms{22.3200}{5.4200} \\
|
| 33 |
+
& top 5\% & \ms{0.9600}{0.8000} & \ms{15.3200}{5.5300} & \ms{36.1900}{9.7300} & \ms{35.2300}{9.1800} \\
|
| 34 |
+
& top 10\% & \ms{0.7300}{0.9300} & \ms{12.6700}{6.3300} & \ms{30.4700}{10.6500} & \ms{29.7500}{9.7500} \\
|
| 35 |
+
& top 20\% & \ms{0.5800}{0.9100} & \ms{10.4200}{7.3400} & \ms{24.6600}{12.4000} & \ms{24.0800}{11.5000} \\
|
| 36 |
+
\addlinespace[1pt]
|
| 37 |
+
AlphaEarth & global & \ms{2.0600}{0.4400} & \ms{29.4500}{6.0100} & \ms{37.4300}{9.9500} & \ms{35.3700}{10.0300} \\
|
| 38 |
+
& top 5\% & \ms{6.9100}{0.8500} & \ms{42.8800}{4.6100} & \ms{51.7400}{8.7300} & \ms{44.8300}{9.0800} \\
|
| 39 |
+
& top 10\% & \ms{6.6400}{0.9900} & \ms{41.9000}{5.9500} & \ms{50.5700}{10.0100} & \ms{43.9300}{9.9200} \\
|
| 40 |
+
& top 20\% & \ms{6.1900}{1.1300} & \ms{38.8300}{7.5000} & \ms{46.3800}{12.1700} & \ms{40.1900}{11.6800} \\
|
| 41 |
+
\addlinespace[1pt]
|
| 42 |
+
DLWP & global & \ms{0.1700}{0.0400} & \ms{14.9100}{3.2400} & \ms{28.1900}{6.9700} & \ms{28.0200}{6.9300} \\
|
| 43 |
+
& top 5\% & \ms{1.8100}{0.4800} & \ms{31.7200}{3.2900} & \ms{55.4600}{5.2900} & \ms{53.6500}{5.4800} \\
|
| 44 |
+
& top 10\% & \ms{1.6100}{0.6000} & \ms{27.6600}{5.9200} & \ms{47.1300}{8.0100} & \ms{45.5200}{7.7900} \\
|
| 45 |
+
& top 20\% & \ms{1.5200}{0.9000} & \ms{20.9400}{4.8000} & \ms{34.9300}{7.8500} & \ms{33.4100}{7.8800} \\
|
| 46 |
+
\addlinespace[1pt]
|
| 47 |
+
FCN & global & \ms{0.2800}{0.0800} & \ms{19.5100}{3.3400} & \ms{40.0600}{9.3700} & \ms{39.7800}{9.3400} \\
|
| 48 |
+
& top 5\% & \ms{1.6200}{0.5100} & \ms{29.3800}{2.7600} & \ms{54.3000}{7.4100} & \ms{52.6800}{7.4400} \\
|
| 49 |
+
& top 10\% & \ms{1.1800}{0.5100} & \ms{22.4200}{3.9800} & \ms{43.4500}{9.2500} & \ms{42.2700}{9.0300} \\
|
| 50 |
+
& top 20\% & \ms{1.0000}{0.4300} & \ms{16.9800}{3.9400} & \ms{34.0900}{8.2600} & \ms{33.0900}{7.9300} \\
|
| 51 |
+
\addlinespace[1pt]
|
| 52 |
+
FengWu & global & \ms{0.2600}{0.0800} & \ms{12.0000}{6.0200} & \ms{24.1000}{13.6300} & \ms{23.8400}{13.5700} \\
|
| 53 |
+
& top 5\% & \ms{1.5700}{0.3600} & \ms{16.2800}{3.7000} & \ms{30.1100}{5.0100} & \ms{28.5400}{4.7700} \\
|
| 54 |
+
& top 10\% & \ms{1.2400}{0.5300} & \ms{12.9500}{5.6100} & \ms{24.1900}{8.6900} & \ms{22.9400}{8.1900} \\
|
| 55 |
+
& top 20\% & \ms{1.1200}{0.5000} & \ms{11.9500}{5.0700} & \ms{22.7900}{7.9100} & \ms{21.6700}{7.4400} \\
|
| 56 |
+
\addlinespace[1pt]
|
| 57 |
+
FuXi & global & \ms{0.3800}{0.1200} & \ms{21.0300}{4.8200} & \ms{37.2900}{9.4500} & \ms{36.9100}{9.4300} \\
|
| 58 |
+
& top 5\% & \ms{2.0300}{0.6800} & \ms{31.8900}{4.7300} & \ms{53.9300}{8.3800} & \ms{51.9000}{8.6900} \\
|
| 59 |
+
& top 10\% & \ms{1.6500}{0.7300} & \ms{24.0100}{5.7800} & \ms{40.2100}{9.9300} & \ms{38.5600}{9.7700} \\
|
| 60 |
+
& top 20\% & \ms{1.3600}{0.6800} & \ms{21.9500}{5.8600} & \ms{36.7300}{10.0300} & \ms{35.3700}{9.9200} \\
|
| 61 |
+
\addlinespace[1pt]
|
| 62 |
+
Pangu-Weather & global & \ms{0.2800}{0.1100} & \ms{17.0900}{4.0500} & \ms{35.6400}{9.0300} & \ms{35.3600}{9.0800} \\
|
| 63 |
+
& top 5\% & \ms{1.3700}{0.3100} & \ms{22.2200}{6.8600} & \ms{43.4200}{13.2400} & \ms{42.0600}{13.0600} \\
|
| 64 |
+
& top 10\% & \ms{1.0900}{0.3500} & \ms{18.9300}{5.9300} & \ms{38.5300}{11.7200} & \ms{37.4400}{11.5300} \\
|
| 65 |
+
& top 20\% & \ms{0.8800}{0.3600} & \ms{17.0200}{5.4900} & \ms{34.5700}{10.2900} & \ms{33.6800}{10.1300} \\
|
| 66 |
+
\bottomrule
|
| 67 |
+
\end{tabular}
|
| 68 |
+
\end{adjustbox}
|
| 69 |
+
\end{table*}
|
artifacts/results/selection_regret_all_backbones_20260504.csv
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_tag,label,scope,n,seeds,exact_regret_mean,exact_regret_std,tolerated_regret_mean,tolerated_regret_std,union_regret_mean,union_regret_std
|
| 2 |
+
reference,Reference,global,5,1 7 42 99 123,0.0,0.0,0.08783024981138902,0.09670495645481135,0.08783024981138902,0.09670495645481135
|
| 3 |
+
reference,Reference,fire_prone,5,1 7 42 99 123,0.0,0.0,0.03402707057672223,0.032044658643147844,0.03402707057672223,0.032044658643147844
|
| 4 |
+
prithvi_wxc,Prithvi-WxC,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 5 |
+
prithvi_wxc,Prithvi-WxC,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 6 |
+
aurora,Aurora,global,5,1 7 42 99 123,0.00020004882767231798,0.00026703384456332115,0.09851983041506818,0.1298781980037557,0.09851983041506818,0.1298781980037557
|
| 7 |
+
aurora,Aurora,fire_prone,5,1 7 42 99 123,0.008202508825959588,0.01834136732088763,0.14391889430974364,0.32121904665016227,0.14391889430974364,0.32121904665016227
|
| 8 |
+
climax,ClimaX,global,5,1 7 42 99 123,3.0287686240700486e-06,4.147312242167625e-06,0.0012959969982639485,0.0017746169760203706,0.0012959969982639485,0.0017746169760203706
|
| 9 |
+
climax,ClimaX,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 10 |
+
stormcast,StormCast,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 11 |
+
stormcast,StormCast,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 12 |
+
pangu_weather,Pangu-Weather,global,5,1 7 42 99 123,0.00013033979247265275,0.0002685372203690466,0.048806713097574374,0.10733308684741971,0.048806713097574374,0.10733308684741971
|
| 13 |
+
pangu_weather,Pangu-Weather,fire_prone,5,1 7 42 99 123,0.027875386332505546,0.02348779386900393,0.43111948243387105,0.39355644251497235,0.43111948243387105,0.39355644251497235
|
| 14 |
+
dlwp,DLWP,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 15 |
+
dlwp,DLWP,fire_prone,5,1 7 42 99 123,0.0007702319787454587,0.0010995336594539604,0.043265915053601556,0.04332331365579739,0.043265915053601556,0.04332331365579739
|
| 16 |
+
fcn,FCN,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 17 |
+
fcn,FCN,fire_prone,5,1 7 42 99 123,5.960229415004348e-06,1.3327478133443526e-05,0.011679805987441694,0.019872372458657642,0.011679805987441694,0.019872372458657642
|
| 18 |
+
fengwu,FengWu,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 19 |
+
fengwu,FengWu,fire_prone,5,1 7 42 99 123,0.0006908222234409067,0.0011910586589384115,0.005222389249812243,0.0062394095558402415,0.005222389249812243,0.0062394095558402415
|
| 20 |
+
fuxi,FuXi,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 21 |
+
fuxi,FuXi,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0010839188523199318,0.0017288780545672386,0.0010839188523199318,0.0017288780545672386
|
| 22 |
+
pangu6,Pangu-Weather,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 23 |
+
pangu6,Pangu-Weather,fire_prone,5,1 7 42 99 123,0.0007280423771922354,0.001178746460551365,0.0018491271881979853,0.0032630386057089294,0.0018491271881979853,0.0032630386057089294
|
| 24 |
+
alphaearth,AlphaEarth,global,5,1 7 42 99 123,0.0,0.0,0.1722171037486726,0.08849214830495522,0.1722171037486726,0.08849214830495522
|
| 25 |
+
alphaearth,AlphaEarth,fire_prone,5,1 7 42 99 123,0.0,0.0,0.038803552655092256,0.0594825313313219,0.038803552655092256,0.0594825313313219
|
artifacts/results/selection_regret_all_backbones_20260504.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
artifacts/results/selection_regret_full_head_table.generated.tex
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
% Full per-head rows are kept in the supplementary CSV files.
|
| 2 |
+
% The manuscript uses the all-backbone selection-regret summaries instead.
|
artifacts/results/selection_regret_head_metrics.csv
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
family,model_tag,scope,seed,selected_by,head_label,test_pr_auc,exact_f1,tolerated_f1,union_f1
|
| 2 |
+
AlphaEarth,alphaearth,fire_prone,1,PR-AUC,shallow spatial adapter,0.04390614036305261,0.09715762273901808,0.7863702028280513,0.7863702028280513
|
| 3 |
+
AlphaEarth,alphaearth,fire_prone,1,decision,shallow spatial adapter,,,,0.7863702028280513
|
| 4 |
+
AlphaEarth,alphaearth,fire_prone,7,PR-AUC,shallow spatial adapter,0.05955397140893137,0.12514898688915374,0.8294499693616161,0.8294499693616161
|
| 5 |
+
AlphaEarth,alphaearth,fire_prone,7,decision,shallow spatial adapter,,,,0.8294499693616161
|
| 6 |
+
AlphaEarth,alphaearth,fire_prone,42,PR-AUC,shallow spatial adapter,0.038083070948941686,0.08702469619756958,0.7112901458230849,0.7112901458230849
|
| 7 |
+
AlphaEarth,alphaearth,fire_prone,42,decision,pixel MLP head,,,,0.8461131676361712
|
| 8 |
+
AlphaEarth,alphaearth,fire_prone,99,PR-AUC,shallow spatial adapter,0.0458102699699856,0.10365251727541955,0.7758298037709835,0.7758298037709835
|
| 9 |
+
AlphaEarth,alphaearth,fire_prone,99,decision,pixel MLP head,,,,0.8350245452333586
|
| 10 |
+
AlphaEarth,alphaearth,fire_prone,123,PR-AUC,shallow spatial adapter,0.045809049876129763,0.10531544957774468,0.7789089693560928,0.7789089693560928
|
| 11 |
+
AlphaEarth,alphaearth,fire_prone,123,decision,shallow spatial adapter,,,,0.7789089693560928
|
| 12 |
+
AlphaEarth,alphaearth,global,1,PR-AUC,shallow spatial adapter,0.0006549130347299629,0.004193290734824281,0.40561891947698747,0.40561891947698747
|
| 13 |
+
AlphaEarth,alphaearth,global,1,decision,pixel MLP head,,,,0.6337627266658229
|
| 14 |
+
AlphaEarth,alphaearth,global,7,PR-AUC,shallow spatial adapter,0.001005722733868245,0.010460251046025104,0.6184842128568402,0.6184842128568402
|
| 15 |
+
AlphaEarth,alphaearth,global,7,decision,pixel MLP head,,,,0.6691395427484861
|
| 16 |
+
AlphaEarth,alphaearth,global,42,PR-AUC,shallow spatial adapter,0.0005634701573991865,0.004809747755451047,0.4087444681515033,0.4087444681515033
|
| 17 |
+
AlphaEarth,alphaearth,global,42,decision,pixel MLP head,,,,0.6812131506751973
|
| 18 |
+
AlphaEarth,alphaearth,global,99,PR-AUC,shallow spatial adapter,0.0006577120081349608,0.006780481898534931,0.3921547570095426,0.3921547570095426
|
| 19 |
+
AlphaEarth,alphaearth,global,99,decision,pixel MLP head,,,,0.5842714676652996
|
| 20 |
+
AlphaEarth,alphaearth,global,123,PR-AUC,shallow spatial adapter,0.0007047712457371991,0.006959088991986505,0.4427625907752311,0.4427625907752311
|
| 21 |
+
AlphaEarth,alphaearth,global,123,decision,pixel MLP head,,,,0.5604635792586619
|
| 22 |
+
Aurora,aurora,fire_prone,1,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 23 |
+
Aurora,aurora,fire_prone,1,decision,linear probe,,,,0.7185324707231184
|
| 24 |
+
Aurora,aurora,fire_prone,7,PR-AUC,linear probe,0.024802820904513342,0.0413500618483831,0.7184857293868923,0.7184857293868923
|
| 25 |
+
Aurora,aurora,fire_prone,7,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 26 |
+
Aurora,aurora,fire_prone,42,PR-AUC,linear probe,0.02613792907867929,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 27 |
+
Aurora,aurora,fire_prone,42,decision,linear probe,,,,0.7185324707231184
|
| 28 |
+
Aurora,aurora,fire_prone,99,PR-AUC,linear probe,0.02093558282208589,0.0,0.0,0.0
|
| 29 |
+
Aurora,aurora,fire_prone,99,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 30 |
+
Aurora,aurora,fire_prone,123,PR-AUC,pixel MLP head,0.03014151567817997,0.04541038665445361,0.7175172112337449,0.7175172112337449
|
| 31 |
+
Aurora,aurora,fire_prone,123,decision,linear probe,,,,0.7185324707231184
|
| 32 |
+
Aurora,aurora,global,1,PR-AUC,linear probe,0.00024254792826221397,0.00048497822606044473,0.23755358049655212,0.23755358049655212
|
| 33 |
+
Aurora,aurora,global,1,decision,shallow spatial adapter,,,,0.240793572992212
|
| 34 |
+
Aurora,aurora,global,7,PR-AUC,linear probe,0.00027660331739269843,0.0,0.23734400297937533,0.23734400297937533
|
| 35 |
+
Aurora,aurora,global,7,decision,shallow spatial adapter,,,,0.240793572992212
|
| 36 |
+
Aurora,aurora,global,42,PR-AUC,linear probe,0.0002876372030063385,0.00048497822606044473,0.0,0.0
|
| 37 |
+
Aurora,aurora,global,42,decision,shallow spatial adapter,,,,0.240793572992212
|
| 38 |
+
Aurora,aurora,global,99,PR-AUC,linear probe,0.00024254792826221397,0.0,0.0,0.0
|
| 39 |
+
Aurora,aurora,global,99,decision,shallow spatial adapter,,,,0.240793572992212
|
| 40 |
+
Aurora,aurora,global,123,PR-AUC,pixel MLP head,0.00031683315961488916,0.0005311562430574265,0.23647112940979162,0.23647112940979162
|
| 41 |
+
Aurora,aurora,global,123,decision,shallow spatial adapter,,,,0.240793572992212
|
| 42 |
+
ClimaX,climax,fire_prone,1,PR-AUC,linear probe,0.02281272244151735,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 43 |
+
ClimaX,climax,fire_prone,1,decision,linear probe,,,,0.7185324707231184
|
| 44 |
+
ClimaX,climax,fire_prone,7,PR-AUC,linear probe,0.021317405351800135,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 45 |
+
ClimaX,climax,fire_prone,7,decision,linear probe,,,,0.7185324707231184
|
| 46 |
+
ClimaX,climax,fire_prone,42,PR-AUC,linear probe,0.021516770872035896,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 47 |
+
ClimaX,climax,fire_prone,42,decision,linear probe,,,,0.7185324707231184
|
| 48 |
+
ClimaX,climax,fire_prone,99,PR-AUC,shallow spatial adapter,0.02099123219536693,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 49 |
+
ClimaX,climax,fire_prone,99,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 50 |
+
ClimaX,climax,fire_prone,123,PR-AUC,shallow spatial adapter,0.024930358757410707,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 51 |
+
ClimaX,climax,fire_prone,123,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 52 |
+
ClimaX,climax,global,1,PR-AUC,linear probe,0.0002543464414550104,0.00048497822606044473,0.23755358049655212,0.23755358049655212
|
| 53 |
+
ClimaX,climax,global,1,decision,shallow spatial adapter,,,,0.240793572992212
|
| 54 |
+
ClimaX,climax,global,7,PR-AUC,pixel MLP head,0.00025423546642937565,0.00048497822606044473,0.23755358049655212,0.23755358049655212
|
| 55 |
+
ClimaX,climax,global,7,decision,shallow spatial adapter,,,,0.240793572992212
|
| 56 |
+
ClimaX,climax,global,42,PR-AUC,shallow spatial adapter,0.00023723426605001756,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 57 |
+
ClimaX,climax,global,42,decision,shallow spatial adapter,,,,0.240793572992212
|
| 58 |
+
ClimaX,climax,global,99,PR-AUC,shallow spatial adapter,0.0002340075376021003,0.00048696535779102983,0.2384111045733381,0.2384111045733381
|
| 59 |
+
ClimaX,climax,global,99,decision,shallow spatial adapter,,,,0.2384111045733381
|
| 60 |
+
ClimaX,climax,global,123,PR-AUC,shallow spatial adapter,0.00025952340213823634,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 61 |
+
ClimaX,climax,global,123,decision,shallow spatial adapter,,,,0.240793572992212
|
| 62 |
+
DLWP,dlwp,fire_prone,1,PR-AUC,linear probe,0.019747545663020845,0.043506471331489265,0.7280364139105968,0.7280364139105968
|
| 63 |
+
DLWP,dlwp,fire_prone,1,decision,linear probe,,,,0.7280364139105968
|
| 64 |
+
DLWP,dlwp,fire_prone,7,PR-AUC,pixel MLP head,0.018519739310339497,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 65 |
+
DLWP,dlwp,fire_prone,7,decision,shallow spatial adapter,,,,0.762536895087842
|
| 66 |
+
DLWP,dlwp,fire_prone,42,PR-AUC,pixel MLP head,0.020762153794205103,0.04637177602565815,0.6606900017471591,0.6606900017471591
|
| 67 |
+
DLWP,dlwp,fire_prone,42,decision,shallow spatial adapter,,,,0.7728400679088107
|
| 68 |
+
DLWP,dlwp,fire_prone,99,PR-AUC,linear probe,0.02136633936888583,0.04819843096725701,0.7187730423241409,0.7187730423241409
|
| 69 |
+
DLWP,dlwp,fire_prone,99,decision,shallow spatial adapter,,,,0.7653346239087763
|
| 70 |
+
DLWP,dlwp,fire_prone,123,PR-AUC,pixel MLP head,0.021118517500793188,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 71 |
+
DLWP,dlwp,fire_prone,123,decision,linear probe,,,,0.7321459738801157
|
| 72 |
+
DLWP,dlwp,global,1,PR-AUC,shallow spatial adapter,0.0006257446338466172,0.00487022180273714,0.38023285660836226,0.38023285660836226
|
| 73 |
+
DLWP,dlwp,global,1,decision,shallow spatial adapter,,,,0.38023285660836226
|
| 74 |
+
DLWP,dlwp,global,7,PR-AUC,shallow spatial adapter,0.0005264872646085452,0.0,0.3432315705541329,0.3432315705541329
|
| 75 |
+
DLWP,dlwp,global,7,decision,shallow spatial adapter,,,,0.3432315705541329
|
| 76 |
+
DLWP,dlwp,global,42,PR-AUC,shallow spatial adapter,0.0006203713852571992,0.0,0.3405125814370199,0.3405125814370199
|
| 77 |
+
DLWP,dlwp,global,42,decision,shallow spatial adapter,,,,0.3405125814370199
|
| 78 |
+
DLWP,dlwp,global,99,PR-AUC,shallow spatial adapter,0.0007477128447471452,0.0,0.3979559626836394,0.3979559626836394
|
| 79 |
+
DLWP,dlwp,global,99,decision,shallow spatial adapter,,,,0.3979559626836394
|
| 80 |
+
DLWP,dlwp,global,123,PR-AUC,shallow spatial adapter,0.0007129763973023342,0.0,0.3797689460796109,0.3797689460796109
|
| 81 |
+
DLWP,dlwp,global,123,decision,shallow spatial adapter,,,,0.3797689460796109
|
| 82 |
+
FCN,fcn,fire_prone,1,PR-AUC,shallow spatial adapter,0.01844011667219625,0.042068766252528166,0.7185324707231184,0.7185324707231184
|
| 83 |
+
FCN,fcn,fire_prone,1,decision,linear probe,,,,0.7182175622542595
|
| 84 |
+
FCN,fcn,fire_prone,7,PR-AUC,pixel MLP head,0.02050876208409485,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 85 |
+
FCN,fcn,fire_prone,7,decision,linear probe,,,,0.7644129739607127
|
| 86 |
+
FCN,fcn,fire_prone,42,PR-AUC,shallow spatial adapter,0.018030815062946615,0.0414596444738876,0.7197180735022655,0.7197180735022655
|
| 87 |
+
FCN,fcn,fire_prone,42,decision,shallow spatial adapter,,,,0.7197180735022655
|
| 88 |
+
FCN,fcn,fire_prone,99,PR-AUC,linear probe,0.029098665712304895,0.042822140550172624,0.726408418760773,0.726408418760773
|
| 89 |
+
FCN,fcn,fire_prone,99,decision,linear probe,,,,0.726408418760773
|
| 90 |
+
FCN,fcn,fire_prone,123,PR-AUC,pixel MLP head,0.019943278646881796,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 91 |
+
FCN,fcn,fire_prone,123,decision,linear probe,,,,0.7310509974227326
|
| 92 |
+
FCN,fcn,global,1,PR-AUC,shallow spatial adapter,0.00037256097806901117,0.0009319664492078285,0.31167484413093016,0.31167484413093016
|
| 93 |
+
FCN,fcn,global,1,decision,shallow spatial adapter,,,,0.31167484413093016
|
| 94 |
+
FCN,fcn,global,7,PR-AUC,shallow spatial adapter,0.0003268363416054406,0.001086071137659517,0.3051941376005135,0.3051941376005135
|
| 95 |
+
FCN,fcn,global,7,decision,shallow spatial adapter,,,,0.3051941376005135
|
| 96 |
+
FCN,fcn,global,42,PR-AUC,shallow spatial adapter,0.00041063897933390575,0.0007027406886858749,0.31987973649439366,0.31987973649439366
|
| 97 |
+
FCN,fcn,global,42,decision,pixel MLP head,,,,0.2870596305028149
|
| 98 |
+
FCN,fcn,global,99,PR-AUC,shallow spatial adapter,0.00038120453362995967,0.0018159806295399514,0.3054145960271247,0.3054145960271247
|
| 99 |
+
FCN,fcn,global,99,decision,shallow spatial adapter,,,,0.3054145960271247
|
| 100 |
+
FCN,fcn,global,123,PR-AUC,shallow spatial adapter,0.000387412312932838,0.0006535947712418301,0.3096850885545486,0.3096850885545486
|
| 101 |
+
FCN,fcn,global,123,decision,shallow spatial adapter,,,,0.3096850885545486
|
| 102 |
+
FengWu,fengwu,fire_prone,1,PR-AUC,shallow spatial adapter,0.022736128443885992,0.04452825597664091,0.7269980510116651,0.7269980510116651
|
| 103 |
+
FengWu,fengwu,fire_prone,1,decision,shallow spatial adapter,,,,0.7269980510116651
|
| 104 |
+
FengWu,fengwu,fire_prone,7,PR-AUC,pixel MLP head,0.016801706970978273,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 105 |
+
FengWu,fengwu,fire_prone,7,decision,shallow spatial adapter,,,,0.722901134194411
|
| 106 |
+
FengWu,fengwu,fire_prone,42,PR-AUC,shallow spatial adapter,0.021165185967854567,0.04574838388861263,0.7265705731122933,0.7265705731122933
|
| 107 |
+
FengWu,fengwu,fire_prone,42,decision,shallow spatial adapter,,,,0.7265705731122933
|
| 108 |
+
FengWu,fengwu,fire_prone,99,PR-AUC,linear probe,0.02199779031689959,0.0,0.7185324707231184,0.7185324707231184
|
| 109 |
+
FengWu,fengwu,fire_prone,99,decision,shallow spatial adapter,,,,0.7336829717908426
|
| 110 |
+
FengWu,fengwu,fire_prone,123,PR-AUC,pixel MLP head,0.020495144103834257,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 111 |
+
FengWu,fengwu,fire_prone,123,decision,shallow spatial adapter,,,,0.7251252524331628
|
| 112 |
+
FengWu,fengwu,global,1,PR-AUC,shallow spatial adapter,0.000398077435365184,0.0,0.31071390711162444,0.31071390711162444
|
| 113 |
+
FengWu,fengwu,global,1,decision,shallow spatial adapter,,,,0.31071390711162444
|
| 114 |
+
FengWu,fengwu,global,7,PR-AUC,shallow spatial adapter,0.00036963872610239895,0.0,0.30641904273669174,0.30641904273669174
|
| 115 |
+
FengWu,fengwu,global,7,decision,shallow spatial adapter,,,,0.30641904273669174
|
| 116 |
+
FengWu,fengwu,global,42,PR-AUC,shallow spatial adapter,0.00036987379624400454,0.0,0.31219058559732665,0.31219058559732665
|
| 117 |
+
FengWu,fengwu,global,42,decision,shallow spatial adapter,,,,0.31219058559732665
|
| 118 |
+
FengWu,fengwu,global,99,PR-AUC,shallow spatial adapter,0.00042782651526874734,0.0,0.3111214819309595,0.3111214819309595
|
| 119 |
+
FengWu,fengwu,global,99,decision,shallow spatial adapter,,,,0.3111214819309595
|
| 120 |
+
FengWu,fengwu,global,123,PR-AUC,shallow spatial adapter,0.0004116035724473925,0.0,0.3145618361221859,0.3145618361221859
|
| 121 |
+
FengWu,fengwu,global,123,decision,shallow spatial adapter,,,,0.3145618361221859
|
| 122 |
+
FuXi,fuxi,fire_prone,1,PR-AUC,shallow spatial adapter,0.01904942261850253,0.043196160341303,0.7246636456247585,0.7246636456247585
|
| 123 |
+
FuXi,fuxi,fire_prone,1,decision,linear probe,,,,0.7261195534617713
|
| 124 |
+
FuXi,fuxi,fire_prone,7,PR-AUC,shallow spatial adapter,0.018717347905238046,0.044572342126298965,0.7235687421646468,0.7235687421646468
|
| 125 |
+
FuXi,fuxi,fire_prone,7,decision,shallow spatial adapter,,,,0.7235687421646468
|
| 126 |
+
FuXi,fuxi,fire_prone,42,PR-AUC,shallow spatial adapter,0.020363596550511454,0.04603830266616599,0.7054843984273774,0.7054843984273774
|
| 127 |
+
FuXi,fuxi,fire_prone,42,decision,shallow spatial adapter,,,,0.7054843984273774
|
| 128 |
+
FuXi,fuxi,fire_prone,99,PR-AUC,pixel MLP head,0.02225455497934009,0.030284377692970574,0.7203102915557309,0.7203102915557309
|
| 129 |
+
FuXi,fuxi,fire_prone,99,decision,shallow spatial adapter,,,,0.7183426482806338
|
| 130 |
+
FuXi,fuxi,fire_prone,123,PR-AUC,pixel MLP head,0.021045021724179047,0.018543768748295608,0.7185324707231184,0.7185324707231184
|
| 131 |
+
FuXi,fuxi,fire_prone,123,decision,linear probe,,,,0.7224961571477053
|
| 132 |
+
FuXi,fuxi,global,1,PR-AUC,shallow spatial adapter,0.0003596048414560045,0.0006866311182961118,0.3091927111996169,0.3091927111996169
|
| 133 |
+
FuXi,fuxi,global,1,decision,linear probe,,,,0.21516044416153002
|
| 134 |
+
FuXi,fuxi,global,7,PR-AUC,shallow spatial adapter,0.00037118462783325537,0.0008450613619815959,0.3062654921252336,0.3062654921252336
|
| 135 |
+
FuXi,fuxi,global,7,decision,shallow spatial adapter,,,,0.3062654921252336
|
| 136 |
+
FuXi,fuxi,global,42,PR-AUC,shallow spatial adapter,0.0003830459807690152,0.0003188165529554294,0.316668570748256,0.316668570748256
|
| 137 |
+
FuXi,fuxi,global,42,decision,shallow spatial adapter,,,,0.316668570748256
|
| 138 |
+
FuXi,fuxi,global,99,PR-AUC,shallow spatial adapter,0.0003758107890486513,0.0007771032641515431,0.3108110703043797,0.3108110703043797
|
| 139 |
+
FuXi,fuxi,global,99,decision,shallow spatial adapter,,,,0.3108110703043797
|
| 140 |
+
FuXi,fuxi,global,123,PR-AUC,shallow spatial adapter,0.00039999784430104664,0.0009888839378897987,0.3096924811079745,0.3096924811079745
|
| 141 |
+
FuXi,fuxi,global,123,decision,shallow spatial adapter,,,,0.3096924811079745
|
| 142 |
+
Pangu-Weather,pangu_weather,fire_prone,1,PR-AUC,pixel MLP head,0.014813375233921266,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 143 |
+
Pangu-Weather,pangu_weather,fire_prone,1,decision,pixel MLP head,,,,0.7185324707231184
|
| 144 |
+
Pangu-Weather,pangu_weather,fire_prone,7,PR-AUC,pixel MLP head,0.029883397445312192,0.0,0.0,0.0
|
| 145 |
+
Pangu-Weather,pangu_weather,fire_prone,7,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 146 |
+
Pangu-Weather,pangu_weather,fire_prone,42,PR-AUC,pixel MLP head,0.02188826028256454,0.0,0.0,0.0
|
| 147 |
+
Pangu-Weather,pangu_weather,fire_prone,42,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 148 |
+
Pangu-Weather,pangu_weather,fire_prone,99,PR-AUC,linear probe,0.02093558282208589,0.0,0.0,0.0
|
| 149 |
+
Pangu-Weather,pangu_weather,fire_prone,99,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 150 |
+
Pangu-Weather,pangu_weather,fire_prone,123,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 151 |
+
Pangu-Weather,pangu_weather,fire_prone,123,decision,linear probe,,,,0.7185324707231184
|
| 152 |
+
Pangu-Weather,pangu_weather,global,1,PR-AUC,linear probe,0.00024254792826221397,0.00048497822606044473,0.23755358049655212,0.23755358049655212
|
| 153 |
+
Pangu-Weather,pangu_weather,global,1,decision,shallow spatial adapter,,,,0.240793572992212
|
| 154 |
+
Pangu-Weather,pangu_weather,global,7,PR-AUC,shallow spatial adapter,0.00028045576992618193,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 155 |
+
Pangu-Weather,pangu_weather,global,7,decision,shallow spatial adapter,,,,0.240793572992212
|
| 156 |
+
Pangu-Weather,pangu_weather,global,42,PR-AUC,pixel MLP head,0.00021817709863716954,0.0,0.0,0.0
|
| 157 |
+
Pangu-Weather,pangu_weather,global,42,decision,shallow spatial adapter,,,,0.240793572992212
|
| 158 |
+
Pangu-Weather,pangu_weather,global,99,PR-AUC,shallow spatial adapter,0.0003408299850116487,0.0004887421693148924,0.23917716245227552,0.23917716245227552
|
| 159 |
+
Pangu-Weather,pangu_weather,global,99,decision,pixel MLP head,,,,0.229804399271568
|
| 160 |
+
Pangu-Weather,pangu_weather,global,123,PR-AUC,shallow spatial adapter,0.0003300754798792237,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 161 |
+
Pangu-Weather,pangu_weather,global,123,decision,shallow spatial adapter,,,,0.240793572992212
|
| 162 |
+
Pangu-Weather,pangu6,fire_prone,1,PR-AUC,shallow spatial adapter,0.02328829578760066,0.04418397717161179,0.7231388400090598,0.7231388400090598
|
| 163 |
+
Pangu-Weather,pangu6,fire_prone,1,decision,shallow spatial adapter,,,,0.7231388400090598
|
| 164 |
+
Pangu-Weather,pangu6,fire_prone,7,PR-AUC,pixel MLP head,0.018664183428008234,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 165 |
+
Pangu-Weather,pangu6,fire_prone,7,decision,shallow spatial adapter,,,,0.719461376864001
|
| 166 |
+
Pangu-Weather,pangu6,fire_prone,42,PR-AUC,shallow spatial adapter,0.021420904714594617,0.0430065972893146,0.7241279907754397,0.7241279907754397
|
| 167 |
+
Pangu-Weather,pangu6,fire_prone,42,decision,shallow spatial adapter,,,,0.7241279907754397
|
| 168 |
+
Pangu-Weather,pangu6,fire_prone,99,PR-AUC,linear probe,0.024740444457605402,0.0044004400440044,0.7183382629739177,0.7183382629739177
|
| 169 |
+
Pangu-Weather,pangu6,fire_prone,99,decision,shallow spatial adapter,,,,0.719015307962107
|
| 170 |
+
Pangu-Weather,pangu6,fire_prone,123,PR-AUC,pixel MLP head,0.02254610440161657,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 171 |
+
Pangu-Weather,pangu6,fire_prone,123,decision,linear probe,,,,0.7261721555350364
|
| 172 |
+
Pangu-Weather,pangu6,global,1,PR-AUC,shallow spatial adapter,0.00042881385578730365,0.0,0.32066974948800614,0.32066974948800614
|
| 173 |
+
Pangu-Weather,pangu6,global,1,decision,shallow spatial adapter,,,,0.32066974948800614
|
| 174 |
+
Pangu-Weather,pangu6,global,7,PR-AUC,shallow spatial adapter,0.00038395193539280824,0.0,0.31120670593952293,0.31120670593952293
|
| 175 |
+
Pangu-Weather,pangu6,global,7,decision,shallow spatial adapter,,,,0.31120670593952293
|
| 176 |
+
Pangu-Weather,pangu6,global,42,PR-AUC,shallow spatial adapter,0.00040651309469793043,0.0,0.32154249424354786,0.32154249424354786
|
| 177 |
+
Pangu-Weather,pangu6,global,42,decision,shallow spatial adapter,,,,0.32154249424354786
|
| 178 |
+
Pangu-Weather,pangu6,global,99,PR-AUC,shallow spatial adapter,0.0004450373086921994,0.0,0.3214547875801752,0.3214547875801752
|
| 179 |
+
Pangu-Weather,pangu6,global,99,decision,shallow spatial adapter,,,,0.3214547875801752
|
| 180 |
+
Pangu-Weather,pangu6,global,123,PR-AUC,shallow spatial adapter,0.00043738577276574255,0.0,0.31812983009681495,0.31812983009681495
|
| 181 |
+
Pangu-Weather,pangu6,global,123,decision,shallow spatial adapter,,,,0.31812983009681495
|
| 182 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,1,PR-AUC,shallow spatial adapter,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 183 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,1,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 184 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,7,PR-AUC,shallow spatial adapter,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 185 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,7,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 186 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,42,PR-AUC,pixel MLP head,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 187 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,42,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 188 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,99,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 189 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,99,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 190 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,123,PR-AUC,shallow spatial adapter,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 191 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,123,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 192 |
+
Prithvi-WxC,prithvi_wxc,global,1,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 193 |
+
Prithvi-WxC,prithvi_wxc,global,1,decision,shallow spatial adapter,,,,0.240793572992212
|
| 194 |
+
Prithvi-WxC,prithvi_wxc,global,7,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 195 |
+
Prithvi-WxC,prithvi_wxc,global,7,decision,shallow spatial adapter,,,,0.240793572992212
|
| 196 |
+
Prithvi-WxC,prithvi_wxc,global,42,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 197 |
+
Prithvi-WxC,prithvi_wxc,global,42,decision,shallow spatial adapter,,,,0.240793572992212
|
| 198 |
+
Prithvi-WxC,prithvi_wxc,global,99,PR-AUC,shallow spatial adapter,0.0002454330184381399,0.00048497822606044473,0.23755358049655212,0.23755358049655212
|
| 199 |
+
Prithvi-WxC,prithvi_wxc,global,99,decision,shallow spatial adapter,,,,0.23755358049655212
|
| 200 |
+
Prithvi-WxC,prithvi_wxc,global,123,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 201 |
+
Prithvi-WxC,prithvi_wxc,global,123,decision,shallow spatial adapter,,,,0.240793572992212
|
| 202 |
+
Reference,reference,fire_prone,1,PR-AUC,shallow spatial adapter,0.10204224118176683,0.1611624834874505,0.799032457577039,0.799032457577039
|
| 203 |
+
Reference,reference,fire_prone,1,decision,linear probe,,,,0.8685988450931266
|
| 204 |
+
Reference,reference,fire_prone,7,PR-AUC,shallow spatial adapter,0.1323902067230726,0.22885572139303484,0.8027807546359551,0.8027807546359551
|
| 205 |
+
Reference,reference,fire_prone,7,decision,shallow spatial adapter,,,,0.8027807546359551
|
| 206 |
+
Reference,reference,fire_prone,42,PR-AUC,shallow spatial adapter,0.12048427320762313,0.19225806451612906,0.8358151221553631,0.8358151221553631
|
| 207 |
+
Reference,reference,fire_prone,42,decision,shallow spatial adapter,,,,0.8358151221553631
|
| 208 |
+
Reference,reference,fire_prone,99,PR-AUC,shallow spatial adapter,0.11947246238005743,0.19477124183006533,0.8534759193943048,0.8534759193943048
|
| 209 |
+
Reference,reference,fire_prone,99,decision,linear probe,,,,0.9039923296574045
|
| 210 |
+
Reference,reference,fire_prone,123,PR-AUC,shallow spatial adapter,0.11551882470432043,0.19165378670788252,0.8066689866810086,0.8066689866810086
|
| 211 |
+
Reference,reference,fire_prone,123,decision,pixel MLP head,,,,0.8567215417854325
|
| 212 |
+
Reference,reference,global,1,PR-AUC,shallow spatial adapter,0.002624341503354088,0.017134572294714646,0.6186566066408326,0.6186566066408326
|
| 213 |
+
Reference,reference,global,1,decision,linear probe,,,,0.7286109603326707
|
| 214 |
+
Reference,reference,global,7,PR-AUC,shallow spatial adapter,0.0030317345997110698,0.02287675150128682,0.5002193417313746,0.5002193417313746
|
| 215 |
+
Reference,reference,global,7,decision,shallow spatial adapter,,,,0.5002193417313746
|
| 216 |
+
Reference,reference,global,42,PR-AUC,shallow spatial adapter,0.0032729435045747413,0.025515210991167808,0.7239943741463363,0.7239943741463363
|
| 217 |
+
Reference,reference,global,42,decision,shallow spatial adapter,,,,0.7239943741463363
|
| 218 |
+
Reference,reference,global,99,PR-AUC,shallow spatial adapter,0.0031953098868323193,0.021876258220373104,0.6698005926442897,0.6698005926442897
|
| 219 |
+
Reference,reference,global,99,decision,linear probe,,,,0.7647466876509988
|
| 220 |
+
Reference,reference,global,123,PR-AUC,shallow spatial adapter,0.0025603887793133394,0.019320660641944532,0.5009707461135111,0.5009707461135111
|
| 221 |
+
Reference,reference,global,123,decision,pixel MLP head,,,,0.735221546471909
|
| 222 |
+
StormCast,stormcast,fire_prone,1,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 223 |
+
StormCast,stormcast,fire_prone,1,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 224 |
+
StormCast,stormcast,fire_prone,7,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 225 |
+
StormCast,stormcast,fire_prone,7,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 226 |
+
StormCast,stormcast,fire_prone,42,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 227 |
+
StormCast,stormcast,fire_prone,42,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 228 |
+
StormCast,stormcast,fire_prone,99,PR-AUC,pixel MLP head,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 229 |
+
StormCast,stormcast,fire_prone,99,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 230 |
+
StormCast,stormcast,fire_prone,123,PR-AUC,linear probe,0.02093558282208589,0.04101254412979794,0.7185324707231184,0.7185324707231184
|
| 231 |
+
StormCast,stormcast,fire_prone,123,decision,shallow spatial adapter,,,,0.7185324707231184
|
| 232 |
+
StormCast,stormcast,global,1,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 233 |
+
StormCast,stormcast,global,1,decision,shallow spatial adapter,,,,0.240793572992212
|
| 234 |
+
StormCast,stormcast,global,7,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 235 |
+
StormCast,stormcast,global,7,decision,shallow spatial adapter,,,,0.240793572992212
|
| 236 |
+
StormCast,stormcast,global,42,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 237 |
+
StormCast,stormcast,global,42,decision,shallow spatial adapter,,,,0.240793572992212
|
| 238 |
+
StormCast,stormcast,global,99,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004905319945803844,0.2399251001974223,0.2399251001974223
|
| 239 |
+
StormCast,stormcast,global,99,decision,shallow spatial adapter,,,,0.2399251001974223
|
| 240 |
+
StormCast,stormcast,global,123,PR-AUC,shallow spatial adapter,0.0002463357401629007,0.0004925501476206198,0.240793572992212,0.240793572992212
|
| 241 |
+
StormCast,stormcast,global,123,decision,shallow spatial adapter,,,,0.240793572992212
|
artifacts/results/selection_regret_main_table.generated.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[!t]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{4pt}
|
| 5 |
+
\caption{Fixed-feature selection-regret check across evaluation scopes. Values are percentage-point regret \(\delta = D(h_D)-D(h_R)\) under union-\(F_1\), where \(h_R\) is selected by PR-AUC and \(h_D\) by the decision metric. Top-\(k\) columns use train-defined fire-prone scopes. Rows report mean with small std over five seeds; \(0.0000\) means the two selectors give the same decision score for all seeds.}
|
| 6 |
+
\label{tab:selection_regret_diagnostic}
|
| 7 |
+
\begin{tabular}{lcccc}
|
| 8 |
+
\toprule
|
| 9 |
+
\textbf{Feature source} & \textbf{\(\Omega=\)global} & \textbf{\(\Omega=\)top 5\%} & \textbf{\(\Omega=\)top 10\%} & \textbf{\(\Omega=\)top 20\%} \\
|
| 10 |
+
\midrule
|
| 11 |
+
\textcolor{blue}{FireWx-FM ref.} & \ms{7.3831}{7.4536} & \ms{0.3664}{0.6812} & \ms{1.2275}{1.2665} & \ms{2.9385}{2.7513} \\
|
| 12 |
+
Prithvi-WxC & 0.0000 & 0.0000 & 0.0000 & 0.0000 \\
|
| 13 |
+
Aurora & \ms{4.9455}{10.6974} & \ms{15.4283}{34.4987} & \ms{13.9934}{31.2903} & \ms{14.3706}{32.1337} \\
|
| 14 |
+
ClimaX & \ms{0.1296}{0.1775} & 0.0000 & 0.0000 & 0.0000 \\
|
| 15 |
+
StormCast & 0.0000 & 0.0000 & 0.0000 & 0.0000 \\
|
| 16 |
+
DLWP & 0.0000 & \ms{1.6716}{1.6079} & \ms{2.8465}{2.6938} & \ms{4.4634}{4.3561} \\
|
| 17 |
+
FCN & 0.0000 & \ms{0.4510}{1.0071} & \ms{0.4200}{0.9390} & \ms{1.1680}{1.9872} \\
|
| 18 |
+
FengWu & 0.0000 & \ms{0.8796}{0.5532} & \ms{0.4023}{0.5511} & \ms{0.5222}{0.6239} \\
|
| 19 |
+
FuXi & 0.0000 & \ms{1.3545}{2.0970} & \ms{0.1656}{0.3703} & \ms{0.2833}{0.3681} \\
|
| 20 |
+
Pangu-Weather & 0.0000 & \ms{0.7593}{0.8974} & \ms{0.3048}{0.5054} & \ms{0.1868}{0.3255} \\
|
| 21 |
+
AlphaEarth & \ms{17.2217}{8.8492} & \ms{6.3846}{4.9653} & \ms{6.5738}{6.8970} & \ms{3.8804}{5.9483} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
artifacts/results/selection_regret_per_seed.csv
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
family,model_tag,scope,seed,ranking_head,decision_head,ranking_pr_auc,ranking_union_f1,decision_union_f1,regret,top1_agreement
|
| 2 |
+
AlphaEarth,alphaearth,fire_prone,1,shallow spatial adapter,shallow spatial adapter,0.04390614036305261,0.7863702028280513,0.7863702028280513,0.0,True
|
| 3 |
+
AlphaEarth,alphaearth,fire_prone,7,shallow spatial adapter,shallow spatial adapter,0.05955397140893137,0.8294499693616161,0.8294499693616161,0.0,True
|
| 4 |
+
AlphaEarth,alphaearth,fire_prone,42,shallow spatial adapter,pixel MLP head,0.038083070948941686,0.7112901458230849,0.8461131676361712,0.13482302181308625,False
|
| 5 |
+
AlphaEarth,alphaearth,fire_prone,99,shallow spatial adapter,pixel MLP head,0.0458102699699856,0.7758298037709835,0.8350245452333586,0.05919474146237502,False
|
| 6 |
+
AlphaEarth,alphaearth,fire_prone,123,shallow spatial adapter,shallow spatial adapter,0.045809049876129763,0.7789089693560928,0.7789089693560928,0.0,True
|
| 7 |
+
AlphaEarth,alphaearth,global,1,shallow spatial adapter,pixel MLP head,0.0006549130347299629,0.40561891947698747,0.6337627266658229,0.22814380718883542,False
|
| 8 |
+
AlphaEarth,alphaearth,global,7,shallow spatial adapter,pixel MLP head,0.001005722733868245,0.6184842128568402,0.6691395427484861,0.050655329891645895,False
|
| 9 |
+
AlphaEarth,alphaearth,global,42,shallow spatial adapter,pixel MLP head,0.0005634701573991865,0.4087444681515033,0.6812131506751973,0.272468682523694,False
|
| 10 |
+
AlphaEarth,alphaearth,global,99,shallow spatial adapter,pixel MLP head,0.0006577120081349608,0.3921547570095426,0.5842714676652996,0.19211671065575697,False
|
| 11 |
+
AlphaEarth,alphaearth,global,123,shallow spatial adapter,pixel MLP head,0.0007047712457371991,0.4427625907752311,0.5604635792586619,0.11770098848343075,False
|
| 12 |
+
Aurora,aurora,fire_prone,1,linear probe,linear probe,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,True
|
| 13 |
+
Aurora,aurora,fire_prone,7,linear probe,shallow spatial adapter,0.024802820904513342,0.7184857293868923,0.7185324707231184,4.674133622617482e-05,False
|
| 14 |
+
Aurora,aurora,fire_prone,42,linear probe,linear probe,0.02613792907867929,0.7185324707231184,0.7185324707231184,0.0,True
|
| 15 |
+
Aurora,aurora,fire_prone,99,linear probe,shallow spatial adapter,0.02093558282208589,0.0,0.7185324707231184,0.7185324707231184,False
|
| 16 |
+
Aurora,aurora,fire_prone,123,pixel MLP head,linear probe,0.03014151567817997,0.7175172112337449,0.7185324707231184,0.0010152594893735323,False
|
| 17 |
+
Aurora,aurora,global,1,linear probe,shallow spatial adapter,0.00024254792826221397,0.23755358049655212,0.240793572992212,0.0032399924956598714,False
|
| 18 |
+
Aurora,aurora,global,7,linear probe,shallow spatial adapter,0.00027660331739269843,0.23734400297937533,0.240793572992212,0.0034495700128366613,False
|
| 19 |
+
Aurora,aurora,global,42,linear probe,shallow spatial adapter,0.0002876372030063385,0.0,0.240793572992212,0.240793572992212,False
|
| 20 |
+
Aurora,aurora,global,99,linear probe,shallow spatial adapter,0.00024254792826221397,0.0,0.240793572992212,0.240793572992212,False
|
| 21 |
+
Aurora,aurora,global,123,pixel MLP head,shallow spatial adapter,0.00031683315961488916,0.23647112940979162,0.240793572992212,0.004322443582420371,False
|
| 22 |
+
ClimaX,climax,fire_prone,1,linear probe,linear probe,0.02281272244151735,0.7185324707231184,0.7185324707231184,0.0,True
|
| 23 |
+
ClimaX,climax,fire_prone,7,linear probe,linear probe,0.021317405351800135,0.7185324707231184,0.7185324707231184,0.0,True
|
| 24 |
+
ClimaX,climax,fire_prone,42,linear probe,linear probe,0.021516770872035896,0.7185324707231184,0.7185324707231184,0.0,True
|
| 25 |
+
ClimaX,climax,fire_prone,99,shallow spatial adapter,shallow spatial adapter,0.02099123219536693,0.7185324707231184,0.7185324707231184,0.0,True
|
| 26 |
+
ClimaX,climax,fire_prone,123,shallow spatial adapter,shallow spatial adapter,0.024930358757410707,0.7185324707231184,0.7185324707231184,0.0,True
|
| 27 |
+
ClimaX,climax,global,1,linear probe,shallow spatial adapter,0.0002543464414550104,0.23755358049655212,0.240793572992212,0.0032399924956598714,False
|
| 28 |
+
ClimaX,climax,global,7,pixel MLP head,shallow spatial adapter,0.00025423546642937565,0.23755358049655212,0.240793572992212,0.0032399924956598714,False
|
| 29 |
+
ClimaX,climax,global,42,shallow spatial adapter,shallow spatial adapter,0.00023723426605001756,0.240793572992212,0.240793572992212,0.0,True
|
| 30 |
+
ClimaX,climax,global,99,shallow spatial adapter,shallow spatial adapter,0.0002340075376021003,0.2384111045733381,0.2384111045733381,0.0,True
|
| 31 |
+
ClimaX,climax,global,123,shallow spatial adapter,shallow spatial adapter,0.00025952340213823634,0.240793572992212,0.240793572992212,0.0,True
|
| 32 |
+
DLWP,dlwp,fire_prone,1,linear probe,linear probe,0.019747545663020845,0.7280364139105968,0.7280364139105968,0.0,True
|
| 33 |
+
DLWP,dlwp,fire_prone,7,pixel MLP head,shallow spatial adapter,0.018519739310339497,0.7185324707231184,0.762536895087842,0.044004424364723516,False
|
| 34 |
+
DLWP,dlwp,fire_prone,42,pixel MLP head,shallow spatial adapter,0.020762153794205103,0.6606900017471591,0.7728400679088107,0.11215006616165157,False
|
| 35 |
+
DLWP,dlwp,fire_prone,99,linear probe,shallow spatial adapter,0.02136633936888583,0.7187730423241409,0.7653346239087763,0.046561581584635414,False
|
| 36 |
+
DLWP,dlwp,fire_prone,123,pixel MLP head,linear probe,0.021118517500793188,0.7185324707231184,0.7321459738801157,0.013613503156997275,False
|
| 37 |
+
DLWP,dlwp,global,1,shallow spatial adapter,shallow spatial adapter,0.0006257446338466172,0.38023285660836226,0.38023285660836226,0.0,True
|
| 38 |
+
DLWP,dlwp,global,7,shallow spatial adapter,shallow spatial adapter,0.0005264872646085452,0.3432315705541329,0.3432315705541329,0.0,True
|
| 39 |
+
DLWP,dlwp,global,42,shallow spatial adapter,shallow spatial adapter,0.0006203713852571992,0.3405125814370199,0.3405125814370199,0.0,True
|
| 40 |
+
DLWP,dlwp,global,99,shallow spatial adapter,shallow spatial adapter,0.0007477128447471452,0.3979559626836394,0.3979559626836394,0.0,True
|
| 41 |
+
DLWP,dlwp,global,123,shallow spatial adapter,shallow spatial adapter,0.0007129763973023342,0.3797689460796109,0.3797689460796109,0.0,True
|
| 42 |
+
FCN,fcn,fire_prone,1,shallow spatial adapter,linear probe,0.01844011667219625,0.7185324707231184,0.7182175622542595,0.0,False
|
| 43 |
+
FCN,fcn,fire_prone,7,pixel MLP head,linear probe,0.02050876208409485,0.7185324707231184,0.7644129739607127,0.045880503237594294,False
|
| 44 |
+
FCN,fcn,fire_prone,42,shallow spatial adapter,shallow spatial adapter,0.018030815062946615,0.7197180735022655,0.7197180735022655,0.0,True
|
| 45 |
+
FCN,fcn,fire_prone,99,linear probe,linear probe,0.029098665712304895,0.726408418760773,0.726408418760773,0.0,True
|
| 46 |
+
FCN,fcn,fire_prone,123,pixel MLP head,linear probe,0.019943278646881796,0.7185324707231184,0.7310509974227326,0.012518526699614174,False
|
| 47 |
+
FCN,fcn,global,1,shallow spatial adapter,shallow spatial adapter,0.00037256097806901117,0.31167484413093016,0.31167484413093016,0.0,True
|
| 48 |
+
FCN,fcn,global,7,shallow spatial adapter,shallow spatial adapter,0.0003268363416054406,0.3051941376005135,0.3051941376005135,0.0,True
|
| 49 |
+
FCN,fcn,global,42,shallow spatial adapter,pixel MLP head,0.00041063897933390575,0.31987973649439366,0.2870596305028149,0.0,False
|
| 50 |
+
FCN,fcn,global,99,shallow spatial adapter,shallow spatial adapter,0.00038120453362995967,0.3054145960271247,0.3054145960271247,0.0,True
|
| 51 |
+
FCN,fcn,global,123,shallow spatial adapter,shallow spatial adapter,0.000387412312932838,0.3096850885545486,0.3096850885545486,0.0,True
|
| 52 |
+
FengWu,fengwu,fire_prone,1,shallow spatial adapter,shallow spatial adapter,0.022736128443885992,0.7269980510116651,0.7269980510116651,0.0,True
|
| 53 |
+
FengWu,fengwu,fire_prone,7,pixel MLP head,shallow spatial adapter,0.016801706970978273,0.7185324707231184,0.722901134194411,0.004368663471292611,False
|
| 54 |
+
FengWu,fengwu,fire_prone,42,shallow spatial adapter,shallow spatial adapter,0.021165185967854567,0.7265705731122933,0.7265705731122933,0.0,True
|
| 55 |
+
FengWu,fengwu,fire_prone,99,linear probe,shallow spatial adapter,0.02199779031689959,0.7185324707231184,0.7336829717908426,0.015150501067724198,False
|
| 56 |
+
FengWu,fengwu,fire_prone,123,pixel MLP head,shallow spatial adapter,0.020495144103834257,0.7185324707231184,0.7251252524331628,0.006592781710044404,False
|
| 57 |
+
FengWu,fengwu,global,1,shallow spatial adapter,shallow spatial adapter,0.000398077435365184,0.31071390711162444,0.31071390711162444,0.0,True
|
| 58 |
+
FengWu,fengwu,global,7,shallow spatial adapter,shallow spatial adapter,0.00036963872610239895,0.30641904273669174,0.30641904273669174,0.0,True
|
| 59 |
+
FengWu,fengwu,global,42,shallow spatial adapter,shallow spatial adapter,0.00036987379624400454,0.31219058559732665,0.31219058559732665,0.0,True
|
| 60 |
+
FengWu,fengwu,global,99,shallow spatial adapter,shallow spatial adapter,0.00042782651526874734,0.3111214819309595,0.3111214819309595,0.0,True
|
| 61 |
+
FengWu,fengwu,global,123,shallow spatial adapter,shallow spatial adapter,0.0004116035724473925,0.3145618361221859,0.3145618361221859,0.0,True
|
| 62 |
+
FuXi,fuxi,fire_prone,1,shallow spatial adapter,linear probe,0.01904942261850253,0.7246636456247585,0.7261195534617713,0.001455907837012771,False
|
| 63 |
+
FuXi,fuxi,fire_prone,7,shallow spatial adapter,shallow spatial adapter,0.018717347905238046,0.7235687421646468,0.7235687421646468,0.0,True
|
| 64 |
+
FuXi,fuxi,fire_prone,42,shallow spatial adapter,shallow spatial adapter,0.020363596550511454,0.7054843984273774,0.7054843984273774,0.0,True
|
| 65 |
+
FuXi,fuxi,fire_prone,99,pixel MLP head,shallow spatial adapter,0.02225455497934009,0.7203102915557309,0.7183426482806338,0.0,False
|
| 66 |
+
FuXi,fuxi,fire_prone,123,pixel MLP head,linear probe,0.021045021724179047,0.7185324707231184,0.7224961571477053,0.0039636864245868875,False
|
| 67 |
+
FuXi,fuxi,global,1,shallow spatial adapter,linear probe,0.0003596048414560045,0.3091927111996169,0.21516044416153002,0.0,False
|
| 68 |
+
FuXi,fuxi,global,7,shallow spatial adapter,shallow spatial adapter,0.00037118462783325537,0.3062654921252336,0.3062654921252336,0.0,True
|
| 69 |
+
FuXi,fuxi,global,42,shallow spatial adapter,shallow spatial adapter,0.0003830459807690152,0.316668570748256,0.316668570748256,0.0,True
|
| 70 |
+
FuXi,fuxi,global,99,shallow spatial adapter,shallow spatial adapter,0.0003758107890486513,0.3108110703043797,0.3108110703043797,0.0,True
|
| 71 |
+
FuXi,fuxi,global,123,shallow spatial adapter,shallow spatial adapter,0.00039999784430104664,0.3096924811079745,0.3096924811079745,0.0,True
|
| 72 |
+
Pangu-Weather,pangu_weather,fire_prone,1,pixel MLP head,pixel MLP head,0.014813375233921266,0.7185324707231184,0.7185324707231184,0.0,True
|
| 73 |
+
Pangu-Weather,pangu_weather,fire_prone,7,pixel MLP head,shallow spatial adapter,0.029883397445312192,0.0,0.7185324707231184,0.7185324707231184,False
|
| 74 |
+
Pangu-Weather,pangu_weather,fire_prone,42,pixel MLP head,shallow spatial adapter,0.02188826028256454,0.0,0.7185324707231184,0.7185324707231184,False
|
| 75 |
+
Pangu-Weather,pangu_weather,fire_prone,99,linear probe,shallow spatial adapter,0.02093558282208589,0.0,0.7185324707231184,0.7185324707231184,False
|
| 76 |
+
Pangu-Weather,pangu_weather,fire_prone,123,linear probe,linear probe,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,True
|
| 77 |
+
Pangu-Weather,pangu_weather,global,1,linear probe,shallow spatial adapter,0.00024254792826221397,0.23755358049655212,0.240793572992212,0.0032399924956598714,False
|
| 78 |
+
Pangu-Weather,pangu_weather,global,7,shallow spatial adapter,shallow spatial adapter,0.00028045576992618193,0.240793572992212,0.240793572992212,0.0,True
|
| 79 |
+
Pangu-Weather,pangu_weather,global,42,pixel MLP head,shallow spatial adapter,0.00021817709863716954,0.0,0.240793572992212,0.240793572992212,False
|
| 80 |
+
Pangu-Weather,pangu_weather,global,99,shallow spatial adapter,pixel MLP head,0.0003408299850116487,0.23917716245227552,0.229804399271568,0.0,False
|
| 81 |
+
Pangu-Weather,pangu_weather,global,123,shallow spatial adapter,shallow spatial adapter,0.0003300754798792237,0.240793572992212,0.240793572992212,0.0,True
|
| 82 |
+
Pangu-Weather,pangu6,fire_prone,1,shallow spatial adapter,shallow spatial adapter,0.02328829578760066,0.7231388400090598,0.7231388400090598,0.0,True
|
| 83 |
+
Pangu-Weather,pangu6,fire_prone,7,pixel MLP head,shallow spatial adapter,0.018664183428008234,0.7185324707231184,0.719461376864001,0.0009289061408825905,False
|
| 84 |
+
Pangu-Weather,pangu6,fire_prone,42,shallow spatial adapter,shallow spatial adapter,0.021420904714594617,0.7241279907754397,0.7241279907754397,0.0,True
|
| 85 |
+
Pangu-Weather,pangu6,fire_prone,99,linear probe,shallow spatial adapter,0.024740444457605402,0.7183382629739177,0.719015307962107,0.0006770449881893237,False
|
| 86 |
+
Pangu-Weather,pangu6,fire_prone,123,pixel MLP head,linear probe,0.02254610440161657,0.7185324707231184,0.7261721555350364,0.007639684811918013,False
|
| 87 |
+
Pangu-Weather,pangu6,global,1,shallow spatial adapter,shallow spatial adapter,0.00042881385578730365,0.32066974948800614,0.32066974948800614,0.0,True
|
| 88 |
+
Pangu-Weather,pangu6,global,7,shallow spatial adapter,shallow spatial adapter,0.00038395193539280824,0.31120670593952293,0.31120670593952293,0.0,True
|
| 89 |
+
Pangu-Weather,pangu6,global,42,shallow spatial adapter,shallow spatial adapter,0.00040651309469793043,0.32154249424354786,0.32154249424354786,0.0,True
|
| 90 |
+
Pangu-Weather,pangu6,global,99,shallow spatial adapter,shallow spatial adapter,0.0004450373086921994,0.3214547875801752,0.3214547875801752,0.0,True
|
| 91 |
+
Pangu-Weather,pangu6,global,123,shallow spatial adapter,shallow spatial adapter,0.00043738577276574255,0.31812983009681495,0.31812983009681495,0.0,True
|
| 92 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,1,shallow spatial adapter,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,True
|
| 93 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,7,shallow spatial adapter,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,True
|
| 94 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,42,pixel MLP head,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 95 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,99,linear probe,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 96 |
+
Prithvi-WxC,prithvi_wxc,fire_prone,123,shallow spatial adapter,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,True
|
| 97 |
+
Prithvi-WxC,prithvi_wxc,global,1,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 98 |
+
Prithvi-WxC,prithvi_wxc,global,7,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 99 |
+
Prithvi-WxC,prithvi_wxc,global,42,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 100 |
+
Prithvi-WxC,prithvi_wxc,global,99,shallow spatial adapter,shallow spatial adapter,0.0002454330184381399,0.23755358049655212,0.23755358049655212,0.0,True
|
| 101 |
+
Prithvi-WxC,prithvi_wxc,global,123,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 102 |
+
Reference,reference,fire_prone,1,shallow spatial adapter,linear probe,0.10204224118176683,0.799032457577039,0.8685988450931266,0.06956638751608757,False
|
| 103 |
+
Reference,reference,fire_prone,7,shallow spatial adapter,shallow spatial adapter,0.1323902067230726,0.8027807546359551,0.8027807546359551,0.0,True
|
| 104 |
+
Reference,reference,fire_prone,42,shallow spatial adapter,shallow spatial adapter,0.12048427320762313,0.8358151221553631,0.8358151221553631,0.0,True
|
| 105 |
+
Reference,reference,fire_prone,99,shallow spatial adapter,linear probe,0.11947246238005743,0.8534759193943048,0.9039923296574045,0.05051641026309972,False
|
| 106 |
+
Reference,reference,fire_prone,123,shallow spatial adapter,pixel MLP head,0.11551882470432043,0.8066689866810086,0.8567215417854325,0.05005255510442386,False
|
| 107 |
+
Reference,reference,global,1,shallow spatial adapter,linear probe,0.002624341503354088,0.6186566066408326,0.7286109603326707,0.10995435369183815,False
|
| 108 |
+
Reference,reference,global,7,shallow spatial adapter,shallow spatial adapter,0.0030317345997110698,0.5002193417313746,0.5002193417313746,0.0,True
|
| 109 |
+
Reference,reference,global,42,shallow spatial adapter,shallow spatial adapter,0.0032729435045747413,0.7239943741463363,0.7239943741463363,0.0,True
|
| 110 |
+
Reference,reference,global,99,shallow spatial adapter,linear probe,0.0031953098868323193,0.6698005926442897,0.7647466876509988,0.09494609500670914,False
|
| 111 |
+
Reference,reference,global,123,shallow spatial adapter,pixel MLP head,0.0025603887793133394,0.5009707461135111,0.735221546471909,0.23425080035839785,False
|
| 112 |
+
StormCast,stormcast,fire_prone,1,linear probe,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 113 |
+
StormCast,stormcast,fire_prone,7,linear probe,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 114 |
+
StormCast,stormcast,fire_prone,42,linear probe,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 115 |
+
StormCast,stormcast,fire_prone,99,pixel MLP head,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 116 |
+
StormCast,stormcast,fire_prone,123,linear probe,shallow spatial adapter,0.02093558282208589,0.7185324707231184,0.7185324707231184,0.0,False
|
| 117 |
+
StormCast,stormcast,global,1,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 118 |
+
StormCast,stormcast,global,7,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 119 |
+
StormCast,stormcast,global,42,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
| 120 |
+
StormCast,stormcast,global,99,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.2399251001974223,0.2399251001974223,0.0,True
|
| 121 |
+
StormCast,stormcast,global,123,shallow spatial adapter,shallow spatial adapter,0.0002463357401629007,0.240793572992212,0.240793572992212,0.0,True
|
artifacts/results/selection_regret_rq2_figure_values.csv
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
feature_source,global_mean_pp,global_std_pp,top20_mean_pp,top20_std_pp
|
| 2 |
+
FireWx-FM ref.,7.3831,7.4536,2.9385,2.7513
|
| 3 |
+
Prithvi-WxC,0.0000,0.0000,0.0000,0.0000
|
| 4 |
+
Aurora,4.9455,10.6974,14.3706,32.1337
|
| 5 |
+
ClimaX,0.1296,0.1775,0.0000,0.0000
|
| 6 |
+
StormCast,0.0000,0.0000,0.0000,0.0000
|
| 7 |
+
DLWP,0.0000,0.0000,4.4634,4.3561
|
| 8 |
+
FCN,0.0000,0.0000,1.1680,1.9872
|
| 9 |
+
FengWu,0.0000,0.0000,0.5222,0.6239
|
| 10 |
+
FuXi,0.0000,0.0000,0.2833,0.3681
|
| 11 |
+
Pangu-Weather,0.0000,0.0000,0.1868,0.3255
|
| 12 |
+
AlphaEarth,17.2217,8.8492,3.8804,5.9483
|
artifacts/results/selection_regret_scope_sweep_20260505.csv
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_tag,label,scope,scope_label,n,seeds,exact_regret_mean,exact_regret_std,exact_regret_min,exact_regret_max,tolerated_regret_mean,tolerated_regret_std,tolerated_regret_min,tolerated_regret_max,union_regret_mean,union_regret_std,union_regret_min,union_regret_max
|
| 2 |
+
reference,FireWx-FM ref.,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.07383089600948442,0.07453636071372995,0.0,0.17497107865629713,0.07383089600948442,0.07453636071372995,0.0,0.17497107865629713
|
| 3 |
+
reference,FireWx-FM ref.,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.003663718115532055,0.006812231244812292,0.0,0.015676762201120686,0.003663718115532055,0.006812231244812292,0.0,0.015676762201120686
|
| 4 |
+
reference,FireWx-FM ref.,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.012275489592085752,0.012665162001740834,0.0,0.02670880922526031,0.012275489592085752,0.012665162001740834,0.0,0.02670880922526031
|
| 5 |
+
reference,FireWx-FM ref.,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.029384646387840017,0.02751315335001922,0.0,0.05675140203555318,0.029384646387840017,0.02751315335001922,0.0,0.05675140203555318
|
| 6 |
+
prithvi_wxc,Prithvi-WxC,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 7 |
+
prithvi_wxc,Prithvi-WxC,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 8 |
+
prithvi_wxc,Prithvi-WxC,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 9 |
+
prithvi_wxc,Prithvi-WxC,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 10 |
+
aurora,Aurora,global,\(\Omega=\)global,5,1 7 42 99 123,0.00010153879814819402,0.00021861477435572763,0.0,0.0004925501476206198,0.04945471159670635,0.10697394238964528,0.0,0.240793572992212,0.04945471159670635,0.10697394238964528,0.0,0.240793572992212
|
| 11 |
+
aurora,Aurora,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.023667154505540456,0.05292136630837888,0.0,0.11833577252770228,0.1542829840966487,0.34498724021162547,0.0,0.7714149204832434,0.1542829840966487,0.34498724021162547,0.0,0.7714149204832434
|
| 12 |
+
aurora,Aurora,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.014651279478173606,0.032761256870543834,0.0,0.07325639739086803,0.1399343063221699,0.31290262132065055,0.0,0.6996715316108496,0.1399343063221699,0.31290262132065055,0.0,0.6996715316108496
|
| 13 |
+
aurora,Aurora,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.008202508825959588,0.01834136732088763,0.0,0.04101254412979794,0.1437064941446237,0.32133748971555404,0.0,0.7185324707231184,0.1437064941446237,0.32133748971555404,0.0,0.7185324707231184
|
| 14 |
+
climax,ClimaX,global,\(\Omega=\)global,5,1 7 42 99 123,3.0287686240700486e-06,4.147312242167625e-06,0.0,7.571921560175121e-06,0.0012959969982639485,0.0017746169760203706,0.0,0.0032399924956598714,0.0012959969982639485,0.0017746169760203706,0.0,0.0032399924956598714
|
| 15 |
+
climax,ClimaX,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 16 |
+
climax,ClimaX,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 17 |
+
climax,ClimaX,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 18 |
+
stormcast,StormCast,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 19 |
+
stormcast,StormCast,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 20 |
+
stormcast,StormCast,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 21 |
+
stormcast,StormCast,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 22 |
+
dlwp,DLWP,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 23 |
+
dlwp,DLWP,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0048037709215293075,0.006217185202152866,0.0,0.015203005078871956,0.016716228534155796,0.016079313546074458,0.0,0.03305057342744666,0.016716228534155796,0.016079313546074458,0.0,0.03305057342744666
|
| 24 |
+
dlwp,DLWP,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0017281632798742507,0.002514722758075371,0.0,0.005523780499856246,0.02846514801700826,0.026938012702643194,0.0,0.053927677500854476,0.02846514801700826,0.026938012702643194,0.0,0.053927677500854476
|
| 25 |
+
dlwp,DLWP,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0007702319787454587,0.0010995336594539604,0.0,0.0023651634514294945,0.04463354681768479,0.04356064433532197,0.0,0.11215006616165157,0.04463354681768479,0.04356064433532197,0.0,0.11215006616165157
|
| 26 |
+
fcn,FCN,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 27 |
+
fcn,FCN,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0006342898232943345,0.0009899554165032742,0.0,0.002257520679520411,0.004509624980300697,0.010070611656609236,0.0,0.022524473456150496,0.004509624980300697,0.010070611656609236,0.0,0.022524473456150496
|
| 28 |
+
fcn,FCN,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.00021156854817603877,0.0004730816556225618,0.0,0.0010578427408801938,0.004199537050817615,0.009390450319657174,0.0,0.020997685254088072,0.004199537050817615,0.009390450319657174,0.0,0.020997685254088072
|
| 29 |
+
fcn,FCN,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,5.754560074337778e-06,1.2867587506825515e-05,0.0,2.877280037168889e-05,0.011679805987441694,0.019872372458657642,0.0,0.045880503237594294,0.011679805987441694,0.019872372458657642,0.0,0.045880503237594294
|
| 30 |
+
fengwu,FengWu,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 31 |
+
fengwu,FengWu,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0005029843170376968,0.0008109166521114917,0.0,0.0018628094907809783,0.008795951947678215,0.005532321338017505,0.0,0.01484136735033148,0.008795951947678215,0.005532321338017505,0.0,0.01484136735033148
|
| 32 |
+
fengwu,FengWu,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.000495228089292582,0.0007349190216431337,0.0,0.0016387212062008855,0.00402300475984525,0.005510851442075993,0.0,0.010273937098576491,0.00402300475984525,0.005510851442075993,0.0,0.010273937098576491
|
| 33 |
+
fengwu,FengWu,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0006908222234409067,0.0011910586589384115,0.0,0.0027505832409660327,0.005222389249812243,0.0062394095558402415,0.0,0.015150501067724198,0.005222389249812243,0.0062394095558402415,0.0,0.015150501067724198
|
| 34 |
+
fuxi,FuXi,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 35 |
+
fuxi,FuXi,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.002973545331200933,0.0023946274991058026,0.0010927807990139538,0.007024214143542151,0.013545122545609134,0.02097023683418404,0.0,0.050156261654859424,0.013545122545609134,0.02097023683418404,0.0,0.050156261654859424
|
| 36 |
+
fuxi,FuXi,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.001383793743586542,0.0019248128430711165,0.0,0.003938013087198336,0.0016559834970027332,0.0037028916689159307,0.0,0.008279917485013666,0.0016559834970027332,0.0037028916689159307,0.0,0.008279917485013666
|
| 37 |
+
fuxi,FuXi,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.00283318355751887,0.0036808289681375247,0.0,0.008746323525994693,0.00283318355751887,0.0036808289681375247,0.0,0.008746323525994693
|
| 38 |
+
pangu6,Pangu-Weather,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
|
| 39 |
+
pangu6,Pangu-Weather,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.003154674487241463,0.002546125713211599,0.0,0.005711594157251587,0.007592888149777122,0.00897418737588444,0.0,0.019790633919317124,0.007592888149777122,0.00897418737588444,0.0,0.019790633919317124
|
| 40 |
+
pangu6,Pangu-Weather,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0017345627303725214,0.0019305189318827886,0.0,0.004535321555179647,0.003047840737004992,0.005053805614558161,0.0,0.011660780793438352,0.003047840737004992,0.005053805614558161,0.0,0.011660780793438352
|
| 41 |
+
pangu6,Pangu-Weather,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0007280423771922354,0.001178746460551365,0.0,0.0027096086413018403,0.0018679847512695024,0.0032548337047755126,0.0,0.007639684811918013,0.0018679847512695024,0.0032548337047755126,0.0,0.007639684811918013
|
| 42 |
+
alphaearth,AlphaEarth,global,\(\Omega=\)global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.1722171037486726,0.08849214830495522,0.050655329891645895,0.272468682523694,0.1722171037486726,0.08849214830495522,0.050655329891645895,0.272468682523694
|
| 43 |
+
alphaearth,AlphaEarth,top5,\(\Omega=\)top 5\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.06384618090125256,0.04965276403138872,0.0,0.1365277562230962,0.06384618090125256,0.04965276403138872,0.0,0.1365277562230962
|
| 44 |
+
alphaearth,AlphaEarth,top10,\(\Omega=\)top 10\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.06573776411084173,0.06897015340160571,0.0,0.1615566566666954,0.06573776411084173,0.06897015340160571,0.0,0.1615566566666954
|
| 45 |
+
alphaearth,AlphaEarth,top20,\(\Omega=\)top 20\%,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.038803552655092256,0.0594825313313219,0.0,0.13482302181308625,0.038803552655092256,0.0594825313313219,0.0,0.13482302181308625
|
artifacts/results/selection_regret_scope_sweep_20260505.generated.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[!t]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{4pt}
|
| 5 |
+
\caption{Fixed-feature selection-regret sweep across evaluation scopes. Values are percentage-point regret \(\delta = D(h_D)-D(h_R)\) under union-\(F_1\). Top-\(k\) scopes are train-defined fire-prone masks. Rows report mean with small std over five seeds.}
|
| 6 |
+
\label{tab:selection_regret_scope_sweep}
|
| 7 |
+
\begin{tabular}{lcccc}
|
| 8 |
+
\toprule
|
| 9 |
+
\textbf{Feature source} & \textbf{\(\Omega=\)global} & \textbf{\(\Omega=\)top 5\%} & \textbf{\(\Omega=\)top 10\%} & \textbf{\(\Omega=\)top 20\%} \\
|
| 10 |
+
\midrule
|
| 11 |
+
\textcolor{blue}{FireWx-FM ref.} & \ms{7.3831}{7.4536} & \ms{0.3664}{0.6812} & \ms{1.2275}{1.2665} & \ms{2.9385}{2.7513} \\
|
| 12 |
+
Prithvi-WxC & 0.0000 & 0.0000 & 0.0000 & 0.0000 \\
|
| 13 |
+
Aurora & \ms{4.9455}{10.6974} & \ms{15.4283}{34.4987} & \ms{13.9934}{31.2903} & \ms{14.3706}{32.1337} \\
|
| 14 |
+
ClimaX & \ms{0.1296}{0.1775} & 0.0000 & 0.0000 & 0.0000 \\
|
| 15 |
+
StormCast & 0.0000 & 0.0000 & 0.0000 & 0.0000 \\
|
| 16 |
+
DLWP & 0.0000 & \ms{1.6716}{1.6079} & \ms{2.8465}{2.6938} & \ms{4.4634}{4.3561} \\
|
| 17 |
+
FCN & 0.0000 & \ms{0.4510}{1.0071} & \ms{0.4200}{0.9390} & \ms{1.1680}{1.9872} \\
|
| 18 |
+
FengWu & 0.0000 & \ms{0.8796}{0.5532} & \ms{0.4023}{0.5511} & \ms{0.5222}{0.6239} \\
|
| 19 |
+
FuXi & 0.0000 & \ms{1.3545}{2.0970} & \ms{0.1656}{0.3703} & \ms{0.2833}{0.3681} \\
|
| 20 |
+
Pangu-Weather & 0.0000 & \ms{0.7593}{0.8974} & \ms{0.3048}{0.5054} & \ms{0.1868}{0.3255} \\
|
| 21 |
+
AlphaEarth & \ms{17.2217}{8.8492} & \ms{6.3846}{4.9653} & \ms{6.5738}{6.8970} & \ms{3.8804}{5.9483} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
artifacts/results/selection_regret_scope_sweep_20260505.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
artifacts/results/selection_regret_summary.csv
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_tag,label,scope,n,seeds,exact_regret_mean,exact_regret_std,tolerated_regret_mean,tolerated_regret_std,union_regret_mean,union_regret_std
|
| 2 |
+
reference,Reference,global,5,1 7 42 99 123,0.0,0.0,0.08783024981138902,0.09670495645481135,0.08783024981138902,0.09670495645481135
|
| 3 |
+
reference,Reference,fire_prone,5,1 7 42 99 123,0.0,0.0,0.03402707057672223,0.032044658643147844,0.03402707057672223,0.032044658643147844
|
| 4 |
+
prithvi_wxc,Prithvi-WxC,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 5 |
+
prithvi_wxc,Prithvi-WxC,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 6 |
+
aurora,Aurora,global,5,1 7 42 99 123,0.00020004882767231798,0.00026703384456332115,0.09851983041506818,0.1298781980037557,0.09851983041506818,0.1298781980037557
|
| 7 |
+
aurora,Aurora,fire_prone,5,1 7 42 99 123,0.008202508825959588,0.01834136732088763,0.14391889430974364,0.32121904665016227,0.14391889430974364,0.32121904665016227
|
| 8 |
+
climax,ClimaX,global,5,1 7 42 99 123,3.0287686240700486e-06,4.147312242167625e-06,0.0012959969982639485,0.0017746169760203706,0.0012959969982639485,0.0017746169760203706
|
| 9 |
+
climax,ClimaX,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 10 |
+
stormcast,StormCast,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 11 |
+
stormcast,StormCast,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 12 |
+
pangu_weather,Pangu-Weather,global,5,1 7 42 99 123,0.00013033979247265275,0.0002685372203690466,0.048806713097574374,0.10733308684741971,0.048806713097574374,0.10733308684741971
|
| 13 |
+
pangu_weather,Pangu-Weather,fire_prone,5,1 7 42 99 123,0.027875386332505546,0.02348779386900393,0.43111948243387105,0.39355644251497235,0.43111948243387105,0.39355644251497235
|
| 14 |
+
dlwp,DLWP,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 15 |
+
dlwp,DLWP,fire_prone,5,1 7 42 99 123,0.0007702319787454587,0.0010995336594539604,0.043265915053601556,0.04332331365579739,0.043265915053601556,0.04332331365579739
|
| 16 |
+
fcn,FCN,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 17 |
+
fcn,FCN,fire_prone,5,1 7 42 99 123,5.960229415004348e-06,1.3327478133443526e-05,0.011679805987441694,0.019872372458657642,0.011679805987441694,0.019872372458657642
|
| 18 |
+
fengwu,FengWu,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 19 |
+
fengwu,FengWu,fire_prone,5,1 7 42 99 123,0.0006908222234409067,0.0011910586589384115,0.005222389249812243,0.0062394095558402415,0.005222389249812243,0.0062394095558402415
|
| 20 |
+
fuxi,FuXi,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 21 |
+
fuxi,FuXi,fire_prone,5,1 7 42 99 123,0.0,0.0,0.0010839188523199318,0.0017288780545672386,0.0010839188523199318,0.0017288780545672386
|
| 22 |
+
pangu6,Pangu-Weather,global,5,1 7 42 99 123,0.0,0.0,0.0,0.0,0.0,0.0
|
| 23 |
+
pangu6,Pangu-Weather,fire_prone,5,1 7 42 99 123,0.0007280423771922354,0.001178746460551365,0.0018491271881979853,0.0032630386057089294,0.0018491271881979853,0.0032630386057089294
|
| 24 |
+
alphaearth,AlphaEarth,global,5,1 7 42 99 123,0.0,0.0,0.1722171037486726,0.08849214830495522,0.1722171037486726,0.08849214830495522
|
| 25 |
+
alphaearth,AlphaEarth,fire_prone,5,1 7 42 99 123,0.0,0.0,0.038803552655092256,0.0594825313313219,0.038803552655092256,0.0594825313313219
|
artifacts/results/selection_regret_tolerance_family_table.generated.tex
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
% Replaced by the all-backbone value table in sections/appendix.tex
|
| 2 |
+
% (Table~\ref{tab:appendix_selection_regret_tolerance}).
|
data_sources/DATA_SOURCES.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Data Sources
|
| 2 |
+
|
| 3 |
+
This repository does not redistribute raw data. The table below records the
|
| 4 |
+
resources used by the paper, their role in the experiments, and public access
|
| 5 |
+
entry points. Users must obtain each source under its own terms.
|
| 6 |
+
|
| 7 |
+
| Source | Role in paper | Public access entry point |
|
| 8 |
+
|---|---|---|
|
| 9 |
+
| NOAA High-Resolution Rapid Refresh (HRRR) | Dynamic weather fields for the California regional gridded occupancy inputs. | NOAA/NCEI HRRR product page: <https://www.ncei.noaa.gov/products/weather-climate-models/high-resolution-rapid-refresh>; AWS Open Data archive: <https://registry.opendata.aws/noaa-hrrr-pds/>. |
|
| 10 |
+
| NASA FIRMS active-fire detections | Active-fire detections used to derive gridded occupancy labels. | FIRMS download and API services: <https://firms.modaps.eosdis.nasa.gov/download/> and <https://firms.modaps.eosdis.nasa.gov/api/>. |
|
| 11 |
+
| LANDFIRE 40 Fire Behavior Fuel Models | Static fuel layer used in the FireWx-FM gridded input. | LANDFIRE data access portal: <https://landfire.gov/data>. |
|
| 12 |
+
| LANDFIRE Forest Canopy Cover | Static canopy layer used in the FireWx-FM gridded input. | LANDFIRE data access portal: <https://landfire.gov/data>. |
|
| 13 |
+
| Wildfire Risk to Communities housing-unit density | Static exposure layer used in the FireWx-FM gridded input. | Wildfire Risk to Communities data access: <https://wildfirerisk.org/download/>. |
|
| 14 |
+
| LandScan Global 2024 | Static population layer used in the FireWx-FM gridded input. | Oak Ridge National Laboratory LandScan access: <https://landscan.ornl.gov/>. |
|
| 15 |
+
| WFIGS incident/perimeter attributes | Event-level incident metadata for supporting burned-area and analog tasks. | NIFC Open Data portal for WFIGS layers: <https://data-nifc.opendata.arcgis.com/>. |
|
| 16 |
+
| MTBS burned area and burn severity | Event-scale burned-area and burn-severity records for supporting tasks. | MTBS data access and direct download pages: <https://www.mtbs.gov/> and <https://www.mtbs.gov/direct-download>. |
|
| 17 |
+
| Earth-FM/backbone sources | Frozen feature sources for transferred Earth-FM comparisons. | Original model providers and their terms. Examples include Hugging Face model cards, model-provider GitHub repositories, and provider-hosted model files. |
|
| 18 |
+
|
| 19 |
+
## Notes
|
| 20 |
+
|
| 21 |
+
- The paper places gridded resources on a projected 5 km EPSG:5070 grid.
|
| 22 |
+
- The bundled artifacts contain summary values only. They are not a substitute
|
| 23 |
+
for the original data.
|
| 24 |
+
- Full raw-data reruns require users to obtain each source independently and to
|
| 25 |
+
construct the intermediate grids/features described in the paper.
|
| 26 |
+
- Access mechanisms and licensing can change. The links above are entry points,
|
| 27 |
+
not redistributed copies.
|
docs/artifact_map.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Paper Artifact Map
|
| 2 |
+
|
| 3 |
+
This map links every table and figure label in the current manuscript to the
|
| 4 |
+
public release artifact and its provenance. Final output checksums are stored in
|
| 5 |
+
`artifacts/manifests/paper_outputs.sha256`.
|
| 6 |
+
|
| 7 |
+
## Figures
|
| 8 |
+
|
| 9 |
+
| Paper label | Release file | Provenance |
|
| 10 |
+
|---|---|---|
|
| 11 |
+
| `fig:toy_occupancy_contract` | `paper_outputs/figures/matching.pdf` | Static vector schematic used by the manuscript. |
|
| 12 |
+
| `fig:task_contract_tiles` | `paper_outputs/figures/fig_task_contract_tiles.pdf` | Static contract-map figure used by the manuscript. |
|
| 13 |
+
| `fig:selection_regret_diagnostic` | `paper_outputs/figures/fig_selection_regret_rq2.tikz` | Rebuilt by `scripts/build_selection_regret_rq2_figure.py` from `artifacts/results/selection_regret_scope_sweep_20260505.csv`. |
|
| 14 |
+
| `fig:fireprone_contract_progression` | `paper_outputs/figures/fig_fireprone_contract_progression_compact.pdf` | Rebuilt by `scripts/build_fireprone_contract_progression_figure.py` from `artifacts/results/fireprone_contract_progression_summary.json`. |
|
| 15 |
+
| `fig:task_comparator_normalized_map` | `paper_outputs/figures/fig_task_rank_map.pdf` | Rebuilt by `scripts/build_task_rank_map.py` from `tab_primary_results.tex` and `tab_supporting_results.tex`. |
|
| 16 |
+
|
| 17 |
+
## Main Tables
|
| 18 |
+
|
| 19 |
+
| Paper label | Release file | Provenance |
|
| 20 |
+
|---|---|---|
|
| 21 |
+
| `tab:primary_results` | `paper_outputs/tables/tab_primary_results.tex` | Frozen paper-output TeX extracted from the current manuscript source and verified by checksum. Raw reruns require the task scripts and non-redistributed feature caches. |
|
| 22 |
+
| `tab:supporting_results` | `paper_outputs/tables/tab_supporting_results.tex` | Frozen paper-output TeX extracted from the current manuscript source and verified by checksum. Raw reruns require the task scripts and non-redistributed feature caches. |
|
| 23 |
+
|
| 24 |
+
## Appendix Tables
|
| 25 |
+
|
| 26 |
+
| Paper label | Release file | Provenance |
|
| 27 |
+
|---|---|---|
|
| 28 |
+
| `tab:app_matching_rule_params` | `paper_outputs/tables/tab_app_matching_rule_params.tex` | Contract parameter table from manuscript source, verified by checksum. |
|
| 29 |
+
| `tab:app_contract_params_full` | `paper_outputs/tables/tab_app_contract_params_full.tex` | Contract parameter table from manuscript source, verified by checksum. |
|
| 30 |
+
| `tab:app_scope_params` | `paper_outputs/tables/tab_app_scope_params.tex` | Scope parameter table from manuscript source, verified by checksum. |
|
| 31 |
+
| `tab:fireprone_contract_progression` | `paper_outputs/tables/tab_fireprone_contract_progression.tex` | Values from `artifacts/results/fireprone_contract_progression_summary.json`. |
|
| 32 |
+
| `tab:appendix_selection_regret_tolerance` | `paper_outputs/tables/tab_appendix_selection_regret_tolerance.tex` | Values from selection-regret summary artifacts. |
|
| 33 |
+
| `tab:app_occupancy_ppr_scope` | `paper_outputs/tables/tab_app_occupancy_ppr_scope.tex` | Values from `artifacts/results/fireprone_contract_progression_summary.json`. |
|
| 34 |
+
| `tab:app_spread_ap_by_scope` | `paper_outputs/tables/tab_app_spread_ap_by_scope.tex` | Frozen paper-output TeX extracted from current manuscript source, verified by checksum. |
|
| 35 |
+
| `tab:app_burned_area_median_acre` | `paper_outputs/tables/tab_app_burned_area_median_acre.tex` | Frozen paper-output TeX extracted from current manuscript source, verified by checksum. |
|
| 36 |
+
| `tab:app_analog_rank_depth` | `paper_outputs/tables/tab_app_analog_rank_depth.tex` | Frozen paper-output TeX extracted from current manuscript source, verified by checksum. |
|
| 37 |
+
| `tab:app_smoke_high_event` | `paper_outputs/tables/tab_app_smoke_high_event.tex` | Frozen paper-output TeX extracted from current manuscript source, verified by checksum. |
|
| 38 |
+
| `tab:app_heat_event_pr` | `paper_outputs/tables/tab_app_heat_event_pr.tex` | Frozen paper-output TeX extracted from current manuscript source, verified by checksum. |
|
| 39 |
+
| `tab:app_seed_robustness` | `paper_outputs/tables/tab_app_seed_robustness.tex` | Seed summary table from manuscript source, verified by checksum. |
|
| 40 |
+
| `tab:app_head_architectures` | `paper_outputs/tables/tab_app_head_architectures.tex` | Architecture description table from manuscript source, verified by checksum. |
|
| 41 |
+
|
| 42 |
+
## Reproduction Commands
|
| 43 |
+
|
| 44 |
+
```bash
|
| 45 |
+
python3 scripts/reproduce_paper_outputs.py
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
This command rebuilds the outputs that depend only on released summary files,
|
| 49 |
+
checks all final paper-output hashes, and runs the release audit.
|
| 50 |
+
|
| 51 |
+
## Raw Rerun Boundary
|
| 52 |
+
|
| 53 |
+
Some tables depend on raw gridded data, event data, or backbone feature caches
|
| 54 |
+
that are not redistributed. For public release, we provide the compact summary
|
| 55 |
+
artifacts used to reproduce the displayed paper values and document the raw data
|
| 56 |
+
sources separately.
|
docs/huggingface_release_design.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hugging Face Release Design
|
| 2 |
+
|
| 3 |
+
This release follows the common Hugging Face pattern for research artifacts:
|
| 4 |
+
|
| 5 |
+
- `README.md` is the public card. It contains YAML metadata, intended use,
|
| 6 |
+
limitations, data provenance, reproduction commands, and citation text.
|
| 7 |
+
- `paper_outputs/` stores the final TeX, TikZ, and PDF artifacts used by the
|
| 8 |
+
manuscript.
|
| 9 |
+
- `artifacts/results/` stores compact CSV/JSON summaries that can be public.
|
| 10 |
+
- `artifacts/manifests/` maps paper labels to files and records output hashes.
|
| 11 |
+
- `data_sources/` documents external data resources without redistributing them.
|
| 12 |
+
- `experiments/` contains raw-rerun reference scripts and Slurm templates.
|
| 13 |
+
|
| 14 |
+
The repository is intentionally a paper-artifact release rather than a dataset
|
| 15 |
+
mirror or model-weight release. Full raw-data reruns require separately obtained
|
| 16 |
+
source data and local feature caches.
|
experiments/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Raw Rerun Notes
|
| 2 |
+
|
| 3 |
+
This directory documents the raw rerun boundary. The public artifact release does
|
| 4 |
+
not include local Slurm scripts with machine paths, raw wildfire inputs, or local
|
| 5 |
+
feature caches. Full raw reruns require users to obtain the source data listed in
|
| 6 |
+
`data_sources/DATA_SOURCES.md` and adapt the templates below to their own cluster.
|
| 7 |
+
|
| 8 |
+
The bundled paper-output reproduction path does not require these raw reruns.
|
| 9 |
+
|
| 10 |
+
## Reference Scripts
|
| 11 |
+
|
| 12 |
+
The scripts under `raw_reference/` are sanitized references for the task-level
|
| 13 |
+
runs used in the paper. They preserve the command-line interfaces and evaluation
|
| 14 |
+
logic, but they require user-provided data tables, feature caches, and model
|
| 15 |
+
dependencies.
|
| 16 |
+
|
| 17 |
+
If a script imports local project modules from an external preprocessing tree,
|
| 18 |
+
set `WILDFIRE_FM_EXTRA_PYTHONPATH` before running it:
|
| 19 |
+
|
| 20 |
+
```bash
|
| 21 |
+
export WILDFIRE_FM_EXTRA_PYTHONPATH=/path/to/your/project/src:/path/to/extra/site-packages
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
The Slurm file in `slurm/` is a template only. Replace all placeholder paths
|
| 25 |
+
before submitting jobs on your own cluster.
|
experiments/raw_reference/run_selection_regret_scope_sweep_20260505.py
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Run fixed-feature head-selection regret for global and top-k fire-prone scopes."""
|
| 3 |
+
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
import argparse
|
| 7 |
+
import csv
|
| 8 |
+
import importlib.util
|
| 9 |
+
import json
|
| 10 |
+
import math
|
| 11 |
+
from pathlib import Path
|
| 12 |
+
from typing import Any
|
| 13 |
+
|
| 14 |
+
import numpy as np
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
BASE_RUNNER = Path(__file__).resolve().parent / "task_scripts" / "run_all_backbone_selection_regret_20260504.py"
|
| 18 |
+
spec = importlib.util.spec_from_file_location("selection_regret_base_20260504", BASE_RUNNER)
|
| 19 |
+
if spec is None or spec.loader is None:
|
| 20 |
+
raise RuntimeError(f"Cannot import base runner: {BASE_RUNNER}")
|
| 21 |
+
base = importlib.util.module_from_spec(spec)
|
| 22 |
+
spec.loader.exec_module(base)
|
| 23 |
+
|
| 24 |
+
head_control = base.head_control
|
| 25 |
+
|
| 26 |
+
SCOPE_FRACS = (0.05, 0.10, 0.20)
|
| 27 |
+
SCOPE_ORDER = ("global", "top5", "top10", "top20")
|
| 28 |
+
SCOPE_LABELS = {
|
| 29 |
+
"global": "global",
|
| 30 |
+
"top5": "top 5%",
|
| 31 |
+
"top10": "top 10%",
|
| 32 |
+
"top20": "top 20%",
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def parse_args() -> argparse.Namespace:
|
| 37 |
+
parser = argparse.ArgumentParser(description="Selection-regret scope sweep.")
|
| 38 |
+
parser.add_argument("--source-kind", choices=("reference", "attached", "spatial", "alphaearth"), required=True)
|
| 39 |
+
parser.add_argument("--feature-root", type=Path, required=True)
|
| 40 |
+
parser.add_argument("--daily-rows-csv", type=Path)
|
| 41 |
+
parser.add_argument("--support-dir", type=Path)
|
| 42 |
+
parser.add_argument("--alphaearth-cache-root", type=Path)
|
| 43 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 44 |
+
parser.add_argument("--fm-family", type=str, required=True)
|
| 45 |
+
parser.add_argument("--model-tag", type=str, required=True)
|
| 46 |
+
parser.add_argument("--seed", type=int, required=True)
|
| 47 |
+
parser.add_argument("--heads", nargs="+", choices=base.HEADS, default=["linear", "pixel_mlp", "shallow"])
|
| 48 |
+
parser.add_argument("--batch-size", type=int, default=8)
|
| 49 |
+
parser.add_argument("--epochs", type=int, default=2)
|
| 50 |
+
parser.add_argument("--learning-rate", type=float, default=8e-4)
|
| 51 |
+
parser.add_argument("--weight-decay", type=float, default=1e-5)
|
| 52 |
+
parser.add_argument("--pos-weight-cap", type=float, default=150.0)
|
| 53 |
+
parser.add_argument("--device", choices=("cpu", "cuda", "auto"), default="cpu")
|
| 54 |
+
parser.add_argument(
|
| 55 |
+
"--metric-thresholds",
|
| 56 |
+
nargs="+",
|
| 57 |
+
type=float,
|
| 58 |
+
default=[
|
| 59 |
+
1e-5,
|
| 60 |
+
2e-5,
|
| 61 |
+
5e-5,
|
| 62 |
+
1e-4,
|
| 63 |
+
2e-4,
|
| 64 |
+
5e-4,
|
| 65 |
+
1e-3,
|
| 66 |
+
2e-3,
|
| 67 |
+
5e-3,
|
| 68 |
+
1e-2,
|
| 69 |
+
2e-2,
|
| 70 |
+
5e-2,
|
| 71 |
+
8e-2,
|
| 72 |
+
1e-1,
|
| 73 |
+
1.5e-1,
|
| 74 |
+
2e-1,
|
| 75 |
+
3e-1,
|
| 76 |
+
5e-1,
|
| 77 |
+
],
|
| 78 |
+
)
|
| 79 |
+
parser.add_argument("--variants", nargs="+", default=["identity"])
|
| 80 |
+
parser.add_argument("--fire-prone-top-fracs", nargs="+", type=float, default=list(SCOPE_FRACS))
|
| 81 |
+
parser.add_argument("--temporal-steps", type=int, default=3)
|
| 82 |
+
parser.add_argument("--spatial-radius", type=int, default=8)
|
| 83 |
+
parser.add_argument("--buffer-radius", type=int, default=8)
|
| 84 |
+
parser.add_argument("--boundary-radius", type=int, default=8)
|
| 85 |
+
parser.add_argument("--coarse-factor", type=int, default=8)
|
| 86 |
+
parser.add_argument("--time-step-hours", type=int, default=6)
|
| 87 |
+
return parser.parse_args()
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def scope_name(top_frac: float) -> str:
|
| 91 |
+
pct = int(round(float(top_frac) * 100.0))
|
| 92 |
+
return f"top{pct}"
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def scope_label(top_frac: float) -> str:
|
| 96 |
+
pct = int(round(float(top_frac) * 100.0))
|
| 97 |
+
return f"top {pct}%"
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def build_scope_masks(
|
| 101 |
+
split_rows: dict[str, list[dict[str, str]]],
|
| 102 |
+
store: Any,
|
| 103 |
+
top_fracs: list[float],
|
| 104 |
+
) -> tuple[dict[str, np.ndarray | None], dict[str, dict[str, Any]]]:
|
| 105 |
+
masks: dict[str, np.ndarray | None] = {"global": None}
|
| 106 |
+
meta: dict[str, dict[str, Any]] = {
|
| 107 |
+
"global": {
|
| 108 |
+
"scope_name": "global",
|
| 109 |
+
"reported_as": "global",
|
| 110 |
+
"top_fraction": None,
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
for frac in top_fracs:
|
| 114 |
+
name = scope_name(frac)
|
| 115 |
+
mask, mask_meta = head_control.build_fire_prone_mask(split_rows["train"], store, float(frac))
|
| 116 |
+
masks[name] = mask
|
| 117 |
+
meta[name] = {
|
| 118 |
+
"scope_name": name,
|
| 119 |
+
"reported_as": scope_label(frac),
|
| 120 |
+
**mask_meta,
|
| 121 |
+
}
|
| 122 |
+
return masks, meta
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def build_posthoc_rows_for_scopes(
|
| 126 |
+
probs: np.ndarray,
|
| 127 |
+
targets: np.ndarray,
|
| 128 |
+
sample_times: np.ndarray,
|
| 129 |
+
split: str,
|
| 130 |
+
scope_masks: dict[str, np.ndarray | None],
|
| 131 |
+
args: argparse.Namespace,
|
| 132 |
+
) -> list[dict[str, object]]:
|
| 133 |
+
rows_out: list[dict[str, object]] = []
|
| 134 |
+
for threshold in [float(v) for v in args.metric_thresholds]:
|
| 135 |
+
base_binary = probs >= threshold
|
| 136 |
+
for variant in args.variants:
|
| 137 |
+
binary = head_control.apply_variant(base_binary, variant)
|
| 138 |
+
tensors = head_control.evaluate_threshold_variant(
|
| 139 |
+
binary_np=binary,
|
| 140 |
+
target_np=targets,
|
| 141 |
+
sample_times=sample_times,
|
| 142 |
+
time_step_hours=args.time_step_hours,
|
| 143 |
+
temporal_steps=args.temporal_steps,
|
| 144 |
+
spatial_radius=args.spatial_radius,
|
| 145 |
+
buffer_radius=args.buffer_radius,
|
| 146 |
+
boundary_radius=args.boundary_radius,
|
| 147 |
+
coarse_factor=args.coarse_factor,
|
| 148 |
+
tolerance_hours=args.temporal_steps * args.time_step_hours,
|
| 149 |
+
)
|
| 150 |
+
for scope, region_mask in scope_masks.items():
|
| 151 |
+
row: dict[str, object] = {
|
| 152 |
+
"split": split,
|
| 153 |
+
"scope": scope,
|
| 154 |
+
"threshold": float(threshold),
|
| 155 |
+
"variant": variant,
|
| 156 |
+
"time_step_hours": int(args.time_step_hours),
|
| 157 |
+
"temporal_steps": int(args.temporal_steps),
|
| 158 |
+
"tolerance_hours": int(args.temporal_steps * args.time_step_hours),
|
| 159 |
+
"spatial_radius": int(args.spatial_radius),
|
| 160 |
+
"buffer_radius": int(args.buffer_radius),
|
| 161 |
+
"boundary_radius": int(args.boundary_radius),
|
| 162 |
+
"coarse_factor": int(args.coarse_factor),
|
| 163 |
+
}
|
| 164 |
+
row.update(head_control.metrics_for_scope(tensors, region_mask))
|
| 165 |
+
rows_out.append(row)
|
| 166 |
+
return rows_out
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
def read_csv(path: Path) -> list[dict[str, str]]:
|
| 170 |
+
with path.open("r", encoding="utf-8", newline="") as fh:
|
| 171 |
+
return list(csv.DictReader(fh))
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def load_head_summary(
|
| 175 |
+
head_dir: Path,
|
| 176 |
+
head_arch: str,
|
| 177 |
+
scopes: tuple[str, ...],
|
| 178 |
+
) -> tuple[list[dict[str, object]], dict[str, dict[str, float]], dict[str, object]] | None:
|
| 179 |
+
posthoc_path = head_dir / "posthoc_rows.csv"
|
| 180 |
+
summary_path = head_dir / "summary.json"
|
| 181 |
+
if not posthoc_path.exists() or not summary_path.exists():
|
| 182 |
+
return None
|
| 183 |
+
rows = [dict(row) for row in read_csv(posthoc_path)]
|
| 184 |
+
if not rows:
|
| 185 |
+
return None
|
| 186 |
+
try:
|
| 187 |
+
summary = json.loads(summary_path.read_text(encoding="utf-8"))
|
| 188 |
+
except json.JSONDecodeError:
|
| 189 |
+
return None
|
| 190 |
+
if str(summary.get("head_arch")) != str(head_arch):
|
| 191 |
+
return None
|
| 192 |
+
raw_pr_auc = summary.get("raw_pr_auc")
|
| 193 |
+
if not isinstance(raw_pr_auc, dict):
|
| 194 |
+
return None
|
| 195 |
+
try:
|
| 196 |
+
parsed_pr_auc = {
|
| 197 |
+
split: {scope: float(raw_pr_auc[split][scope]) for scope in scopes}
|
| 198 |
+
for split in ("val", "test")
|
| 199 |
+
}
|
| 200 |
+
except Exception:
|
| 201 |
+
return None
|
| 202 |
+
return rows, parsed_pr_auc, summary
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def finite_json(value: Any) -> Any:
|
| 206 |
+
if isinstance(value, float):
|
| 207 |
+
return value if math.isfinite(value) else None
|
| 208 |
+
if isinstance(value, dict):
|
| 209 |
+
return {key: finite_json(val) for key, val in value.items()}
|
| 210 |
+
if isinstance(value, list):
|
| 211 |
+
return [finite_json(val) for val in value]
|
| 212 |
+
return value
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
def main() -> None:
|
| 216 |
+
args = parse_args()
|
| 217 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 218 |
+
base.set_seed(int(args.seed))
|
| 219 |
+
device = base.choose_device(args.device)
|
| 220 |
+
|
| 221 |
+
top_fracs = sorted({float(v) for v in args.fire_prone_top_fracs})
|
| 222 |
+
scope_order = ("global",) + tuple(scope_name(frac) for frac in top_fracs)
|
| 223 |
+
base.SCOPE_ORDER = scope_order
|
| 224 |
+
|
| 225 |
+
split_rows = {
|
| 226 |
+
split: base.read_rows(args.feature_root / "splits" / f"{split}.csv")
|
| 227 |
+
for split in ("train", "val", "test")
|
| 228 |
+
}
|
| 229 |
+
if args.source_kind == "reference":
|
| 230 |
+
store = base.build_reference_store(split_rows)
|
| 231 |
+
elif args.source_kind == "attached":
|
| 232 |
+
store = base.build_attached_store(args, split_rows)
|
| 233 |
+
elif args.source_kind == "spatial":
|
| 234 |
+
store = base.build_spatial_store(args, split_rows)
|
| 235 |
+
else:
|
| 236 |
+
store = base.build_alphaearth_store(args, split_rows)
|
| 237 |
+
|
| 238 |
+
loaders = base.make_loaders(split_rows, store, int(args.batch_size), device, int(args.seed))
|
| 239 |
+
first = next(iter(loaders["train"]))
|
| 240 |
+
in_ch = int(first["x"].shape[1])
|
| 241 |
+
prior_prob = base.total_positive_rate(split_rows["train"])
|
| 242 |
+
scope_masks, scope_meta = build_scope_masks(split_rows, store, top_fracs)
|
| 243 |
+
|
| 244 |
+
head_metrics: list[dict[str, object]] = []
|
| 245 |
+
head_artifacts: dict[str, str] = {}
|
| 246 |
+
for head_index, head_arch in enumerate(args.heads):
|
| 247 |
+
head_dir = args.output_dir / head_arch
|
| 248 |
+
head_dir.mkdir(parents=True, exist_ok=True)
|
| 249 |
+
cached = load_head_summary(head_dir, head_arch, scope_order)
|
| 250 |
+
if cached is not None:
|
| 251 |
+
posthoc_rows, raw_pr_auc, _ = cached
|
| 252 |
+
print(f"[scope-sweep] reuse {args.fm_family} seed={args.seed} head={head_arch}", flush=True)
|
| 253 |
+
else:
|
| 254 |
+
print(f"[scope-sweep] training {args.fm_family} seed={args.seed} head={head_arch}", flush=True)
|
| 255 |
+
model, history = base.train_one_head(
|
| 256 |
+
head_arch=head_arch,
|
| 257 |
+
in_ch=in_ch,
|
| 258 |
+
prior_prob=prior_prob,
|
| 259 |
+
loaders=loaders,
|
| 260 |
+
args=args,
|
| 261 |
+
device=device,
|
| 262 |
+
seed_offset=1009 * (head_index + 1),
|
| 263 |
+
)
|
| 264 |
+
posthoc_rows = []
|
| 265 |
+
raw_pr_auc: dict[str, dict[str, float]] = {}
|
| 266 |
+
for split in ("val", "test"):
|
| 267 |
+
probs, targets = base.collect_predictions(model, loaders[split], device)
|
| 268 |
+
sample_times = base.build_sample_times(split_rows[split])
|
| 269 |
+
raw_pr_auc[split] = {
|
| 270 |
+
scope: head_control._masked_average_precision(probs, targets, region_mask=mask)
|
| 271 |
+
for scope, mask in scope_masks.items()
|
| 272 |
+
}
|
| 273 |
+
posthoc_rows.extend(
|
| 274 |
+
build_posthoc_rows_for_scopes(
|
| 275 |
+
probs=probs,
|
| 276 |
+
targets=targets,
|
| 277 |
+
sample_times=sample_times,
|
| 278 |
+
split=split,
|
| 279 |
+
scope_masks=scope_masks,
|
| 280 |
+
args=args,
|
| 281 |
+
)
|
| 282 |
+
)
|
| 283 |
+
base.write_csv(posthoc_rows, head_dir / "posthoc_rows.csv")
|
| 284 |
+
head_summary = {
|
| 285 |
+
"head_arch": head_arch,
|
| 286 |
+
"head_label": head_control.HEAD_LABELS[head_arch],
|
| 287 |
+
"history": history,
|
| 288 |
+
"raw_pr_auc": raw_pr_auc,
|
| 289 |
+
"scope_meta": scope_meta,
|
| 290 |
+
"posthoc_rows_csv": str(head_dir / "posthoc_rows.csv"),
|
| 291 |
+
}
|
| 292 |
+
(head_dir / "summary.json").write_text(json.dumps(finite_json(head_summary), indent=2), encoding="utf-8")
|
| 293 |
+
head_artifacts[head_arch] = str(head_dir / "summary.json")
|
| 294 |
+
base.append_head_metrics(head_metrics, posthoc_rows, raw_pr_auc, head_arch, args)
|
| 295 |
+
|
| 296 |
+
selection_rows = base.summarize_head_scores(head_metrics)
|
| 297 |
+
for row in selection_rows:
|
| 298 |
+
row["model_tag"] = args.model_tag
|
| 299 |
+
row["family"] = args.fm_family
|
| 300 |
+
row["seed"] = int(args.seed)
|
| 301 |
+
|
| 302 |
+
base.write_csv(head_metrics, args.output_dir / "head_metrics.csv")
|
| 303 |
+
base.write_csv(selection_rows, args.output_dir / "selection_rows.csv")
|
| 304 |
+
summary = {
|
| 305 |
+
"experiment": "fixed-feature head-selection regret scope sweep",
|
| 306 |
+
"task": "wildfire_occupancy",
|
| 307 |
+
"model_tag": args.model_tag,
|
| 308 |
+
"fm_family": args.fm_family,
|
| 309 |
+
"source_kind": args.source_kind,
|
| 310 |
+
"seed": int(args.seed),
|
| 311 |
+
"feature_root": str(args.feature_root),
|
| 312 |
+
"daily_rows_csv": str(args.daily_rows_csv) if args.daily_rows_csv else None,
|
| 313 |
+
"support_dir": str(args.support_dir) if args.support_dir else None,
|
| 314 |
+
"alphaearth_cache_root": str(args.alphaearth_cache_root) if args.alphaearth_cache_root else None,
|
| 315 |
+
"device": str(device),
|
| 316 |
+
"heads": list(args.heads),
|
| 317 |
+
"scope_order": list(scope_order),
|
| 318 |
+
"scope_meta": scope_meta,
|
| 319 |
+
"input_channels": int(in_ch),
|
| 320 |
+
"prior_prob": float(prior_prob),
|
| 321 |
+
"metrics": base.METRICS,
|
| 322 |
+
"head_metrics": head_metrics,
|
| 323 |
+
"selection_rows": selection_rows,
|
| 324 |
+
"head_artifacts": head_artifacts,
|
| 325 |
+
"artifacts": {
|
| 326 |
+
"head_metrics_csv": str(args.output_dir / "head_metrics.csv"),
|
| 327 |
+
"selection_rows_csv": str(args.output_dir / "selection_rows.csv"),
|
| 328 |
+
},
|
| 329 |
+
}
|
| 330 |
+
(args.output_dir / "summary.json").write_text(json.dumps(finite_json(summary), indent=2), encoding="utf-8")
|
| 331 |
+
print(json.dumps(finite_json(summary), indent=2), flush=True)
|
| 332 |
+
|
| 333 |
+
|
| 334 |
+
if __name__ == "__main__":
|
| 335 |
+
main()
|
experiments/raw_reference/task_scripts/run_all_backbone_selection_regret_20260504.py
ADDED
|
@@ -0,0 +1,656 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Run one fixed-feature head-selection regret job for one backbone and seed."""
|
| 3 |
+
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
import argparse
|
| 7 |
+
import csv
|
| 8 |
+
import json
|
| 9 |
+
import math
|
| 10 |
+
import random
|
| 11 |
+
import sys
|
| 12 |
+
from pathlib import Path
|
| 13 |
+
from typing import Any
|
| 14 |
+
|
| 15 |
+
import numpy as np
|
| 16 |
+
import torch
|
| 17 |
+
import torch.nn as nn
|
| 18 |
+
from torch.utils.data import DataLoader, Dataset
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
import os
|
| 22 |
+
|
| 23 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 24 |
+
if _p and _p not in sys.path:
|
| 25 |
+
sys.path.insert(0, _p)
|
| 26 |
+
|
| 27 |
+
import run_alphaearth_occupancy_benchmark as alpha_runner # noqa: E402
|
| 28 |
+
import run_attached_daily_occupancy_head_control as head_control # noqa: E402
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
HEADS = ("constant", "linear", "pixel_mlp", "shallow", "shallow_wide")
|
| 32 |
+
METRICS = {
|
| 33 |
+
"exact": "strict_f1",
|
| 34 |
+
"tolerated": "ts_f1",
|
| 35 |
+
"union": "comprehensive_union_f1",
|
| 36 |
+
}
|
| 37 |
+
SCOPE_ORDER = ("global", "fire_prone")
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def parse_args() -> argparse.Namespace:
|
| 41 |
+
parser = argparse.ArgumentParser(description="All-backbone fixed-feature head-selection regret.")
|
| 42 |
+
parser.add_argument("--source-kind", choices=("reference", "attached", "spatial", "alphaearth"), required=True)
|
| 43 |
+
parser.add_argument("--feature-root", type=Path, required=True)
|
| 44 |
+
parser.add_argument("--daily-rows-csv", type=Path)
|
| 45 |
+
parser.add_argument("--support-dir", type=Path)
|
| 46 |
+
parser.add_argument("--alphaearth-cache-root", type=Path)
|
| 47 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 48 |
+
parser.add_argument("--fm-family", type=str, required=True)
|
| 49 |
+
parser.add_argument("--model-tag", type=str, required=True)
|
| 50 |
+
parser.add_argument("--seed", type=int, required=True)
|
| 51 |
+
parser.add_argument("--heads", nargs="+", choices=HEADS, default=list(HEADS))
|
| 52 |
+
parser.add_argument("--batch-size", type=int, default=4)
|
| 53 |
+
parser.add_argument("--epochs", type=int, default=4)
|
| 54 |
+
parser.add_argument("--learning-rate", type=float, default=8e-4)
|
| 55 |
+
parser.add_argument("--weight-decay", type=float, default=1e-5)
|
| 56 |
+
parser.add_argument("--pos-weight-cap", type=float, default=150.0)
|
| 57 |
+
parser.add_argument("--device", choices=("cpu", "cuda", "auto"), default="auto")
|
| 58 |
+
parser.add_argument(
|
| 59 |
+
"--metric-thresholds",
|
| 60 |
+
nargs="+",
|
| 61 |
+
type=float,
|
| 62 |
+
default=[
|
| 63 |
+
1e-5,
|
| 64 |
+
2e-5,
|
| 65 |
+
5e-5,
|
| 66 |
+
1e-4,
|
| 67 |
+
2e-4,
|
| 68 |
+
5e-4,
|
| 69 |
+
1e-3,
|
| 70 |
+
2e-3,
|
| 71 |
+
5e-3,
|
| 72 |
+
1e-2,
|
| 73 |
+
2e-2,
|
| 74 |
+
5e-2,
|
| 75 |
+
8e-2,
|
| 76 |
+
1e-1,
|
| 77 |
+
1.5e-1,
|
| 78 |
+
2e-1,
|
| 79 |
+
3e-1,
|
| 80 |
+
5e-1,
|
| 81 |
+
],
|
| 82 |
+
)
|
| 83 |
+
parser.add_argument(
|
| 84 |
+
"--variants",
|
| 85 |
+
nargs="+",
|
| 86 |
+
default=["identity", "erode_r1", "close_r1"],
|
| 87 |
+
)
|
| 88 |
+
parser.add_argument("--fire-prone-top-frac", type=float, default=0.20)
|
| 89 |
+
parser.add_argument("--temporal-steps", type=int, default=3)
|
| 90 |
+
parser.add_argument("--spatial-radius", type=int, default=8)
|
| 91 |
+
parser.add_argument("--buffer-radius", type=int, default=8)
|
| 92 |
+
parser.add_argument("--boundary-radius", type=int, default=8)
|
| 93 |
+
parser.add_argument("--coarse-factor", type=int, default=8)
|
| 94 |
+
parser.add_argument("--time-step-hours", type=int, default=6)
|
| 95 |
+
return parser.parse_args()
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def read_rows(path: Path) -> list[dict[str, str]]:
|
| 99 |
+
with path.open("r", encoding="utf-8", newline="") as fh:
|
| 100 |
+
return list(csv.DictReader(fh))
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def choose_device(value: str) -> torch.device:
|
| 104 |
+
if value == "auto":
|
| 105 |
+
return torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 106 |
+
device = torch.device(value)
|
| 107 |
+
if device.type == "cuda" and not torch.cuda.is_available():
|
| 108 |
+
raise RuntimeError("CUDA requested but not available.")
|
| 109 |
+
return device
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
def set_seed(seed: int) -> None:
|
| 113 |
+
random.seed(seed)
|
| 114 |
+
np.random.seed(seed)
|
| 115 |
+
torch.manual_seed(seed)
|
| 116 |
+
torch.cuda.manual_seed_all(seed)
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def total_positive_rate(rows: list[dict[str, str]]) -> float:
|
| 120 |
+
pos = float(sum(int(row["pos_cells"]) for row in rows))
|
| 121 |
+
arr = np.load(rows[0]["feature_path"], allow_pickle=True)
|
| 122 |
+
try:
|
| 123 |
+
total = float(len(rows) * np.squeeze(arr["y_occ"]).size)
|
| 124 |
+
finally:
|
| 125 |
+
arr.close()
|
| 126 |
+
return float(pos / total) if total > 0 else 0.0
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
class Normalizer:
|
| 130 |
+
def __init__(self, mean: np.ndarray, std: np.ndarray) -> None:
|
| 131 |
+
self.mean = mean.astype(np.float32)
|
| 132 |
+
self.std = np.maximum(std.astype(np.float32), 1e-6)
|
| 133 |
+
|
| 134 |
+
def apply(self, x: np.ndarray) -> np.ndarray:
|
| 135 |
+
return (x.astype(np.float32) - self.mean[:, None, None]) / self.std[:, None, None]
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
def compute_map_normalizer(rows: list[dict[str, str]], map_path_fn: Any) -> Normalizer:
|
| 139 |
+
sum_c: np.ndarray | None = None
|
| 140 |
+
sumsq_c: np.ndarray | None = None
|
| 141 |
+
count = 0
|
| 142 |
+
for row in rows:
|
| 143 |
+
arr = np.load(map_path_fn(row), allow_pickle=True)
|
| 144 |
+
try:
|
| 145 |
+
x = np.nan_to_num(arr["features"].astype(np.float32), nan=0.0, posinf=0.0, neginf=0.0)
|
| 146 |
+
finally:
|
| 147 |
+
arr.close()
|
| 148 |
+
flat = x.reshape(x.shape[0], -1)
|
| 149 |
+
if sum_c is None:
|
| 150 |
+
sum_c = np.zeros(x.shape[0], dtype=np.float64)
|
| 151 |
+
sumsq_c = np.zeros(x.shape[0], dtype=np.float64)
|
| 152 |
+
sum_c += flat.sum(axis=1)
|
| 153 |
+
sumsq_c += np.square(flat, dtype=np.float64).sum(axis=1)
|
| 154 |
+
count += flat.shape[1]
|
| 155 |
+
if sum_c is None or sumsq_c is None or count == 0:
|
| 156 |
+
raise RuntimeError("Cannot compute feature normalizer.")
|
| 157 |
+
mean = sum_c / float(count)
|
| 158 |
+
var = np.maximum(sumsq_c / float(count) - mean * mean, 1e-12)
|
| 159 |
+
return Normalizer(mean=mean.astype(np.float32), std=np.sqrt(var).astype(np.float32))
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def load_support_manifest(path: Path) -> dict[str, dict[str, str]]:
|
| 163 |
+
rows = read_rows(path)
|
| 164 |
+
support: dict[str, dict[str, str]] = {}
|
| 165 |
+
for row in rows:
|
| 166 |
+
support_path = Path(row["support_path"])
|
| 167 |
+
if row.get("status") in {"generated", "existing"} and support_path.exists():
|
| 168 |
+
support[str(row["sample_id"])] = row
|
| 169 |
+
return support
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
class ReferenceFeatureStore:
|
| 173 |
+
def __init__(self, rows: list[dict[str, str]], normalizer: Normalizer) -> None:
|
| 174 |
+
self.rows_by_id = {str(row["sample_id"]): row for row in rows}
|
| 175 |
+
self.normalizer = normalizer
|
| 176 |
+
|
| 177 |
+
def get(self, sample_id: str) -> dict[str, np.ndarray | str]:
|
| 178 |
+
row = self.rows_by_id[str(sample_id)]
|
| 179 |
+
arr = np.load(row["feature_path"], allow_pickle=True)
|
| 180 |
+
try:
|
| 181 |
+
x = np.nan_to_num(arr["features"].astype(np.float32), nan=0.0, posinf=0.0, neginf=0.0)
|
| 182 |
+
y = np.nan_to_num(arr["y_occ"].astype(np.float32), nan=0.0, posinf=0.0, neginf=0.0)
|
| 183 |
+
finally:
|
| 184 |
+
arr.close()
|
| 185 |
+
return {"x": self.normalizer.apply(x), "y_occ": y, "target_timestamp": row["target_timestamp"]}
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
class SpatialSupportStore:
|
| 189 |
+
def __init__(
|
| 190 |
+
self,
|
| 191 |
+
rows: list[dict[str, str]],
|
| 192 |
+
support: dict[str, dict[str, str]],
|
| 193 |
+
normalizer: Normalizer,
|
| 194 |
+
) -> None:
|
| 195 |
+
self.rows_by_id = {str(row["sample_id"]): row for row in rows}
|
| 196 |
+
self.support = support
|
| 197 |
+
self.normalizer = normalizer
|
| 198 |
+
|
| 199 |
+
def get(self, sample_id: str) -> dict[str, np.ndarray | str]:
|
| 200 |
+
sid = str(sample_id)
|
| 201 |
+
row = self.rows_by_id[sid]
|
| 202 |
+
sarr = np.load(self.support[sid]["support_path"], allow_pickle=True)
|
| 203 |
+
farr = np.load(row["feature_path"], allow_pickle=True)
|
| 204 |
+
try:
|
| 205 |
+
x = np.nan_to_num(sarr["features"].astype(np.float32), nan=0.0, posinf=0.0, neginf=0.0)
|
| 206 |
+
y = np.nan_to_num(farr["y_occ"].astype(np.float32), nan=0.0, posinf=0.0, neginf=0.0)
|
| 207 |
+
finally:
|
| 208 |
+
sarr.close()
|
| 209 |
+
farr.close()
|
| 210 |
+
return {"x": self.normalizer.apply(x), "y_occ": y, "target_timestamp": row["target_timestamp"]}
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
class FullMapDataset(Dataset):
|
| 214 |
+
def __init__(self, rows: list[dict[str, str]], store: Any) -> None:
|
| 215 |
+
self.rows = rows
|
| 216 |
+
self.store = store
|
| 217 |
+
|
| 218 |
+
def __len__(self) -> int:
|
| 219 |
+
return len(self.rows)
|
| 220 |
+
|
| 221 |
+
def __getitem__(self, idx: int) -> dict[str, Any]:
|
| 222 |
+
row = self.rows[idx]
|
| 223 |
+
sample = self.store.get(str(row["sample_id"]))
|
| 224 |
+
return {
|
| 225 |
+
"x": torch.from_numpy(np.asarray(sample["x"], dtype=np.float32)),
|
| 226 |
+
"y": torch.from_numpy(np.asarray(sample["y_occ"], dtype=np.float32)),
|
| 227 |
+
"sample_id": str(row["sample_id"]),
|
| 228 |
+
"target_timestamp": str(sample["target_timestamp"]),
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
def make_loaders(
|
| 233 |
+
split_rows: dict[str, list[dict[str, str]]],
|
| 234 |
+
store: Any,
|
| 235 |
+
batch_size: int,
|
| 236 |
+
device: torch.device,
|
| 237 |
+
seed: int,
|
| 238 |
+
) -> dict[str, DataLoader]:
|
| 239 |
+
loaders: dict[str, DataLoader] = {}
|
| 240 |
+
for split, rows in split_rows.items():
|
| 241 |
+
kwargs: dict[str, Any] = {}
|
| 242 |
+
if split == "train":
|
| 243 |
+
kwargs["generator"] = torch.Generator().manual_seed(int(seed))
|
| 244 |
+
loaders[split] = DataLoader(
|
| 245 |
+
FullMapDataset(rows, store),
|
| 246 |
+
batch_size=int(batch_size),
|
| 247 |
+
shuffle=(split == "train"),
|
| 248 |
+
num_workers=0,
|
| 249 |
+
pin_memory=device.type == "cuda",
|
| 250 |
+
**kwargs,
|
| 251 |
+
)
|
| 252 |
+
return loaders
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
def build_attached_store(args: argparse.Namespace, split_rows: dict[str, list[dict[str, str]]]) -> Any:
|
| 256 |
+
if args.daily_rows_csv is None:
|
| 257 |
+
raise ValueError("--daily-rows-csv is required for attached source.")
|
| 258 |
+
daily_lookup, ordered_times, ordered_features = head_control.build_daily_lookup(args.daily_rows_csv)
|
| 259 |
+
return head_control.FeatureStore(
|
| 260 |
+
split_rows["train"] + split_rows["val"] + split_rows["test"],
|
| 261 |
+
daily_lookup,
|
| 262 |
+
ordered_times,
|
| 263 |
+
ordered_features,
|
| 264 |
+
)
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
def build_alphaearth_store(args: argparse.Namespace, split_rows: dict[str, list[dict[str, str]]]) -> Any:
|
| 268 |
+
if args.alphaearth_cache_root is None:
|
| 269 |
+
raise ValueError("--alphaearth-cache-root is required for AlphaEarth source.")
|
| 270 |
+
grid_cache = alpha_runner.GridCache(args.alphaearth_cache_root)
|
| 271 |
+
return alpha_runner.FeatureStore(split_rows["train"] + split_rows["val"] + split_rows["test"], grid_cache)
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def build_spatial_store(args: argparse.Namespace, split_rows: dict[str, list[dict[str, str]]]) -> SpatialSupportStore:
|
| 275 |
+
if args.support_dir is None:
|
| 276 |
+
raise ValueError("--support-dir is required for spatial source.")
|
| 277 |
+
support = load_support_manifest(args.support_dir / "support_manifest.csv")
|
| 278 |
+
missing = [
|
| 279 |
+
row["sample_id"]
|
| 280 |
+
for rows in split_rows.values()
|
| 281 |
+
for row in rows
|
| 282 |
+
if str(row["sample_id"]) not in support
|
| 283 |
+
]
|
| 284 |
+
if missing:
|
| 285 |
+
raise RuntimeError(f"Missing spatial support maps for {len(missing)} samples; first={missing[:5]}")
|
| 286 |
+
normalizer = compute_map_normalizer(split_rows["train"], lambda row: support[str(row["sample_id"])]["support_path"])
|
| 287 |
+
return SpatialSupportStore(split_rows["train"] + split_rows["val"] + split_rows["test"], support, normalizer)
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
def build_reference_store(split_rows: dict[str, list[dict[str, str]]]) -> ReferenceFeatureStore:
|
| 291 |
+
normalizer = compute_map_normalizer(split_rows["train"], lambda row: row["feature_path"])
|
| 292 |
+
return ReferenceFeatureStore(split_rows["train"] + split_rows["val"] + split_rows["test"], normalizer)
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
def build_head(head_arch: str, in_ch: int, prior_prob: float) -> nn.Module:
|
| 296 |
+
if head_arch == "constant":
|
| 297 |
+
return head_control.ConstantHead(prior_prob=prior_prob)
|
| 298 |
+
if head_arch == "linear":
|
| 299 |
+
return head_control.LinearHead(in_ch=in_ch, prior_prob=prior_prob)
|
| 300 |
+
if head_arch == "pixel_mlp":
|
| 301 |
+
return head_control.PixelMLPHead(in_ch=in_ch, hidden=16, dropout=0.05, prior_prob=prior_prob)
|
| 302 |
+
if head_arch == "shallow_wide":
|
| 303 |
+
return head_control.WildfireHead(
|
| 304 |
+
in_ch=in_ch,
|
| 305 |
+
hidden=64,
|
| 306 |
+
dropout=0.10,
|
| 307 |
+
norm_type="group",
|
| 308 |
+
norm_groups=8,
|
| 309 |
+
prior_prob=prior_prob,
|
| 310 |
+
)
|
| 311 |
+
return head_control.WildfireHead(
|
| 312 |
+
in_ch=in_ch,
|
| 313 |
+
hidden=32,
|
| 314 |
+
dropout=0.05,
|
| 315 |
+
norm_type="group",
|
| 316 |
+
norm_groups=8,
|
| 317 |
+
prior_prob=prior_prob,
|
| 318 |
+
)
|
| 319 |
+
|
| 320 |
+
|
| 321 |
+
@torch.no_grad()
|
| 322 |
+
def collect_predictions(model: nn.Module, loader: DataLoader, device: torch.device) -> tuple[np.ndarray, np.ndarray]:
|
| 323 |
+
model.eval()
|
| 324 |
+
probs: list[np.ndarray] = []
|
| 325 |
+
targets: list[np.ndarray] = []
|
| 326 |
+
for batch in loader:
|
| 327 |
+
x = batch["x"].to(device, non_blocking=True)
|
| 328 |
+
y = batch["y"].to(device, non_blocking=True)
|
| 329 |
+
logits = model(x)
|
| 330 |
+
probs.append(np.nan_to_num(torch.sigmoid(logits).detach().cpu().numpy()[:, 0], nan=0.0, posinf=1.0, neginf=0.0))
|
| 331 |
+
targets.append(np.nan_to_num(y.detach().cpu().numpy()[:, 0], nan=0.0, posinf=0.0, neginf=0.0))
|
| 332 |
+
return np.concatenate(probs, axis=0), np.concatenate(targets, axis=0)
|
| 333 |
+
|
| 334 |
+
|
| 335 |
+
def train_one_head(
|
| 336 |
+
head_arch: str,
|
| 337 |
+
in_ch: int,
|
| 338 |
+
prior_prob: float,
|
| 339 |
+
loaders: dict[str, DataLoader],
|
| 340 |
+
args: argparse.Namespace,
|
| 341 |
+
device: torch.device,
|
| 342 |
+
seed_offset: int,
|
| 343 |
+
) -> tuple[nn.Module, list[dict[str, float]]]:
|
| 344 |
+
set_seed(int(args.seed) + int(seed_offset))
|
| 345 |
+
model = build_head(head_arch, in_ch=in_ch, prior_prob=prior_prob).to(device)
|
| 346 |
+
optimizer = torch.optim.AdamW(model.parameters(), lr=float(args.learning_rate), weight_decay=float(args.weight_decay))
|
| 347 |
+
raw_weight = (1.0 - float(prior_prob)) / max(float(prior_prob), 1e-9)
|
| 348 |
+
pos_weight = float(min(float(args.pos_weight_cap), raw_weight))
|
| 349 |
+
criterion = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([pos_weight], dtype=torch.float32, device=device))
|
| 350 |
+
history: list[dict[str, float]] = []
|
| 351 |
+
for epoch in range(1, int(args.epochs) + 1):
|
| 352 |
+
model.train()
|
| 353 |
+
losses: list[float] = []
|
| 354 |
+
for batch in loaders["train"]:
|
| 355 |
+
x = batch["x"].to(device, non_blocking=True)
|
| 356 |
+
y = batch["y"].to(device, non_blocking=True)
|
| 357 |
+
optimizer.zero_grad(set_to_none=True)
|
| 358 |
+
logits = model(x)
|
| 359 |
+
loss = criterion(logits, y)
|
| 360 |
+
if not torch.isfinite(loss):
|
| 361 |
+
raise RuntimeError(f"Non-finite loss for head={head_arch}")
|
| 362 |
+
loss.backward()
|
| 363 |
+
optimizer.step()
|
| 364 |
+
losses.append(float(loss.item()))
|
| 365 |
+
history.append({"epoch": epoch, "train_bce": float(np.mean(losses)), "pos_weight": pos_weight})
|
| 366 |
+
return model, history
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
def build_sample_times(rows: list[dict[str, str]]) -> np.ndarray:
|
| 370 |
+
return np.array([row["target_timestamp"] for row in rows], dtype="datetime64[h]")
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def select_val_posthoc(
|
| 374 |
+
rows: list[dict[str, object]],
|
| 375 |
+
scope: str,
|
| 376 |
+
metric: str,
|
| 377 |
+
) -> dict[str, object]:
|
| 378 |
+
prefix = metric.rsplit("_", 1)[0]
|
| 379 |
+
precision_key = f"{prefix}_precision"
|
| 380 |
+
recall_key = f"{prefix}_recall"
|
| 381 |
+
selected = [row for row in rows if row["split"] == "val" and row["scope"] == scope]
|
| 382 |
+
if not selected:
|
| 383 |
+
raise RuntimeError(f"No validation rows for scope={scope}")
|
| 384 |
+
return max(
|
| 385 |
+
selected,
|
| 386 |
+
key=lambda row: (
|
| 387 |
+
float(row.get(metric, 0.0)),
|
| 388 |
+
float(row.get(precision_key, 0.0)),
|
| 389 |
+
float(row.get(recall_key, 0.0)),
|
| 390 |
+
-abs(float(row["threshold"]) - 0.5),
|
| 391 |
+
),
|
| 392 |
+
)
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
def matching_test_row(rows: list[dict[str, object]], scope: str, selected: dict[str, object]) -> dict[str, object]:
|
| 396 |
+
threshold = float(selected["threshold"])
|
| 397 |
+
variant = str(selected["variant"])
|
| 398 |
+
for row in rows:
|
| 399 |
+
if (
|
| 400 |
+
row["split"] == "test"
|
| 401 |
+
and row["scope"] == scope
|
| 402 |
+
and str(row["variant"]) == variant
|
| 403 |
+
and abs(float(row["threshold"]) - threshold) < 1e-12
|
| 404 |
+
):
|
| 405 |
+
return row
|
| 406 |
+
raise RuntimeError(f"No matching test row for scope={scope}, threshold={threshold}, variant={variant}")
|
| 407 |
+
|
| 408 |
+
|
| 409 |
+
def summarize_head_scores(
|
| 410 |
+
head_metrics: list[dict[str, object]],
|
| 411 |
+
) -> list[dict[str, object]]:
|
| 412 |
+
selection_rows: list[dict[str, object]] = []
|
| 413 |
+
for scope in SCOPE_ORDER:
|
| 414 |
+
candidates = [row for row in head_metrics if row["scope"] == scope]
|
| 415 |
+
if not candidates:
|
| 416 |
+
continue
|
| 417 |
+
ranking_selected = max(
|
| 418 |
+
candidates,
|
| 419 |
+
key=lambda row: (
|
| 420 |
+
float(row["val_pr_auc"]),
|
| 421 |
+
float(row["val_union_f1"]),
|
| 422 |
+
float(row["val_tolerated_f1"]),
|
| 423 |
+
float(row["val_exact_f1"]),
|
| 424 |
+
),
|
| 425 |
+
)
|
| 426 |
+
out: dict[str, object] = {
|
| 427 |
+
"scope": scope,
|
| 428 |
+
"ranking_selected_head": ranking_selected["head_label"],
|
| 429 |
+
"ranking_selected_head_arch": ranking_selected["head_arch"],
|
| 430 |
+
"ranking_selected_val_pr_auc": float(ranking_selected["val_pr_auc"]),
|
| 431 |
+
"ranking_selected_test_pr_auc": float(ranking_selected["test_pr_auc"]),
|
| 432 |
+
}
|
| 433 |
+
for short, column in (("exact", "exact_f1"), ("tolerated", "tolerated_f1"), ("union", "union_f1")):
|
| 434 |
+
val_column = f"val_{column}"
|
| 435 |
+
test_column = f"test_{column}"
|
| 436 |
+
decision_selected = max(
|
| 437 |
+
candidates,
|
| 438 |
+
key=lambda row: (
|
| 439 |
+
float(row[val_column]),
|
| 440 |
+
float(row["val_pr_auc"]),
|
| 441 |
+
str(row["head_arch"]),
|
| 442 |
+
),
|
| 443 |
+
)
|
| 444 |
+
val_gap = float(decision_selected[val_column]) - float(ranking_selected[val_column])
|
| 445 |
+
test_gap = float(decision_selected[test_column]) - float(ranking_selected[test_column])
|
| 446 |
+
out[f"{short}_val_ranking_score"] = float(ranking_selected[val_column])
|
| 447 |
+
out[f"{short}_val_decision_score"] = float(decision_selected[val_column])
|
| 448 |
+
out[f"{short}_val_gap"] = float(max(0.0, val_gap))
|
| 449 |
+
out[f"{short}_ranking_score"] = float(ranking_selected[test_column])
|
| 450 |
+
out[f"{short}_decision_score"] = float(decision_selected[test_column])
|
| 451 |
+
out[f"{short}_test_gap"] = float(test_gap)
|
| 452 |
+
out[f"{short}_regret"] = float(max(0.0, test_gap))
|
| 453 |
+
out[f"{short}_decision_head"] = decision_selected["head_label"]
|
| 454 |
+
out[f"{short}_decision_head_arch"] = decision_selected["head_arch"]
|
| 455 |
+
selection_rows.append(out)
|
| 456 |
+
return selection_rows
|
| 457 |
+
|
| 458 |
+
|
| 459 |
+
def write_csv(rows: list[dict[str, object]], path: Path) -> None:
|
| 460 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 461 |
+
fieldnames = sorted({key for row in rows for key in row})
|
| 462 |
+
with path.open("w", newline="", encoding="utf-8") as fh:
|
| 463 |
+
writer = csv.DictWriter(fh, fieldnames=fieldnames)
|
| 464 |
+
writer.writeheader()
|
| 465 |
+
writer.writerows(rows)
|
| 466 |
+
|
| 467 |
+
|
| 468 |
+
def load_head_summary(head_dir: Path, head_arch: str) -> tuple[list[dict[str, object]], dict[str, dict[str, float]], dict[str, object]] | None:
|
| 469 |
+
posthoc_path = head_dir / "posthoc_rows.csv"
|
| 470 |
+
summary_path = head_dir / "summary.json"
|
| 471 |
+
if not posthoc_path.exists() or not summary_path.exists():
|
| 472 |
+
return None
|
| 473 |
+
rows = [dict(row) for row in read_rows(posthoc_path)]
|
| 474 |
+
if not rows:
|
| 475 |
+
return None
|
| 476 |
+
try:
|
| 477 |
+
summary = json.loads(summary_path.read_text(encoding="utf-8"))
|
| 478 |
+
except json.JSONDecodeError:
|
| 479 |
+
return None
|
| 480 |
+
if str(summary.get("head_arch")) != str(head_arch):
|
| 481 |
+
return None
|
| 482 |
+
raw_pr_auc = summary.get("raw_pr_auc")
|
| 483 |
+
if not isinstance(raw_pr_auc, dict):
|
| 484 |
+
return None
|
| 485 |
+
try:
|
| 486 |
+
parsed_pr_auc = {
|
| 487 |
+
split: {
|
| 488 |
+
scope: float(raw_pr_auc[split][scope])
|
| 489 |
+
for scope in SCOPE_ORDER
|
| 490 |
+
}
|
| 491 |
+
for split in ("val", "test")
|
| 492 |
+
}
|
| 493 |
+
except Exception:
|
| 494 |
+
return None
|
| 495 |
+
return rows, parsed_pr_auc, summary
|
| 496 |
+
|
| 497 |
+
|
| 498 |
+
def append_head_metrics(
|
| 499 |
+
head_metrics: list[dict[str, object]],
|
| 500 |
+
posthoc_rows: list[dict[str, object]],
|
| 501 |
+
raw_pr_auc: dict[str, dict[str, float]],
|
| 502 |
+
head_arch: str,
|
| 503 |
+
args: argparse.Namespace,
|
| 504 |
+
) -> None:
|
| 505 |
+
for scope in SCOPE_ORDER:
|
| 506 |
+
metric_scores: dict[str, float] = {}
|
| 507 |
+
selected_thresholds: dict[str, float] = {}
|
| 508 |
+
selected_variants: dict[str, str] = {}
|
| 509 |
+
for short, metric in METRICS.items():
|
| 510 |
+
selected = select_val_posthoc(posthoc_rows, scope, metric)
|
| 511 |
+
test_row = matching_test_row(posthoc_rows, scope, selected)
|
| 512 |
+
metric_scores[f"val_{short}_f1"] = float(selected[metric])
|
| 513 |
+
metric_scores[f"test_{short}_f1"] = float(test_row[metric])
|
| 514 |
+
selected_thresholds[short] = float(selected["threshold"])
|
| 515 |
+
selected_variants[short] = str(selected["variant"])
|
| 516 |
+
head_metrics.append(
|
| 517 |
+
{
|
| 518 |
+
"model_tag": args.model_tag,
|
| 519 |
+
"family": args.fm_family,
|
| 520 |
+
"seed": int(args.seed),
|
| 521 |
+
"scope": scope,
|
| 522 |
+
"head_arch": head_arch,
|
| 523 |
+
"head_label": head_control.HEAD_LABELS[head_arch],
|
| 524 |
+
"val_pr_auc": float(raw_pr_auc["val"][scope]),
|
| 525 |
+
"test_pr_auc": float(raw_pr_auc["test"][scope]),
|
| 526 |
+
**metric_scores,
|
| 527 |
+
"selected_thresholds": selected_thresholds,
|
| 528 |
+
"selected_variants": selected_variants,
|
| 529 |
+
}
|
| 530 |
+
)
|
| 531 |
+
|
| 532 |
+
|
| 533 |
+
def main() -> None:
|
| 534 |
+
args = parse_args()
|
| 535 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 536 |
+
set_seed(int(args.seed))
|
| 537 |
+
device = choose_device(args.device)
|
| 538 |
+
|
| 539 |
+
split_rows = {
|
| 540 |
+
split: read_rows(args.feature_root / "splits" / f"{split}.csv")
|
| 541 |
+
for split in ("train", "val", "test")
|
| 542 |
+
}
|
| 543 |
+
if args.source_kind == "reference":
|
| 544 |
+
store = build_reference_store(split_rows)
|
| 545 |
+
elif args.source_kind == "attached":
|
| 546 |
+
store = build_attached_store(args, split_rows)
|
| 547 |
+
elif args.source_kind == "spatial":
|
| 548 |
+
store = build_spatial_store(args, split_rows)
|
| 549 |
+
else:
|
| 550 |
+
store = build_alphaearth_store(args, split_rows)
|
| 551 |
+
|
| 552 |
+
loaders = make_loaders(split_rows, store, int(args.batch_size), device, int(args.seed))
|
| 553 |
+
first = next(iter(loaders["train"]))
|
| 554 |
+
in_ch = int(first["x"].shape[1])
|
| 555 |
+
prior_prob = total_positive_rate(split_rows["train"])
|
| 556 |
+
fire_prone_mask, fire_prone_meta = head_control.build_fire_prone_mask(
|
| 557 |
+
split_rows["train"],
|
| 558 |
+
store,
|
| 559 |
+
float(args.fire_prone_top_frac),
|
| 560 |
+
)
|
| 561 |
+
|
| 562 |
+
head_metrics: list[dict[str, object]] = []
|
| 563 |
+
head_artifacts: dict[str, str] = {}
|
| 564 |
+
for head_index, head_arch in enumerate(args.heads):
|
| 565 |
+
head_dir = args.output_dir / head_arch
|
| 566 |
+
head_dir.mkdir(parents=True, exist_ok=True)
|
| 567 |
+
cached = load_head_summary(head_dir, head_arch)
|
| 568 |
+
if cached is not None:
|
| 569 |
+
posthoc_rows, raw_pr_auc, _ = cached
|
| 570 |
+
print(f"[selection-regret] reuse {args.fm_family} seed={args.seed} head={head_arch}", flush=True)
|
| 571 |
+
else:
|
| 572 |
+
print(f"[selection-regret] training {args.fm_family} seed={args.seed} head={head_arch}", flush=True)
|
| 573 |
+
model, history = train_one_head(
|
| 574 |
+
head_arch=head_arch,
|
| 575 |
+
in_ch=in_ch,
|
| 576 |
+
prior_prob=prior_prob,
|
| 577 |
+
loaders=loaders,
|
| 578 |
+
args=args,
|
| 579 |
+
device=device,
|
| 580 |
+
seed_offset=1009 * (head_index + 1),
|
| 581 |
+
)
|
| 582 |
+
posthoc_rows = []
|
| 583 |
+
raw_pr_auc = {}
|
| 584 |
+
for split in ("val", "test"):
|
| 585 |
+
probs, targets = collect_predictions(model, loaders[split], device)
|
| 586 |
+
sample_times = build_sample_times(split_rows[split])
|
| 587 |
+
raw_pr_auc[split] = {
|
| 588 |
+
"global": head_control._masked_average_precision(probs, targets, region_mask=None),
|
| 589 |
+
"fire_prone": head_control._masked_average_precision(probs, targets, region_mask=fire_prone_mask),
|
| 590 |
+
}
|
| 591 |
+
posthoc_rows.extend(
|
| 592 |
+
head_control.build_posthoc_rows(
|
| 593 |
+
probs=probs,
|
| 594 |
+
targets=targets,
|
| 595 |
+
sample_times=sample_times,
|
| 596 |
+
split=split,
|
| 597 |
+
fire_prone_mask=fire_prone_mask,
|
| 598 |
+
args=args,
|
| 599 |
+
)
|
| 600 |
+
)
|
| 601 |
+
|
| 602 |
+
write_csv(posthoc_rows, head_dir / "posthoc_rows.csv")
|
| 603 |
+
head_summary = {
|
| 604 |
+
"head_arch": head_arch,
|
| 605 |
+
"head_label": head_control.HEAD_LABELS[head_arch],
|
| 606 |
+
"history": history,
|
| 607 |
+
"raw_pr_auc": raw_pr_auc,
|
| 608 |
+
"posthoc_rows_csv": str(head_dir / "posthoc_rows.csv"),
|
| 609 |
+
}
|
| 610 |
+
(head_dir / "summary.json").write_text(json.dumps(head_summary, indent=2), encoding="utf-8")
|
| 611 |
+
head_artifacts[head_arch] = str(head_dir / "summary.json")
|
| 612 |
+
append_head_metrics(head_metrics, posthoc_rows, raw_pr_auc, head_arch, args)
|
| 613 |
+
|
| 614 |
+
selection_rows = summarize_head_scores(head_metrics)
|
| 615 |
+
for row in selection_rows:
|
| 616 |
+
row["model_tag"] = args.model_tag
|
| 617 |
+
row["family"] = args.fm_family
|
| 618 |
+
row["seed"] = int(args.seed)
|
| 619 |
+
|
| 620 |
+
write_csv(head_metrics, args.output_dir / "head_metrics.csv")
|
| 621 |
+
write_csv(selection_rows, args.output_dir / "selection_rows.csv")
|
| 622 |
+
summary = {
|
| 623 |
+
"experiment": "all-backbone fixed-feature head-selection regret",
|
| 624 |
+
"task": "wildfire_occupancy",
|
| 625 |
+
"model_tag": args.model_tag,
|
| 626 |
+
"fm_family": args.fm_family,
|
| 627 |
+
"source_kind": args.source_kind,
|
| 628 |
+
"seed": int(args.seed),
|
| 629 |
+
"feature_root": str(args.feature_root),
|
| 630 |
+
"daily_rows_csv": str(args.daily_rows_csv) if args.daily_rows_csv else None,
|
| 631 |
+
"support_dir": str(args.support_dir) if args.support_dir else None,
|
| 632 |
+
"alphaearth_cache_root": str(args.alphaearth_cache_root) if args.alphaearth_cache_root else None,
|
| 633 |
+
"device": str(device),
|
| 634 |
+
"heads": list(args.heads),
|
| 635 |
+
"input_channels": int(in_ch),
|
| 636 |
+
"prior_prob": float(prior_prob),
|
| 637 |
+
"fire_prone_scope": {
|
| 638 |
+
"scope_name": "fire_prone",
|
| 639 |
+
"reported_as": "top 20%",
|
| 640 |
+
**fire_prone_meta,
|
| 641 |
+
},
|
| 642 |
+
"metrics": METRICS,
|
| 643 |
+
"head_metrics": head_metrics,
|
| 644 |
+
"selection_rows": selection_rows,
|
| 645 |
+
"head_artifacts": head_artifacts,
|
| 646 |
+
"artifacts": {
|
| 647 |
+
"head_metrics_csv": str(args.output_dir / "head_metrics.csv"),
|
| 648 |
+
"selection_rows_csv": str(args.output_dir / "selection_rows.csv"),
|
| 649 |
+
},
|
| 650 |
+
}
|
| 651 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 652 |
+
print(json.dumps(summary, indent=2), flush=True)
|
| 653 |
+
|
| 654 |
+
|
| 655 |
+
if __name__ == "__main__":
|
| 656 |
+
main()
|
experiments/raw_reference/task_scripts/run_analog_extended_retrieval_sweep_seeded.py
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import sys
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from typing import Dict, List, Tuple
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
import os
|
| 12 |
+
|
| 13 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 14 |
+
if _p and _p not in sys.path:
|
| 15 |
+
sys.path.insert(0, _p)
|
| 16 |
+
|
| 17 |
+
import numpy as np
|
| 18 |
+
import pandas as pd
|
| 19 |
+
from sklearn.compose import ColumnTransformer
|
| 20 |
+
from sklearn.impute import SimpleImputer
|
| 21 |
+
from sklearn.linear_model import ElasticNet, Ridge
|
| 22 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
| 23 |
+
from sklearn.pipeline import Pipeline
|
| 24 |
+
from sklearn.preprocessing import OneHotEncoder, StandardScaler
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
DROP_COLUMNS = {
|
| 28 |
+
"Event_ID",
|
| 29 |
+
"Incid_Name",
|
| 30 |
+
"incident_name_norm",
|
| 31 |
+
"wfigs_name",
|
| 32 |
+
"Ig_Date",
|
| 33 |
+
"weather_date",
|
| 34 |
+
"BurnBndAc",
|
| 35 |
+
"target_log_burn_acres",
|
| 36 |
+
}
|
| 37 |
+
CATEGORICAL_COLUMNS = ["Incid_Type", "state_abbr", "county_name", "wfigs_match_type"]
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def build_splits(df: pd.DataFrame) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
| 41 |
+
ordered = df.sort_values("Ig_Date").reset_index(drop=True)
|
| 42 |
+
n = len(ordered)
|
| 43 |
+
train_end = max(int(round(n * 0.6)), 1)
|
| 44 |
+
val_end = max(int(round(n * 0.8)), train_end + 1)
|
| 45 |
+
val_end = min(val_end, n - 1) if n >= 3 else n
|
| 46 |
+
train = ordered.iloc[:train_end].copy()
|
| 47 |
+
val = ordered.iloc[train_end:val_end].copy()
|
| 48 |
+
test = ordered.iloc[val_end:].copy()
|
| 49 |
+
if len(val) == 0 and len(test) > 1:
|
| 50 |
+
val = test.iloc[:1].copy()
|
| 51 |
+
test = test.iloc[1:].copy()
|
| 52 |
+
return train, val, test
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def block_columns(df: pd.DataFrame, exclude: set[str]) -> Dict[str, List[str]]:
|
| 56 |
+
numeric = [
|
| 57 |
+
c
|
| 58 |
+
for c in df.columns
|
| 59 |
+
if c not in DROP_COLUMNS
|
| 60 |
+
and c not in CATEGORICAL_COLUMNS
|
| 61 |
+
and c not in exclude
|
| 62 |
+
and pd.api.types.is_numeric_dtype(df[c])
|
| 63 |
+
]
|
| 64 |
+
return {
|
| 65 |
+
"weather": [c for c in numeric if c.startswith("weather_")],
|
| 66 |
+
"geo_fire": [
|
| 67 |
+
c
|
| 68 |
+
for c in numeric
|
| 69 |
+
if c.startswith("firms_")
|
| 70 |
+
or c.startswith("landfire_")
|
| 71 |
+
or c in {"BurnBndLat", "BurnBndLon", "lat", "lon", "wfigs_acres", "wfigs_date_diff_days", "wfigs_dist_km", "is_conus_static"}
|
| 72 |
+
],
|
| 73 |
+
"categorical": [c for c in CATEGORICAL_COLUMNS if c in df.columns and c not in exclude],
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def make_block_matrix(train: pd.DataFrame, val: pd.DataFrame, test: pd.DataFrame, cols: List[str], categorical: bool) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
| 78 |
+
if not cols:
|
| 79 |
+
n_train, n_val, n_test = len(train), len(val), len(test)
|
| 80 |
+
return np.zeros((n_train, 0), dtype=np.float32), np.zeros((n_val, 0), dtype=np.float32), np.zeros((n_test, 0), dtype=np.float32)
|
| 81 |
+
if categorical:
|
| 82 |
+
transformer = ColumnTransformer(
|
| 83 |
+
[("cat", Pipeline([("impute", SimpleImputer(strategy="most_frequent")), ("onehot", OneHotEncoder(handle_unknown="ignore"))]), cols)],
|
| 84 |
+
remainder="drop",
|
| 85 |
+
)
|
| 86 |
+
else:
|
| 87 |
+
transformer = ColumnTransformer(
|
| 88 |
+
[("num", Pipeline([("impute", SimpleImputer(strategy="median")), ("scale", StandardScaler())]), cols)],
|
| 89 |
+
remainder="drop",
|
| 90 |
+
)
|
| 91 |
+
train_x = transformer.fit_transform(train[cols])
|
| 92 |
+
val_x = transformer.transform(val[cols])
|
| 93 |
+
test_x = transformer.transform(test[cols])
|
| 94 |
+
if hasattr(train_x, "toarray"):
|
| 95 |
+
train_x = train_x.toarray()
|
| 96 |
+
val_x = val_x.toarray()
|
| 97 |
+
test_x = test_x.toarray()
|
| 98 |
+
return train_x.astype(np.float32), val_x.astype(np.float32), test_x.astype(np.float32)
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def graded_relevance(query_target: float, retrieved_targets: np.ndarray) -> np.ndarray:
|
| 102 |
+
delta = np.abs(np.asarray(retrieved_targets, dtype=np.float64) - float(query_target))
|
| 103 |
+
return np.select([delta <= 0.5, delta <= 1.0, delta <= 1.5], [3.0, 2.0, 1.0], default=0.0)
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def dcg(relevance: np.ndarray) -> float:
|
| 107 |
+
rel = np.asarray(relevance, dtype=np.float64)
|
| 108 |
+
discounts = 1.0 / np.log2(np.arange(rel.size, dtype=np.float64) + 2.0)
|
| 109 |
+
return float(np.sum(rel * discounts))
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
def ndcg_at_k(relevance: np.ndarray, ideal_relevance: np.ndarray, k: int) -> float:
|
| 113 |
+
denom = dcg(ideal_relevance[:k])
|
| 114 |
+
return float(dcg(relevance[:k]) / denom) if denom > 0 else 0.0
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 118 |
+
return float(np.sqrt(np.mean((np.asarray(y_true) - np.asarray(y_pred)) ** 2)))
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def spearman_corr(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 122 |
+
value = pd.Series(y_true).corr(pd.Series(y_pred), method="spearman")
|
| 123 |
+
return float(value) if pd.notna(value) else 0.0
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def target_weight_vectors(train_vec: np.ndarray, val_vec: np.ndarray, test_vec: np.ndarray, target: np.ndarray, power: float, floor: float) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
| 127 |
+
if train_vec.shape[1] == 0:
|
| 128 |
+
return train_vec, val_vec, test_vec
|
| 129 |
+
x = np.asarray(train_vec, dtype=np.float64)
|
| 130 |
+
y = np.asarray(target, dtype=np.float64)
|
| 131 |
+
y = y - y.mean()
|
| 132 |
+
x_centered = x - x.mean(axis=0, keepdims=True)
|
| 133 |
+
denom = np.clip(np.sqrt(np.sum(x_centered**2, axis=0)) * np.sqrt(np.sum(y**2)), 1e-12, None)
|
| 134 |
+
corr = np.abs(np.sum(x_centered * y[:, None], axis=0) / denom)
|
| 135 |
+
corr = np.nan_to_num(corr, nan=0.0, posinf=0.0, neginf=0.0)
|
| 136 |
+
if float(corr.max()) > 0:
|
| 137 |
+
corr = corr / float(corr.max())
|
| 138 |
+
weights = (floor + np.power(corr, power)).astype(np.float32)
|
| 139 |
+
return train_vec * weights, val_vec * weights, test_vec * weights
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def score_vectors(query_vec: np.ndarray, library_vec: np.ndarray, query_df: pd.DataFrame, library_df: pd.DataFrame, k: int, mode: str) -> Dict[str, float]:
|
| 143 |
+
k_eff = min(k, library_vec.shape[0])
|
| 144 |
+
lib_norm = library_vec / np.clip(np.linalg.norm(library_vec, axis=1, keepdims=True), 1e-12, None)
|
| 145 |
+
query_norm = query_vec / np.clip(np.linalg.norm(query_vec, axis=1, keepdims=True), 1e-12, None)
|
| 146 |
+
sim_all = cosine_similarity(query_norm, lib_norm)
|
| 147 |
+
knn_idx = np.argsort(-sim_all, axis=1)[:, :k_eff]
|
| 148 |
+
knn_sim = np.take_along_axis(sim_all, knn_idx, axis=1)
|
| 149 |
+
target_lib = library_df["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 150 |
+
preds = []
|
| 151 |
+
ndcg5 = []
|
| 152 |
+
ndcg10 = []
|
| 153 |
+
hit1 = []
|
| 154 |
+
hit5 = []
|
| 155 |
+
hit10 = []
|
| 156 |
+
best_abs = []
|
| 157 |
+
for i in range(query_df.shape[0]):
|
| 158 |
+
idx = knn_idx[i]
|
| 159 |
+
sims = knn_sim[i]
|
| 160 |
+
top_targets = target_lib[idx]
|
| 161 |
+
true = float(query_df.iloc[i]["target_log_burn_acres"])
|
| 162 |
+
relevance = graded_relevance(true, top_targets)
|
| 163 |
+
ideal = np.sort(graded_relevance(true, target_lib))[::-1]
|
| 164 |
+
ndcg5.append(ndcg_at_k(relevance, ideal, 5))
|
| 165 |
+
ndcg10.append(ndcg_at_k(relevance, ideal, 10))
|
| 166 |
+
hit1.append(float(relevance[:1].max() >= 2.0))
|
| 167 |
+
hit5.append(float(relevance[: min(5, k_eff)].max() >= 2.0))
|
| 168 |
+
hit10.append(float(relevance[: min(10, k_eff)].max() >= 2.0))
|
| 169 |
+
best_abs.append(float(np.min(np.abs(top_targets - true))))
|
| 170 |
+
if mode == "weighted":
|
| 171 |
+
weights = np.maximum((sims + 1.0) / 2.0, 1e-6)
|
| 172 |
+
preds.append(float(np.sum(weights * top_targets) / np.sum(weights)))
|
| 173 |
+
else:
|
| 174 |
+
preds.append(float(np.mean(top_targets)))
|
| 175 |
+
pred = np.asarray(preds, dtype=np.float64)
|
| 176 |
+
true_log = query_df["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 177 |
+
return {
|
| 178 |
+
"count": int(len(query_df)),
|
| 179 |
+
"log_mae": float(np.mean(np.abs(true_log - pred))),
|
| 180 |
+
"log_rmse": rmse(true_log, pred),
|
| 181 |
+
"log_spearman": spearman_corr(true_log, pred),
|
| 182 |
+
"ndcg_at_5": float(np.mean(ndcg5)),
|
| 183 |
+
"ndcg_at_10": float(np.mean(ndcg10)),
|
| 184 |
+
"hit_at_1_tol1": float(np.mean(hit1)),
|
| 185 |
+
"hit_at_5_tol1": float(np.mean(hit5)),
|
| 186 |
+
"hit_at_10_tol1": float(np.mean(hit10)),
|
| 187 |
+
"mean_best_abs_log_delta_at_k": float(np.mean(best_abs)),
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
|
| 191 |
+
def append_supervised_scalar(
|
| 192 |
+
train_vec: np.ndarray,
|
| 193 |
+
val_vec: np.ndarray,
|
| 194 |
+
test_vec: np.ndarray,
|
| 195 |
+
train_df: pd.DataFrame,
|
| 196 |
+
model_name: str,
|
| 197 |
+
weight: float,
|
| 198 |
+
seed: int,
|
| 199 |
+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
| 200 |
+
y = train_df["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 201 |
+
model = Ridge(alpha=1.0) if model_name == "ridge" else ElasticNet(alpha=0.01, l1_ratio=0.2, random_state=seed, max_iter=10000)
|
| 202 |
+
model.fit(train_vec, y)
|
| 203 |
+
train_pred = model.predict(train_vec)
|
| 204 |
+
val_pred = model.predict(val_vec)
|
| 205 |
+
test_pred = model.predict(test_vec)
|
| 206 |
+
mean = float(np.mean(train_pred))
|
| 207 |
+
std = float(np.std(train_pred)) or 1.0
|
| 208 |
+
def _append(x: np.ndarray, pred: np.ndarray) -> np.ndarray:
|
| 209 |
+
scalar = ((pred - mean) / std).reshape(-1, 1).astype(np.float32) * float(weight)
|
| 210 |
+
return np.concatenate([x, scalar], axis=1)
|
| 211 |
+
return _append(train_vec, train_pred), _append(val_vec, val_pred), _append(test_vec, test_pred)
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def main() -> None:
|
| 215 |
+
parser = argparse.ArgumentParser()
|
| 216 |
+
parser.add_argument("--event-table", type=Path, required=True)
|
| 217 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 218 |
+
parser.add_argument("--exclude-columns", nargs="*", default=[])
|
| 219 |
+
parser.add_argument("--seed", type=int, default=7)
|
| 220 |
+
args = parser.parse_args()
|
| 221 |
+
|
| 222 |
+
df = pd.read_csv(args.event_table)
|
| 223 |
+
df["Ig_Date"] = pd.to_datetime(df["Ig_Date"])
|
| 224 |
+
train_df, val_df, test_df = build_splits(df)
|
| 225 |
+
exclude = set(args.exclude_columns)
|
| 226 |
+
blocks = block_columns(df, exclude)
|
| 227 |
+
matrices = {
|
| 228 |
+
"weather": make_block_matrix(train_df, val_df, test_df, blocks["weather"], categorical=False),
|
| 229 |
+
"geo_fire": make_block_matrix(train_df, val_df, test_df, blocks["geo_fire"], categorical=False),
|
| 230 |
+
"categorical": make_block_matrix(train_df, val_df, test_df, blocks["categorical"], categorical=True),
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
candidate_rows: List[Dict[str, object]] = []
|
| 234 |
+
best = None
|
| 235 |
+
best_score = None
|
| 236 |
+
best_test = None
|
| 237 |
+
block_weight_grid = [
|
| 238 |
+
{"weather": 1.0, "geo_fire": 1.0, "categorical": 1.0},
|
| 239 |
+
{"weather": 0.5, "geo_fire": 1.5, "categorical": 1.0},
|
| 240 |
+
{"weather": 0.25, "geo_fire": 2.0, "categorical": 1.0},
|
| 241 |
+
{"weather": 1.5, "geo_fire": 1.0, "categorical": 0.5},
|
| 242 |
+
{"weather": 0.0, "geo_fire": 2.0, "categorical": 1.0},
|
| 243 |
+
{"weather": 2.0, "geo_fire": 0.5, "categorical": 0.5},
|
| 244 |
+
]
|
| 245 |
+
target_weight_settings = [(0.0, 1.0), (0.5, 0.25), (1.0, 0.25), (2.0, 0.10)]
|
| 246 |
+
scalar_settings = [("none", 0.0), ("ridge", 0.5), ("ridge", 1.0), ("ridge", 2.0), ("enet", 1.0), ("enet", 2.0)]
|
| 247 |
+
|
| 248 |
+
for bw in block_weight_grid:
|
| 249 |
+
base_train = np.concatenate([matrices[name][0] * bw[name] for name in ["weather", "geo_fire", "categorical"]], axis=1)
|
| 250 |
+
base_val = np.concatenate([matrices[name][1] * bw[name] for name in ["weather", "geo_fire", "categorical"]], axis=1)
|
| 251 |
+
base_test = np.concatenate([matrices[name][2] * bw[name] for name in ["weather", "geo_fire", "categorical"]], axis=1)
|
| 252 |
+
for power, floor in target_weight_settings:
|
| 253 |
+
tw_train, tw_val, tw_test = target_weight_vectors(
|
| 254 |
+
base_train,
|
| 255 |
+
base_val,
|
| 256 |
+
base_test,
|
| 257 |
+
train_df["target_log_burn_acres"].to_numpy(dtype=np.float64),
|
| 258 |
+
power=power,
|
| 259 |
+
floor=floor,
|
| 260 |
+
)
|
| 261 |
+
for scalar_model, scalar_weight in scalar_settings:
|
| 262 |
+
if scalar_model == "none":
|
| 263 |
+
train_vec, val_vec, test_vec = tw_train, tw_val, tw_test
|
| 264 |
+
else:
|
| 265 |
+
train_vec, val_vec, test_vec = append_supervised_scalar(
|
| 266 |
+
tw_train,
|
| 267 |
+
tw_val,
|
| 268 |
+
tw_test,
|
| 269 |
+
train_df,
|
| 270 |
+
scalar_model,
|
| 271 |
+
scalar_weight,
|
| 272 |
+
args.seed,
|
| 273 |
+
)
|
| 274 |
+
for k in [3, 5, 10, 15, 20]:
|
| 275 |
+
for mode in ["mean", "weighted"]:
|
| 276 |
+
val_metrics = score_vectors(val_vec, train_vec, val_df, train_df, k=k, mode=mode)
|
| 277 |
+
test_metrics = score_vectors(test_vec, train_vec, test_df, train_df, k=k, mode=mode)
|
| 278 |
+
row = {
|
| 279 |
+
"block_weights": bw,
|
| 280 |
+
"target_weight_power": power,
|
| 281 |
+
"target_weight_floor": floor,
|
| 282 |
+
"supervised_scalar": scalar_model,
|
| 283 |
+
"supervised_scalar_weight": scalar_weight,
|
| 284 |
+
"k": k,
|
| 285 |
+
"mode": mode,
|
| 286 |
+
"val_metrics": val_metrics,
|
| 287 |
+
"test_metrics": test_metrics,
|
| 288 |
+
}
|
| 289 |
+
candidate_rows.append(row)
|
| 290 |
+
score = float(val_metrics["ndcg_at_10"])
|
| 291 |
+
if best_score is None or score > best_score:
|
| 292 |
+
best_score = score
|
| 293 |
+
best = row
|
| 294 |
+
best_test = test_metrics
|
| 295 |
+
|
| 296 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 297 |
+
candidate_df = pd.DataFrame(
|
| 298 |
+
[
|
| 299 |
+
{
|
| 300 |
+
"val_ndcg_at_10": r["val_metrics"]["ndcg_at_10"],
|
| 301 |
+
"val_log_mae": r["val_metrics"]["log_mae"],
|
| 302 |
+
"test_ndcg_at_10": r["test_metrics"]["ndcg_at_10"],
|
| 303 |
+
"test_log_mae": r["test_metrics"]["log_mae"],
|
| 304 |
+
"k": r["k"],
|
| 305 |
+
"mode": r["mode"],
|
| 306 |
+
"target_weight_power": r["target_weight_power"],
|
| 307 |
+
"target_weight_floor": r["target_weight_floor"],
|
| 308 |
+
"supervised_scalar": r["supervised_scalar"],
|
| 309 |
+
"supervised_scalar_weight": r["supervised_scalar_weight"],
|
| 310 |
+
**{f"block_{k}": v for k, v in r["block_weights"].items()},
|
| 311 |
+
}
|
| 312 |
+
for r in candidate_rows
|
| 313 |
+
]
|
| 314 |
+
)
|
| 315 |
+
candidate_df.to_csv(args.output_dir / "candidate_grid.csv", index=False)
|
| 316 |
+
summary = {
|
| 317 |
+
"task_id": "wildfire_analog_retrieval_extended_hybrid_sweep",
|
| 318 |
+
"event_table": str(args.event_table),
|
| 319 |
+
"seed": int(args.seed),
|
| 320 |
+
"excluded_columns": sorted(exclude),
|
| 321 |
+
"split_sizes": {"train": len(train_df), "val": len(val_df), "test": len(test_df)},
|
| 322 |
+
"feature_blocks": blocks,
|
| 323 |
+
"selection_metric": "val_ndcg_at_10",
|
| 324 |
+
"selected_retrieval": best,
|
| 325 |
+
"test_metrics": best_test,
|
| 326 |
+
"candidate_count": len(candidate_rows),
|
| 327 |
+
}
|
| 328 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 329 |
+
print(json.dumps(summary, indent=2))
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
if __name__ == "__main__":
|
| 333 |
+
main()
|
experiments/raw_reference/task_scripts/run_event_analog_taskmodel_seeded.py
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import sys
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from typing import Dict, List, Tuple
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
import os
|
| 12 |
+
|
| 13 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 14 |
+
if _p and _p not in sys.path:
|
| 15 |
+
sys.path.insert(0, _p)
|
| 16 |
+
|
| 17 |
+
import faiss
|
| 18 |
+
import hnswlib
|
| 19 |
+
import numpy as np
|
| 20 |
+
import pandas as pd
|
| 21 |
+
from sklearn.compose import ColumnTransformer
|
| 22 |
+
from sklearn.impute import SimpleImputer
|
| 23 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
| 24 |
+
from sklearn.pipeline import Pipeline
|
| 25 |
+
from sklearn.preprocessing import OneHotEncoder, StandardScaler
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
DROP_COLUMNS = {
|
| 29 |
+
"Event_ID",
|
| 30 |
+
"Incid_Name",
|
| 31 |
+
"incident_name_norm",
|
| 32 |
+
"wfigs_name",
|
| 33 |
+
"Ig_Date",
|
| 34 |
+
"weather_date",
|
| 35 |
+
"BurnBndAc",
|
| 36 |
+
"target_log_burn_acres",
|
| 37 |
+
}
|
| 38 |
+
CATEGORICAL_COLUMNS = ["Incid_Type", "state_abbr", "county_name", "wfigs_match_type"]
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 42 |
+
return float(np.sqrt(np.mean((np.asarray(y_true) - np.asarray(y_pred)) ** 2)))
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def mape(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 46 |
+
denom = np.clip(np.asarray(y_true, dtype=np.float64), 1e-6, None)
|
| 47 |
+
frac = np.abs(np.asarray(y_true, dtype=np.float64) - np.asarray(y_pred, dtype=np.float64)) / denom
|
| 48 |
+
return float(np.mean(frac))
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def r2_score_manual(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 52 |
+
y_true = np.asarray(y_true, dtype=np.float64)
|
| 53 |
+
y_pred = np.asarray(y_pred, dtype=np.float64)
|
| 54 |
+
ss_res = float(np.sum((y_true - y_pred) ** 2))
|
| 55 |
+
ss_tot = float(np.sum((y_true - y_true.mean()) ** 2))
|
| 56 |
+
return float(1.0 - ss_res / ss_tot) if ss_tot > 0 else 0.0
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def spearman_corr(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 60 |
+
a = pd.Series(np.asarray(y_true, dtype=np.float64))
|
| 61 |
+
b = pd.Series(np.asarray(y_pred, dtype=np.float64))
|
| 62 |
+
value = a.corr(b, method="spearman")
|
| 63 |
+
return float(value) if pd.notna(value) else 0.0
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def build_splits(df: pd.DataFrame) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
| 67 |
+
ordered = df.sort_values("Ig_Date").reset_index(drop=True)
|
| 68 |
+
n = len(ordered)
|
| 69 |
+
train_end = max(int(round(n * 0.6)), 1)
|
| 70 |
+
val_end = max(int(round(n * 0.8)), train_end + 1)
|
| 71 |
+
val_end = min(val_end, n - 1) if n >= 3 else n
|
| 72 |
+
train = ordered.iloc[:train_end].copy()
|
| 73 |
+
val = ordered.iloc[train_end:val_end].copy()
|
| 74 |
+
test = ordered.iloc[val_end:].copy()
|
| 75 |
+
if len(val) == 0 and len(test) > 1:
|
| 76 |
+
val = test.iloc[:1].copy()
|
| 77 |
+
test = test.iloc[1:].copy()
|
| 78 |
+
return train, val, test
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def feature_columns(df: pd.DataFrame, feature_profile: str = "all") -> Tuple[List[str], List[str]]:
|
| 82 |
+
categorical = [c for c in CATEGORICAL_COLUMNS if c in df.columns]
|
| 83 |
+
numeric = []
|
| 84 |
+
for col in df.columns:
|
| 85 |
+
if col in DROP_COLUMNS or col in categorical:
|
| 86 |
+
continue
|
| 87 |
+
if pd.api.types.is_numeric_dtype(df[col]):
|
| 88 |
+
numeric.append(col)
|
| 89 |
+
if feature_profile == "weather_fm":
|
| 90 |
+
numeric = [c for c in numeric if c.startswith("weather_")]
|
| 91 |
+
categorical = []
|
| 92 |
+
return numeric, categorical
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def make_preprocessor(numeric_cols: List[str], categorical_cols: List[str]) -> ColumnTransformer:
|
| 96 |
+
return ColumnTransformer(
|
| 97 |
+
transformers=[
|
| 98 |
+
(
|
| 99 |
+
"num",
|
| 100 |
+
Pipeline(
|
| 101 |
+
steps=[
|
| 102 |
+
("impute", SimpleImputer(strategy="median")),
|
| 103 |
+
("scale", StandardScaler()),
|
| 104 |
+
]
|
| 105 |
+
),
|
| 106 |
+
numeric_cols,
|
| 107 |
+
),
|
| 108 |
+
(
|
| 109 |
+
"cat",
|
| 110 |
+
Pipeline(
|
| 111 |
+
steps=[
|
| 112 |
+
("impute", SimpleImputer(strategy="most_frequent")),
|
| 113 |
+
("onehot", OneHotEncoder(handle_unknown="ignore")),
|
| 114 |
+
]
|
| 115 |
+
),
|
| 116 |
+
categorical_cols,
|
| 117 |
+
),
|
| 118 |
+
],
|
| 119 |
+
remainder="drop",
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def to_dense_float32(x) -> np.ndarray:
|
| 124 |
+
if hasattr(x, "toarray"):
|
| 125 |
+
x = x.toarray()
|
| 126 |
+
return np.asarray(x, dtype=np.float32)
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def weighted_prediction(sim: np.ndarray, targets: np.ndarray) -> float:
|
| 130 |
+
weights = np.maximum((np.asarray(sim, dtype=np.float64) + 1.0) / 2.0, 1e-6)
|
| 131 |
+
return float(np.sum(weights * targets) / np.sum(weights))
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def graded_relevance(query_target: float, retrieved_targets: np.ndarray) -> np.ndarray:
|
| 135 |
+
delta = np.abs(np.asarray(retrieved_targets, dtype=np.float64) - float(query_target))
|
| 136 |
+
return np.select([delta <= 0.5, delta <= 1.0, delta <= 1.5], [3.0, 2.0, 1.0], default=0.0)
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def dcg(relevance: np.ndarray) -> float:
|
| 140 |
+
rel = np.asarray(relevance, dtype=np.float64)
|
| 141 |
+
if rel.size == 0:
|
| 142 |
+
return 0.0
|
| 143 |
+
discounts = 1.0 / np.log2(np.arange(rel.size, dtype=np.float64) + 2.0)
|
| 144 |
+
return float(np.sum(rel * discounts))
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def ndcg_at_k(relevance: np.ndarray, ideal_relevance: np.ndarray, k: int) -> float:
|
| 148 |
+
rel = np.asarray(relevance, dtype=np.float64)[:k]
|
| 149 |
+
ideal = np.asarray(ideal_relevance, dtype=np.float64)[:k]
|
| 150 |
+
denom = dcg(ideal)
|
| 151 |
+
return float(dcg(rel) / denom) if denom > 0 else 0.0
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def score_backend(
|
| 155 |
+
name: str,
|
| 156 |
+
query_vec: np.ndarray,
|
| 157 |
+
library_vec: np.ndarray,
|
| 158 |
+
query_df: pd.DataFrame,
|
| 159 |
+
library_df: pd.DataFrame,
|
| 160 |
+
k: int,
|
| 161 |
+
mode: str,
|
| 162 |
+
) -> Tuple[Dict[str, float], pd.DataFrame]:
|
| 163 |
+
target_lib = library_df["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 164 |
+
rows = []
|
| 165 |
+
preds = []
|
| 166 |
+
ndcg5 = []
|
| 167 |
+
ndcg10 = []
|
| 168 |
+
hit1 = []
|
| 169 |
+
hit5 = []
|
| 170 |
+
hit10 = []
|
| 171 |
+
best_abs_delta = []
|
| 172 |
+
|
| 173 |
+
k_eff = min(int(k), int(library_vec.shape[0]))
|
| 174 |
+
if name == "cosine_exact":
|
| 175 |
+
sim_all = cosine_similarity(query_vec, library_vec)
|
| 176 |
+
knn_idx = np.argsort(-sim_all, axis=1)[:, :k_eff]
|
| 177 |
+
knn_sim = np.take_along_axis(sim_all, knn_idx, axis=1)
|
| 178 |
+
else:
|
| 179 |
+
library_norm = library_vec / np.clip(np.linalg.norm(library_vec, axis=1, keepdims=True), 1e-12, None)
|
| 180 |
+
query_norm = query_vec / np.clip(np.linalg.norm(query_vec, axis=1, keepdims=True), 1e-12, None)
|
| 181 |
+
if name == "faiss_flat_ip":
|
| 182 |
+
index = faiss.IndexFlatIP(library_norm.shape[1])
|
| 183 |
+
index.add(library_norm.astype(np.float32))
|
| 184 |
+
knn_sim, knn_idx = index.search(query_norm.astype(np.float32), k_eff)
|
| 185 |
+
elif name == "hnsw_cosine":
|
| 186 |
+
index = hnswlib.Index(space="cosine", dim=library_norm.shape[1])
|
| 187 |
+
index.init_index(max_elements=library_norm.shape[0], ef_construction=100, M=16)
|
| 188 |
+
index.add_items(library_norm.astype(np.float32), np.arange(library_norm.shape[0]))
|
| 189 |
+
index.set_ef(max(50, k_eff))
|
| 190 |
+
knn_idx, dist = index.knn_query(query_norm.astype(np.float32), k=k_eff)
|
| 191 |
+
knn_sim = 1.0 - dist
|
| 192 |
+
else:
|
| 193 |
+
raise ValueError(name)
|
| 194 |
+
|
| 195 |
+
for i in range(query_df.shape[0]):
|
| 196 |
+
order = knn_idx[i]
|
| 197 |
+
top_sim = knn_sim[i]
|
| 198 |
+
top_targets = target_lib[order]
|
| 199 |
+
query_target = float(query_df.iloc[i]["target_log_burn_acres"])
|
| 200 |
+
relevance = graded_relevance(query_target, top_targets)
|
| 201 |
+
ideal_relevance = np.sort(graded_relevance(query_target, target_lib))[::-1]
|
| 202 |
+
abs_delta = np.abs(top_targets - float(query_df.iloc[i]["target_log_burn_acres"]))
|
| 203 |
+
ndcg5.append(ndcg_at_k(relevance, ideal_relevance, 5))
|
| 204 |
+
ndcg10.append(ndcg_at_k(relevance, ideal_relevance, 10))
|
| 205 |
+
hit1.append(float(relevance[:1].max() >= 2.0))
|
| 206 |
+
hit5.append(float(relevance[: min(5, k_eff)].max() >= 2.0))
|
| 207 |
+
hit10.append(float(relevance[: min(10, k_eff)].max() >= 2.0))
|
| 208 |
+
best_abs_delta.append(float(abs_delta.min()))
|
| 209 |
+
pred = float(np.mean(top_targets)) if mode == "mean" else weighted_prediction(top_sim, top_targets)
|
| 210 |
+
preds.append(pred)
|
| 211 |
+
rows.append(
|
| 212 |
+
{
|
| 213 |
+
"query_event_id": query_df.iloc[i]["Event_ID"],
|
| 214 |
+
"true_log_burn_acres": float(query_df.iloc[i]["target_log_burn_acres"]),
|
| 215 |
+
"pred_log_burn_acres": pred,
|
| 216 |
+
"backend": name,
|
| 217 |
+
"k": k,
|
| 218 |
+
"effective_k": k_eff,
|
| 219 |
+
"mode": mode,
|
| 220 |
+
"top_relevance": relevance.tolist(),
|
| 221 |
+
"best_abs_log_delta": float(abs_delta.min()),
|
| 222 |
+
}
|
| 223 |
+
)
|
| 224 |
+
|
| 225 |
+
pred_arr = np.asarray(preds, dtype=np.float64)
|
| 226 |
+
true_log = query_df["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 227 |
+
true_acres = query_df["BurnBndAc"].to_numpy(dtype=np.float64)
|
| 228 |
+
pred_acres = np.exp(pred_arr)
|
| 229 |
+
metrics = {
|
| 230 |
+
"count": int(len(query_df)),
|
| 231 |
+
"log_mae": float(np.mean(np.abs(true_log - pred_arr))),
|
| 232 |
+
"log_rmse": rmse(true_log, pred_arr),
|
| 233 |
+
"log_r2": r2_score_manual(true_log, pred_arr),
|
| 234 |
+
"log_spearman": spearman_corr(true_log, pred_arr),
|
| 235 |
+
"log_median_ae": float(np.median(np.abs(true_log - pred_arr))),
|
| 236 |
+
"acres_mae": float(np.mean(np.abs(true_acres - pred_acres))),
|
| 237 |
+
"acres_rmse": rmse(true_acres, pred_acres),
|
| 238 |
+
"acres_median_ae": float(np.median(np.abs(true_acres - pred_acres))),
|
| 239 |
+
"acres_mape": mape(true_acres, pred_acres),
|
| 240 |
+
"ndcg_at_5": float(np.mean(ndcg5)) if ndcg5 else 0.0,
|
| 241 |
+
"ndcg_at_10": float(np.mean(ndcg10)) if ndcg10 else 0.0,
|
| 242 |
+
"hit_at_1_tol1": float(np.mean(hit1)) if hit1 else 0.0,
|
| 243 |
+
"hit_at_5_tol1": float(np.mean(hit5)) if hit5 else 0.0,
|
| 244 |
+
"hit_at_10_tol1": float(np.mean(hit10)) if hit10 else 0.0,
|
| 245 |
+
"mean_best_abs_log_delta_at_k": float(np.mean(best_abs_delta)) if best_abs_delta else 0.0,
|
| 246 |
+
}
|
| 247 |
+
return metrics, pd.DataFrame(rows)
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
def target_weight_vectors(train_vec: np.ndarray, val_vec: np.ndarray, test_vec: np.ndarray, target: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
| 251 |
+
x = np.asarray(train_vec, dtype=np.float64)
|
| 252 |
+
y = np.asarray(target, dtype=np.float64)
|
| 253 |
+
y = y - y.mean()
|
| 254 |
+
x_centered = x - x.mean(axis=0, keepdims=True)
|
| 255 |
+
denom = np.clip(np.sqrt(np.sum(x_centered**2, axis=0)) * np.sqrt(np.sum(y**2)), 1e-12, None)
|
| 256 |
+
corr = np.abs(np.sum(x_centered * y[:, None], axis=0) / denom)
|
| 257 |
+
corr = np.nan_to_num(corr, nan=0.0, posinf=0.0, neginf=0.0)
|
| 258 |
+
if float(corr.max()) > 0:
|
| 259 |
+
corr = corr / float(corr.max())
|
| 260 |
+
weights = (0.25 + corr).astype(np.float32)
|
| 261 |
+
return train_vec * weights, val_vec * weights, test_vec * weights
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
def main() -> None:
|
| 265 |
+
parser = argparse.ArgumentParser()
|
| 266 |
+
parser.add_argument("--event-table", type=Path, required=True)
|
| 267 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 268 |
+
parser.add_argument("--selection-metric", choices=("log_mae", "ndcg_at_10"), default="ndcg_at_10")
|
| 269 |
+
parser.add_argument("--feature-profile", choices=("all", "weather_fm"), default="all")
|
| 270 |
+
parser.add_argument("--fm-family", type=str, default="")
|
| 271 |
+
parser.add_argument("--seed", type=int, default=7)
|
| 272 |
+
args = parser.parse_args()
|
| 273 |
+
|
| 274 |
+
df = pd.read_csv(args.event_table)
|
| 275 |
+
df["Ig_Date"] = pd.to_datetime(df["Ig_Date"])
|
| 276 |
+
train_df, val_df, test_df = build_splits(df)
|
| 277 |
+
numeric_cols, categorical_cols = feature_columns(df, feature_profile=args.feature_profile)
|
| 278 |
+
if not numeric_cols and not categorical_cols:
|
| 279 |
+
raise SystemExit(f"No usable features found for profile={args.feature_profile}")
|
| 280 |
+
x_cols = numeric_cols + categorical_cols
|
| 281 |
+
pre = make_preprocessor(numeric_cols, categorical_cols)
|
| 282 |
+
train_vec = to_dense_float32(pre.fit_transform(train_df[x_cols]))
|
| 283 |
+
val_vec = to_dense_float32(pre.transform(val_df[x_cols]))
|
| 284 |
+
test_vec = to_dense_float32(pre.transform(test_df[x_cols]))
|
| 285 |
+
weighted_train_vec, weighted_val_vec, weighted_test_vec = target_weight_vectors(
|
| 286 |
+
train_vec,
|
| 287 |
+
val_vec,
|
| 288 |
+
test_vec,
|
| 289 |
+
train_df["target_log_burn_acres"].to_numpy(dtype=np.float64),
|
| 290 |
+
)
|
| 291 |
+
vector_variants = {
|
| 292 |
+
"standard": (train_vec, val_vec, test_vec),
|
| 293 |
+
"target_weighted": (weighted_train_vec, weighted_val_vec, weighted_test_vec),
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
candidate_validation: List[Dict[str, object]] = []
|
| 297 |
+
best = None
|
| 298 |
+
best_score = None
|
| 299 |
+
best_val_rows = None
|
| 300 |
+
best_test_rows = None
|
| 301 |
+
for variant, (lib_vec, v_vec, _) in vector_variants.items():
|
| 302 |
+
for backend in ["cosine_exact", "faiss_flat_ip", "hnsw_cosine"]:
|
| 303 |
+
for k in [1, 3, 5, 10]:
|
| 304 |
+
for mode in ["mean", "weighted"]:
|
| 305 |
+
val_metrics, val_rows = score_backend(backend, v_vec, lib_vec, val_df, train_df, k, mode)
|
| 306 |
+
candidate_validation.append({"variant": variant, "backend": backend, "k": k, "mode": mode, "val_metrics": val_metrics})
|
| 307 |
+
score = float(val_metrics[args.selection_metric])
|
| 308 |
+
better = score > best_score if args.selection_metric == "ndcg_at_10" and best_score is not None else score < best_score if best_score is not None else True
|
| 309 |
+
if better:
|
| 310 |
+
best_score = score
|
| 311 |
+
best = {"variant": variant, "backend": backend, "k": k, "mode": mode}
|
| 312 |
+
best_val_rows = val_rows
|
| 313 |
+
|
| 314 |
+
assert best is not None
|
| 315 |
+
best_train_vec, _, best_test_vec = vector_variants[str(best["variant"])]
|
| 316 |
+
test_metrics, test_rows = score_backend(best["backend"], best_test_vec, best_train_vec, test_df, train_df, int(best["k"]), str(best["mode"]))
|
| 317 |
+
best_test_rows = test_rows
|
| 318 |
+
|
| 319 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 320 |
+
if best_val_rows is not None:
|
| 321 |
+
best_val_rows.to_csv(args.output_dir / "val_retrieval_examples.csv", index=False)
|
| 322 |
+
if best_test_rows is not None:
|
| 323 |
+
best_test_rows.to_csv(args.output_dir / "test_retrieval_examples.csv", index=False)
|
| 324 |
+
|
| 325 |
+
summary = {
|
| 326 |
+
"task_id": "wildfire_analog_retrieval_taskmodels",
|
| 327 |
+
"task_form": "event_level_retrieval_with_induced_outcome_error",
|
| 328 |
+
"event_table": str(args.event_table),
|
| 329 |
+
"output_dir": str(args.output_dir),
|
| 330 |
+
"feature_profile": args.feature_profile,
|
| 331 |
+
"seed": int(args.seed),
|
| 332 |
+
"split_sizes": {
|
| 333 |
+
"train": int(len(train_df)),
|
| 334 |
+
"val": int(len(val_df)),
|
| 335 |
+
"test": int(len(test_df)),
|
| 336 |
+
},
|
| 337 |
+
"feature_columns": {"numeric": numeric_cols, "categorical": categorical_cols},
|
| 338 |
+
"candidate_validation": candidate_validation,
|
| 339 |
+
"selected_retrieval": best,
|
| 340 |
+
"selection_metric": args.selection_metric,
|
| 341 |
+
"test_metrics": test_metrics,
|
| 342 |
+
"model_family": "popular_open_source_retrieval_backends_with_train_only_target_weighting",
|
| 343 |
+
"fm_family": (args.fm_family or "weather_fm_derived_features") if args.feature_profile == "weather_fm" else None,
|
| 344 |
+
}
|
| 345 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 346 |
+
print(json.dumps(summary, indent=2))
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
if __name__ == "__main__":
|
| 350 |
+
main()
|
experiments/raw_reference/task_scripts/run_extreme_heat_alphaearth_suite_seeded.py
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import math
|
| 7 |
+
import re
|
| 8 |
+
import sys
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from typing import Dict, Iterable, List, Optional, Tuple
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
import os
|
| 14 |
+
|
| 15 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 16 |
+
if _p and _p not in sys.path:
|
| 17 |
+
sys.path.insert(0, _p)
|
| 18 |
+
|
| 19 |
+
import numpy as np
|
| 20 |
+
import pandas as pd
|
| 21 |
+
from catboost import CatBoostRegressor
|
| 22 |
+
from lightgbm import LGBMRegressor
|
| 23 |
+
from netCDF4 import Dataset
|
| 24 |
+
from sklearn.linear_model import ElasticNet, Ridge
|
| 25 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
| 26 |
+
from xgboost import XGBRegressor
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
PRED_RE = re.compile(r"pred_(\d{8})_(\d{2})\.nc$")
|
| 30 |
+
WEATHER_VARS = ["T2M", "QV2M", "TQV", "U10M", "V10M", "TS"]
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def parse_args() -> argparse.Namespace:
|
| 34 |
+
parser = argparse.ArgumentParser()
|
| 35 |
+
parser.add_argument("--pred-root", type=Path, action="append", required=True)
|
| 36 |
+
parser.add_argument("--merra-root", type=Path, required=True)
|
| 37 |
+
parser.add_argument("--alphaearth-year-csv", type=Path, required=True)
|
| 38 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 39 |
+
parser.add_argument("--model-family", choices=("full", "lite"), default="full")
|
| 40 |
+
parser.add_argument("--alphaearth-prefix", type=str, default="alphaearth_")
|
| 41 |
+
parser.add_argument("--lat-min", type=float, default=24.0)
|
| 42 |
+
parser.add_argument("--lat-max", type=float, default=50.0)
|
| 43 |
+
parser.add_argument("--lon-min", type=float, default=-125.0)
|
| 44 |
+
parser.add_argument("--lon-max", type=float, default=-66.0)
|
| 45 |
+
parser.add_argument("--seed", type=int, default=7)
|
| 46 |
+
return parser.parse_args()
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def choose_split(path: Path) -> Optional[str]:
|
| 50 |
+
name = path.name
|
| 51 |
+
if name == "output2022":
|
| 52 |
+
return "train"
|
| 53 |
+
if name == "output2024":
|
| 54 |
+
return "val"
|
| 55 |
+
if name == "output2025":
|
| 56 |
+
return "test"
|
| 57 |
+
return None
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def parse_pred_timestamp(path: Path) -> Tuple[str, int]:
|
| 61 |
+
match = PRED_RE.match(path.name)
|
| 62 |
+
if not match:
|
| 63 |
+
raise ValueError(f"Unexpected prediction filename: {path}")
|
| 64 |
+
return match.group(1), int(match.group(2))
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def nearest_indices(src: np.ndarray, dst: np.ndarray) -> np.ndarray:
|
| 68 |
+
idx = np.searchsorted(dst, src)
|
| 69 |
+
idx = np.clip(idx, 0, len(dst) - 1)
|
| 70 |
+
prev_idx = np.clip(idx - 1, 0, len(dst) - 1)
|
| 71 |
+
choose_prev = np.abs(dst[prev_idx] - src) <= np.abs(dst[idx] - src)
|
| 72 |
+
return np.where(choose_prev, prev_idx, idx).astype(np.int64)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def build_grid_alignment(sample_pred: Path, sample_merra: Path, lat_min: float, lat_max: float, lon_min: float, lon_max: float) -> Dict[str, np.ndarray]:
|
| 76 |
+
with Dataset(sample_pred) as pred_ds, Dataset(sample_merra) as merra_ds:
|
| 77 |
+
pred_lat = np.asarray(pred_ds.variables["lat"][:], dtype=np.float64)
|
| 78 |
+
pred_lon = np.asarray(pred_ds.variables["lon"][:], dtype=np.float64)
|
| 79 |
+
merra_lat = np.asarray(merra_ds.variables["lat"][:], dtype=np.float64)
|
| 80 |
+
merra_lon = np.asarray(merra_ds.variables["lon"][:], dtype=np.float64)
|
| 81 |
+
|
| 82 |
+
lat_mask = (pred_lat >= lat_min) & (pred_lat <= lat_max)
|
| 83 |
+
lon_mask = (pred_lon >= lon_min) & (pred_lon <= lon_max)
|
| 84 |
+
pred_lat_idx = np.flatnonzero(lat_mask)
|
| 85 |
+
pred_lon_idx = np.flatnonzero(lon_mask)
|
| 86 |
+
pred_lat_sel = pred_lat[pred_lat_idx]
|
| 87 |
+
pred_lon_sel = pred_lon[pred_lon_idx]
|
| 88 |
+
merra_lat_idx = nearest_indices(pred_lat_sel, merra_lat)
|
| 89 |
+
merra_lon_idx = nearest_indices(pred_lon_sel, merra_lon)
|
| 90 |
+
|
| 91 |
+
return {
|
| 92 |
+
"pred_lat_idx": pred_lat_idx,
|
| 93 |
+
"pred_lon_idx": pred_lon_idx,
|
| 94 |
+
"merra_lat_idx": merra_lat_idx,
|
| 95 |
+
"merra_lon_idx": merra_lon_idx,
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def feature_stats(arr: np.ndarray) -> Dict[str, float]:
|
| 100 |
+
return {"mean": float(np.mean(arr)), "max": float(np.max(arr)), "std": float(np.std(arr))}
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def build_rows(pred_roots: Iterable[Path], merra_root: Path, alignment: Dict[str, np.ndarray]) -> pd.DataFrame:
|
| 104 |
+
rows: List[Dict[str, float]] = []
|
| 105 |
+
for root in pred_roots:
|
| 106 |
+
split = choose_split(root)
|
| 107 |
+
if split is None:
|
| 108 |
+
continue
|
| 109 |
+
for path in sorted(root.glob("pred_*.nc")):
|
| 110 |
+
day, hour = parse_pred_timestamp(path)
|
| 111 |
+
if hour % 3 != 0:
|
| 112 |
+
continue
|
| 113 |
+
merra_path = merra_root / f"MERRA2_sfc_{day}.nc"
|
| 114 |
+
if not merra_path.exists():
|
| 115 |
+
continue
|
| 116 |
+
time_index = hour // 3
|
| 117 |
+
with Dataset(path) as pred_ds, Dataset(merra_path) as merra_ds:
|
| 118 |
+
date = pd.Timestamp(day)
|
| 119 |
+
record: Dict[str, float] = {"split": split, "hour": float(hour), "year": float(date.year), "date": day}
|
| 120 |
+
record["doy"] = float(date.dayofyear)
|
| 121 |
+
record["month"] = float(date.month)
|
| 122 |
+
for var in WEATHER_VARS:
|
| 123 |
+
pred_arr = np.asarray(
|
| 124 |
+
pred_ds.variables[var][0, alignment["pred_lat_idx"], alignment["pred_lon_idx"]],
|
| 125 |
+
dtype=np.float64,
|
| 126 |
+
)
|
| 127 |
+
stats = feature_stats(pred_arr)
|
| 128 |
+
record[f"pred_{var.lower()}_mean"] = stats["mean"]
|
| 129 |
+
record[f"pred_{var.lower()}_max"] = stats["max"]
|
| 130 |
+
record[f"pred_{var.lower()}_std"] = stats["std"]
|
| 131 |
+
record["pred_wind_mean"] = float(
|
| 132 |
+
np.mean(
|
| 133 |
+
np.sqrt(
|
| 134 |
+
np.square(pred_ds.variables["U10M"][0, alignment["pred_lat_idx"], alignment["pred_lon_idx"]])
|
| 135 |
+
+ np.square(pred_ds.variables["V10M"][0, alignment["pred_lat_idx"], alignment["pred_lon_idx"]])
|
| 136 |
+
)
|
| 137 |
+
)
|
| 138 |
+
)
|
| 139 |
+
truth_t2m = np.asarray(merra_ds.variables["T2M"][time_index], dtype=np.float64)[
|
| 140 |
+
np.ix_(alignment["merra_lat_idx"], alignment["merra_lon_idx"])
|
| 141 |
+
]
|
| 142 |
+
truth_ts = np.asarray(merra_ds.variables["TS"][time_index], dtype=np.float64)[
|
| 143 |
+
np.ix_(alignment["merra_lat_idx"], alignment["merra_lon_idx"])
|
| 144 |
+
]
|
| 145 |
+
record["target_t2m_mean_c"] = float(np.mean(truth_t2m) - 273.15)
|
| 146 |
+
record["target_t2m_max_c"] = float(np.max(truth_t2m) - 273.15)
|
| 147 |
+
record["target_ts_mean_c"] = float(np.mean(truth_ts) - 273.15)
|
| 148 |
+
rows.append(record)
|
| 149 |
+
|
| 150 |
+
if not rows:
|
| 151 |
+
raise SystemExit("No extreme-heat rows were built from the provided roots.")
|
| 152 |
+
df = pd.DataFrame(rows)
|
| 153 |
+
angle_day = 2.0 * np.pi * df["doy"].to_numpy(dtype=np.float64) / 366.0
|
| 154 |
+
angle_hour = 2.0 * np.pi * df["hour"].to_numpy(dtype=np.float64) / 24.0
|
| 155 |
+
df["doy_sin"] = np.sin(angle_day)
|
| 156 |
+
df["doy_cos"] = np.cos(angle_day)
|
| 157 |
+
df["hour_sin"] = np.sin(angle_hour)
|
| 158 |
+
df["hour_cos"] = np.cos(angle_hour)
|
| 159 |
+
return df
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def drop_nonfinite_rows(df: pd.DataFrame, columns: List[str]) -> pd.DataFrame:
|
| 163 |
+
mask = np.ones(len(df), dtype=bool)
|
| 164 |
+
for col in columns:
|
| 165 |
+
mask &= np.isfinite(pd.to_numeric(df[col], errors="coerce").to_numpy(dtype=np.float64))
|
| 166 |
+
return df.loc[mask].reset_index(drop=True)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 170 |
+
return float(math.sqrt(mean_squared_error(y_true, y_pred)))
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
def pearson_corr(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 174 |
+
a = np.asarray(y_true, dtype=np.float64)
|
| 175 |
+
b = np.asarray(y_pred, dtype=np.float64)
|
| 176 |
+
if a.size < 2 or np.allclose(a, a[0]) or np.allclose(b, b[0]):
|
| 177 |
+
return 0.0
|
| 178 |
+
value = float(np.corrcoef(a, b)[0, 1])
|
| 179 |
+
return value if np.isfinite(value) else 0.0
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
def prf(y_true: np.ndarray, y_pred: np.ndarray, threshold: float) -> Dict[str, float]:
|
| 183 |
+
truth = np.asarray(y_true >= threshold)
|
| 184 |
+
pred = np.asarray(y_pred >= threshold)
|
| 185 |
+
tp = int(np.logical_and(pred, truth).sum())
|
| 186 |
+
fp = int(np.logical_and(pred, ~truth).sum())
|
| 187 |
+
fn = int(np.logical_and(~pred, truth).sum())
|
| 188 |
+
precision = float(tp / (tp + fp)) if (tp + fp) else 0.0
|
| 189 |
+
recall = float(tp / (tp + fn)) if (tp + fn) else 0.0
|
| 190 |
+
f1 = float((2.0 * precision * recall) / (precision + recall)) if (precision + recall) else 0.0
|
| 191 |
+
return {"precision": precision, "recall": recall, "f1": f1}
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
def evaluate(y_true: np.ndarray, y_pred: np.ndarray) -> Dict[str, float]:
|
| 195 |
+
return {
|
| 196 |
+
"count": int(y_true.shape[0]),
|
| 197 |
+
"rmse_c": rmse(y_true, y_pred),
|
| 198 |
+
"mae_c": float(mean_absolute_error(y_true, y_pred)),
|
| 199 |
+
"pearson_r": pearson_corr(y_true, y_pred),
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
def main() -> None:
|
| 204 |
+
args = parse_args()
|
| 205 |
+
pred_files = [path for root in args.pred_root for path in root.glob("pred_*.nc")]
|
| 206 |
+
if not pred_files:
|
| 207 |
+
raise SystemExit("No prediction files found.")
|
| 208 |
+
sample_pred = sorted(pred_files)[0]
|
| 209 |
+
sample_day, _ = parse_pred_timestamp(sample_pred)
|
| 210 |
+
sample_merra = args.merra_root / f"MERRA2_sfc_{sample_day}.nc"
|
| 211 |
+
if not sample_merra.exists():
|
| 212 |
+
raise SystemExit(f"Sample MERRA file missing: {sample_merra}")
|
| 213 |
+
|
| 214 |
+
alignment = build_grid_alignment(
|
| 215 |
+
sample_pred,
|
| 216 |
+
sample_merra,
|
| 217 |
+
lat_min=args.lat_min,
|
| 218 |
+
lat_max=args.lat_max,
|
| 219 |
+
lon_min=args.lon_min,
|
| 220 |
+
lon_max=args.lon_max,
|
| 221 |
+
)
|
| 222 |
+
df = build_rows(args.pred_root, args.merra_root, alignment)
|
| 223 |
+
|
| 224 |
+
alpha = pd.read_csv(args.alphaearth_year_csv)
|
| 225 |
+
alpha["source_year_key"] = pd.to_numeric(alpha["alphaearth_source_year"], errors="coerce").astype("Int64")
|
| 226 |
+
df["source_year_key"] = pd.to_numeric(df["year"], errors="coerce").clip(lower=2017, upper=2024).astype("Int64")
|
| 227 |
+
df = df.merge(alpha.drop(columns=[c for c in ["requested_year"] if c in alpha.columns]), on="source_year_key", how="left")
|
| 228 |
+
|
| 229 |
+
feature_cols = [c for c in df.columns if c.startswith("pred_") or c in {"month", "doy_sin", "doy_cos", "hour_sin", "hour_cos"}]
|
| 230 |
+
feature_cols.extend(sorted([c for c in df.columns if c.startswith(args.alphaearth_prefix)]))
|
| 231 |
+
finite_cols = feature_cols + ["target_t2m_mean_c"]
|
| 232 |
+
df = drop_nonfinite_rows(df, finite_cols)
|
| 233 |
+
if df.empty:
|
| 234 |
+
raise SystemExit("Extreme-heat AlphaEarth suite has no finite rows after filtering.")
|
| 235 |
+
|
| 236 |
+
train = df[df["split"] == "train"].copy()
|
| 237 |
+
val = df[df["split"] == "val"].copy()
|
| 238 |
+
test = df[df["split"] == "test"].copy()
|
| 239 |
+
if len(train) == 0 or len(val) == 0 or len(test) == 0:
|
| 240 |
+
raise SystemExit("Extreme-heat AlphaEarth suite is missing one of train/val/test.")
|
| 241 |
+
|
| 242 |
+
x_train = train[feature_cols].to_numpy(dtype=np.float64)
|
| 243 |
+
x_val = val[feature_cols].to_numpy(dtype=np.float64)
|
| 244 |
+
x_test = test[feature_cols].to_numpy(dtype=np.float64)
|
| 245 |
+
y_train = train["target_t2m_mean_c"].to_numpy(dtype=np.float64)
|
| 246 |
+
y_val = val["target_t2m_mean_c"].to_numpy(dtype=np.float64)
|
| 247 |
+
y_test = test["target_t2m_mean_c"].to_numpy(dtype=np.float64)
|
| 248 |
+
|
| 249 |
+
candidates: Dict[str, object] = {
|
| 250 |
+
"ridge": Ridge(alpha=1.0, random_state=args.seed),
|
| 251 |
+
"enet": ElasticNet(alpha=0.01, l1_ratio=0.2, random_state=args.seed, max_iter=10000),
|
| 252 |
+
}
|
| 253 |
+
if args.model_family == "full":
|
| 254 |
+
candidates.update(
|
| 255 |
+
{
|
| 256 |
+
"xgboost": XGBRegressor(
|
| 257 |
+
n_estimators=300,
|
| 258 |
+
max_depth=6,
|
| 259 |
+
learning_rate=0.05,
|
| 260 |
+
subsample=0.8,
|
| 261 |
+
colsample_bytree=0.8,
|
| 262 |
+
objective="reg:squarederror",
|
| 263 |
+
tree_method="hist",
|
| 264 |
+
random_state=args.seed,
|
| 265 |
+
n_jobs=8,
|
| 266 |
+
),
|
| 267 |
+
"lightgbm": LGBMRegressor(
|
| 268 |
+
n_estimators=300,
|
| 269 |
+
learning_rate=0.05,
|
| 270 |
+
num_leaves=63,
|
| 271 |
+
subsample=0.8,
|
| 272 |
+
colsample_bytree=0.8,
|
| 273 |
+
random_state=args.seed,
|
| 274 |
+
n_jobs=8,
|
| 275 |
+
verbose=-1,
|
| 276 |
+
),
|
| 277 |
+
"catboost": CatBoostRegressor(
|
| 278 |
+
iterations=400,
|
| 279 |
+
depth=8,
|
| 280 |
+
learning_rate=0.05,
|
| 281 |
+
loss_function="RMSE",
|
| 282 |
+
eval_metric="RMSE",
|
| 283 |
+
random_seed=args.seed,
|
| 284 |
+
verbose=False,
|
| 285 |
+
),
|
| 286 |
+
}
|
| 287 |
+
)
|
| 288 |
+
|
| 289 |
+
candidate_rows = []
|
| 290 |
+
best_name = None
|
| 291 |
+
best_model = None
|
| 292 |
+
best_rmse = None
|
| 293 |
+
for name, model in candidates.items():
|
| 294 |
+
model.fit(x_train, y_train)
|
| 295 |
+
val_pred = np.asarray(model.predict(x_val), dtype=np.float64)
|
| 296 |
+
val_metrics = evaluate(y_val, val_pred)
|
| 297 |
+
candidate_rows.append({"model": name, "validation": val_metrics})
|
| 298 |
+
if best_rmse is None or val_metrics["rmse_c"] < best_rmse:
|
| 299 |
+
best_name = name
|
| 300 |
+
best_model = model
|
| 301 |
+
best_rmse = val_metrics["rmse_c"]
|
| 302 |
+
|
| 303 |
+
assert best_model is not None and best_name is not None
|
| 304 |
+
val_pred = np.asarray(best_model.predict(x_val), dtype=np.float64)
|
| 305 |
+
test_pred = np.asarray(best_model.predict(x_test), dtype=np.float64)
|
| 306 |
+
|
| 307 |
+
thresholds = [27.0, 30.0, 33.0]
|
| 308 |
+
val_events = [{"threshold_c": t, **prf(y_val, val_pred, t)} for t in thresholds]
|
| 309 |
+
val_events = sorted(val_events, key=lambda row: (-row["f1"], -row["recall"], -row["precision"], row["threshold_c"]))
|
| 310 |
+
selected_event = val_events[0]
|
| 311 |
+
test_event = {"threshold_c": selected_event["threshold_c"], **prf(y_test, test_pred, selected_event["threshold_c"])}
|
| 312 |
+
|
| 313 |
+
summary = {
|
| 314 |
+
"task_id": "extreme_heat_alphaearth",
|
| 315 |
+
"core_line": "extreme_heat",
|
| 316 |
+
"task_form": "continuous_temperature_forecast_with_secondary_exceedance_view",
|
| 317 |
+
"seed": int(args.seed),
|
| 318 |
+
"pred_roots": [str(path) for path in args.pred_root],
|
| 319 |
+
"merra_root": str(args.merra_root),
|
| 320 |
+
"alphaearth_year_csv": str(args.alphaearth_year_csv),
|
| 321 |
+
"model_family": args.model_family,
|
| 322 |
+
"feature_columns": feature_cols,
|
| 323 |
+
"alphaearth_feature_count": int(sum(c.startswith(args.alphaearth_prefix) for c in feature_cols)),
|
| 324 |
+
"candidate_validation": candidate_rows,
|
| 325 |
+
"selected_model": best_name,
|
| 326 |
+
"validation_metrics": evaluate(y_val, val_pred),
|
| 327 |
+
"test_metrics": evaluate(y_test, test_pred),
|
| 328 |
+
"selected_event_candidate": selected_event,
|
| 329 |
+
"selected_event_candidate_test": test_event,
|
| 330 |
+
"selection_rule": "same heat benchmark; choose regressor by validation RMSE and choose exceedance threshold by validation F1",
|
| 331 |
+
"tmt_policy": {
|
| 332 |
+
"task": "extreme_heat",
|
| 333 |
+
"metric": "continuous RMSE/MAE with thresholded exceedance as a secondary event policy",
|
| 334 |
+
"tolerance": "none for continuous headline; event threshold only for operational view"
|
| 335 |
+
},
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 339 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 340 |
+
print(json.dumps(summary, indent=2))
|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
if __name__ == "__main__":
|
| 344 |
+
main()
|
experiments/raw_reference/task_scripts/run_final_area_taskmodel_seeded.py
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import sys
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from typing import Dict, List, Tuple
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
import os
|
| 12 |
+
|
| 13 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 14 |
+
if _p and _p not in sys.path:
|
| 15 |
+
sys.path.insert(0, _p)
|
| 16 |
+
|
| 17 |
+
import numpy as np
|
| 18 |
+
import pandas as pd
|
| 19 |
+
from catboost import CatBoostRegressor
|
| 20 |
+
from lightgbm import LGBMRegressor
|
| 21 |
+
from sklearn.compose import ColumnTransformer
|
| 22 |
+
from sklearn.impute import SimpleImputer
|
| 23 |
+
from sklearn.linear_model import ElasticNet
|
| 24 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
|
| 25 |
+
from sklearn.pipeline import Pipeline
|
| 26 |
+
from sklearn.preprocessing import OneHotEncoder, StandardScaler
|
| 27 |
+
from xgboost import XGBRegressor
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
DROP_COLUMNS = {
|
| 31 |
+
"Event_ID",
|
| 32 |
+
"Incid_Name",
|
| 33 |
+
"incident_name_norm",
|
| 34 |
+
"wfigs_name",
|
| 35 |
+
"Ig_Date",
|
| 36 |
+
"weather_date",
|
| 37 |
+
"BurnBndAc",
|
| 38 |
+
"target_log_burn_acres",
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
CATEGORICAL_COLUMNS = [
|
| 42 |
+
"Incid_Type",
|
| 43 |
+
"state_abbr",
|
| 44 |
+
"county_name",
|
| 45 |
+
"wfigs_match_type",
|
| 46 |
+
]
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 50 |
+
return float(np.sqrt(mean_squared_error(y_true, y_pred)))
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def mape(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 54 |
+
denom = np.clip(np.asarray(y_true, dtype=np.float64), 1e-6, None)
|
| 55 |
+
frac = np.abs(np.asarray(y_true, dtype=np.float64) - np.asarray(y_pred, dtype=np.float64)) / denom
|
| 56 |
+
return float(np.mean(frac))
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def spearman_corr(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 60 |
+
a = pd.Series(np.asarray(y_true, dtype=np.float64))
|
| 61 |
+
b = pd.Series(np.asarray(y_pred, dtype=np.float64))
|
| 62 |
+
value = a.corr(b, method="spearman")
|
| 63 |
+
return float(value) if pd.notna(value) else 0.0
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def build_splits(df: pd.DataFrame) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
| 67 |
+
ordered = df.sort_values("Ig_Date").reset_index(drop=True)
|
| 68 |
+
n = len(ordered)
|
| 69 |
+
train_end = max(int(round(n * 0.6)), 1)
|
| 70 |
+
val_end = max(int(round(n * 0.8)), train_end + 1)
|
| 71 |
+
val_end = min(val_end, n - 1) if n >= 3 else n
|
| 72 |
+
train = ordered.iloc[:train_end].copy()
|
| 73 |
+
val = ordered.iloc[train_end:val_end].copy()
|
| 74 |
+
test = ordered.iloc[val_end:].copy()
|
| 75 |
+
if len(val) == 0 and len(test) > 1:
|
| 76 |
+
val = test.iloc[:1].copy()
|
| 77 |
+
test = test.iloc[1:].copy()
|
| 78 |
+
return train, val, test
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def feature_columns(df: pd.DataFrame, feature_profile: str = "all") -> Tuple[List[str], List[str]]:
|
| 82 |
+
categorical = [c for c in CATEGORICAL_COLUMNS if c in df.columns]
|
| 83 |
+
numeric = []
|
| 84 |
+
for col in df.columns:
|
| 85 |
+
if col in DROP_COLUMNS or col in categorical:
|
| 86 |
+
continue
|
| 87 |
+
if pd.api.types.is_numeric_dtype(df[col]):
|
| 88 |
+
numeric.append(col)
|
| 89 |
+
if feature_profile == "weather_fm":
|
| 90 |
+
numeric = [c for c in numeric if c.startswith("weather_")]
|
| 91 |
+
categorical = []
|
| 92 |
+
return numeric, categorical
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def make_sparse_preprocessor(numeric_cols: List[str], categorical_cols: List[str]) -> ColumnTransformer:
|
| 96 |
+
return ColumnTransformer(
|
| 97 |
+
transformers=[
|
| 98 |
+
(
|
| 99 |
+
"num",
|
| 100 |
+
Pipeline(
|
| 101 |
+
steps=[
|
| 102 |
+
("impute", SimpleImputer(strategy="median")),
|
| 103 |
+
("scale", StandardScaler()),
|
| 104 |
+
]
|
| 105 |
+
),
|
| 106 |
+
numeric_cols,
|
| 107 |
+
),
|
| 108 |
+
(
|
| 109 |
+
"cat",
|
| 110 |
+
Pipeline(
|
| 111 |
+
steps=[
|
| 112 |
+
("impute", SimpleImputer(strategy="most_frequent")),
|
| 113 |
+
("onehot", OneHotEncoder(handle_unknown="ignore")),
|
| 114 |
+
]
|
| 115 |
+
),
|
| 116 |
+
categorical_cols,
|
| 117 |
+
),
|
| 118 |
+
],
|
| 119 |
+
remainder="drop",
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def prepare_catboost_frames(
|
| 124 |
+
train_df: pd.DataFrame,
|
| 125 |
+
val_df: pd.DataFrame,
|
| 126 |
+
test_df: pd.DataFrame,
|
| 127 |
+
numeric_cols: List[str],
|
| 128 |
+
categorical_cols: List[str],
|
| 129 |
+
) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
| 130 |
+
medians = {c: float(train_df[c].median()) for c in numeric_cols}
|
| 131 |
+
modes = {
|
| 132 |
+
c: str(train_df[c].mode(dropna=True).iloc[0]) if not train_df[c].mode(dropna=True).empty else "missing"
|
| 133 |
+
for c in categorical_cols
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
def _prep(frame: pd.DataFrame) -> pd.DataFrame:
|
| 137 |
+
out = frame[numeric_cols + categorical_cols].copy()
|
| 138 |
+
for col in numeric_cols:
|
| 139 |
+
out[col] = pd.to_numeric(out[col], errors="coerce").fillna(medians[col])
|
| 140 |
+
for col in categorical_cols:
|
| 141 |
+
out[col] = out[col].astype("string").fillna(modes[col]).astype(str)
|
| 142 |
+
return out
|
| 143 |
+
|
| 144 |
+
return _prep(train_df), _prep(val_df), _prep(test_df)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def evaluate_split(frame: pd.DataFrame, pred_log: np.ndarray) -> Dict[str, float]:
|
| 148 |
+
true_log = frame["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 149 |
+
true_acres = frame["BurnBndAc"].to_numpy(dtype=np.float64)
|
| 150 |
+
pred_log = np.asarray(pred_log, dtype=np.float64)
|
| 151 |
+
pred_acres = np.exp(pred_log)
|
| 152 |
+
return {
|
| 153 |
+
"count": int(len(frame)),
|
| 154 |
+
"log_mae": float(mean_absolute_error(true_log, pred_log)),
|
| 155 |
+
"log_rmse": rmse(true_log, pred_log),
|
| 156 |
+
"log_r2": float(r2_score(true_log, pred_log)) if len(frame) > 1 else 0.0,
|
| 157 |
+
"log_spearman": spearman_corr(true_log, pred_log),
|
| 158 |
+
"log_median_ae": float(np.median(np.abs(true_log - pred_log))),
|
| 159 |
+
"acres_mae": float(mean_absolute_error(true_acres, pred_acres)),
|
| 160 |
+
"acres_rmse": rmse(true_acres, pred_acres),
|
| 161 |
+
"acres_median_ae": float(np.median(np.abs(true_acres - pred_acres))),
|
| 162 |
+
"acres_mape": mape(true_acres, pred_acres),
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def main() -> None:
|
| 167 |
+
parser = argparse.ArgumentParser()
|
| 168 |
+
parser.add_argument("--event-table", type=Path, required=True)
|
| 169 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 170 |
+
parser.add_argument("--feature-profile", choices=("all", "weather_fm"), default="all")
|
| 171 |
+
parser.add_argument("--model-family", choices=("full", "lite"), default="full")
|
| 172 |
+
parser.add_argument("--fm-family", type=str, default="")
|
| 173 |
+
parser.add_argument("--seed", type=int, default=7)
|
| 174 |
+
args = parser.parse_args()
|
| 175 |
+
|
| 176 |
+
df = pd.read_csv(args.event_table)
|
| 177 |
+
df["Ig_Date"] = pd.to_datetime(df["Ig_Date"])
|
| 178 |
+
train_df, val_df, test_df = build_splits(df)
|
| 179 |
+
numeric_cols, categorical_cols = feature_columns(df, feature_profile=args.feature_profile)
|
| 180 |
+
if not numeric_cols and not categorical_cols:
|
| 181 |
+
raise SystemExit(f"No usable features found for profile={args.feature_profile}")
|
| 182 |
+
x_cols = numeric_cols + categorical_cols
|
| 183 |
+
|
| 184 |
+
pre = make_sparse_preprocessor(numeric_cols, categorical_cols)
|
| 185 |
+
x_train = pre.fit_transform(train_df[x_cols])
|
| 186 |
+
x_val = pre.transform(val_df[x_cols])
|
| 187 |
+
x_test = pre.transform(test_df[x_cols])
|
| 188 |
+
y_train = train_df["target_log_burn_acres"].to_numpy(dtype=np.float64)
|
| 189 |
+
|
| 190 |
+
cat_train, cat_val, cat_test = prepare_catboost_frames(train_df, val_df, test_df, numeric_cols, categorical_cols)
|
| 191 |
+
cat_feature_idx = list(range(len(numeric_cols), len(numeric_cols) + len(categorical_cols)))
|
| 192 |
+
|
| 193 |
+
candidates: List[Tuple[str, object, str]] = [
|
| 194 |
+
(
|
| 195 |
+
"enet",
|
| 196 |
+
ElasticNet(alpha=0.01, l1_ratio=0.2, random_state=args.seed, max_iter=10000),
|
| 197 |
+
"sparse",
|
| 198 |
+
),
|
| 199 |
+
]
|
| 200 |
+
if args.model_family == "full":
|
| 201 |
+
candidates.extend(
|
| 202 |
+
[
|
| 203 |
+
(
|
| 204 |
+
"xgboost",
|
| 205 |
+
XGBRegressor(
|
| 206 |
+
n_estimators=400,
|
| 207 |
+
max_depth=6,
|
| 208 |
+
learning_rate=0.05,
|
| 209 |
+
subsample=0.8,
|
| 210 |
+
colsample_bytree=0.8,
|
| 211 |
+
reg_lambda=1.0,
|
| 212 |
+
objective="reg:squarederror",
|
| 213 |
+
tree_method="hist",
|
| 214 |
+
random_state=args.seed,
|
| 215 |
+
n_jobs=8,
|
| 216 |
+
),
|
| 217 |
+
"sparse",
|
| 218 |
+
),
|
| 219 |
+
(
|
| 220 |
+
"lightgbm",
|
| 221 |
+
LGBMRegressor(
|
| 222 |
+
n_estimators=400,
|
| 223 |
+
learning_rate=0.05,
|
| 224 |
+
num_leaves=63,
|
| 225 |
+
subsample=0.8,
|
| 226 |
+
colsample_bytree=0.8,
|
| 227 |
+
reg_lambda=1.0,
|
| 228 |
+
random_state=args.seed,
|
| 229 |
+
n_jobs=8,
|
| 230 |
+
verbose=-1,
|
| 231 |
+
),
|
| 232 |
+
"sparse",
|
| 233 |
+
),
|
| 234 |
+
(
|
| 235 |
+
"catboost",
|
| 236 |
+
CatBoostRegressor(
|
| 237 |
+
iterations=500,
|
| 238 |
+
depth=8,
|
| 239 |
+
learning_rate=0.05,
|
| 240 |
+
loss_function="RMSE",
|
| 241 |
+
eval_metric="RMSE",
|
| 242 |
+
random_seed=args.seed,
|
| 243 |
+
verbose=False,
|
| 244 |
+
),
|
| 245 |
+
"cat",
|
| 246 |
+
),
|
| 247 |
+
]
|
| 248 |
+
)
|
| 249 |
+
|
| 250 |
+
candidate_validation: List[Dict[str, object]] = []
|
| 251 |
+
best_name = None
|
| 252 |
+
best_kind = None
|
| 253 |
+
best_model = None
|
| 254 |
+
best_score = None
|
| 255 |
+
|
| 256 |
+
for name, model, kind in candidates:
|
| 257 |
+
if kind == "sparse":
|
| 258 |
+
model.fit(x_train, y_train)
|
| 259 |
+
val_pred = model.predict(x_val)
|
| 260 |
+
else:
|
| 261 |
+
model.fit(cat_train, y_train, cat_features=cat_feature_idx, eval_set=(cat_val, val_df["target_log_burn_acres"]), use_best_model=False)
|
| 262 |
+
val_pred = model.predict(cat_val)
|
| 263 |
+
val_metrics = evaluate_split(val_df, val_pred)
|
| 264 |
+
candidate_validation.append({"model_name": name, "val_metrics": val_metrics})
|
| 265 |
+
score = float(val_metrics["log_mae"])
|
| 266 |
+
if best_score is None or score < best_score:
|
| 267 |
+
best_score = score
|
| 268 |
+
best_name = name
|
| 269 |
+
best_kind = kind
|
| 270 |
+
best_model = model
|
| 271 |
+
|
| 272 |
+
assert best_model is not None and best_name is not None and best_kind is not None
|
| 273 |
+
|
| 274 |
+
combined_train = pd.concat([train_df, val_df], ignore_index=True)
|
| 275 |
+
if best_kind == "sparse":
|
| 276 |
+
x_combined = pre.fit_transform(combined_train[x_cols])
|
| 277 |
+
x_train_final = pre.transform(train_df[x_cols])
|
| 278 |
+
x_val_final = pre.transform(val_df[x_cols])
|
| 279 |
+
x_test_final = pre.transform(test_df[x_cols])
|
| 280 |
+
best_model.fit(x_combined, combined_train["target_log_burn_acres"].to_numpy(dtype=np.float64))
|
| 281 |
+
train_pred = best_model.predict(x_train_final)
|
| 282 |
+
val_pred = best_model.predict(x_val_final)
|
| 283 |
+
test_pred = best_model.predict(x_test_final)
|
| 284 |
+
else:
|
| 285 |
+
cat_combined, cat_train_final, cat_test_final = prepare_catboost_frames(
|
| 286 |
+
combined_train, train_df, test_df, numeric_cols, categorical_cols
|
| 287 |
+
)
|
| 288 |
+
cat_val_final = prepare_catboost_frames(val_df, val_df, val_df, numeric_cols, categorical_cols)[0]
|
| 289 |
+
best_model.fit(
|
| 290 |
+
cat_combined,
|
| 291 |
+
combined_train["target_log_burn_acres"].to_numpy(dtype=np.float64),
|
| 292 |
+
cat_features=cat_feature_idx,
|
| 293 |
+
use_best_model=False,
|
| 294 |
+
)
|
| 295 |
+
train_pred = best_model.predict(cat_train_final)
|
| 296 |
+
val_pred = best_model.predict(cat_val_final)
|
| 297 |
+
test_pred = best_model.predict(cat_test_final)
|
| 298 |
+
|
| 299 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 300 |
+
pred_df = pd.concat(
|
| 301 |
+
[
|
| 302 |
+
train_df.assign(split="train", pred_log_burn_acres=train_pred, pred_burn_acres=np.exp(train_pred)),
|
| 303 |
+
val_df.assign(split="val", pred_log_burn_acres=val_pred, pred_burn_acres=np.exp(val_pred)),
|
| 304 |
+
test_df.assign(split="test", pred_log_burn_acres=test_pred, pred_burn_acres=np.exp(test_pred)),
|
| 305 |
+
],
|
| 306 |
+
axis=0,
|
| 307 |
+
ignore_index=True,
|
| 308 |
+
)
|
| 309 |
+
pred_path = args.output_dir / "predictions.csv"
|
| 310 |
+
pred_df.to_csv(pred_path, index=False)
|
| 311 |
+
|
| 312 |
+
summary = {
|
| 313 |
+
"task_id": "wildfire_final_area_scalar_taskmodels",
|
| 314 |
+
"task_form": "event_level_regression",
|
| 315 |
+
"event_table": str(args.event_table),
|
| 316 |
+
"output_dir": str(args.output_dir),
|
| 317 |
+
"feature_profile": args.feature_profile,
|
| 318 |
+
"seed": int(args.seed),
|
| 319 |
+
"benchmark_protocol": "fm_lite_protocol" if args.feature_profile == "weather_fm" and args.model_family == "lite" else "standard_protocol",
|
| 320 |
+
"split_sizes": {
|
| 321 |
+
"train": int(len(train_df)),
|
| 322 |
+
"val": int(len(val_df)),
|
| 323 |
+
"test": int(len(test_df)),
|
| 324 |
+
},
|
| 325 |
+
"feature_columns": {
|
| 326 |
+
"numeric": numeric_cols,
|
| 327 |
+
"categorical": categorical_cols,
|
| 328 |
+
},
|
| 329 |
+
"candidate_validation": candidate_validation,
|
| 330 |
+
"selected_model": best_name,
|
| 331 |
+
"train_metrics": evaluate_split(train_df, train_pred),
|
| 332 |
+
"val_metrics": evaluate_split(val_df, val_pred),
|
| 333 |
+
"test_metrics": evaluate_split(test_df, test_pred),
|
| 334 |
+
"headline_metrics": {
|
| 335 |
+
"log_mae": float(evaluate_split(test_df, test_pred)["log_mae"]),
|
| 336 |
+
"log_rmse": float(evaluate_split(test_df, test_pred)["log_rmse"]),
|
| 337 |
+
"log_spearman": float(evaluate_split(test_df, test_pred)["log_spearman"]),
|
| 338 |
+
},
|
| 339 |
+
"predictions_path": str(pred_path),
|
| 340 |
+
"model_family": "lightweight_linear_task_heads" if args.model_family == "lite" else "popular_open_source_task_models",
|
| 341 |
+
"fm_family": (args.fm_family or "weather_fm_derived_features") if args.feature_profile == "weather_fm" else None,
|
| 342 |
+
"tmt_policy": {
|
| 343 |
+
"task": "final_burned_area",
|
| 344 |
+
"metric": "log-area regression error with rank agreement",
|
| 345 |
+
"tolerance": "secondary magnitude-band interpretation only",
|
| 346 |
+
},
|
| 347 |
+
}
|
| 348 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 349 |
+
print(json.dumps(summary, indent=2))
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
if __name__ == "__main__":
|
| 353 |
+
main()
|
experiments/raw_reference/task_scripts/run_smoke_pm25_alphaearth_suite_seeded.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import math
|
| 7 |
+
import sys
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
from typing import Dict, List, Tuple
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 15 |
+
if _p and _p not in sys.path:
|
| 16 |
+
sys.path.insert(0, _p)
|
| 17 |
+
|
| 18 |
+
import numpy as np
|
| 19 |
+
import pandas as pd
|
| 20 |
+
from catboost import CatBoostRegressor
|
| 21 |
+
from lightgbm import LGBMRegressor
|
| 22 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
| 23 |
+
from xgboost import XGBRegressor
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def parse_args() -> argparse.Namespace:
|
| 27 |
+
parser = argparse.ArgumentParser()
|
| 28 |
+
parser.add_argument("--aqs-daily", type=Path, required=True)
|
| 29 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 30 |
+
parser.add_argument("--exceedance-threshold", type=float, default=35.0)
|
| 31 |
+
parser.add_argument("--alphaearth-prefix", type=str, default="alphaearth_")
|
| 32 |
+
parser.add_argument("--seed", type=int, default=7)
|
| 33 |
+
return parser.parse_args()
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def assign_split(ts: pd.Timestamp) -> str:
|
| 37 |
+
year = int(ts.year)
|
| 38 |
+
if year <= 2023:
|
| 39 |
+
return "train"
|
| 40 |
+
if year == 2024:
|
| 41 |
+
return "val"
|
| 42 |
+
if year == 2025:
|
| 43 |
+
return "test"
|
| 44 |
+
return "other"
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 48 |
+
return float(math.sqrt(mean_squared_error(y_true, y_pred)))
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def pearson_corr(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 52 |
+
a = np.asarray(y_true, dtype=np.float64)
|
| 53 |
+
b = np.asarray(y_pred, dtype=np.float64)
|
| 54 |
+
if a.size < 2 or np.allclose(a, a[0]) or np.allclose(b, b[0]):
|
| 55 |
+
return 0.0
|
| 56 |
+
value = float(np.corrcoef(a, b)[0, 1])
|
| 57 |
+
return value if np.isfinite(value) else 0.0
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def prf(y_true: np.ndarray, y_pred: np.ndarray, threshold: float) -> Dict[str, float]:
|
| 61 |
+
truth = np.asarray(y_true >= threshold)
|
| 62 |
+
pred = np.asarray(y_pred >= threshold)
|
| 63 |
+
tp = int(np.logical_and(pred, truth).sum())
|
| 64 |
+
fp = int(np.logical_and(pred, ~truth).sum())
|
| 65 |
+
fn = int(np.logical_and(~pred, truth).sum())
|
| 66 |
+
precision = float(tp / (tp + fp)) if (tp + fp) else 0.0
|
| 67 |
+
recall = float(tp / (tp + fn)) if (tp + fn) else 0.0
|
| 68 |
+
f1 = float((2.0 * precision * recall) / (precision + recall)) if (precision + recall) else 0.0
|
| 69 |
+
return {"precision": precision, "recall": recall, "f1": f1}
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def evaluate_frame(frame: pd.DataFrame, pred_col: str, threshold: float) -> Dict[str, float]:
|
| 73 |
+
y_true = frame["pm25_mean"].to_numpy(dtype=np.float64)
|
| 74 |
+
y_pred = frame[pred_col].to_numpy(dtype=np.float64)
|
| 75 |
+
event = prf(y_true, y_pred, threshold)
|
| 76 |
+
bias = np.asarray(y_pred - y_true, dtype=np.float64)
|
| 77 |
+
denom = float(np.sum(y_true))
|
| 78 |
+
return {
|
| 79 |
+
"count": int(len(frame)),
|
| 80 |
+
"rmse": rmse(y_true, y_pred),
|
| 81 |
+
"mae": float(mean_absolute_error(y_true, y_pred)),
|
| 82 |
+
"mean_bias": float(np.mean(bias)),
|
| 83 |
+
"normalized_mean_bias": float(np.sum(bias) / denom) if abs(denom) > 1e-12 else 0.0,
|
| 84 |
+
"pearson_r": pearson_corr(y_true, y_pred),
|
| 85 |
+
"event_precision": event["precision"],
|
| 86 |
+
"event_recall": event["recall"],
|
| 87 |
+
"event_f1": event["f1"],
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def tune_event_shift(val_frame: pd.DataFrame, pred_col: str, threshold: float) -> Dict[str, float]:
|
| 92 |
+
best = None
|
| 93 |
+
for delta in np.linspace(-5.0, 15.0, 161):
|
| 94 |
+
shifted = val_frame.copy()
|
| 95 |
+
shifted["_shifted_pred"] = shifted[pred_col] + float(delta)
|
| 96 |
+
metrics = evaluate_frame(shifted, "_shifted_pred", threshold)
|
| 97 |
+
score = (metrics["event_f1"], metrics["event_recall"], -abs(float(delta)))
|
| 98 |
+
if best is None or score > best["score"]:
|
| 99 |
+
best = {"delta": float(delta), "metrics": metrics, "score": score}
|
| 100 |
+
assert best is not None
|
| 101 |
+
return {"delta": best["delta"], "val_event_calibrated_metrics": best["metrics"]}
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def build_features(df: pd.DataFrame) -> pd.DataFrame:
|
| 105 |
+
df = df.sort_values(["site_key", "date"]).reset_index(drop=True).copy()
|
| 106 |
+
df["doy"] = df["date"].dt.dayofyear.astype(np.int32)
|
| 107 |
+
df["month"] = df["date"].dt.month.astype(np.int32)
|
| 108 |
+
df["doy_sin"] = np.sin(2.0 * np.pi * df["doy"] / 366.0)
|
| 109 |
+
df["doy_cos"] = np.cos(2.0 * np.pi * df["doy"] / 366.0)
|
| 110 |
+
grp = df.groupby("site_key", sort=False)
|
| 111 |
+
for lag in [1, 2, 3, 7]:
|
| 112 |
+
df[f"lag{lag}_pm25"] = grp["pm25_mean"].shift(lag)
|
| 113 |
+
df["roll3_prev"] = grp["pm25_mean"].rolling(3, min_periods=1).mean().reset_index(level=0, drop=True).shift(1)
|
| 114 |
+
df["roll7_prev"] = grp["pm25_mean"].rolling(7, min_periods=1).mean().reset_index(level=0, drop=True).shift(1)
|
| 115 |
+
return df
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def prepare_frames(df: pd.DataFrame, alphaearth_prefix: str) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame, List[str]]:
|
| 119 |
+
df = build_features(df)
|
| 120 |
+
train = df[df["split"] == "train"].copy()
|
| 121 |
+
val = df[df["split"] == "val"].copy()
|
| 122 |
+
test = df[df["split"] == "test"].copy()
|
| 123 |
+
|
| 124 |
+
site_mean = train.groupby("site_key")["pm25_mean"].mean()
|
| 125 |
+
global_mean = float(train["pm25_mean"].mean())
|
| 126 |
+
for frame in [train, val, test]:
|
| 127 |
+
frame["site_climo"] = frame["site_key"].map(site_mean).fillna(global_mean)
|
| 128 |
+
for frame in [train, val, test]:
|
| 129 |
+
for col in ["lag1_pm25", "lag2_pm25", "lag3_pm25", "lag7_pm25", "roll3_prev", "roll7_prev"]:
|
| 130 |
+
frame[col] = pd.to_numeric(frame[col], errors="coerce").fillna(frame["site_climo"])
|
| 131 |
+
|
| 132 |
+
feature_cols = [
|
| 133 |
+
"latitude",
|
| 134 |
+
"longitude",
|
| 135 |
+
"obs_count",
|
| 136 |
+
"site_climo",
|
| 137 |
+
"lag1_pm25",
|
| 138 |
+
"lag2_pm25",
|
| 139 |
+
"lag3_pm25",
|
| 140 |
+
"lag7_pm25",
|
| 141 |
+
"roll3_prev",
|
| 142 |
+
"roll7_prev",
|
| 143 |
+
"doy_sin",
|
| 144 |
+
"doy_cos",
|
| 145 |
+
"month",
|
| 146 |
+
]
|
| 147 |
+
alpha_cols = [
|
| 148 |
+
c for c in df.columns
|
| 149 |
+
if c.startswith(alphaearth_prefix) and pd.api.types.is_numeric_dtype(df[c])
|
| 150 |
+
]
|
| 151 |
+
feature_cols.extend(sorted(alpha_cols))
|
| 152 |
+
medians = train[feature_cols].median(numeric_only=True).fillna(0.0)
|
| 153 |
+
for frame in [train, val, test]:
|
| 154 |
+
frame.loc[:, feature_cols] = frame[feature_cols].fillna(medians)
|
| 155 |
+
frame.loc[:, feature_cols] = frame[feature_cols].fillna(0.0)
|
| 156 |
+
return train, val, test, feature_cols
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def main() -> None:
|
| 160 |
+
args = parse_args()
|
| 161 |
+
df = pd.read_csv(args.aqs_daily, compression="infer", low_memory=False)
|
| 162 |
+
df["date"] = pd.to_datetime(df["date_gmt"], errors="coerce")
|
| 163 |
+
df["pm25_mean"] = pd.to_numeric(df["pm25_mean"], errors="coerce")
|
| 164 |
+
df["pm25_max"] = pd.to_numeric(df["pm25_max"], errors="coerce")
|
| 165 |
+
df["obs_count"] = pd.to_numeric(df["obs_count"], errors="coerce")
|
| 166 |
+
df = df.dropna(subset=["date", "site_key", "pm25_mean"]).copy()
|
| 167 |
+
df = (
|
| 168 |
+
df.groupby(["date", "site_key"], as_index=False)
|
| 169 |
+
.agg(
|
| 170 |
+
latitude=("Latitude", "first"),
|
| 171 |
+
longitude=("Longitude", "first"),
|
| 172 |
+
pm25_mean=("pm25_mean", "mean"),
|
| 173 |
+
pm25_max=("pm25_max", "max"),
|
| 174 |
+
obs_count=("obs_count", "sum"),
|
| 175 |
+
**{c: (c, "first") for c in df.columns if c.startswith(args.alphaearth_prefix)},
|
| 176 |
+
)
|
| 177 |
+
.sort_values(["site_key", "date"])
|
| 178 |
+
.reset_index(drop=True)
|
| 179 |
+
)
|
| 180 |
+
df["split"] = df["date"].map(assign_split)
|
| 181 |
+
df = df[df["split"].isin(["train", "val", "test"])].copy()
|
| 182 |
+
|
| 183 |
+
train, val, test, feature_cols = prepare_frames(df, alphaearth_prefix=args.alphaearth_prefix)
|
| 184 |
+
y_train = train["pm25_mean"].to_numpy(dtype=np.float64)
|
| 185 |
+
|
| 186 |
+
candidates = {
|
| 187 |
+
"xgboost": XGBRegressor(
|
| 188 |
+
n_estimators=300,
|
| 189 |
+
max_depth=8,
|
| 190 |
+
learning_rate=0.05,
|
| 191 |
+
subsample=0.8,
|
| 192 |
+
colsample_bytree=0.8,
|
| 193 |
+
objective="reg:squarederror",
|
| 194 |
+
tree_method="hist",
|
| 195 |
+
random_state=args.seed,
|
| 196 |
+
n_jobs=8,
|
| 197 |
+
),
|
| 198 |
+
"lightgbm": LGBMRegressor(
|
| 199 |
+
n_estimators=300,
|
| 200 |
+
learning_rate=0.05,
|
| 201 |
+
num_leaves=127,
|
| 202 |
+
subsample=0.8,
|
| 203 |
+
colsample_bytree=0.8,
|
| 204 |
+
random_state=args.seed,
|
| 205 |
+
n_jobs=8,
|
| 206 |
+
verbose=-1,
|
| 207 |
+
),
|
| 208 |
+
"catboost": CatBoostRegressor(
|
| 209 |
+
iterations=400,
|
| 210 |
+
depth=8,
|
| 211 |
+
learning_rate=0.05,
|
| 212 |
+
loss_function="RMSE",
|
| 213 |
+
eval_metric="RMSE",
|
| 214 |
+
random_seed=args.seed,
|
| 215 |
+
verbose=False,
|
| 216 |
+
),
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
candidate_validation: List[Dict[str, object]] = []
|
| 220 |
+
best_name = None
|
| 221 |
+
best_model = None
|
| 222 |
+
best_score = None
|
| 223 |
+
for name, model in candidates.items():
|
| 224 |
+
if name == "catboost":
|
| 225 |
+
model.fit(train[feature_cols], y_train, use_best_model=False)
|
| 226 |
+
val_pred = model.predict(val[feature_cols])
|
| 227 |
+
else:
|
| 228 |
+
model.fit(train[feature_cols].to_numpy(dtype=np.float32), y_train)
|
| 229 |
+
val_pred = model.predict(val[feature_cols].to_numpy(dtype=np.float32))
|
| 230 |
+
val_frame = val.copy()
|
| 231 |
+
val_frame["pred"] = val_pred
|
| 232 |
+
metrics = evaluate_frame(val_frame, "pred", args.exceedance_threshold)
|
| 233 |
+
candidate_validation.append({"candidate": name, "val_metrics": metrics})
|
| 234 |
+
score = float(metrics["rmse"])
|
| 235 |
+
if best_score is None or score < best_score:
|
| 236 |
+
best_score = score
|
| 237 |
+
best_name = name
|
| 238 |
+
best_model = model
|
| 239 |
+
|
| 240 |
+
assert best_name is not None and best_model is not None
|
| 241 |
+
combined = pd.concat([train, val], ignore_index=True)
|
| 242 |
+
if best_name == "catboost":
|
| 243 |
+
best_model.fit(combined[feature_cols], combined["pm25_mean"].to_numpy(dtype=np.float64), use_best_model=False)
|
| 244 |
+
train_pred = best_model.predict(train[feature_cols])
|
| 245 |
+
val_pred = best_model.predict(val[feature_cols])
|
| 246 |
+
test_pred = best_model.predict(test[feature_cols])
|
| 247 |
+
else:
|
| 248 |
+
best_model.fit(combined[feature_cols].to_numpy(dtype=np.float32), combined["pm25_mean"].to_numpy(dtype=np.float64))
|
| 249 |
+
train_pred = best_model.predict(train[feature_cols].to_numpy(dtype=np.float32))
|
| 250 |
+
val_pred = best_model.predict(val[feature_cols].to_numpy(dtype=np.float32))
|
| 251 |
+
test_pred = best_model.predict(test[feature_cols].to_numpy(dtype=np.float32))
|
| 252 |
+
|
| 253 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 254 |
+
pred_df = pd.concat(
|
| 255 |
+
[
|
| 256 |
+
train.assign(pred_pm25=train_pred),
|
| 257 |
+
val.assign(pred_pm25=val_pred),
|
| 258 |
+
test.assign(pred_pm25=test_pred),
|
| 259 |
+
],
|
| 260 |
+
ignore_index=True,
|
| 261 |
+
)
|
| 262 |
+
pred_path = args.output_dir / "predictions.csv.gz"
|
| 263 |
+
pred_df.to_csv(pred_path, index=False, compression="gzip")
|
| 264 |
+
|
| 265 |
+
train_eval = train.assign(pred=train_pred)
|
| 266 |
+
val_eval = val.assign(pred=val_pred)
|
| 267 |
+
test_eval = test.assign(pred=test_pred)
|
| 268 |
+
event_shift = tune_event_shift(val_eval, "pred", args.exceedance_threshold)
|
| 269 |
+
delta = event_shift["delta"]
|
| 270 |
+
train_event_eval = train_eval.assign(pred_event_calibrated=train_eval["pred"] + delta)
|
| 271 |
+
val_event_eval = val_eval.assign(pred_event_calibrated=val_eval["pred"] + delta)
|
| 272 |
+
test_event_eval = test_eval.assign(pred_event_calibrated=test_eval["pred"] + delta)
|
| 273 |
+
|
| 274 |
+
summary = {
|
| 275 |
+
"task_id": "smoke_pm25_alphaearth",
|
| 276 |
+
"task_form": "station_daily_regression",
|
| 277 |
+
"aqs_daily": str(args.aqs_daily),
|
| 278 |
+
"output_dir": str(args.output_dir),
|
| 279 |
+
"seed": int(args.seed),
|
| 280 |
+
"feature_columns": feature_cols,
|
| 281 |
+
"alphaearth_feature_count": int(sum(c.startswith(args.alphaearth_prefix) for c in feature_cols)),
|
| 282 |
+
"split_sizes": {"train": int(len(train)), "val": int(len(val)), "test": int(len(test))},
|
| 283 |
+
"candidate_validation": candidate_validation,
|
| 284 |
+
"selected_model": best_name,
|
| 285 |
+
"train_metrics": evaluate_frame(train_eval, "pred", args.exceedance_threshold),
|
| 286 |
+
"val_metrics": evaluate_frame(val_eval, "pred", args.exceedance_threshold),
|
| 287 |
+
"test_metrics": evaluate_frame(test_eval, "pred", args.exceedance_threshold),
|
| 288 |
+
"event_calibration": {
|
| 289 |
+
"delta": float(delta),
|
| 290 |
+
"val_metrics": event_shift["val_event_calibrated_metrics"],
|
| 291 |
+
"test_metrics": evaluate_frame(test_event_eval, "pred_event_calibrated", args.exceedance_threshold),
|
| 292 |
+
},
|
| 293 |
+
"predictions_path": str(pred_path),
|
| 294 |
+
"selection_rule": "same smoke benchmark; choose task-specific regressor by validation RMSE, then calibrate exceedance on validation only",
|
| 295 |
+
"tmt_policy": {
|
| 296 |
+
"task": "smoke_pm25",
|
| 297 |
+
"metric": "continuous RMSE/MAE with thresholded exceedance PRF",
|
| 298 |
+
"tolerance": "secondary event policy only",
|
| 299 |
+
},
|
| 300 |
+
}
|
| 301 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 302 |
+
print(json.dumps(summary, indent=2))
|
| 303 |
+
|
| 304 |
+
|
| 305 |
+
if __name__ == "__main__":
|
| 306 |
+
main()
|
experiments/raw_reference/task_scripts/run_smoke_pm25_attached_fm_suite_seeded.py
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import math
|
| 7 |
+
import sys
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
from typing import Dict, List
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
for _p in os.environ.get("WILDFIRE_FM_EXTRA_PYTHONPATH", "").split(os.pathsep):
|
| 15 |
+
if _p and _p not in sys.path:
|
| 16 |
+
sys.path.insert(0, _p)
|
| 17 |
+
|
| 18 |
+
import numpy as np
|
| 19 |
+
import pandas as pd
|
| 20 |
+
from catboost import CatBoostRegressor
|
| 21 |
+
from lightgbm import LGBMRegressor
|
| 22 |
+
from sklearn.linear_model import ElasticNet, Ridge
|
| 23 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
| 24 |
+
from xgboost import XGBRegressor
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def parse_args() -> argparse.Namespace:
|
| 28 |
+
parser = argparse.ArgumentParser()
|
| 29 |
+
parser.add_argument("--attached-csv", type=Path, required=True)
|
| 30 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 31 |
+
parser.add_argument("--fm-prefix", type=str, required=True)
|
| 32 |
+
parser.add_argument("--fm-family", type=str, required=True)
|
| 33 |
+
parser.add_argument("--model-family", choices=("full", "lite"), default="lite")
|
| 34 |
+
parser.add_argument("--exceedance-threshold", type=float, default=35.0)
|
| 35 |
+
parser.add_argument("--seed", type=int, default=7)
|
| 36 |
+
return parser.parse_args()
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 40 |
+
return float(math.sqrt(mean_squared_error(y_true, y_pred)))
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def pearson_corr(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
| 44 |
+
a = np.asarray(y_true, dtype=np.float64)
|
| 45 |
+
b = np.asarray(y_pred, dtype=np.float64)
|
| 46 |
+
if a.size < 2 or np.allclose(a, a[0]) or np.allclose(b, b[0]):
|
| 47 |
+
return 0.0
|
| 48 |
+
value = float(np.corrcoef(a, b)[0, 1])
|
| 49 |
+
return value if np.isfinite(value) else 0.0
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def prf(y_true: np.ndarray, y_pred: np.ndarray, threshold: float) -> Dict[str, float]:
|
| 53 |
+
truth = np.asarray(y_true >= threshold)
|
| 54 |
+
pred = np.asarray(y_pred >= threshold)
|
| 55 |
+
tp = int(np.logical_and(pred, truth).sum())
|
| 56 |
+
fp = int(np.logical_and(pred, ~truth).sum())
|
| 57 |
+
fn = int(np.logical_and(~pred, truth).sum())
|
| 58 |
+
precision = float(tp / (tp + fp)) if (tp + fp) else 0.0
|
| 59 |
+
recall = float(tp / (tp + fn)) if (tp + fn) else 0.0
|
| 60 |
+
f1 = float((2.0 * precision * recall) / (precision + recall)) if (precision + recall) else 0.0
|
| 61 |
+
return {"precision": precision, "recall": recall, "f1": f1}
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def evaluate_frame(frame: pd.DataFrame, pred_col: str, threshold: float) -> Dict[str, float]:
|
| 65 |
+
y_true = frame["pm25_mean"].to_numpy(dtype=np.float64)
|
| 66 |
+
y_pred = frame[pred_col].to_numpy(dtype=np.float64)
|
| 67 |
+
event = prf(y_true, y_pred, threshold)
|
| 68 |
+
bias = np.asarray(y_pred - y_true, dtype=np.float64)
|
| 69 |
+
denom = float(np.sum(y_true))
|
| 70 |
+
return {
|
| 71 |
+
"count": int(len(frame)),
|
| 72 |
+
"rmse": rmse(y_true, y_pred),
|
| 73 |
+
"mae": float(mean_absolute_error(y_true, y_pred)),
|
| 74 |
+
"mean_bias": float(np.mean(bias)),
|
| 75 |
+
"normalized_mean_bias": float(np.sum(bias) / denom) if abs(denom) > 1e-12 else 0.0,
|
| 76 |
+
"pearson_r": pearson_corr(y_true, y_pred),
|
| 77 |
+
"event_precision": event["precision"],
|
| 78 |
+
"event_recall": event["recall"],
|
| 79 |
+
"event_f1": event["f1"],
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def main() -> None:
|
| 84 |
+
args = parse_args()
|
| 85 |
+
df = pd.read_csv(args.attached_csv)
|
| 86 |
+
df["date"] = pd.to_datetime(df["date_gmt"], errors="coerce")
|
| 87 |
+
df["pm25_mean"] = pd.to_numeric(df["pm25_mean"], errors="coerce")
|
| 88 |
+
df = df.dropna(subset=["date", "pm25_mean"]).copy()
|
| 89 |
+
|
| 90 |
+
feature_cols = [c for c in df.columns if c.startswith(args.fm_prefix)]
|
| 91 |
+
feature_cols = [c for c in feature_cols if pd.api.types.is_numeric_dtype(df[c])]
|
| 92 |
+
if not feature_cols:
|
| 93 |
+
raise SystemExit(f"No numeric FM feature columns found with prefix {args.fm_prefix}")
|
| 94 |
+
|
| 95 |
+
split_map = {"2020": "train", "2021": "train", "2022": "train", "2024": "val", "2025": "test"}
|
| 96 |
+
df["split"] = df["date"].dt.year.astype(str).map(split_map)
|
| 97 |
+
df = df[df["split"].isin(["train", "val", "test"])].copy()
|
| 98 |
+
train = df[df["split"] == "train"].copy()
|
| 99 |
+
val = df[df["split"] == "val"].copy()
|
| 100 |
+
test = df[df["split"] == "test"].copy()
|
| 101 |
+
if len(train) == 0 or len(val) == 0 or len(test) == 0:
|
| 102 |
+
raise SystemExit("Attached FM smoke table is missing one of train/val/test.")
|
| 103 |
+
|
| 104 |
+
medians = train[feature_cols].median(numeric_only=True).fillna(0.0)
|
| 105 |
+
train.loc[:, feature_cols] = train[feature_cols].fillna(medians)
|
| 106 |
+
val.loc[:, feature_cols] = val[feature_cols].fillna(medians)
|
| 107 |
+
test.loc[:, feature_cols] = test[feature_cols].fillna(medians)
|
| 108 |
+
train.loc[:, feature_cols] = train[feature_cols].fillna(0.0)
|
| 109 |
+
val.loc[:, feature_cols] = val[feature_cols].fillna(0.0)
|
| 110 |
+
test.loc[:, feature_cols] = test[feature_cols].fillna(0.0)
|
| 111 |
+
|
| 112 |
+
y_train = train["pm25_mean"].to_numpy(dtype=np.float64)
|
| 113 |
+
candidates: Dict[str, object] = {
|
| 114 |
+
"ridge": Ridge(alpha=1.0, random_state=args.seed),
|
| 115 |
+
"enet": ElasticNet(alpha=0.01, l1_ratio=0.2, random_state=args.seed, max_iter=10000),
|
| 116 |
+
}
|
| 117 |
+
if args.model_family == "full":
|
| 118 |
+
candidates.update(
|
| 119 |
+
{
|
| 120 |
+
"xgboost": XGBRegressor(
|
| 121 |
+
n_estimators=300,
|
| 122 |
+
max_depth=8,
|
| 123 |
+
learning_rate=0.05,
|
| 124 |
+
subsample=0.8,
|
| 125 |
+
colsample_bytree=0.8,
|
| 126 |
+
objective="reg:squarederror",
|
| 127 |
+
tree_method="hist",
|
| 128 |
+
random_state=args.seed,
|
| 129 |
+
n_jobs=8,
|
| 130 |
+
),
|
| 131 |
+
"lightgbm": LGBMRegressor(
|
| 132 |
+
n_estimators=300,
|
| 133 |
+
learning_rate=0.05,
|
| 134 |
+
num_leaves=127,
|
| 135 |
+
subsample=0.8,
|
| 136 |
+
colsample_bytree=0.8,
|
| 137 |
+
random_state=args.seed,
|
| 138 |
+
n_jobs=8,
|
| 139 |
+
verbose=-1,
|
| 140 |
+
),
|
| 141 |
+
"catboost": CatBoostRegressor(
|
| 142 |
+
iterations=400,
|
| 143 |
+
depth=8,
|
| 144 |
+
learning_rate=0.05,
|
| 145 |
+
loss_function="RMSE",
|
| 146 |
+
eval_metric="RMSE",
|
| 147 |
+
random_seed=args.seed,
|
| 148 |
+
verbose=False,
|
| 149 |
+
),
|
| 150 |
+
}
|
| 151 |
+
)
|
| 152 |
+
|
| 153 |
+
candidate_validation: List[Dict[str, object]] = []
|
| 154 |
+
best_name = None
|
| 155 |
+
best_model = None
|
| 156 |
+
best_score = None
|
| 157 |
+
for name, model in candidates.items():
|
| 158 |
+
if name == "catboost":
|
| 159 |
+
model.fit(train[feature_cols], y_train, use_best_model=False)
|
| 160 |
+
val_pred = model.predict(val[feature_cols])
|
| 161 |
+
else:
|
| 162 |
+
model.fit(train[feature_cols].to_numpy(dtype=np.float32), y_train)
|
| 163 |
+
val_pred = model.predict(val[feature_cols].to_numpy(dtype=np.float32))
|
| 164 |
+
val_frame = val.copy()
|
| 165 |
+
val_frame["pred"] = val_pred
|
| 166 |
+
metrics = evaluate_frame(val_frame, "pred", args.exceedance_threshold)
|
| 167 |
+
candidate_validation.append({"candidate": name, "val_metrics": metrics})
|
| 168 |
+
score = float(metrics["rmse"])
|
| 169 |
+
if best_score is None or score < best_score:
|
| 170 |
+
best_score = score
|
| 171 |
+
best_name = name
|
| 172 |
+
best_model = model
|
| 173 |
+
|
| 174 |
+
assert best_name is not None and best_model is not None
|
| 175 |
+
combined = pd.concat([train, val], ignore_index=True)
|
| 176 |
+
if best_name == "catboost":
|
| 177 |
+
best_model.fit(combined[feature_cols], combined["pm25_mean"].to_numpy(dtype=np.float64), use_best_model=False)
|
| 178 |
+
train_pred = best_model.predict(train[feature_cols])
|
| 179 |
+
val_pred = best_model.predict(val[feature_cols])
|
| 180 |
+
test_pred = best_model.predict(test[feature_cols])
|
| 181 |
+
else:
|
| 182 |
+
best_model.fit(combined[feature_cols].to_numpy(dtype=np.float32), combined["pm25_mean"].to_numpy(dtype=np.float64))
|
| 183 |
+
train_pred = best_model.predict(train[feature_cols].to_numpy(dtype=np.float32))
|
| 184 |
+
val_pred = best_model.predict(val[feature_cols].to_numpy(dtype=np.float32))
|
| 185 |
+
test_pred = best_model.predict(test[feature_cols].to_numpy(dtype=np.float32))
|
| 186 |
+
|
| 187 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 188 |
+
pred_df = pd.concat(
|
| 189 |
+
[
|
| 190 |
+
train.assign(pred_pm25=train_pred),
|
| 191 |
+
val.assign(pred_pm25=val_pred),
|
| 192 |
+
test.assign(pred_pm25=test_pred),
|
| 193 |
+
],
|
| 194 |
+
ignore_index=True,
|
| 195 |
+
)
|
| 196 |
+
pred_path = args.output_dir / "predictions.csv.gz"
|
| 197 |
+
pred_df.to_csv(pred_path, index=False, compression="gzip")
|
| 198 |
+
|
| 199 |
+
train_eval = train.assign(pred=train_pred)
|
| 200 |
+
val_eval = val.assign(pred=val_pred)
|
| 201 |
+
test_eval = test.assign(pred=test_pred)
|
| 202 |
+
summary = {
|
| 203 |
+
"task_id": "smoke_pm25_named_fm",
|
| 204 |
+
"task_form": "station_daily_regression",
|
| 205 |
+
"attached_csv": str(args.attached_csv),
|
| 206 |
+
"output_dir": str(args.output_dir),
|
| 207 |
+
"seed": int(args.seed),
|
| 208 |
+
"feature_columns": feature_cols,
|
| 209 |
+
"split_sizes": {"train": int(len(train)), "val": int(len(val)), "test": int(len(test))},
|
| 210 |
+
"candidate_validation": candidate_validation,
|
| 211 |
+
"selected_model": best_name,
|
| 212 |
+
"train_metrics": evaluate_frame(train_eval, "pred", args.exceedance_threshold),
|
| 213 |
+
"val_metrics": evaluate_frame(val_eval, "pred", args.exceedance_threshold),
|
| 214 |
+
"test_metrics": evaluate_frame(test_eval, "pred", args.exceedance_threshold),
|
| 215 |
+
"predictions_path": str(pred_path),
|
| 216 |
+
"model_family": "lightweight_linear_task_heads" if args.model_family == "lite" else "popular_open_source_task_models",
|
| 217 |
+
"fm_family": args.fm_family,
|
| 218 |
+
"benchmark_protocol": "fm_lite_protocol" if args.model_family == "lite" else "standard_protocol",
|
| 219 |
+
"selection_rule": "choose model by validation RMSE on named-FM attached rows; report on held-out test dates",
|
| 220 |
+
"tmt_policy": {
|
| 221 |
+
"task": "smoke_pm25",
|
| 222 |
+
"metric": "continuous RMSE/MAE with thresholded exceedance PRF",
|
| 223 |
+
"tolerance": "secondary event policy only",
|
| 224 |
+
},
|
| 225 |
+
}
|
| 226 |
+
(args.output_dir / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 227 |
+
print(json.dumps(summary, indent=2))
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
if __name__ == "__main__":
|
| 231 |
+
main()
|
experiments/raw_reference/task_scripts/summarize_forced_meanstd_20260429.py
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import json
|
| 6 |
+
import math
|
| 7 |
+
import re
|
| 8 |
+
import statistics
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from typing import Any
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
SLUG_LABELS = {
|
| 14 |
+
"reference": "Reference",
|
| 15 |
+
"prithvi_wxc": "Prithvi-WxC",
|
| 16 |
+
"stormcast": "StormCast",
|
| 17 |
+
"aurora": "Aurora",
|
| 18 |
+
"climax": "ClimaX",
|
| 19 |
+
"alphaearth": "AlphaEarth",
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def load(path: Path) -> dict[str, Any]:
|
| 24 |
+
return json.loads(path.read_text(encoding="utf-8"))
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def stats(values: list[float]) -> dict[str, float | int]:
|
| 28 |
+
values = [float(v) for v in values if math.isfinite(float(v))]
|
| 29 |
+
if not values:
|
| 30 |
+
return {"n": 0, "mean": math.nan, "std": math.nan}
|
| 31 |
+
return {
|
| 32 |
+
"n": len(values),
|
| 33 |
+
"mean": float(statistics.fmean(values)),
|
| 34 |
+
"std": float(statistics.stdev(values)) if len(values) > 1 else 0.0,
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def seed_from_path(path: Path) -> int | None:
|
| 39 |
+
match = re.search(r"_seed_(\d+)", str(path))
|
| 40 |
+
return int(match.group(1)) if match else None
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def label_from_seed_dir(path: Path, prefix: str) -> str:
|
| 44 |
+
for part in path.parts:
|
| 45 |
+
if part.startswith(prefix) and "_seed_" in part:
|
| 46 |
+
slug = part[len(prefix) :].split("_seed_", 1)[0]
|
| 47 |
+
return SLUG_LABELS.get(slug, slug)
|
| 48 |
+
return "unknown"
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def dedupe_rows(rows: list[dict[str, Any]], keys: tuple[str, ...]) -> list[dict[str, Any]]:
|
| 52 |
+
selected: dict[tuple[Any, ...], dict[str, Any]] = {}
|
| 53 |
+
for row in rows:
|
| 54 |
+
key = tuple(row.get(name) for name in keys)
|
| 55 |
+
old = selected.get(key)
|
| 56 |
+
if old is None:
|
| 57 |
+
selected[key] = row
|
| 58 |
+
continue
|
| 59 |
+
old_mtime = Path(str(old["path"])).stat().st_mtime
|
| 60 |
+
new_mtime = Path(str(row["path"])).stat().st_mtime
|
| 61 |
+
if new_mtime >= old_mtime:
|
| 62 |
+
selected[key] = row
|
| 63 |
+
return list(selected.values())
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def best_val_threshold(data: dict[str, Any]) -> str:
|
| 67 |
+
entries = data["splits"]["val"]["threshold_metrics"]
|
| 68 |
+
return max(entries, key=lambda key: (float(entries[key]["f1"]), -float(entries[key]["threshold"])))
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def collect_occupancy(run_root: Path) -> dict[str, Any]:
|
| 72 |
+
rows: list[dict[str, Any]] = []
|
| 73 |
+
for path in sorted(run_root.glob("table3_occupancy_*_seed_*/run_*/summary.json")):
|
| 74 |
+
data = load(path)
|
| 75 |
+
threshold_key = best_val_threshold(data)
|
| 76 |
+
test = data["splits"]["test"]
|
| 77 |
+
rows.append(
|
| 78 |
+
{
|
| 79 |
+
"label": data.get("fm_family") or label_from_seed_dir(path, "table3_occupancy_"),
|
| 80 |
+
"seed": seed_from_path(path),
|
| 81 |
+
"strict_f1": float(test["threshold_metrics"][threshold_key]["f1"]),
|
| 82 |
+
"tolerant_f1": float(test["tolerant_threshold_metrics"]["t0_s3"][threshold_key]["f1"]),
|
| 83 |
+
"union_f1": float(test["tolerant_threshold_metrics"]["t3_s3"][threshold_key]["f1"]),
|
| 84 |
+
"path": str(path),
|
| 85 |
+
}
|
| 86 |
+
)
|
| 87 |
+
return group(rows, ["strict_f1", "tolerant_f1", "union_f1"])
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def collect_headcontrol(run_root: Path) -> dict[str, Any]:
|
| 91 |
+
rows: list[dict[str, Any]] = []
|
| 92 |
+
for path in sorted(run_root.glob("table2_prithvi_wxc_headcontrol_seed_*/run_*/summary.json")):
|
| 93 |
+
data = load(path)
|
| 94 |
+
seed = seed_from_path(path)
|
| 95 |
+
for row in data.get("selection_summary", {}).get("rows", []):
|
| 96 |
+
rows.append(
|
| 97 |
+
{
|
| 98 |
+
"label": "Prithvi-WxC",
|
| 99 |
+
"scope": row["scope"],
|
| 100 |
+
"seed": seed,
|
| 101 |
+
"ranking_selected_union_f1": float(row["ranking_selected_union_f1"]),
|
| 102 |
+
"decision_selected_union_f1": float(row["decision_selected_union_f1"]),
|
| 103 |
+
"decision_regret_union_f1": float(row["decision_regret_union_f1"]),
|
| 104 |
+
"selection_failure": bool(row.get("selection_failure", False)),
|
| 105 |
+
"path": str(path),
|
| 106 |
+
}
|
| 107 |
+
)
|
| 108 |
+
grouped: dict[str, Any] = {}
|
| 109 |
+
rows = dedupe_rows(rows, ("label", "scope", "seed"))
|
| 110 |
+
for scope in sorted({str(row["scope"]) for row in rows}):
|
| 111 |
+
selected = [row for row in rows if row["scope"] == scope]
|
| 112 |
+
grouped[scope] = {
|
| 113 |
+
"n": len(selected),
|
| 114 |
+
"failure_count": int(sum(1 for row in selected if row["selection_failure"])),
|
| 115 |
+
"ranking_selected_union_f1": stats([row["ranking_selected_union_f1"] for row in selected]),
|
| 116 |
+
"decision_selected_union_f1": stats([row["decision_selected_union_f1"] for row in selected]),
|
| 117 |
+
"decision_regret_union_f1": stats([row["decision_regret_union_f1"] for row in selected]),
|
| 118 |
+
}
|
| 119 |
+
return {"rows": rows, "summary": grouped}
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def collect_spread(run_root: Path) -> dict[str, Any]:
|
| 123 |
+
rows: list[dict[str, Any]] = []
|
| 124 |
+
for pattern, prefix in [
|
| 125 |
+
("table3_spread_*_seed_*/run_*/summary.json", "table3_spread_"),
|
| 126 |
+
("table3_reference_spread_seed_*/run_*/summary.json", "table3_reference_spread_"),
|
| 127 |
+
]:
|
| 128 |
+
for path in sorted(run_root.glob(pattern)):
|
| 129 |
+
data = load(path)
|
| 130 |
+
headline = data["headline_metrics"]
|
| 131 |
+
label = data.get("fm_family") or ("Reference" if "reference_spread" in str(path) else label_from_seed_dir(path, prefix))
|
| 132 |
+
rows.append(
|
| 133 |
+
{
|
| 134 |
+
"label": label,
|
| 135 |
+
"seed": seed_from_path(path),
|
| 136 |
+
"strict_f1": float(headline["strict_f1"]),
|
| 137 |
+
"spatial_f1": float(headline["same_sample_spatial_tolerance_f1"]["s4"]),
|
| 138 |
+
"ap": float(headline["strict_AP"]),
|
| 139 |
+
"path": str(path),
|
| 140 |
+
}
|
| 141 |
+
)
|
| 142 |
+
return group(rows, ["strict_f1", "spatial_f1", "ap"])
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
def collect_task(run_root: Path, glob_pattern: str, prefix: str, metrics_path: list[str], metric_keys: list[str]) -> dict[str, Any]:
|
| 146 |
+
rows: list[dict[str, Any]] = []
|
| 147 |
+
for path in sorted(run_root.glob(glob_pattern)):
|
| 148 |
+
data = load(path)
|
| 149 |
+
label = data.get("fm_family") or label_from_seed_dir(path, prefix)
|
| 150 |
+
node: Any = data
|
| 151 |
+
for key in metrics_path:
|
| 152 |
+
node = node[key]
|
| 153 |
+
row = {"label": label, "seed": seed_from_path(path), "path": str(path)}
|
| 154 |
+
for key in metric_keys:
|
| 155 |
+
row[key] = float(node[key])
|
| 156 |
+
rows.append(row)
|
| 157 |
+
return group(rows, metric_keys)
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def group(rows: list[dict[str, Any]], metric_keys: list[str]) -> dict[str, Any]:
|
| 161 |
+
if rows and "seed" in rows[0]:
|
| 162 |
+
rows = dedupe_rows(rows, ("label", "seed"))
|
| 163 |
+
summary: dict[str, Any] = {}
|
| 164 |
+
for label in sorted({str(row["label"]) for row in rows}):
|
| 165 |
+
selected = [row for row in rows if row["label"] == label]
|
| 166 |
+
summary[label] = {"n": len(selected)}
|
| 167 |
+
for key in metric_keys:
|
| 168 |
+
summary[label][key] = stats([row[key] for row in selected])
|
| 169 |
+
return {"rows": rows, "summary": summary}
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def fmt(value: dict[str, Any], scale: float = 1.0, digits: int = 2) -> str:
|
| 173 |
+
if int(value["n"]) == 0:
|
| 174 |
+
return "missing"
|
| 175 |
+
return f"{float(value['mean']) * scale:.{digits}f} +/- {float(value['std']) * scale:.{digits}f} (n={int(value['n'])})"
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def write_markdown(out: Path, summary: dict[str, Any]) -> None:
|
| 179 |
+
lines = ["# Forced Mean/Std Gap-Fill Summary", ""]
|
| 180 |
+
for section in [
|
| 181 |
+
"table2_headcontrol",
|
| 182 |
+
"table3_occupancy",
|
| 183 |
+
"table3_spread",
|
| 184 |
+
"table4_final_area",
|
| 185 |
+
"table4_analog",
|
| 186 |
+
"table4_smoke",
|
| 187 |
+
"table4_heat",
|
| 188 |
+
]:
|
| 189 |
+
lines += [f"## {section}", ""]
|
| 190 |
+
sec = summary.get(section, {}).get("summary", {})
|
| 191 |
+
if section == "table2_headcontrol":
|
| 192 |
+
for scope, row in sec.items():
|
| 193 |
+
lines.append(
|
| 194 |
+
f"- {scope}: regret {fmt(row['decision_regret_union_f1'], 100.0)}; "
|
| 195 |
+
f"ranking union {fmt(row['ranking_selected_union_f1'], 100.0)}; "
|
| 196 |
+
f"decision union {fmt(row['decision_selected_union_f1'], 100.0)}; "
|
| 197 |
+
f"failures {row['failure_count']}/{row['n']}"
|
| 198 |
+
)
|
| 199 |
+
else:
|
| 200 |
+
for label, row in sec.items():
|
| 201 |
+
pieces = [f"{key} {fmt(val, 100.0 if key.endswith('_f1') or key == 'ap' else 1.0)}" for key, val in row.items() if isinstance(val, dict)]
|
| 202 |
+
lines.append(f"- {label}: " + "; ".join(pieces))
|
| 203 |
+
lines.append("")
|
| 204 |
+
out.write_text("\n".join(lines), encoding="utf-8")
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
def main() -> None:
|
| 208 |
+
parser = argparse.ArgumentParser()
|
| 209 |
+
parser.add_argument("--run-root", type=Path, default=Path("${RUN_ROOT}"))
|
| 210 |
+
parser.add_argument("--out-json", type=Path, default=Path("${OUT_JSON}"))
|
| 211 |
+
parser.add_argument("--out-md", type=Path, default=Path("${OUT_MD}"))
|
| 212 |
+
args = parser.parse_args()
|
| 213 |
+
|
| 214 |
+
summary = {
|
| 215 |
+
"run_root": str(args.run_root),
|
| 216 |
+
"table2_headcontrol": collect_headcontrol(args.run_root),
|
| 217 |
+
"table3_occupancy": collect_occupancy(args.run_root),
|
| 218 |
+
"table3_spread": collect_spread(args.run_root),
|
| 219 |
+
"table4_final_area": collect_task(args.run_root, "table4_final_area_*_seed_*/run_*/summary.json", "table4_final_area_", ["headline_metrics"], ["log_rmse", "log_mae", "log_spearman"]),
|
| 220 |
+
"table4_analog": collect_task(args.run_root, "table4_analog_*_seed_*/run_*/summary.json", "table4_analog_", ["test_metrics"], ["ndcg_at_10", "log_rmse", "log_mae"]),
|
| 221 |
+
"table4_smoke": collect_task(args.run_root, "table4_smoke_*_seed_*/run_*/summary.json", "table4_smoke_", ["test_metrics"], ["rmse", "mae", "pearson_r"]),
|
| 222 |
+
"table4_heat": collect_task(args.run_root, "table4_heat_*_seed_*/run_*/summary.json", "table4_heat_", ["test_metrics"], ["rmse_c", "mae_c", "pearson_r"]),
|
| 223 |
+
}
|
| 224 |
+
args.out_json.parent.mkdir(parents=True, exist_ok=True)
|
| 225 |
+
args.out_json.write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
| 226 |
+
write_markdown(args.out_md, summary)
|
| 227 |
+
print(f"wrote={args.out_json}")
|
| 228 |
+
print(f"wrote={args.out_md}")
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
if __name__ == "__main__":
|
| 232 |
+
main()
|
experiments/slurm/submit_template.sbatch
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
#SBATCH --job-name=wildfire-contract-rerun
|
| 3 |
+
#SBATCH --cpus-per-task=4
|
| 4 |
+
#SBATCH --mem=24G
|
| 5 |
+
#SBATCH --time=02:00:00
|
| 6 |
+
|
| 7 |
+
# Template only. Set these paths for your environment after obtaining data.
|
| 8 |
+
PROJECT_ROOT=/path/to/this/repository
|
| 9 |
+
DATA_ROOT=/path/to/raw/or/processed/data
|
| 10 |
+
OUTPUT_ROOT=/path/to/output
|
| 11 |
+
|
| 12 |
+
cd "$PROJECT_ROOT"
|
| 13 |
+
python3 scripts/reproduce_paper_outputs.py
|
paper_outputs/figures/fig_fireprone_contract_progression_compact.pdf
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
%PDF-1.4
|
| 2 |
+
%����
|
| 3 |
+
1 0 obj
|
| 4 |
+
<< /Type /Catalog /Pages 2 0 R >>
|
| 5 |
+
endobj
|
| 6 |
+
2 0 obj
|
| 7 |
+
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
| 8 |
+
endobj
|
| 9 |
+
3 0 obj
|
| 10 |
+
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 1320 470] /Resources << /Font << /F1 4 0 R /F2 5 0 R >> >> /Contents 6 0 R >>
|
| 11 |
+
endobj
|
| 12 |
+
4 0 obj
|
| 13 |
+
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
|
| 14 |
+
endobj
|
| 15 |
+
5 0 obj
|
| 16 |
+
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>
|
| 17 |
+
endobj
|
| 18 |
+
6 0 obj
|
| 19 |
+
<< /Length 19373 >>
|
| 20 |
+
stream
|
| 21 |
+
1.0000 1.0000 1.0000 rg 0.00 0.00 1320.00 470.00 re f
|
| 22 |
+
0.80 w 0.1500 0.1500 0.1500 RG 72.00 132.00 m 72.00 400.00 l S
|
| 23 |
+
0.80 w 0.1500 0.1500 0.1500 RG 72.00 132.00 m 1266.00 132.00 l S
|
| 24 |
+
0.45 w 0.8600 0.8600 0.8600 RG 68.00 132.00 m 1266.00 132.00 l S
|
| 25 |
+
BT /F1 7.00 Tf 0.2500 0.2500 0.2500 rg 1 0 0 1 60.36 129.00 Tm (0) Tj ET
|
| 26 |
+
0.45 w 0.8600 0.8600 0.8600 RG 68.00 199.00 m 1266.00 199.00 l S
|
| 27 |
+
BT /F1 7.00 Tf 0.2500 0.2500 0.2500 rg 1 0 0 1 56.72 196.00 Tm (20) Tj ET
|
| 28 |
+
0.45 w 0.8600 0.8600 0.8600 RG 68.00 266.00 m 1266.00 266.00 l S
|
| 29 |
+
BT /F1 7.00 Tf 0.2500 0.2500 0.2500 rg 1 0 0 1 56.72 263.00 Tm (40) Tj ET
|
| 30 |
+
0.45 w 0.8600 0.8600 0.8600 RG 68.00 333.00 m 1266.00 333.00 l S
|
| 31 |
+
BT /F1 7.00 Tf 0.2500 0.2500 0.2500 rg 1 0 0 1 56.72 330.00 Tm (60) Tj ET
|
| 32 |
+
0.45 w 0.8600 0.8600 0.8600 RG 68.00 400.00 m 1266.00 400.00 l S
|
| 33 |
+
BT /F1 7.00 Tf 0.2500 0.2500 0.2500 rg 1 0 0 1 56.72 397.00 Tm (80) Tj ET
|
| 34 |
+
BT /F2 8.00 Tf 0.1500 0.1500 0.1500 rg 1 0 0 1 34.00 408.00 Tm (F1 \(%\)) Tj ET
|
| 35 |
+
BT /F2 15.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 202.93 417.00 Tm (global) Tj ET
|
| 36 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 126.00 m 380.50 133.00 l S
|
| 37 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 138.00 m 380.50 145.00 l S
|
| 38 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 150.00 m 380.50 157.00 l S
|
| 39 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 162.00 m 380.50 169.00 l S
|
| 40 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 174.00 m 380.50 181.00 l S
|
| 41 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 186.00 m 380.50 193.00 l S
|
| 42 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 198.00 m 380.50 205.00 l S
|
| 43 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 210.00 m 380.50 217.00 l S
|
| 44 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 222.00 m 380.50 229.00 l S
|
| 45 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 234.00 m 380.50 241.00 l S
|
| 46 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 246.00 m 380.50 253.00 l S
|
| 47 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 258.00 m 380.50 265.00 l S
|
| 48 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 270.00 m 380.50 277.00 l S
|
| 49 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 282.00 m 380.50 289.00 l S
|
| 50 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 294.00 m 380.50 301.00 l S
|
| 51 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 306.00 m 380.50 313.00 l S
|
| 52 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 318.00 m 380.50 325.00 l S
|
| 53 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 330.00 m 380.50 337.00 l S
|
| 54 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 342.00 m 380.50 349.00 l S
|
| 55 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 354.00 m 380.50 361.00 l S
|
| 56 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 366.00 m 380.50 373.00 l S
|
| 57 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 378.00 m 380.50 385.00 l S
|
| 58 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 390.00 m 380.50 397.00 l S
|
| 59 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 402.00 m 380.50 409.00 l S
|
| 60 |
+
0.75 w 0.4200 0.4400 0.4600 RG 380.50 414.00 m 380.50 416.00 l S
|
| 61 |
+
BT /F2 15.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 515.07 417.00 Tm (top 5%) Tj ET
|
| 62 |
+
BT /F2 15.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 807.48 417.00 Tm (top 10%) Tj ET
|
| 63 |
+
BT /F2 15.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 1103.97 417.00 Tm (top 20%) Tj ET
|
| 64 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 84.02 132.00 18.00 1.52 re B
|
| 65 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 84.02 133.52 18.00 98.13 re B
|
| 66 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 84.02 231.66 18.00 98.21 re B
|
| 67 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 76.52 69.51 Tm (Ref.) Tj ET
|
| 68 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 110.07 132.00 18.00 0.19 re B
|
| 69 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 110.07 132.19 18.00 23.82 re B
|
| 70 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 110.07 156.00 18.00 43.62 re B
|
| 71 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 102.21 69.86 Tm (WxC) Tj ET
|
| 72 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 136.11 132.00 18.00 0.22 re B
|
| 73 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 136.11 132.22 18.00 28.26 re B
|
| 74 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 136.11 160.48 18.00 48.92 re B
|
| 75 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 119.34 78.77 Tm (Aurora) Tj ET
|
| 76 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 162.16 132.00 18.00 1.17 re B
|
| 77 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 162.16 133.17 18.00 98.51 re B
|
| 78 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 162.16 231.67 18.00 101.83 re B
|
| 79 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 146.38 77.78 Tm (ClimaX) Tj ET
|
| 80 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 188.20 132.00 18.00 0.21 re B
|
| 81 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 188.20 132.21 18.00 27.24 re B
|
| 82 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 188.20 159.45 18.00 47.52 re B
|
| 83 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 172.99 77.21 Tm (Storm) Tj ET
|
| 84 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 214.25 132.00 18.00 0.57 re B
|
| 85 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 214.25 132.57 18.00 49.40 re B
|
| 86 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 214.25 181.96 18.00 44.47 re B
|
| 87 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 201.30 74.95 Tm (DLWP) Tj ET
|
| 88 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 240.30 132.00 18.00 0.95 re B
|
| 89 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 240.30 132.95 18.00 64.40 re B
|
| 90 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 240.30 197.35 18.00 68.86 re B
|
| 91 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 233.14 69.15 Tm (FCN) Tj ET
|
| 92 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 266.34 132.00 18.00 0.88 re B
|
| 93 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 266.34 132.88 18.00 39.34 re B
|
| 94 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 266.34 172.22 18.00 40.53 re B
|
| 95 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 247.45 80.89 Tm (FengWu) Tj ET
|
| 96 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 292.39 132.00 18.00 1.26 re B
|
| 97 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 292.39 133.26 18.00 69.19 re B
|
| 98 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 292.39 202.46 18.00 54.46 re B
|
| 99 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 284.17 70.21 Tm (FuXi) Tj ET
|
| 100 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 318.43 132.00 18.00 0.92 re B
|
| 101 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 318.43 132.92 18.00 56.33 re B
|
| 102 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 318.43 189.25 18.00 62.13 re B
|
| 103 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 295.86 84.57 Tm (Pangu-W) Tj ET
|
| 104 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 344.48 132.00 18.00 6.90 re B
|
| 105 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 344.48 138.90 18.00 91.75 re B
|
| 106 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 344.48 230.65 18.00 26.74 re B
|
| 107 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 333.29 73.18 Tm (Alpha) Tj ET
|
| 108 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 398.52 132.00 18.00 11.93 re B
|
| 109 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 398.52 143.93 18.00 119.60 re B
|
| 110 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 398.52 263.53 18.00 112.45 re B
|
| 111 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 391.02 69.51 Tm (Ref.) Tj ET
|
| 112 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 424.57 132.00 18.00 4.73 re B
|
| 113 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 424.57 136.73 18.00 59.80 re B
|
| 114 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 424.57 196.53 18.00 78.11 re B
|
| 115 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 416.71 69.86 Tm (WxC) Tj ET
|
| 116 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 450.61 132.00 18.00 3.30 re B
|
| 117 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 450.61 135.30 18.00 47.40 re B
|
| 118 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 450.61 182.70 18.00 68.17 re B
|
| 119 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 433.84 78.77 Tm (Aurora) Tj ET
|
| 120 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 476.66 132.00 18.00 4.33 re B
|
| 121 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 476.66 136.33 18.00 111.51 re B
|
| 122 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 476.66 247.84 18.00 116.04 re B
|
| 123 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 460.88 77.78 Tm (ClimaX) Tj ET
|
| 124 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 502.70 132.00 18.00 3.21 re B
|
| 125 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 502.70 135.21 18.00 48.12 re B
|
| 126 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 502.70 183.33 18.00 69.89 re B
|
| 127 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 487.49 77.21 Tm (Storm) Tj ET
|
| 128 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 528.75 132.00 18.00 6.05 re B
|
| 129 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 528.75 138.05 18.00 100.22 re B
|
| 130 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 528.75 238.27 18.00 79.52 re B
|
| 131 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 515.80 74.95 Tm (DLWP) Tj ET
|
| 132 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 554.80 132.00 18.00 5.44 re B
|
| 133 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 554.80 137.44 18.00 92.98 re B
|
| 134 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 554.80 230.41 18.00 83.50 re B
|
| 135 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 547.64 69.15 Tm (FCN) Tj ET
|
| 136 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 580.84 132.00 18.00 5.26 re B
|
| 137 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 580.84 137.26 18.00 49.27 re B
|
| 138 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 580.84 186.53 18.00 46.33 re B
|
| 139 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 561.95 80.89 Tm (FengWu) Tj ET
|
| 140 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 606.89 132.00 18.00 6.80 re B
|
| 141 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 606.89 138.80 18.00 100.04 re B
|
| 142 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 606.89 238.85 18.00 73.82 re B
|
| 143 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 598.67 70.21 Tm (FuXi) Tj ET
|
| 144 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 632.93 132.00 18.00 4.57 re B
|
| 145 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 632.93 136.57 18.00 69.87 re B
|
| 146 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 632.93 206.44 18.00 71.02 re B
|
| 147 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 610.36 84.57 Tm (Pangu-W) Tj ET
|
| 148 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 658.98 132.00 18.00 23.16 re B
|
| 149 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 658.98 155.16 18.00 120.48 re B
|
| 150 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 658.98 275.64 18.00 29.70 re B
|
| 151 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 647.79 73.18 Tm (Alpha) Tj ET
|
| 152 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 695.02 132.00 18.00 11.92 re B
|
| 153 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 695.02 143.92 18.00 119.29 re B
|
| 154 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 695.02 263.21 18.00 111.74 re B
|
| 155 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 687.52 69.51 Tm (Ref.) Tj ET
|
| 156 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 721.07 132.00 18.00 4.15 re B
|
| 157 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 721.07 136.15 18.00 45.70 re B
|
| 158 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 721.07 181.84 18.00 59.67 re B
|
| 159 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 713.21 69.86 Tm (WxC) Tj ET
|
| 160 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 747.11 132.00 18.00 2.61 re B
|
| 161 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 747.11 134.61 18.00 40.06 re B
|
| 162 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 747.11 174.67 18.00 59.60 re B
|
| 163 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 730.34 78.77 Tm (Aurora) Tj ET
|
| 164 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 773.16 132.00 18.00 4.19 re B
|
| 165 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 773.16 136.19 18.00 110.82 re B
|
| 166 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 773.16 247.02 18.00 114.69 re B
|
| 167 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 757.38 77.78 Tm (ClimaX) Tj ET
|
| 168 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 799.20 132.00 18.00 2.44 re B
|
| 169 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 799.20 134.44 18.00 39.99 re B
|
| 170 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 799.20 174.43 18.00 59.66 re B
|
| 171 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 783.99 77.21 Tm (Storm) Tj ET
|
| 172 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 825.25 132.00 18.00 5.40 re B
|
| 173 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 825.25 137.40 18.00 87.26 re B
|
| 174 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 825.25 224.65 18.00 65.22 re B
|
| 175 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 812.30 74.95 Tm (DLWP) Tj ET
|
| 176 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 851.30 132.00 18.00 3.95 re B
|
| 177 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 851.30 135.95 18.00 71.17 re B
|
| 178 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 851.30 207.11 18.00 70.45 re B
|
| 179 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 844.14 69.15 Tm (FCN) Tj ET
|
| 180 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 877.34 132.00 18.00 4.16 re B
|
| 181 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 877.34 136.16 18.00 39.22 re B
|
| 182 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 877.34 175.38 18.00 37.64 re B
|
| 183 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 858.45 80.89 Tm (FengWu) Tj ET
|
| 184 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 903.39 132.00 18.00 5.54 re B
|
| 185 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 903.39 137.54 18.00 74.90 re B
|
| 186 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 903.39 212.44 18.00 54.27 re B
|
| 187 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 895.17 70.21 Tm (FuXi) Tj ET
|
| 188 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 929.43 132.00 18.00 3.66 re B
|
| 189 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 929.43 135.66 18.00 59.77 re B
|
| 190 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 929.43 195.43 18.00 65.66 re B
|
| 191 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 906.86 84.57 Tm (Pangu-W) Tj ET
|
| 192 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 955.48 132.00 18.00 22.23 re B
|
| 193 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 955.48 154.23 18.00 118.13 re B
|
| 194 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 955.48 272.36 18.00 29.05 re B
|
| 195 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 944.29 73.18 Tm (Alpha) Tj ET
|
| 196 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 991.52 132.00 18.00 11.83 re B
|
| 197 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 991.52 143.83 18.00 116.43 re B
|
| 198 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 991.52 260.25 18.00 105.32 re B
|
| 199 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 984.02 69.51 Tm (Ref.) Tj ET
|
| 200 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1017.57 132.00 18.00 3.86 re B
|
| 201 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1017.57 135.86 18.00 40.20 re B
|
| 202 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1017.57 176.06 18.00 50.19 re B
|
| 203 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1009.71 69.86 Tm (WxC) Tj ET
|
| 204 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1043.61 132.00 18.00 2.23 re B
|
| 205 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1043.61 134.23 18.00 33.05 re B
|
| 206 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1043.61 167.28 18.00 48.29 re B
|
| 207 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1026.84 78.77 Tm (Aurora) Tj ET
|
| 208 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1069.66 132.00 18.00 3.45 re B
|
| 209 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1069.66 135.45 18.00 97.77 re B
|
| 210 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1069.66 233.22 18.00 100.00 re B
|
| 211 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1053.88 77.78 Tm (ClimaX) Tj ET
|
| 212 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1095.70 132.00 18.00 1.94 re B
|
| 213 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1095.70 133.94 18.00 32.95 re B
|
| 214 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1095.70 166.89 18.00 47.72 re B
|
| 215 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1080.49 77.21 Tm (Storm) Tj ET
|
| 216 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1121.75 132.00 18.00 5.11 re B
|
| 217 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1121.75 137.11 18.00 65.04 re B
|
| 218 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1121.75 202.15 18.00 46.87 re B
|
| 219 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1108.80 74.95 Tm (DLWP) Tj ET
|
| 220 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1147.80 132.00 18.00 3.34 re B
|
| 221 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1147.80 135.34 18.00 53.54 re B
|
| 222 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1147.80 188.88 18.00 57.31 re B
|
| 223 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1140.64 69.15 Tm (FCN) Tj ET
|
| 224 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1173.84 132.00 18.00 3.75 re B
|
| 225 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1173.84 135.75 18.00 36.29 re B
|
| 226 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1173.84 172.04 18.00 36.30 re B
|
| 227 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1154.95 80.89 Tm (FengWu) Tj ET
|
| 228 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1199.89 132.00 18.00 4.57 re B
|
| 229 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1199.89 136.57 18.00 68.98 re B
|
| 230 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1199.89 205.55 18.00 49.50 re B
|
| 231 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1191.67 70.21 Tm (FuXi) Tj ET
|
| 232 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1225.93 132.00 18.00 2.96 re B
|
| 233 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1225.93 134.96 18.00 54.04 re B
|
| 234 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1225.93 189.01 18.00 58.80 re B
|
| 235 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1203.36 84.57 Tm (Pangu-W) Tj ET
|
| 236 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 1251.98 132.00 18.00 20.74 re B
|
| 237 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 1251.98 152.74 18.00 109.35 re B
|
| 238 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 1251.98 262.09 18.00 25.30 re B
|
| 239 |
+
BT /F1 10.00 Tf 0.0000 0.0000 0.0000 rg 0.70711 -0.70711 0.70711 0.70711 1240.79 73.18 Tm (Alpha) Tj ET
|
| 240 |
+
0.45 w 0.9800 0.9800 0.9600 rg 0.7800 0.8000 0.7800 RG 77.00 362.00 304.00 23.00 re B
|
| 241 |
+
0.35 w 0.0900 0.2200 0.3700 rg 1.0000 1.0000 1.0000 RG 90.00 371.00 24.00 9.00 re B
|
| 242 |
+
BT /F1 8.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 121.00 373.00 Tm (Strict) Tj ET
|
| 243 |
+
0.35 w 0.3100 0.5500 0.8000 rg 1.0000 1.0000 1.0000 RG 188.00 371.00 24.00 9.00 re B
|
| 244 |
+
BT /F1 8.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 219.00 373.00 Tm (Tolerance) Tj ET
|
| 245 |
+
0.35 w 0.7500 0.8400 0.9400 rg 1.0000 1.0000 1.0000 RG 286.00 371.00 24.00 9.00 re B
|
| 246 |
+
BT /F1 8.00 Tf 0.0000 0.0000 0.0000 rg 1 0 0 1 317.00 373.00 Tm (Union) Tj ET
|
| 247 |
+
endstream
|
| 248 |
+
endobj
|
| 249 |
+
xref
|
| 250 |
+
0 7
|
| 251 |
+
0000000000 65535 f
|
| 252 |
+
0000000015 00000 n
|
| 253 |
+
0000000064 00000 n
|
| 254 |
+
0000000121 00000 n
|
| 255 |
+
0000000258 00000 n
|
| 256 |
+
0000000328 00000 n
|
| 257 |
+
0000000403 00000 n
|
| 258 |
+
trailer
|
| 259 |
+
<< /Size 7 /Root 1 0 R >>
|
| 260 |
+
startxref
|
| 261 |
+
19829
|
| 262 |
+
%%EOF
|
paper_outputs/figures/fig_selection_regret_rq2.tikz
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
% Auto-generated by scripts/build_selection_regret_rq2_figure.py.
|
| 2 |
+
\begin{tikzpicture}[x=1cm,y=1cm]
|
| 3 |
+
\footnotesize
|
| 4 |
+
\draw[black!12, line width=0.35pt] (2.450,-0.350) -- (2.450,4.530);
|
| 5 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (2.450,-0.410) {-20};
|
| 6 |
+
\draw[black!12, line width=0.35pt] (3.243,-0.350) -- (3.243,4.530);
|
| 7 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (3.243,-0.410) {-10};
|
| 8 |
+
\draw[wfgray, line width=0.55pt] (4.036,-0.350) -- (4.036,4.530);
|
| 9 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (4.036,-0.410) {0};
|
| 10 |
+
\draw[black!12, line width=0.35pt] (4.829,-0.350) -- (4.829,4.530);
|
| 11 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (4.829,-0.410) {10};
|
| 12 |
+
\draw[black!12, line width=0.35pt] (5.621,-0.350) -- (5.621,4.530);
|
| 13 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (5.621,-0.410) {20};
|
| 14 |
+
\draw[black!12, line width=0.35pt] (6.414,-0.350) -- (6.414,4.530);
|
| 15 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (6.414,-0.410) {30};
|
| 16 |
+
\draw[black!12, line width=0.35pt] (7.207,-0.350) -- (7.207,4.530);
|
| 17 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (7.207,-0.410) {40};
|
| 18 |
+
\draw[black!12, line width=0.35pt] (8.000,-0.350) -- (8.000,4.530);
|
| 19 |
+
\node[anchor=north, font=\scriptsize, text=black!70] at (8.000,-0.410) {50};
|
| 20 |
+
\draw[black!45, line width=0.4pt] (2.450,-0.350) -- (8.000,-0.350);
|
| 21 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,4.350) {\textcolor{wfblue}{\textbf{FireWx-FM ref.}}};
|
| 22 |
+
\draw[wfslate, line width=0.72pt] (4.030,4.220) -- (5.212,4.220);
|
| 23 |
+
\draw[wfslate, line width=0.72pt] (4.030,4.185) -- (4.030,4.255);
|
| 24 |
+
\draw[wfslate, line width=0.72pt] (5.212,4.185) -- (5.212,4.255);
|
| 25 |
+
\filldraw[wfslate] (4.621,4.220) circle[radius=0.045];
|
| 26 |
+
\draw[wforange, line width=0.72pt] (4.051,4.480) -- (4.487,4.480);
|
| 27 |
+
\draw[wforange, line width=0.72pt] (4.051,4.445) -- (4.051,4.515);
|
| 28 |
+
\draw[wforange, line width=0.72pt] (4.487,4.445) -- (4.487,4.515);
|
| 29 |
+
\filldraw[wforange] (4.224,4.435) rectangle (4.314,4.525);
|
| 30 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,3.940) {Prithvi-WxC};
|
| 31 |
+
\draw[wfslate, line width=0.72pt] (4.036,3.810) -- (4.036,3.810);
|
| 32 |
+
\draw[wfslate, line width=0.72pt] (4.036,3.775) -- (4.036,3.845);
|
| 33 |
+
\draw[wfslate, line width=0.72pt] (4.036,3.775) -- (4.036,3.845);
|
| 34 |
+
\filldraw[wfslate] (4.036,3.810) circle[radius=0.045];
|
| 35 |
+
\draw[wforange, line width=0.72pt] (4.036,4.070) -- (4.036,4.070);
|
| 36 |
+
\draw[wforange, line width=0.72pt] (4.036,4.035) -- (4.036,4.105);
|
| 37 |
+
\draw[wforange, line width=0.72pt] (4.036,4.035) -- (4.036,4.105);
|
| 38 |
+
\filldraw[wforange] (3.991,4.025) rectangle (4.081,4.115);
|
| 39 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,3.530) {Aurora};
|
| 40 |
+
\draw[wfslate, line width=0.72pt] (3.580,3.400) -- (5.276,3.400);
|
| 41 |
+
\draw[wfslate, line width=0.72pt] (3.580,3.365) -- (3.580,3.435);
|
| 42 |
+
\draw[wfslate, line width=0.72pt] (5.276,3.365) -- (5.276,3.435);
|
| 43 |
+
\filldraw[wfslate] (4.428,3.400) circle[radius=0.045];
|
| 44 |
+
\draw[wforange, line width=0.72pt] (2.627,3.660) -- (7.723,3.660);
|
| 45 |
+
\draw[wforange, line width=0.72pt] (2.627,3.625) -- (2.627,3.695);
|
| 46 |
+
\draw[wforange, line width=0.72pt] (7.723,3.625) -- (7.723,3.695);
|
| 47 |
+
\filldraw[wforange] (5.130,3.615) rectangle (5.220,3.705);
|
| 48 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,3.120) {ClimaX};
|
| 49 |
+
\draw[wfslate, line width=0.72pt] (4.032,2.990) -- (4.060,2.990);
|
| 50 |
+
\draw[wfslate, line width=0.72pt] (4.032,2.955) -- (4.032,3.025);
|
| 51 |
+
\draw[wfslate, line width=0.72pt] (4.060,2.955) -- (4.060,3.025);
|
| 52 |
+
\filldraw[wfslate] (4.046,2.990) circle[radius=0.045];
|
| 53 |
+
\draw[wforange, line width=0.72pt] (4.036,3.250) -- (4.036,3.250);
|
| 54 |
+
\draw[wforange, line width=0.72pt] (4.036,3.215) -- (4.036,3.285);
|
| 55 |
+
\draw[wforange, line width=0.72pt] (4.036,3.215) -- (4.036,3.285);
|
| 56 |
+
\filldraw[wforange] (3.991,3.205) rectangle (4.081,3.295);
|
| 57 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,2.710) {StormCast};
|
| 58 |
+
\draw[wfslate, line width=0.72pt] (4.036,2.580) -- (4.036,2.580);
|
| 59 |
+
\draw[wfslate, line width=0.72pt] (4.036,2.545) -- (4.036,2.615);
|
| 60 |
+
\draw[wfslate, line width=0.72pt] (4.036,2.545) -- (4.036,2.615);
|
| 61 |
+
\filldraw[wfslate] (4.036,2.580) circle[radius=0.045];
|
| 62 |
+
\draw[wforange, line width=0.72pt] (4.036,2.840) -- (4.036,2.840);
|
| 63 |
+
\draw[wforange, line width=0.72pt] (4.036,2.805) -- (4.036,2.875);
|
| 64 |
+
\draw[wforange, line width=0.72pt] (4.036,2.805) -- (4.036,2.875);
|
| 65 |
+
\filldraw[wforange] (3.991,2.795) rectangle (4.081,2.885);
|
| 66 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,2.300) {DLWP};
|
| 67 |
+
\draw[wfslate, line width=0.72pt] (4.036,2.170) -- (4.036,2.170);
|
| 68 |
+
\draw[wfslate, line width=0.72pt] (4.036,2.135) -- (4.036,2.205);
|
| 69 |
+
\draw[wfslate, line width=0.72pt] (4.036,2.135) -- (4.036,2.205);
|
| 70 |
+
\filldraw[wfslate] (4.036,2.170) circle[radius=0.045];
|
| 71 |
+
\draw[wforange, line width=0.72pt] (4.044,2.430) -- (4.735,2.430);
|
| 72 |
+
\draw[wforange, line width=0.72pt] (4.044,2.395) -- (4.044,2.465);
|
| 73 |
+
\draw[wforange, line width=0.72pt] (4.735,2.395) -- (4.735,2.465);
|
| 74 |
+
\filldraw[wforange] (4.345,2.385) rectangle (4.435,2.475);
|
| 75 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,1.890) {FCN};
|
| 76 |
+
\draw[wfslate, line width=0.72pt] (4.036,1.760) -- (4.036,1.760);
|
| 77 |
+
\draw[wfslate, line width=0.72pt] (4.036,1.725) -- (4.036,1.795);
|
| 78 |
+
\draw[wfslate, line width=0.72pt] (4.036,1.725) -- (4.036,1.795);
|
| 79 |
+
\filldraw[wfslate] (4.036,1.760) circle[radius=0.045];
|
| 80 |
+
\draw[wforange, line width=0.72pt] (3.971,2.020) -- (4.286,2.020);
|
| 81 |
+
\draw[wforange, line width=0.72pt] (3.971,1.985) -- (3.971,2.055);
|
| 82 |
+
\draw[wforange, line width=0.72pt] (4.286,1.985) -- (4.286,2.055);
|
| 83 |
+
\filldraw[wforange] (4.083,1.975) rectangle (4.173,2.065);
|
| 84 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,1.480) {FengWu};
|
| 85 |
+
\draw[wfslate, line width=0.72pt] (4.036,1.350) -- (4.036,1.350);
|
| 86 |
+
\draw[wfslate, line width=0.72pt] (4.036,1.315) -- (4.036,1.385);
|
| 87 |
+
\draw[wfslate, line width=0.72pt] (4.036,1.315) -- (4.036,1.385);
|
| 88 |
+
\filldraw[wfslate] (4.036,1.350) circle[radius=0.045];
|
| 89 |
+
\draw[wforange, line width=0.72pt] (4.028,1.610) -- (4.127,1.610);
|
| 90 |
+
\draw[wforange, line width=0.72pt] (4.028,1.575) -- (4.028,1.645);
|
| 91 |
+
\draw[wforange, line width=0.72pt] (4.127,1.575) -- (4.127,1.645);
|
| 92 |
+
\filldraw[wforange] (4.032,1.565) rectangle (4.122,1.655);
|
| 93 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,1.070) {FuXi};
|
| 94 |
+
\draw[wfslate, line width=0.72pt] (4.036,0.940) -- (4.036,0.940);
|
| 95 |
+
\draw[wfslate, line width=0.72pt] (4.036,0.905) -- (4.036,0.975);
|
| 96 |
+
\draw[wfslate, line width=0.72pt] (4.036,0.905) -- (4.036,0.975);
|
| 97 |
+
\filldraw[wfslate] (4.036,0.940) circle[radius=0.045];
|
| 98 |
+
\draw[wforange, line width=0.72pt] (4.029,1.200) -- (4.087,1.200);
|
| 99 |
+
\draw[wforange, line width=0.72pt] (4.029,1.165) -- (4.029,1.235);
|
| 100 |
+
\draw[wforange, line width=0.72pt] (4.087,1.165) -- (4.087,1.235);
|
| 101 |
+
\filldraw[wforange] (4.013,1.155) rectangle (4.103,1.245);
|
| 102 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,0.660) {Pangu-Weather};
|
| 103 |
+
\draw[wfslate, line width=0.72pt] (4.036,0.530) -- (4.036,0.530);
|
| 104 |
+
\draw[wfslate, line width=0.72pt] (4.036,0.495) -- (4.036,0.565);
|
| 105 |
+
\draw[wfslate, line width=0.72pt] (4.036,0.495) -- (4.036,0.565);
|
| 106 |
+
\filldraw[wfslate] (4.036,0.530) circle[radius=0.045];
|
| 107 |
+
\draw[wforange, line width=0.72pt] (4.025,0.790) -- (4.076,0.790);
|
| 108 |
+
\draw[wforange, line width=0.72pt] (4.025,0.755) -- (4.025,0.825);
|
| 109 |
+
\draw[wforange, line width=0.72pt] (4.076,0.755) -- (4.076,0.825);
|
| 110 |
+
\filldraw[wforange] (4.006,0.745) rectangle (4.096,0.835);
|
| 111 |
+
\node[anchor=east, font=\scriptsize, text=black!82] at (2.320,0.250) {AlphaEarth};
|
| 112 |
+
\draw[wfslate, line width=0.72pt] (4.700,0.120) -- (6.103,0.120);
|
| 113 |
+
\draw[wfslate, line width=0.72pt] (4.700,0.085) -- (4.700,0.155);
|
| 114 |
+
\draw[wfslate, line width=0.72pt] (6.103,0.085) -- (6.103,0.155);
|
| 115 |
+
\filldraw[wfslate] (5.401,0.120) circle[radius=0.045];
|
| 116 |
+
\draw[wforange, line width=0.72pt] (3.872,0.380) -- (4.815,0.380);
|
| 117 |
+
\draw[wforange, line width=0.72pt] (3.872,0.345) -- (3.872,0.415);
|
| 118 |
+
\draw[wforange, line width=0.72pt] (4.815,0.345) -- (4.815,0.415);
|
| 119 |
+
\filldraw[wforange] (4.298,0.335) rectangle (4.388,0.425);
|
| 120 |
+
\end{tikzpicture}
|
paper_outputs/figures/fig_task_contract_tiles.pdf
ADDED
|
Binary file (49.6 kB). View file
|
|
|
paper_outputs/figures/fig_task_rank_map.pdf
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
%PDF-1.4
|
| 2 |
+
%����
|
| 3 |
+
1 0 obj
|
| 4 |
+
<< /Type /Catalog /Pages 2 0 R >>
|
| 5 |
+
endobj
|
| 6 |
+
2 0 obj
|
| 7 |
+
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
| 8 |
+
endobj
|
| 9 |
+
3 0 obj
|
| 10 |
+
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 1120 430] /Resources << /Font << /F1 4 0 R /F2 5 0 R >> >> /Contents 6 0 R >>
|
| 11 |
+
endobj
|
| 12 |
+
4 0 obj
|
| 13 |
+
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
|
| 14 |
+
endobj
|
| 15 |
+
5 0 obj
|
| 16 |
+
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>
|
| 17 |
+
endobj
|
| 18 |
+
6 0 obj
|
| 19 |
+
<< /Length 22799 >>
|
| 20 |
+
stream
|
| 21 |
+
1.0000 1.0000 1.0000 rg 0.00 0.00 1120.00 430.00 re f
|
| 22 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 117.66 376.00 Tm (FireWx-FM ref.) Tj ET
|
| 23 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 211.06 376.00 Tm (Prithvi-WxC) Tj ET
|
| 24 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 308.29 376.00 Tm (Aurora) Tj ET
|
| 25 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 394.93 376.00 Tm (ClimaX) Tj ET
|
| 26 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 471.34 376.00 Tm (StormCast) Tj ET
|
| 27 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 568.76 376.00 Tm (DLWP) Tj ET
|
| 28 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 658.50 376.00 Tm (FCN) Tj ET
|
| 29 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 736.92 376.00 Tm (FengWu) Tj ET
|
| 30 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 829.82 376.00 Tm (FuXi) Tj ET
|
| 31 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 892.30 376.00 Tm (Pangu-Weather) Tj ET
|
| 32 |
+
BT /F2 8.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 987.57 376.00 Tm (AlphaEarth) Tj ET
|
| 33 |
+
BT /F2 7.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 325.00 Tm (Occupancy) Tj ET
|
| 34 |
+
BT /F2 7.10 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 314.00 Tm (Union F1 \(%\)) Tj ET
|
| 35 |
+
BT /F1 6.40 Tf 0.4200 0.4400 0.4600 rg 1 0 0 1 12.00 303.00 Tm (higher better) Tj ET
|
| 36 |
+
0.80 w 0.1500 0.4760 0.4860 rg 1.0000 1.0000 1.0000 RG 108.00 300.00 86.00 42.00 re B
|
| 37 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.88 324.00 Tm (#2) Tj ET
|
| 38 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 142.84 309.00 Tm (59.07) Tj ET
|
| 39 |
+
0.80 w 0.9300 0.9500 0.9400 rg 1.0000 1.0000 1.0000 RG 194.00 300.00 86.00 42.00 re B
|
| 40 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 227.83 324.00 Tm (#11) Tj ET
|
| 41 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 228.84 309.00 Tm (20.19) Tj ET
|
| 42 |
+
0.80 w 0.7780 0.8820 0.8640 rg 1.0000 1.0000 1.0000 RG 280.00 300.00 86.00 42.00 re B
|
| 43 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 316.88 324.00 Tm (#9) Tj ET
|
| 44 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 314.85 309.00 Tm (23.10) Tj ET
|
| 45 |
+
0.80 w 0.0500 0.4000 0.4200 rg 1.0000 1.0000 1.0000 RG 366.00 300.00 86.00 42.00 re B
|
| 46 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 402.88 324.00 Tm (#1) Tj ET
|
| 47 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 400.85 309.00 Tm (60.15) Tj ET
|
| 48 |
+
0.80 w 0.8540 0.9160 0.9020 rg 1.0000 1.0000 1.0000 RG 452.00 300.00 86.00 42.00 re B
|
| 49 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 485.83 324.00 Tm (#10) Tj ET
|
| 50 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 486.85 309.00 Tm (22.38) Tj ET
|
| 51 |
+
0.80 w 0.6260 0.8140 0.7880 rg 1.0000 1.0000 1.0000 RG 538.00 300.00 86.00 42.00 re B
|
| 52 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.88 324.00 Tm (#7) Tj ET
|
| 53 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 572.85 309.00 Tm (28.19) Tj ET
|
| 54 |
+
0.80 w 0.2500 0.5520 0.5520 rg 1.0000 1.0000 1.0000 RG 624.00 300.00 86.00 42.00 re B
|
| 55 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.88 324.00 Tm (#3) Tj ET
|
| 56 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 658.85 309.00 Tm (40.06) Tj ET
|
| 57 |
+
0.80 w 0.7020 0.8480 0.8260 rg 1.0000 1.0000 1.0000 RG 710.00 300.00 86.00 42.00 re B
|
| 58 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.88 324.00 Tm (#8) Tj ET
|
| 59 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 744.85 309.00 Tm (24.10) Tj ET
|
| 60 |
+
0.80 w 0.4500 0.7040 0.6840 rg 1.0000 1.0000 1.0000 RG 796.00 300.00 86.00 42.00 re B
|
| 61 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.88 324.00 Tm (#5) Tj ET
|
| 62 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 830.85 309.00 Tm (37.29) Tj ET
|
| 63 |
+
0.80 w 0.5500 0.7800 0.7500 rg 1.0000 1.0000 1.0000 RG 882.00 300.00 86.00 42.00 re B
|
| 64 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.88 324.00 Tm (#6) Tj ET
|
| 65 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 916.85 309.00 Tm (35.64) Tj ET
|
| 66 |
+
0.80 w 0.3500 0.6280 0.6180 rg 1.0000 1.0000 1.0000 RG 968.00 300.00 86.00 42.00 re B
|
| 67 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 1004.88 324.00 Tm (#4) Tj ET
|
| 68 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 1002.85 309.00 Tm (37.43) Tj ET
|
| 69 |
+
BT /F2 7.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 283.00 Tm (Fire spread) Tj ET
|
| 70 |
+
BT /F2 7.10 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 272.00 Tm (AP \(%\)) Tj ET
|
| 71 |
+
BT /F1 6.40 Tf 0.4200 0.4400 0.4600 rg 1 0 0 1 12.00 261.00 Tm (higher better) Tj ET
|
| 72 |
+
0.80 w 0.0500 0.4000 0.4200 rg 1.0000 1.0000 1.0000 RG 108.00 258.00 86.00 42.00 re B
|
| 73 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.88 282.00 Tm (#1) Tj ET
|
| 74 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 142.84 267.00 Tm (30.09) Tj ET
|
| 75 |
+
0.80 w 0.7780 0.8820 0.8640 rg 1.0000 1.0000 1.0000 RG 194.00 258.00 86.00 42.00 re B
|
| 76 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.88 282.00 Tm (#9) Tj ET
|
| 77 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.66 267.00 Tm (5.00) Tj ET
|
| 78 |
+
0.80 w 0.1500 0.4760 0.4860 rg 1.0000 1.0000 1.0000 RG 280.00 258.00 86.00 42.00 re B
|
| 79 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 316.88 282.00 Tm (#2) Tj ET
|
| 80 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 314.85 267.00 Tm (16.62) Tj ET
|
| 81 |
+
0.80 w 0.6260 0.8140 0.7880 rg 1.0000 1.0000 1.0000 RG 366.00 258.00 86.00 42.00 re B
|
| 82 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 402.88 282.00 Tm (#7) Tj ET
|
| 83 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 400.85 267.00 Tm (11.17) Tj ET
|
| 84 |
+
0.80 w 0.8540 0.9160 0.9020 rg 1.0000 1.0000 1.0000 RG 452.00 258.00 86.00 42.00 re B
|
| 85 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 485.83 282.00 Tm (#10) Tj ET
|
| 86 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.67 267.00 Tm (2.81) Tj ET
|
| 87 |
+
0.80 w 0.7020 0.8480 0.8260 rg 1.0000 1.0000 1.0000 RG 538.00 258.00 86.00 42.00 re B
|
| 88 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.88 282.00 Tm (#8) Tj ET
|
| 89 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.66 267.00 Tm (5.94) Tj ET
|
| 90 |
+
0.80 w 0.9300 0.9500 0.9400 rg 1.0000 1.0000 1.0000 RG 624.00 258.00 86.00 42.00 re B
|
| 91 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 657.83 282.00 Tm (#11) Tj ET
|
| 92 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.66 267.00 Tm (2.39) Tj ET
|
| 93 |
+
0.80 w 0.3500 0.6280 0.6180 rg 1.0000 1.0000 1.0000 RG 710.00 258.00 86.00 42.00 re B
|
| 94 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.88 282.00 Tm (#4) Tj ET
|
| 95 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 744.85 267.00 Tm (13.17) Tj ET
|
| 96 |
+
0.80 w 0.2500 0.5520 0.5520 rg 1.0000 1.0000 1.0000 RG 796.00 258.00 86.00 42.00 re B
|
| 97 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.88 282.00 Tm (#3) Tj ET
|
| 98 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 830.85 267.00 Tm (14.35) Tj ET
|
| 99 |
+
0.80 w 0.4500 0.7040 0.6840 rg 1.0000 1.0000 1.0000 RG 882.00 258.00 86.00 42.00 re B
|
| 100 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.88 282.00 Tm (#5) Tj ET
|
| 101 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 916.85 267.00 Tm (12.69) Tj ET
|
| 102 |
+
0.80 w 0.5500 0.7800 0.7500 rg 1.0000 1.0000 1.0000 RG 968.00 258.00 86.00 42.00 re B
|
| 103 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 1004.88 282.00 Tm (#6) Tj ET
|
| 104 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 1002.85 267.00 Tm (11.83) Tj ET
|
| 105 |
+
BT /F2 7.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 241.00 Tm (Burned area) Tj ET
|
| 106 |
+
BT /F2 7.10 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 230.00 Tm (log-RMSE) Tj ET
|
| 107 |
+
BT /F1 6.40 Tf 0.4200 0.4400 0.4600 rg 1 0 0 1 12.00 219.00 Tm (lower better) Tj ET
|
| 108 |
+
0.80 w 0.0500 0.4000 0.4200 rg 1.0000 1.0000 1.0000 RG 108.00 216.00 86.00 42.00 re B
|
| 109 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.88 240.00 Tm (#1) Tj ET
|
| 110 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.66 225.00 Tm (1.17) Tj ET
|
| 111 |
+
0.80 w 0.3500 0.6280 0.6180 rg 1.0000 1.0000 1.0000 RG 194.00 216.00 86.00 42.00 re B
|
| 112 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.88 240.00 Tm (#4) Tj ET
|
| 113 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.66 225.00 Tm (1.36) Tj ET
|
| 114 |
+
0.80 w 0.7780 0.8820 0.8640 rg 1.0000 1.0000 1.0000 RG 280.00 216.00 86.00 42.00 re B
|
| 115 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 316.88 240.00 Tm (#9) Tj ET
|
| 116 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 316.67 225.00 Tm (1.87) Tj ET
|
| 117 |
+
0.80 w 0.8540 0.9160 0.9020 rg 1.0000 1.0000 1.0000 RG 366.00 216.00 86.00 42.00 re B
|
| 118 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 399.83 240.00 Tm (#10) Tj ET
|
| 119 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 402.67 225.00 Tm (2.03) Tj ET
|
| 120 |
+
0.80 w 0.7020 0.8480 0.8260 rg 1.0000 1.0000 1.0000 RG 452.00 216.00 86.00 42.00 re B
|
| 121 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.88 240.00 Tm (#8) Tj ET
|
| 122 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.67 225.00 Tm (1.67) Tj ET
|
| 123 |
+
0.80 w 0.1500 0.4760 0.4860 rg 1.0000 1.0000 1.0000 RG 538.00 216.00 86.00 42.00 re B
|
| 124 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 574.88 240.00 Tm (#2) Tj ET
|
| 125 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 574.66 225.00 Tm (1.31) Tj ET
|
| 126 |
+
0.80 w 0.4500 0.7040 0.6840 rg 1.0000 1.0000 1.0000 RG 624.00 216.00 86.00 42.00 re B
|
| 127 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.88 240.00 Tm (#5) Tj ET
|
| 128 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.66 225.00 Tm (1.37) Tj ET
|
| 129 |
+
0.80 w 0.5500 0.7800 0.7500 rg 1.0000 1.0000 1.0000 RG 710.00 216.00 86.00 42.00 re B
|
| 130 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.88 240.00 Tm (#6) Tj ET
|
| 131 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.66 225.00 Tm (1.37) Tj ET
|
| 132 |
+
0.80 w 0.6260 0.8140 0.7880 rg 1.0000 1.0000 1.0000 RG 796.00 216.00 86.00 42.00 re B
|
| 133 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.88 240.00 Tm (#7) Tj ET
|
| 134 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.66 225.00 Tm (1.41) Tj ET
|
| 135 |
+
0.80 w 0.2500 0.5520 0.5520 rg 1.0000 1.0000 1.0000 RG 882.00 216.00 86.00 42.00 re B
|
| 136 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.88 240.00 Tm (#3) Tj ET
|
| 137 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.66 225.00 Tm (1.33) Tj ET
|
| 138 |
+
0.80 w 0.9300 0.9500 0.9400 rg 1.0000 1.0000 1.0000 RG 968.00 216.00 86.00 42.00 re B
|
| 139 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 1001.83 240.00 Tm (#11) Tj ET
|
| 140 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 1004.66 225.00 Tm (2.41) Tj ET
|
| 141 |
+
BT /F2 7.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 199.00 Tm (Analog retrieval) Tj ET
|
| 142 |
+
BT /F2 7.10 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 188.00 Tm (nDCG@10) Tj ET
|
| 143 |
+
BT /F1 6.40 Tf 0.4200 0.4400 0.4600 rg 1 0 0 1 12.00 177.00 Tm (higher better) Tj ET
|
| 144 |
+
0.80 w 0.0500 0.4000 0.4200 rg 1.0000 1.0000 1.0000 RG 108.00 174.00 86.00 42.00 re B
|
| 145 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.88 198.00 Tm (#1) Tj ET
|
| 146 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 142.84 183.00 Tm (0.510) Tj ET
|
| 147 |
+
0.80 w 0.9300 0.9500 0.9400 rg 1.0000 1.0000 1.0000 RG 194.00 174.00 86.00 42.00 re B
|
| 148 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 227.83 198.00 Tm (#11) Tj ET
|
| 149 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 228.84 183.00 Tm (0.386) Tj ET
|
| 150 |
+
0.80 w 0.7020 0.8480 0.8260 rg 1.0000 1.0000 1.0000 RG 280.00 174.00 86.00 42.00 re B
|
| 151 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 316.88 198.00 Tm (#8) Tj ET
|
| 152 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 314.85 183.00 Tm (0.405) Tj ET
|
| 153 |
+
0.80 w 0.5500 0.7800 0.7500 rg 1.0000 1.0000 1.0000 RG 366.00 174.00 86.00 42.00 re B
|
| 154 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 402.88 198.00 Tm (#6) Tj ET
|
| 155 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 400.85 183.00 Tm (0.414) Tj ET
|
| 156 |
+
0.80 w 0.6260 0.8140 0.7880 rg 1.0000 1.0000 1.0000 RG 452.00 174.00 86.00 42.00 re B
|
| 157 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.88 198.00 Tm (#7) Tj ET
|
| 158 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 486.85 183.00 Tm (0.408) Tj ET
|
| 159 |
+
0.80 w 0.8540 0.9160 0.9020 rg 1.0000 1.0000 1.0000 RG 538.00 174.00 86.00 42.00 re B
|
| 160 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 571.83 198.00 Tm (#10) Tj ET
|
| 161 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 572.85 183.00 Tm (0.397) Tj ET
|
| 162 |
+
0.80 w 0.2500 0.5520 0.5520 rg 1.0000 1.0000 1.0000 RG 624.00 174.00 86.00 42.00 re B
|
| 163 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.88 198.00 Tm (#3) Tj ET
|
| 164 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 658.85 183.00 Tm (0.432) Tj ET
|
| 165 |
+
0.80 w 0.4500 0.7040 0.6840 rg 1.0000 1.0000 1.0000 RG 710.00 174.00 86.00 42.00 re B
|
| 166 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.88 198.00 Tm (#5) Tj ET
|
| 167 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 744.85 183.00 Tm (0.425) Tj ET
|
| 168 |
+
0.80 w 0.3500 0.6280 0.6180 rg 1.0000 1.0000 1.0000 RG 796.00 174.00 86.00 42.00 re B
|
| 169 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.88 198.00 Tm (#4) Tj ET
|
| 170 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 830.85 183.00 Tm (0.428) Tj ET
|
| 171 |
+
0.80 w 0.7780 0.8820 0.8640 rg 1.0000 1.0000 1.0000 RG 882.00 174.00 86.00 42.00 re B
|
| 172 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.88 198.00 Tm (#9) Tj ET
|
| 173 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 916.85 183.00 Tm (0.402) Tj ET
|
| 174 |
+
0.80 w 0.1500 0.4760 0.4860 rg 1.0000 1.0000 1.0000 RG 968.00 174.00 86.00 42.00 re B
|
| 175 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 1004.88 198.00 Tm (#2) Tj ET
|
| 176 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 1002.85 183.00 Tm (0.509) Tj ET
|
| 177 |
+
BT /F2 7.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 157.00 Tm (Smoke PM2.5) Tj ET
|
| 178 |
+
BT /F2 7.10 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 146.00 Tm (RMSE) Tj ET
|
| 179 |
+
BT /F1 6.40 Tf 0.4200 0.4400 0.4600 rg 1 0 0 1 12.00 135.00 Tm (lower better) Tj ET
|
| 180 |
+
0.80 w 0.1500 0.4760 0.4860 rg 1.0000 1.0000 1.0000 RG 108.00 132.00 86.00 42.00 re B
|
| 181 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.88 156.00 Tm (#2) Tj ET
|
| 182 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.66 141.00 Tm (4.46) Tj ET
|
| 183 |
+
0.80 w 0.7020 0.8480 0.8260 rg 1.0000 1.0000 1.0000 RG 194.00 132.00 86.00 42.00 re B
|
| 184 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.88 156.00 Tm (#8) Tj ET
|
| 185 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.66 141.00 Tm (6.04) Tj ET
|
| 186 |
+
0.80 w 0.7780 0.8820 0.8640 rg 1.0000 1.0000 1.0000 RG 280.00 132.00 86.00 42.00 re B
|
| 187 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 316.88 156.00 Tm (#9) Tj ET
|
| 188 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 316.67 141.00 Tm (6.04) Tj ET
|
| 189 |
+
0.80 w 0.8540 0.9160 0.9020 rg 1.0000 1.0000 1.0000 RG 366.00 132.00 86.00 42.00 re B
|
| 190 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 399.83 156.00 Tm (#10) Tj ET
|
| 191 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 402.67 141.00 Tm (6.04) Tj ET
|
| 192 |
+
0.80 w 0.9300 0.9500 0.9400 rg 1.0000 1.0000 1.0000 RG 452.00 132.00 86.00 42.00 re B
|
| 193 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 485.83 156.00 Tm (#11) Tj ET
|
| 194 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.67 141.00 Tm (6.12) Tj ET
|
| 195 |
+
0.80 w 0.4500 0.7040 0.6840 rg 1.0000 1.0000 1.0000 RG 538.00 132.00 86.00 42.00 re B
|
| 196 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.88 156.00 Tm (#5) Tj ET
|
| 197 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.66 141.00 Tm (5.93) Tj ET
|
| 198 |
+
0.80 w 0.3500 0.6280 0.6180 rg 1.0000 1.0000 1.0000 RG 624.00 132.00 86.00 42.00 re B
|
| 199 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.88 156.00 Tm (#4) Tj ET
|
| 200 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.66 141.00 Tm (5.93) Tj ET
|
| 201 |
+
0.80 w 0.5500 0.7800 0.7500 rg 1.0000 1.0000 1.0000 RG 710.00 132.00 86.00 42.00 re B
|
| 202 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.88 156.00 Tm (#6) Tj ET
|
| 203 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.66 141.00 Tm (5.93) Tj ET
|
| 204 |
+
0.80 w 0.6260 0.8140 0.7880 rg 1.0000 1.0000 1.0000 RG 796.00 132.00 86.00 42.00 re B
|
| 205 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.88 156.00 Tm (#7) Tj ET
|
| 206 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.66 141.00 Tm (5.93) Tj ET
|
| 207 |
+
0.80 w 0.2500 0.5520 0.5520 rg 1.0000 1.0000 1.0000 RG 882.00 132.00 86.00 42.00 re B
|
| 208 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.88 156.00 Tm (#3) Tj ET
|
| 209 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.66 141.00 Tm (5.93) Tj ET
|
| 210 |
+
0.80 w 0.0500 0.4000 0.4200 rg 1.0000 1.0000 1.0000 RG 968.00 132.00 86.00 42.00 re B
|
| 211 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 1004.88 156.00 Tm (#1) Tj ET
|
| 212 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 1004.66 141.00 Tm (4.44) Tj ET
|
| 213 |
+
BT /F2 7.70 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 115.00 Tm (Extreme heat) Tj ET
|
| 214 |
+
BT /F2 7.10 Tf 0.1200 0.1400 0.1600 rg 1 0 0 1 12.00 104.00 Tm (RMSE-C) Tj ET
|
| 215 |
+
BT /F1 6.40 Tf 0.4200 0.4400 0.4600 rg 1 0 0 1 12.00 93.00 Tm (lower better) Tj ET
|
| 216 |
+
0.80 w 0.0500 0.4000 0.4200 rg 1.0000 1.0000 1.0000 RG 108.00 90.00 86.00 42.00 re B
|
| 217 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 144.88 114.00 Tm (#1) Tj ET
|
| 218 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 142.84 99.00 Tm (0.218) Tj ET
|
| 219 |
+
0.80 w 0.7780 0.8820 0.8640 rg 1.0000 1.0000 1.0000 RG 194.00 90.00 86.00 42.00 re B
|
| 220 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.88 114.00 Tm (#9) Tj ET
|
| 221 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 230.66 99.00 Tm (4.62) Tj ET
|
| 222 |
+
0.80 w 0.9300 0.9500 0.9400 rg 1.0000 1.0000 1.0000 RG 280.00 90.00 86.00 42.00 re B
|
| 223 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 313.83 114.00 Tm (#11) Tj ET
|
| 224 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 314.85 99.00 Tm (18.05) Tj ET
|
| 225 |
+
0.80 w 0.8540 0.9160 0.9020 rg 1.0000 1.0000 1.0000 RG 366.00 90.00 86.00 42.00 re B
|
| 226 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 399.83 114.00 Tm (#10) Tj ET
|
| 227 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 400.85 99.00 Tm (17.65) Tj ET
|
| 228 |
+
0.80 w 0.2500 0.5520 0.5520 rg 1.0000 1.0000 1.0000 RG 452.00 90.00 86.00 42.00 re B
|
| 229 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.88 114.00 Tm (#3) Tj ET
|
| 230 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 488.67 99.00 Tm (1.77) Tj ET
|
| 231 |
+
0.80 w 0.7020 0.8480 0.8260 rg 1.0000 1.0000 1.0000 RG 538.00 90.00 86.00 42.00 re B
|
| 232 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.88 114.00 Tm (#8) Tj ET
|
| 233 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 574.66 99.00 Tm (2.27) Tj ET
|
| 234 |
+
0.80 w 0.5500 0.7800 0.7500 rg 1.0000 1.0000 1.0000 RG 624.00 90.00 86.00 42.00 re B
|
| 235 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.88 114.00 Tm (#6) Tj ET
|
| 236 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 660.66 99.00 Tm (2.17) Tj ET
|
| 237 |
+
0.80 w 0.3500 0.6280 0.6180 rg 1.0000 1.0000 1.0000 RG 710.00 90.00 86.00 42.00 re B
|
| 238 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.88 114.00 Tm (#4) Tj ET
|
| 239 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 746.66 99.00 Tm (2.13) Tj ET
|
| 240 |
+
0.80 w 0.4500 0.7040 0.6840 rg 1.0000 1.0000 1.0000 RG 796.00 90.00 86.00 42.00 re B
|
| 241 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.88 114.00 Tm (#5) Tj ET
|
| 242 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 832.66 99.00 Tm (2.13) Tj ET
|
| 243 |
+
0.80 w 0.6260 0.8140 0.7880 rg 1.0000 1.0000 1.0000 RG 882.00 90.00 86.00 42.00 re B
|
| 244 |
+
BT /F2 11.20 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.88 114.00 Tm (#7) Tj ET
|
| 245 |
+
BT /F1 7.00 Tf 0.0700 0.0900 0.1100 rg 1 0 0 1 918.66 99.00 Tm (2.20) Tj ET
|
| 246 |
+
0.80 w 0.1500 0.4760 0.4860 rg 1.0000 1.0000 1.0000 RG 968.00 90.00 86.00 42.00 re B
|
| 247 |
+
BT /F2 11.20 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 1004.88 114.00 Tm (#2) Tj ET
|
| 248 |
+
BT /F1 7.00 Tf 1.0000 1.0000 1.0000 rg 1 0 0 1 1002.85 99.00 Tm (0.219) Tj ET
|
| 249 |
+
0.80 w 0.2000 0.2200 0.2400 RG 108.00 90.00 946.00 252.00 re S
|
| 250 |
+
BT /F2 9.00 Tf 0.2400 0.2500 0.2600 rg 1 0 0 1 908.00 63.00 Tm (within-row rank) Tj ET
|
| 251 |
+
0.9300 0.9500 0.9400 rg 834.00 46.00 2.60 10.00 re f
|
| 252 |
+
0.9300 0.9500 0.9400 rg 836.50 46.00 2.60 10.00 re f
|
| 253 |
+
0.9300 0.9500 0.9400 rg 839.00 46.00 2.60 10.00 re f
|
| 254 |
+
0.9300 0.9500 0.9400 rg 841.50 46.00 2.60 10.00 re f
|
| 255 |
+
0.9300 0.9500 0.9400 rg 844.00 46.00 2.60 10.00 re f
|
| 256 |
+
0.9300 0.9500 0.9400 rg 846.50 46.00 2.60 10.00 re f
|
| 257 |
+
0.9300 0.9500 0.9400 rg 849.00 46.00 2.60 10.00 re f
|
| 258 |
+
0.9300 0.9500 0.9400 rg 851.50 46.00 2.60 10.00 re f
|
| 259 |
+
0.8540 0.9160 0.9020 rg 854.00 46.00 2.60 10.00 re f
|
| 260 |
+
0.8540 0.9160 0.9020 rg 856.50 46.00 2.60 10.00 re f
|
| 261 |
+
0.8540 0.9160 0.9020 rg 859.00 46.00 2.60 10.00 re f
|
| 262 |
+
0.8540 0.9160 0.9020 rg 861.50 46.00 2.60 10.00 re f
|
| 263 |
+
0.8540 0.9160 0.9020 rg 864.00 46.00 2.60 10.00 re f
|
| 264 |
+
0.8540 0.9160 0.9020 rg 866.50 46.00 2.60 10.00 re f
|
| 265 |
+
0.8540 0.9160 0.9020 rg 869.00 46.00 2.60 10.00 re f
|
| 266 |
+
0.8540 0.9160 0.9020 rg 871.50 46.00 2.60 10.00 re f
|
| 267 |
+
0.7780 0.8820 0.8640 rg 874.00 46.00 2.60 10.00 re f
|
| 268 |
+
0.7780 0.8820 0.8640 rg 876.50 46.00 2.60 10.00 re f
|
| 269 |
+
0.7780 0.8820 0.8640 rg 879.00 46.00 2.60 10.00 re f
|
| 270 |
+
0.7780 0.8820 0.8640 rg 881.50 46.00 2.60 10.00 re f
|
| 271 |
+
0.7780 0.8820 0.8640 rg 884.00 46.00 2.60 10.00 re f
|
| 272 |
+
0.7780 0.8820 0.8640 rg 886.50 46.00 2.60 10.00 re f
|
| 273 |
+
0.7780 0.8820 0.8640 rg 889.00 46.00 2.60 10.00 re f
|
| 274 |
+
0.7780 0.8820 0.8640 rg 891.50 46.00 2.60 10.00 re f
|
| 275 |
+
0.7020 0.8480 0.8260 rg 894.00 46.00 2.60 10.00 re f
|
| 276 |
+
0.7020 0.8480 0.8260 rg 896.50 46.00 2.60 10.00 re f
|
| 277 |
+
0.7020 0.8480 0.8260 rg 899.00 46.00 2.60 10.00 re f
|
| 278 |
+
0.7020 0.8480 0.8260 rg 901.50 46.00 2.60 10.00 re f
|
| 279 |
+
0.7020 0.8480 0.8260 rg 904.00 46.00 2.60 10.00 re f
|
| 280 |
+
0.7020 0.8480 0.8260 rg 906.50 46.00 2.60 10.00 re f
|
| 281 |
+
0.7020 0.8480 0.8260 rg 909.00 46.00 2.60 10.00 re f
|
| 282 |
+
0.7020 0.8480 0.8260 rg 911.50 46.00 2.60 10.00 re f
|
| 283 |
+
0.6260 0.8140 0.7880 rg 914.00 46.00 2.60 10.00 re f
|
| 284 |
+
0.6260 0.8140 0.7880 rg 916.50 46.00 2.60 10.00 re f
|
| 285 |
+
0.6260 0.8140 0.7880 rg 919.00 46.00 2.60 10.00 re f
|
| 286 |
+
0.6260 0.8140 0.7880 rg 921.50 46.00 2.60 10.00 re f
|
| 287 |
+
0.6260 0.8140 0.7880 rg 924.00 46.00 2.60 10.00 re f
|
| 288 |
+
0.6260 0.8140 0.7880 rg 926.50 46.00 2.60 10.00 re f
|
| 289 |
+
0.6260 0.8140 0.7880 rg 929.00 46.00 2.60 10.00 re f
|
| 290 |
+
0.6260 0.8140 0.7880 rg 931.50 46.00 2.60 10.00 re f
|
| 291 |
+
0.5500 0.7800 0.7500 rg 934.00 46.00 2.60 10.00 re f
|
| 292 |
+
0.5500 0.7800 0.7500 rg 936.50 46.00 2.60 10.00 re f
|
| 293 |
+
0.5500 0.7800 0.7500 rg 939.00 46.00 2.60 10.00 re f
|
| 294 |
+
0.5500 0.7800 0.7500 rg 941.50 46.00 2.60 10.00 re f
|
| 295 |
+
0.5500 0.7800 0.7500 rg 944.00 46.00 2.60 10.00 re f
|
| 296 |
+
0.5500 0.7800 0.7500 rg 946.50 46.00 2.60 10.00 re f
|
| 297 |
+
0.5500 0.7800 0.7500 rg 949.00 46.00 2.60 10.00 re f
|
| 298 |
+
0.5500 0.7800 0.7500 rg 951.50 46.00 2.60 10.00 re f
|
| 299 |
+
0.4500 0.7040 0.6840 rg 954.00 46.00 2.60 10.00 re f
|
| 300 |
+
0.4500 0.7040 0.6840 rg 956.50 46.00 2.60 10.00 re f
|
| 301 |
+
0.4500 0.7040 0.6840 rg 959.00 46.00 2.60 10.00 re f
|
| 302 |
+
0.4500 0.7040 0.6840 rg 961.50 46.00 2.60 10.00 re f
|
| 303 |
+
0.4500 0.7040 0.6840 rg 964.00 46.00 2.60 10.00 re f
|
| 304 |
+
0.4500 0.7040 0.6840 rg 966.50 46.00 2.60 10.00 re f
|
| 305 |
+
0.4500 0.7040 0.6840 rg 969.00 46.00 2.60 10.00 re f
|
| 306 |
+
0.4500 0.7040 0.6840 rg 971.50 46.00 2.60 10.00 re f
|
| 307 |
+
0.3500 0.6280 0.6180 rg 974.00 46.00 2.60 10.00 re f
|
| 308 |
+
0.3500 0.6280 0.6180 rg 976.50 46.00 2.60 10.00 re f
|
| 309 |
+
0.3500 0.6280 0.6180 rg 979.00 46.00 2.60 10.00 re f
|
| 310 |
+
0.3500 0.6280 0.6180 rg 981.50 46.00 2.60 10.00 re f
|
| 311 |
+
0.3500 0.6280 0.6180 rg 984.00 46.00 2.60 10.00 re f
|
| 312 |
+
0.3500 0.6280 0.6180 rg 986.50 46.00 2.60 10.00 re f
|
| 313 |
+
0.3500 0.6280 0.6180 rg 989.00 46.00 2.60 10.00 re f
|
| 314 |
+
0.3500 0.6280 0.6180 rg 991.50 46.00 2.60 10.00 re f
|
| 315 |
+
0.2500 0.5520 0.5520 rg 994.00 46.00 2.60 10.00 re f
|
| 316 |
+
0.2500 0.5520 0.5520 rg 996.50 46.00 2.60 10.00 re f
|
| 317 |
+
0.2500 0.5520 0.5520 rg 999.00 46.00 2.60 10.00 re f
|
| 318 |
+
0.2500 0.5520 0.5520 rg 1001.50 46.00 2.60 10.00 re f
|
| 319 |
+
0.2500 0.5520 0.5520 rg 1004.00 46.00 2.60 10.00 re f
|
| 320 |
+
0.2500 0.5520 0.5520 rg 1006.50 46.00 2.60 10.00 re f
|
| 321 |
+
0.2500 0.5520 0.5520 rg 1009.00 46.00 2.60 10.00 re f
|
| 322 |
+
0.2500 0.5520 0.5520 rg 1011.50 46.00 2.60 10.00 re f
|
| 323 |
+
0.1500 0.4760 0.4860 rg 1014.00 46.00 2.60 10.00 re f
|
| 324 |
+
0.1500 0.4760 0.4860 rg 1016.50 46.00 2.60 10.00 re f
|
| 325 |
+
0.1500 0.4760 0.4860 rg 1019.00 46.00 2.60 10.00 re f
|
| 326 |
+
0.1500 0.4760 0.4860 rg 1021.50 46.00 2.60 10.00 re f
|
| 327 |
+
0.1500 0.4760 0.4860 rg 1024.00 46.00 2.60 10.00 re f
|
| 328 |
+
0.1500 0.4760 0.4860 rg 1026.50 46.00 2.60 10.00 re f
|
| 329 |
+
0.1500 0.4760 0.4860 rg 1029.00 46.00 2.60 10.00 re f
|
| 330 |
+
0.1500 0.4760 0.4860 rg 1031.50 46.00 2.60 10.00 re f
|
| 331 |
+
BT /F1 7.00 Tf 0.2500 0.2600 0.2700 rg 1 0 0 1 834.00 34.00 Tm (rank 11) Tj ET
|
| 332 |
+
BT /F1 7.00 Tf 0.2500 0.2600 0.2700 rg 1 0 0 1 1013.84 34.00 Tm (rank 1) Tj ET
|
| 333 |
+
endstream
|
| 334 |
+
endobj
|
| 335 |
+
xref
|
| 336 |
+
0 7
|
| 337 |
+
0000000000 65535 f
|
| 338 |
+
0000000015 00000 n
|
| 339 |
+
0000000064 00000 n
|
| 340 |
+
0000000121 00000 n
|
| 341 |
+
0000000258 00000 n
|
| 342 |
+
0000000328 00000 n
|
| 343 |
+
0000000403 00000 n
|
| 344 |
+
trailer
|
| 345 |
+
<< /Size 7 /Root 1 0 R >>
|
| 346 |
+
startxref
|
| 347 |
+
23255
|
| 348 |
+
%%EOF
|
paper_outputs/figures/matching.pdf
ADDED
|
Binary file (42.8 kB). View file
|
|
|
paper_outputs/tables/tab_app_analog_rank_depth.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{3pt}
|
| 5 |
+
\caption{For fixed retrieval \(\mathcal{T}\) and \(\Omega\), this table reports nDCG@5, best log gap, and rank \(\rho\) in addition to the main nDCG@10/log-error metrics. Cells report mean with small std.}
|
| 6 |
+
\label{tab:app_analog_rank_depth}
|
| 7 |
+
\begin{tabular}{lccc}
|
| 8 |
+
\toprule
|
| 9 |
+
Backbone & nDCG@5 & best log gap & rank $\rho$ \\
|
| 10 |
+
\midrule
|
| 11 |
+
FireWx-FM ref. & \ms{0.5175}{0.0445} & \ms{0.1868}{0.0285} & \ms{0.6019}{0.1460} \\
|
| 12 |
+
Prithvi-WxC & \ms{0.3591}{0.0107} & \ms{0.2151}{0.0594} & \ms{0.1514}{0.1489} \\
|
| 13 |
+
Aurora & \ms{0.4423}{0.0210} & \ms{0.1551}{0.0437} & \ms{0.2162}{0.1856} \\
|
| 14 |
+
ClimaX & \ms{0.4151}{0.0293} & \ms{0.2129}{0.0653} & \ms{0.1587}{0.2831} \\
|
| 15 |
+
StormCast & \ms{0.3960}{0.0240} & \ms{0.1714}{0.0310} & \ms{0.1258}{0.1625} \\
|
| 16 |
+
DLWP & \ms{0.3795}{0.0274} & \ms{0.1944}{0.0807} & \ms{-0.3865}{0.2802} \\
|
| 17 |
+
FCN & \ms{0.4250}{0.0112} & \ms{0.1856}{0.0846} & \ms{-0.1357}{0.2571} \\
|
| 18 |
+
FengWu & \ms{0.4228}{0.0310} & \ms{0.1870}{0.0858} & \ms{-0.1926}{0.2194} \\
|
| 19 |
+
FuXi & \ms{0.4544}{0.0356} & \ms{0.2171}{0.0806} & \ms{-0.1367}{0.2885} \\
|
| 20 |
+
Pangu-Weather & \ms{0.3988}{0.0506} & \ms{0.1901}{0.0838} & \ms{-0.1970}{0.2216} \\
|
| 21 |
+
AlphaEarth & \ms{0.5276}{0.0531} & \ms{0.1782}{0.0454} & \ms{0.4639}{0.2802} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
paper_outputs/tables/tab_app_burned_area_median_acre.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{3pt}
|
| 5 |
+
\caption{For fixed final-area \(\mathcal{T}\) and \(\Omega\), this table reports median log error and acre-scale errors in addition to the main log-RMSE/log-MAE/Spearman metrics. Cells report mean with small std.}
|
| 6 |
+
\label{tab:app_burned_area_median_acre}
|
| 7 |
+
\begin{tabular}{lccc}
|
| 8 |
+
\toprule
|
| 9 |
+
Backbone & log median AE & acre median AE & acre MAPE \\
|
| 10 |
+
\midrule
|
| 11 |
+
FireWx-FM ref. & \ms{1.0235}{0.0982} & \ms{4504.0692}{459.0483} & \ms{1.4525}{0.0254} \\
|
| 12 |
+
Prithvi-WxC & \ms{1.2184}{0.2107} & \ms{5375.8770}{788.7906} & \ms{1.9517}{0.2875} \\
|
| 13 |
+
Aurora & \ms{1.4547}{0.0301} & \ms{9904.9483}{457.4260} & \ms{6.8728}{3.0026} \\
|
| 14 |
+
ClimaX & \ms{1.6841}{0.1818} & \ms{18130.4820}{3248.3873} & \ms{8.2373}{2.8540} \\
|
| 15 |
+
StormCast & \ms{1.4522}{0.1519} & \ms{11155.7881}{2020.8656} & \ms{4.6142}{1.1500} \\
|
| 16 |
+
DLWP & \ms{1.0952}{0.1306} & \ms{4406.9315}{303.0944} & \ms{1.7357}{0.3625} \\
|
| 17 |
+
FCN & \ms{1.1688}{0.1139} & \ms{5166.9993}{213.0333} & \ms{2.0800}{0.4004} \\
|
| 18 |
+
FengWu & \ms{1.1589}{0.1772} & \ms{5137.2822}{628.7543} & \ms{2.0944}{0.4545} \\
|
| 19 |
+
FuXi & \ms{1.1855}{0.0612} & \ms{5697.7117}{796.8785} & \ms{2.4411}{0.5567} \\
|
| 20 |
+
Pangu-Weather & \ms{1.1221}{0.1470} & \ms{5092.3621}{483.8243} & \ms{1.9571}{0.3113} \\
|
| 21 |
+
AlphaEarth & \ms{1.7459}{0.6057} & \ms{15110.7573}{7106.3417} & \ms{9.7398}{2.7425} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
paper_outputs/tables/tab_app_contract_params_full.tex
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table}[h]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{3.5pt}
|
| 5 |
+
\renewcommand{\arraystretch}{1.2}
|
| 6 |
+
\caption{Fixed scoring values used by each task-form contract.}
|
| 7 |
+
\label{tab:app_contract_params_full}
|
| 8 |
+
\begin{adjustbox}{max width=\textwidth}
|
| 9 |
+
\begin{tabular}{llll}
|
| 10 |
+
\toprule
|
| 11 |
+
\textbf{\(\mathcal{T}\)} & \textbf{Scoring} & \textbf{Validation} & \textbf{\(\Omega\)} \\
|
| 12 |
+
\midrule
|
| 13 |
+
Occupancy & \(k=8,\Delta t=3\); exact/tol./union \(F_1\) & val. strict \(F_1\) & global; top-5/10/20\% fire-prone \\
|
| 14 |
+
Fire spread & \(k=4,\Delta t=0\); exact/spatial \(F_1\), AP & val. spatial \(F_1\) & spread-region cells \\
|
| 15 |
+
Final burned area & log-RMSE, log-MAE, Spearman \(\rho\) & val. log-RMSE & test events \\
|
| 16 |
+
Analog retrieval & nDCG@10; retrieved-event log error & val. nDCG@10 & test events \\
|
| 17 |
+
Smoke PM\(_{2.5}\) & RMSE, MAE, Pearson \(r\); exceedance 35 & val. RMSE & test stations \\
|
| 18 |
+
Extreme heat & RMSE-C, MAE-C, exceedance \(F_1\) & val. threshold 27/30/33\(^{\circ}\)C & heat-region stations \\
|
| 19 |
+
\bottomrule
|
| 20 |
+
\end{tabular}
|
| 21 |
+
\end{adjustbox}
|
| 22 |
+
\end{table}
|
paper_outputs/tables/tab_app_head_architectures.tex
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table}[h]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{5pt}
|
| 5 |
+
\renewcommand{\arraystretch}{1.3}
|
| 6 |
+
\caption{Lightweight head architectures used in the fixed-contract transfer comparisons.
|
| 7 |
+
All heads are trained from random initialisation on the frozen backbone features.
|
| 8 |
+
Parameter counts are approximate and depend on the feature dimensionality of each backbone.}
|
| 9 |
+
\label{tab:app_head_architectures}
|
| 10 |
+
\begin{tabular}{p{0.15\textwidth}p{0.30\textwidth}p{0.12\textwidth}p{0.33\textwidth}}
|
| 11 |
+
\toprule
|
| 12 |
+
\textbf{$\mathcal{A}$ head} & \textbf{Architecture} & \textbf{Approx.\ params} & \textbf{Notes} \\
|
| 13 |
+
\midrule
|
| 14 |
+
Constant prior &
|
| 15 |
+
Outputs a fixed bias vector, ignoring input features. &
|
| 16 |
+
Output dimension only &
|
| 17 |
+
Provides a degenerate baseline; selected when backbone features carry no useful signal. \\
|
| 18 |
+
Linear probe &
|
| 19 |
+
Single linear layer mapping backbone features to output. No nonlinearity. &
|
| 20 |
+
$d\times c + c$ &
|
| 21 |
+
Standard frozen-representation baseline. \\
|
| 22 |
+
Pixel MLP &
|
| 23 |
+
Two-layer MLP applied independently per spatial unit. &
|
| 24 |
+
$d\times h + h\times c$ &
|
| 25 |
+
Captures per-pixel nonlinearity; ignores spatial context. \\
|
| 26 |
+
Shallow adapter &
|
| 27 |
+
Two-layer MLP with a spatial context window; uses $3\times3$ convolution before the linear output. &
|
| 28 |
+
$9dh + hc$ &
|
| 29 |
+
Balances local spatial context with parameter efficiency. \\
|
| 30 |
+
Wide adapter &
|
| 31 |
+
Shallow adapter with wider hidden dimension. &
|
| 32 |
+
$9dH + Hc$ &
|
| 33 |
+
Higher capacity variant; can overfit on small fire-event sets. \\
|
| 34 |
+
\bottomrule
|
| 35 |
+
\end{tabular}
|
| 36 |
+
\end{table}
|
paper_outputs/tables/tab_app_heat_event_pr.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{3pt}
|
| 5 |
+
\caption{For fixed heat \(\mathcal{T}\) and heat-region \(\Omega\), this table reports precision and recall for the exceedance label used by the main \(F_1\). Cells report mean with small std.}
|
| 6 |
+
\label{tab:app_heat_event_pr}
|
| 7 |
+
\begin{tabular}{lcc}
|
| 8 |
+
\toprule
|
| 9 |
+
Backbone & precision & recall \\
|
| 10 |
+
\midrule
|
| 11 |
+
FireWx-FM ref. & \ms{0.9767}{0.0117} & \ms{0.9330}{0.0299} \\
|
| 12 |
+
Prithvi-WxC & \ms{0.8260}{0.0030} & \ms{0.9173}{0.0033} \\
|
| 13 |
+
Aurora & \ms{0.5920}{0.0347} & \ms{0.0517}{0.0020} \\
|
| 14 |
+
ClimaX & \ms{0.7397}{0.0099} & \ms{0.7994}{0.0051} \\
|
| 15 |
+
StormCast & \ms{0.8840}{0.0237} & \ms{0.9320}{0.0165} \\
|
| 16 |
+
DLWP & \ms{0.9429}{0.0085} & \ms{0.8899}{0.0167} \\
|
| 17 |
+
FCN & \ms{0.9408}{0.0097} & \ms{0.9111}{0.0127} \\
|
| 18 |
+
FengWu & \ms{0.3808}{0.2719} & \ms{0.0266}{0.0267} \\
|
| 19 |
+
FuXi & \ms{0.3262}{0.1262} & \ms{0.1810}{0.0481} \\
|
| 20 |
+
Pangu-Weather & \ms{0.1159}{0.0743} & \ms{0.0112}{0.0032} \\
|
| 21 |
+
AlphaEarth & \ms{0.9824}{0.0040} & \ms{0.9278}{0.0178} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
paper_outputs/tables/tab_app_matching_rule_params.tex
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table}[h]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{10pt}
|
| 5 |
+
\renewcommand{\arraystretch}{1.2}
|
| 6 |
+
\caption{Matching-rule values used in the evaluation contracts.}
|
| 7 |
+
\label{tab:app_matching_rule_params}
|
| 8 |
+
\begin{tabular}{lll}
|
| 9 |
+
\toprule
|
| 10 |
+
\textbf{Parameter} & \textbf{Occupancy} & \textbf{Fire spread} \\
|
| 11 |
+
\midrule
|
| 12 |
+
\(k\) & 8 cells & 4 cells \\
|
| 13 |
+
\(\Delta t\) & 3 for union; 0 spatial-only & 0 \\
|
| 14 |
+
\(\tau\) & val. strict \(F_1\) & val. spatial \(F_1\) \\
|
| 15 |
+
\bottomrule
|
| 16 |
+
\end{tabular}
|
| 17 |
+
\end{table}
|
paper_outputs/tables/tab_app_occupancy_ppr_scope.tex
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{4pt}
|
| 5 |
+
\renewcommand{\arraystretch}{1.18}
|
| 6 |
+
\caption{For fixed occupancy \(\mathcal{T}\), this table reports predicted-positive rate.
|
| 7 |
+
Values are percentages under the same validation-selected strict threshold.
|
| 8 |
+
Scopes \(\Omega\) are fixed before test scoring; cells report five-seed mean with std in small type.}
|
| 9 |
+
\label{tab:app_occupancy_ppr_scope}
|
| 10 |
+
\begin{tabular}{lcccc}
|
| 11 |
+
\toprule
|
| 12 |
+
\textbf{Backbone} & \textbf{\(\Omega=\)global} & \textbf{\(\Omega=\)top 5\%} & \textbf{\(\Omega=\)top 10\%} & \textbf{\(\Omega=\)top 20\%} \\
|
| 13 |
+
\midrule
|
| 14 |
+
FireWx-FM ref. & \ms{1.6808}{0.3684} & \ms{3.0619}{1.0925} & \ms{1.5310}{0.5463} & \ms{0.7655}{0.2732} \\
|
| 15 |
+
Prithvi-WxC & \ms{61.9711}{30.9101} & \ms{57.4117}{47.8987} & \ms{58.4565}{51.0897} & \ms{58.9788}{52.6991} \\
|
| 16 |
+
Aurora & \ms{55.5849}{19.7524} & \ms{57.2238}{35.3400} & \ms{68.7942}{37.6958} & \ms{67.2891}{38.3991} \\
|
| 17 |
+
ClimaX & \ms{5.6763}{3.9261} & \ms{24.0091}{9.2816} & \ms{11.8450}{4.5067} & \ms{5.7442}{4.1341} \\
|
| 18 |
+
StormCast & \ms{60.6507}{17.4895} & \ms{57.6017}{35.2921} & \ms{68.0766}{37.3899} & \ms{67.8397}{39.2410} \\
|
| 19 |
+
DLWP & \ms{4.3221}{1.5619} & \ms{9.4001}{5.0807} & \ms{4.9700}{3.6849} & \ms{1.9198}{1.4678} \\
|
| 20 |
+
FCN & \ms{1.5202}{1.3446} & \ms{4.7856}{2.9409} & \ms{2.7257}{1.6353} & \ms{0.8368}{0.2358} \\
|
| 21 |
+
FengWu & \ms{0.4277}{0.4830} & \ms{0.6004}{0.3041} & \ms{0.2609}{0.1935} & \ms{0.1501}{0.1206} \\
|
| 22 |
+
FuXi & \ms{0.4505}{0.2773} & \ms{2.9315}{2.6392} & \ms{0.5197}{0.6074} & \ms{0.3621}{0.4346} \\
|
| 23 |
+
Pangu-Weather & \ms{1.0801}{1.1308} & \ms{2.0549}{2.1893} & \ms{1.4029}{1.4739} & \ms{1.0103}{1.1084} \\
|
| 24 |
+
AlphaEarth & \ms{0.0691}{0.0499} & \ms{0.2826}{0.1497} & \ms{0.1524}{0.0770} & \ms{0.0656}{0.0414} \\
|
| 25 |
+
\bottomrule
|
| 26 |
+
\end{tabular}
|
| 27 |
+
\end{table*}
|
paper_outputs/tables/tab_app_scope_params.tex
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table}[h]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{8pt}
|
| 5 |
+
\renewcommand{\arraystretch}{1.2}
|
| 6 |
+
\caption{Scope values used in the evaluation contracts.}
|
| 7 |
+
\label{tab:app_scope_params}
|
| 8 |
+
\begin{tabular}{lcc}
|
| 9 |
+
\toprule
|
| 10 |
+
\textbf{\(\Omega\)} & \textbf{Definition} & \textbf{Units} \\
|
| 11 |
+
\midrule
|
| 12 |
+
Global & full domain & 8,085,000 test cells \\
|
| 13 |
+
Fire-prone top-5\% & top 5\% by training-period fire frequency & 404,280 test cells \\
|
| 14 |
+
Fire-prone top-10\% & top 10\% by training-period fire frequency & 808,560 test cells \\
|
| 15 |
+
Fire-prone top-20\% & top 20\% by training-period fire frequency & 1,617,000 test cells \\
|
| 16 |
+
Spread region & union of \(\widehat{B}\) and \(B\) & event-specific cells \\
|
| 17 |
+
\bottomrule
|
| 18 |
+
\end{tabular}
|
| 19 |
+
\end{table}
|
paper_outputs/tables/tab_app_seed_robustness.tex
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table}[h]
|
| 2 |
+
\centering
|
| 3 |
+
\small
|
| 4 |
+
\setlength{\tabcolsep}{5pt}
|
| 5 |
+
\renewcommand{\arraystretch}{1.2}
|
| 6 |
+
\caption{Seed summaries for stochastic checks. Values report mean with small std over completed seeds.}
|
| 7 |
+
\label{tab:app_seed_robustness}
|
| 8 |
+
\begin{adjustbox}{max width=\textwidth}
|
| 9 |
+
\begin{tabular}{p{0.28\textwidth}cllp{0.18\textwidth}}
|
| 10 |
+
\toprule
|
| 11 |
+
\textbf{\(\mathcal{T}\) check} & \textbf{Seeds} & \textbf{Primary value} & \textbf{Other value(s)} & \textbf{Reading} \\
|
| 12 |
+
\midrule
|
| 13 |
+
Final burned area &
|
| 14 |
+
5 & log-RMSE \ms{1.1657}{0.0126} &
|
| 15 |
+
log-MAE \ms{1.0423}{0.0081}; Spear.\ \ms{0.6298}{0.0338} &
|
| 16 |
+
stable across seeds \\
|
| 17 |
+
Smoke PM\(_{2.5}\) &
|
| 18 |
+
5 & RMSE \ms{4.4646}{0.0060} &
|
| 19 |
+
MAE \ms{2.4108}{0.0016}; \(r\) \ms{0.6368}{0.0013} &
|
| 20 |
+
stable at table precision \\
|
| 21 |
+
Extreme heat &
|
| 22 |
+
5 & RMSE-C \ms{0.2179}{0.0043} &
|
| 23 |
+
MAE-C \ms{0.1787}{0.0018}; exceed.\ \(F_1\) \ms{0.9541}{0.0164} &
|
| 24 |
+
stable across seeds \\
|
| 25 |
+
Fire spread &
|
| 26 |
+
5 & exact \(F_1\) \ms{37.6700}{0.9800} &
|
| 27 |
+
spatial \(F_1\) \ms{80.9700}{2.0200}; AP \ms{30.0900}{1.2500} &
|
| 28 |
+
stable across seeds \\
|
| 29 |
+
Aurora paired-head check &
|
| 30 |
+
5 & fire-prone score diff.\ \ms{6.3500}{13.2800} &
|
| 31 |
+
PR-AUC and union choices differ in 2/5 seeds &
|
| 32 |
+
variable across seeds \\
|
| 33 |
+
\bottomrule
|
| 34 |
+
\end{tabular}
|
| 35 |
+
\end{adjustbox}
|
| 36 |
+
\end{table}
|
paper_outputs/tables/tab_app_smoke_high_event.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{3pt}
|
| 5 |
+
\caption{For fixed smoke \(\mathcal{T}\) and station \(\Omega\), this table reports RMSE, MAE, and 90th-percentile absolute error on test rows with observed PM$_{2.5}\ge35$; std uses a row bootstrap over those rows. Cells report mean with small std.}
|
| 6 |
+
\label{tab:app_smoke_high_event}
|
| 7 |
+
\begin{tabular}{lccc}
|
| 8 |
+
\toprule
|
| 9 |
+
Backbone & high-smoke RMSE & high-smoke MAE & high-smoke 90th AE \\
|
| 10 |
+
\midrule
|
| 11 |
+
FireWx-FM ref. & \ms{47.4870}{0.6346} & \ms{34.3954}{0.7654} & \ms{65.6213}{3.8778} \\
|
| 12 |
+
Prithvi-WxC & \ms{57.2224}{1.7268} & \ms{47.3871}{0.3153} & \ms{74.9666}{3.2381} \\
|
| 13 |
+
Aurora & \ms{57.2752}{1.7248} & \ms{47.4368}{0.3149} & \ms{75.0755}{3.1074} \\
|
| 14 |
+
ClimaX & \ms{57.2828}{1.7239} & \ms{47.4407}{0.3140} & \ms{75.1012}{3.0777} \\
|
| 15 |
+
StormCast & \ms{56.6512}{1.7517} & \ms{46.7914}{0.3281} & \ms{74.0794}{3.4707} \\
|
| 16 |
+
DLWP & \ms{57.0075}{1.7359} & \ms{47.1971}{0.3198} & \ms{74.4936}{3.3826} \\
|
| 17 |
+
FCN & \ms{57.0582}{1.7339} & \ms{47.2401}{0.3187} & \ms{74.6431}{3.1982} \\
|
| 18 |
+
FengWu & \ms{57.0158}{1.7357} & \ms{47.1957}{0.3194} & \ms{74.5652}{3.2871} \\
|
| 19 |
+
FuXi & \ms{56.9622}{1.7371} & \ms{47.1508}{0.3201} & \ms{74.3278}{3.4435} \\
|
| 20 |
+
Pangu-Weather & \ms{57.1282}{1.7307} & \ms{47.3050}{0.3170} & \ms{74.6830}{3.2375} \\
|
| 21 |
+
AlphaEarth & \ms{48.0665}{0.7904} & \ms{35.6088}{0.7341} & \ms{66.7613}{3.9235} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
paper_outputs/tables/tab_app_spread_ap_by_scope.tex
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{3pt}
|
| 5 |
+
\caption{For fixed spread \(\mathcal{T}\) and strict \(\Lambda\), this table reports AP under three \(\Omega\) scopes: full test, top-5\% train-fire area, and top-10\% train-fire area. Values are percentages; cells report mean with small std.}
|
| 6 |
+
\label{tab:app_spread_ap_by_scope}
|
| 7 |
+
\begin{tabular}{lccc}
|
| 8 |
+
\toprule
|
| 9 |
+
Backbone & full \(\Omega\) AP & top-5\% \(\Omega\) AP & top-10\% \(\Omega\) AP \\
|
| 10 |
+
\midrule
|
| 11 |
+
FireWx-FM ref. & \ms{30.0197}{1.5651} & \ms{40.7452}{2.0542} & \ms{37.4096}{1.8731} \\
|
| 12 |
+
Prithvi-WxC & \ms{4.8319}{0.1731} & \ms{12.6086}{0.4468} & \ms{8.7051}{0.1889} \\
|
| 13 |
+
Aurora & \ms{17.7723}{0.4293} & \ms{30.3106}{0.9404} & \ms{26.4732}{0.6932} \\
|
| 14 |
+
ClimaX & \ms{11.1726}{0.2337} & \ms{25.7871}{1.2896} & \ms{19.9977}{1.2217} \\
|
| 15 |
+
StormCast & \ms{8.1147}{1.1569} & \ms{18.5461}{1.1727} & \ms{14.1286}{1.2956} \\
|
| 16 |
+
DLWP & \ms{9.2142}{2.6587} & \ms{19.3346}{2.3922} & \ms{14.9788}{2.6696} \\
|
| 17 |
+
FCN & \ms{6.6774}{1.3001} & \ms{16.7396}{3.2955} & \ms{11.9308}{2.3881} \\
|
| 18 |
+
FengWu & \ms{11.0046}{2.7092} & \ms{21.1506}{1.2163} & \ms{17.0113}{1.5778} \\
|
| 19 |
+
FuXi & \ms{13.5507}{0.3840} & \ms{22.5434}{0.4100} & \ms{19.1964}{0.3943} \\
|
| 20 |
+
Pangu-Weather & \ms{10.6250}{1.4643} & \ms{19.8294}{1.3044} & \ms{15.8013}{1.1602} \\
|
| 21 |
+
AlphaEarth & \ms{12.2847}{1.3562} & \ms{22.8692}{0.4915} & \ms{18.2992}{1.2110} \\
|
| 22 |
+
\bottomrule
|
| 23 |
+
\end{tabular}
|
| 24 |
+
\end{table*}
|
paper_outputs/tables/tab_appendix_selection_regret_tolerance.tex
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\begin{table*}[!t]
|
| 2 |
+
\centering
|
| 3 |
+
\scriptsize
|
| 4 |
+
\setlength{\tabcolsep}{4pt}
|
| 5 |
+
\caption{Selection-regret values under exact, tolerated, and union matching. Values are percentage-point regret from selecting \(h_R\) by PR-AUC instead of \(h_D\) by the decision metric. Rows report mean with small std over five seeds; \(0.0000\) denotes exact zero regret.}
|
| 6 |
+
\label{tab:appendix_selection_regret_tolerance}
|
| 7 |
+
\begin{adjustbox}{max width=\textwidth}
|
| 8 |
+
\begin{tabular}{llccc}
|
| 9 |
+
\toprule
|
| 10 |
+
\textbf{Feature} & \textbf{\(\Omega\)} & \textbf{Exact regret} & \textbf{Tolerated regret} & \textbf{Union regret} \\
|
| 11 |
+
\midrule
|
| 12 |
+
FireWx-FM ref. & global & 0.0000 & \ms{8.7830}{9.6705} & \ms{8.7830}{9.6705} \\
|
| 13 |
+
FireWx-FM ref. & fire-prone & 0.0000 & \ms{3.4027}{3.2045} & \ms{3.4027}{3.2045} \\
|
| 14 |
+
Prithvi-WxC & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 15 |
+
Prithvi-WxC & fire-prone & 0.0000 & 0.0000 & 0.0000 \\
|
| 16 |
+
Aurora & global & \ms{0.0200}{0.0267} & \ms{9.8520}{12.9878} & \ms{9.8520}{12.9878} \\
|
| 17 |
+
Aurora & fire-prone & \ms{0.8203}{1.8341} & \ms{14.3919}{32.1219} & \ms{14.3919}{32.1219} \\
|
| 18 |
+
ClimaX & global & \ms{0.0003}{0.0004} & \ms{0.1296}{0.1775} & \ms{0.1296}{0.1775} \\
|
| 19 |
+
ClimaX & fire-prone & 0.0000 & 0.0000 & 0.0000 \\
|
| 20 |
+
StormCast & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 21 |
+
StormCast & fire-prone & 0.0000 & 0.0000 & 0.0000 \\
|
| 22 |
+
DLWP & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 23 |
+
DLWP & fire-prone & \ms{0.0770}{0.1100} & \ms{4.3266}{4.3323} & \ms{4.3266}{4.3323} \\
|
| 24 |
+
FCN & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 25 |
+
FCN & fire-prone & \ms{0.0006}{0.0013} & \ms{1.1680}{1.9872} & \ms{1.1680}{1.9872} \\
|
| 26 |
+
FengWu & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 27 |
+
FengWu & fire-prone & \ms{0.0691}{0.1191} & \ms{0.5222}{0.6239} & \ms{0.5222}{0.6239} \\
|
| 28 |
+
FuXi & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 29 |
+
FuXi & fire-prone & 0.0000 & \ms{0.1084}{0.1729} & \ms{0.1084}{0.1729} \\
|
| 30 |
+
Pangu-Weather & global & 0.0000 & 0.0000 & 0.0000 \\
|
| 31 |
+
Pangu-Weather & fire-prone & \ms{0.0728}{0.1179} & \ms{0.1849}{0.3263} & \ms{0.1849}{0.3263} \\
|
| 32 |
+
AlphaEarth & global & 0.0000 & \ms{17.2217}{8.8492} & \ms{17.2217}{8.8492} \\
|
| 33 |
+
AlphaEarth & fire-prone & 0.0000 & \ms{3.8804}{5.9483} & \ms{3.8804}{5.9483} \\
|
| 34 |
+
\bottomrule
|
| 35 |
+
\end{tabular}
|
| 36 |
+
\end{adjustbox}
|
| 37 |
+
\end{table*}
|