Spaces:
Running
Running
| 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`. |