factcircuit
FactCircuit는 불변 출처와 단계별 검증, 제한된 검색, 재현 가능한 평가를 제공하는 감사 가능한 주장·증거 검증 루프입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Which Missouri & Illinois counties lose power when storms hit — and why. DuckDB, dbt, XGBoost, MLflow, Streamlit.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Which counties lose power when a storm hits — and why does the same storm hit some places much harder than others?
A county-level power-outage model for the 216 counties of Missouri and Illinois, built on public data: DOE EAGLE-I outage records, NOAA HRRR storm ingredients and storm reports, USFS tree canopy and Census housing data. The pipeline runs locally on DuckDB and dbt; models are compared in a benchmark suite tracked with MLflow; results are served in a Streamlit dashboard packaged with Docker.
PR-AUC on new outages (onset blocks), XGBoost (800 trees, depth 4) trained on 2020–2024, with settings chosen on 2024 and checked over five seeds, tested once on 2025. For rare events a model with no skill scores the event rate, shown for reference.
| Outage size | New-outage rate | Climatology baseline | Weather only | + place | + recent outages |
|---|---|---|---|---|---|
| Next year (train 2020–2024 → test 2025) | |||||
| ≥ 1% | 1.97% | 0.032 | 0.116 | 0.145 | 0.153 |
| ≥ 5% | 0.53% | 0.009 | 0.068 | 0.091 | 0.106 |
| ≥ 10% | 0.26% | 0.005 | 0.047 | 0.062 | 0.083 |
| Unseen counties (5-fold by county, 2020–2025) | |||||
| ≥ 1% | 1.73% | 0.016 | 0.109 | 0.110 | 0.122 |
| ≥ 5% | 0.46% | 0.004 | 0.070 | 0.071 | 0.086 |
| ≥ 10% | 0.22% | 0.002 | 0.054 | 0.054 | 0.068 |
Source: ml/results/leaderboard_final_2025.md; settings from tune.yaml and
seeds_tune.yaml, feature choices from seeds_ablate.yaml.
What the numbers say:
years_2020.yaml,
years_2024.yaml).PR-AUC on new ≥ 5% outages, next year (ml/results/leaderboard_official.md,
ml/results/leaderboard_weathernext.md). Official forecasts are taken as they stood when
the block started; the model's HRRR weather covers the block itself.
| Approach | Known | PR-AUC |
|---|---|---|
| NWS warnings in force at block start (event rate per combination) | in advance | 0.024 |
| SPC Day 1 outlook (event rate per risk level) | in advance | 0.033 |
| Warnings + outlook | in advance | 0.044 |
| weathernext-outage-forecasting's setup, reproduced on this data | during the block | 0.053 |
| This model | during the block | 0.106 |
| This model with warnings + outlook as features | during the block | 0.122 |
If a utility had staged repair crews wherever each forecast pointed in 2025, how much
would it have saved? pixi run value (ml/value.py) scores every forecast on the same
new outages, two ways:
| Net savings in 2025 | Range over the four scenarios |
|---|---|
| Perfect forecast | $11.6M to $99.5M |
| This model | $3.5M to $38.8M |
| Warnings + outlook | −$14.9M to −$0.6M |
| SPC outlook | −$18.9M to −$1.4M |
| NWS warnings | −$57.7M to $2.0M |
The estimate: about $4–39 million saved in 2025, where acting on the official
forecasts would mostly have lost money: they point at far more counties than lose power.
At each forecast's best cutoff in hindsight, the model still saves about 3× as much.
Almost all the avoided cost is businesses' (for households alone, staging never pays), the
figures are customers' losses rather than the utility's, and like every score here they are
a best case because the weather inputs are near-observed. Results:
ml/results/value_2025.csv, ml/results/value_curves_2025.csv.
ingest/ (Python) dbt/ (SQL on DuckDB) ml/ (Python) app/
EAGLE-I, HRRR, ──► staging → intermediate → marts ──► benchmark suite (MLflow) ──► Streamlit
storm reports, 47 tests; 3.5M-row modeling table YAML configs, 3 splits, (Docker)
canopy, Census + resilience scorecard onset + all-block metrics
| Layer | Tool |
|---|---|
| Environment | pixi — one lock file; default, app and ci environments |
| Storage / SQL | DuckDB |
| Transformations | dbt Core + dbt-duckdb, dbt_utils tests |
| Geo | geopandas, rasterio |
| ML | XGBoost, LightGBM, scikit-learn, MLflow |
| Dashboard | Streamlit, Plotly |
| Packaging | Docker (linux/amd64), Hugging Face Spaces |
| Quality | pytest, ruff, GitHub Actions |
Design choices worth knowing:
The data traps found along the way (a renamed column in 2023, duplicated snapshots in 2025, a raster whose no-data value was a real value, county codes swapped for years, and more) are in docs/data-notes.md.
pixi install
# EAGLE-I outages: manual download — see data/README.md
pixi run fetch-counties && pixi run fetch-tree-canopy && pixi run fetch-acs && pixi run fetch-storm-events
pixi run fetch-weather 2024 2025 # rate-limited (free tier): ~a day for 216 counties
pixi run build # dbt: every model + test
pixi run train # quick benchmark → ml/results/
pixi run export-app && pixi run app # dashboard at http://localhost:8501
docker compose up --build runs the dashboard in a container.
| Folder | Contents |
|---|---|
ingest/ | download scripts, one per source |
dbt/ | SQL models (staging → intermediate → marts), seeds, tests |
ml/ | data loading, splits, model registry, metrics, benchmark runner, configs, results |
app/ | Streamlit dashboard |
notebooks/ | explore_warehouse (inspect tables), benchmark_lab (try configs interactively) |
tests/ | pytest: benchmark machinery and dashboard pages |
scripts/ | download queue, Hugging Face publishing |
legacy/ | the first St. Louis hourly prototype |
docs/ | data dictionary, data notes, decisions, experiments, development guide, roadmap |
Full source list with URLs: docs/data-dictionary.md.