deforestation-app / README.md
GitHub Action
sync from GitHub repo earth-engine
79873c2
|
Raw
History Blame Contribute Delete
4.94 kB
---
license: apache-2.0
title: Smokey the Bear Helper
sdk: streamlit
emoji: 🐨
colorFrom: purple
colorTo: purple
short_description: App to detect deforestation and explore satellite embeddings
---
# Streamlit App
A 4-page portfolio app for exploring the forest loss classification project. Runs locally or via Docker.
---
## Navigation
A custom sidebar nav (HTML GET-form buttons with active-state highlighting) links the four pages. A region selector below the nav links controls which "other" AOI is shown in supplemental sidebar stats.
---
## Pages
### Page 1 β€” Project Overview
Hero section with a Lottie animation, project title, and a one-paragraph summary of the approach.
**KPI cards** (loaded from `resources/cache/kpi_summary.json`):
- Pixel-Years, Regions, Features Engineered, Best PR-AUC, Best F1, Brier Score
- PR-AUC Lift metric β€” improvement over logistic regression baseline
**A Tale of Two Forests** β€” side-by-side stat cards comparing Canada (PR-AUC 0.91) and Amazon Basin (PR-AUC 0.62), plus a delta callout. This frames the central question the app explores.
*Bonus: Smokey's birthday easter egg fires on August 9th.*
---
### Page 2 β€” Explore the Data
AOI radio selector (inline) drives all four tabs. Each tab loads pre-computed parquet/JSON from `resources/cache/` via `@st.cache_data`.
| Tab | Contents |
|---|---|
| πŸ“‘ Embedding Profiles | Mean embedding delta profile per dimension, grouped by class (Loss / No Loss) or by year. Bar chart of top 10 most divergent embedding dimensions. |
| 🎯 Target Distribution | Pie chart of class distribution. Metric cards: total pixel-years, loss pixel count, no-loss count, class imbalance ratio. |
| 🌊 Drift + Timelapse | Line chart of mean drift magnitude by year. Pixel timelapse β€” scatter map of sampled pixel locations colored by loss label. |
| πŸ”¬ Drift Explorer | Year selector + violin/histogram of drift magnitude distribution, split by class. |
---
### Page 3 β€” Canada vs. Amazon Basin
Focused comparison of the two focus-region XGBoost models (PR-AUC 0.91 vs 0.62) to explore what the performance gap reveals about the data and the signal.
**Metrics & Confusion Matrices** β€” side-by-side columns with PR-AUC / F1 / Recall metric cards and Plotly confusion matrices for Canada and Amazon Basin.
**Feature Importance (XGBoost Gain)** β€” side-by-side horizontal bar charts of the top 15 features for each model.
**Expandable analysis sections:**
- *Why does Canada score 0.91 and Amazon only 0.62?* β€” narrative covering class balance, the fire year paradox, forest loss vs. deforestation definitions, feature importance as evidence, and cloud cover.
- *Best Optuna hyperparameters β€” Canada vs. Amazon Basin* β€” side-by-side parameter table with trial counts.
**Threshold Explorer** β€” AOI radio selector, probability score distribution histogram, interactive threshold slider (0.01–0.99), live confusion matrix, and precision / recall / F1 metric cards. Includes a Precision-Recall curve for the selected region.
---
### Page 4 β€” How I Built This
Two tabs: **πŸ› οΈ Build** and **πŸ’³ Credits**.
**Build tab:**
*Pipeline Architecture* β€” animated Plotly pipeline diagram (7 nodes, data-flow animation). A stage selector dropdown below the diagram shows a detail card for each pipeline step (GEE β†’ Feature Engineering β†’ Baseline Experiments β†’ Optuna + MLflow β†’ XGBoost Classifier β†’ Model Evaluation β†’ Streamlit + Docker).
*Build Timeline* β€” 8-day numbered SVG timeline cards (Day 1: GEE data acquisition through Day 8: CI/CD pipeline).
*Key Decisions & Lessons* β€” six expandable sections covering:
- Same pixel, different years β€” why the per-(pixel, year) framing beat single snapshots and LSTM sequences
- Why per-region models instead of one global model
- Drift magnitude as the primary engineered feature β€” why additional features didn't help
- Handling severe class imbalance (balanced weights, PR-AUC, Brier score)
- Geo-stratified train/test split β€” preventing spatial leakage
- Optuna over grid search β€” why Bayesian optimization fits this problem
*Source Code* β€” GitHub link button.
**Credits tab:** Data source attributions (AEF, Hansen GFC, RADD), library credits, and acknowledgements.
---
## Running the App
**Docker (recommended):**
```bash
docker compose up
# open http://localhost:8501
```
**Local:**
```bash
pip install -r app/requirements-app.txt
streamlit run app/streamlit_app.py
```
---
## Configuration
- **Theme:** `.streamlit/config.toml` β€” font, primary color, background. Fine-tune colors by running `app/theme_preview.py` locally.
- **Pipeline params:** `config/config.yaml` β€” AOIs, GEE export settings
- **Pre-computed artifacts:** `resources/cache/` β€” the app reads JSON metrics and parquet data samples at startup via `@st.cache_data`; no model inference happens at runtime. Regenerate with `python resources/precompute.py`.