Skip to content

Repository files navigation

Geo-Economic Stress Prediction System

A country-level risk model: feed it macroeconomic indicators for a country-year and it gives back a stress score (0–100), a risk category, a one-year-ahead forecast, and a ranked list of what's driving the number. Built for the kind of team that currently does this by hand — investment desks, banks, policy shops — and needs something faster and more consistent than a quarterly analyst review.

There's also a companion guide for wiring the same outputs into a Power BI executive dashboard (reports/powerbi_guide.md), so the CEO/CFO/Sales crowd can see country risk sitting next to the rest of the business numbers they already look at.

Why this exists

Most country risk assessment still runs on analyst judgment, refreshed every quarter, and it's inconsistent from one analyst to the next. This replaces that with a model that scores every country the same way, updates the moment new indicators land, and — critically — can explain itself, so nobody has to just take the score on faith.

Problem Country risk scoring is slow, manual, and inconsistent across analysts
What this does Scores, forecasts, and explains country-level economic stress from a reproducible pipeline
Output Risk Score, Risk Category, one-year forecast, driver ranking
Where you see it Streamlit dashboard, plus a CSV export for Power BI/Excel
Models tried Linear Regression, Random Forest, XGBoost, LightGBM — best one picked automatically

The full stakeholder-facing case (problem, KPIs, ROI, risks) is in reports/business_understanding.md; the component-level technical writeup is in reports/architecture.md.

How it's put together

Data Sources -> Ingestion -> Validation -> Cleaning -> Feature Engineering -> EDA
    -> Model Training -> Experiment Tracking (MLflow) -> Model Registry
    -> Prediction Pipeline -> Dashboard -> Deployment

(reports/architecture.md has the full breakdown of each stage.)

Data

Four files go in data/raw/:

File Grain What's in it
country_metadata.csv one row per country name, region, income group, population
country_year_indicators.csv one row per country-year GDP growth, inflation, unemployment, debt, reserves, FX volatility, political stability, etc.
economic_stress_score.csv one row per country-year the modeling target (0–100)
indicator_dictionary.csv one row per indicator definitions and how to read each one

No real data shipped with this build, so data/raw/_generate_synthetic_data.py builds a synthetic panel (15 countries, 2000–2023) so the pipeline runs out of the box. Swap in real extracts whenever you have them — as long as the column names match what's in src/validation/schema_validation.py::EXPECTED_SCHEMA, nothing downstream needs to change.

Layout

geo_stress_project/
├── data/
│   ├── raw/            # source CSVs + the synthetic data generator
│   ├── interim/         # merged, pre-clean panel
│   ├── processed/        # cleaned panel + full feature set
│   └── external/          # room for supplementary sources later
├── notebooks/              # exploratory work
├── src/
│   ├── ingestion/            # loads and merges raw sources
│   ├── validation/            # schema + data quality checks
│   ├── preprocessing/          # cleaning + orchestration
│   ├── features/                 # feature engineering (116 features)
│   ├── training/                   # model training + tuning
│   ├── evaluation/                   # metrics + diagnostic plots
│   ├── prediction/                     # scoring, forecasting, driver ranking
│   ├── monitoring/                       # drift/monitoring jobs go here eventually
│   └── utils/                              # logger, config/IO helpers, model loader
├── models/                   # trained model artifacts + registry metadata
├── reports/                    # business docs, validation/eval reports, plots
├── dashboard/                    # Streamlit app
├── deployment/                      # deployment-specific assets
├── tests/                              # pytest suite (18 tests)
├── mlruns.db                              # MLflow tracking store (SQLite)
├── config/config.yaml                        # all pipeline config lives here
├── requirements.txt
├── setup.py
├── Dockerfile
├── docker-compose.yml
└── main.py                                      # single entry point for the whole pipeline

Getting it running

python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt

Generate the synthetic data (skip once you've got real CSVs in place):

python data/raw/_generate_synthetic_data.py

Run everything — preprocessing, features, training, evaluation, prediction:

python main.py

Already trained models and just want fresh scores? Skips training, much faster:

python main.py --skip-training

Dashboard:

streamlit run dashboard/app.py

Look at experiment runs:

mlflow ui --backend-store-uri sqlite:///mlruns.db

Tests:

pytest tests/ -v

What's on the dashboard

Five tabs, dashboard/app.py:

  • Executive Summary — world risk map, portfolio risk mix, who's riskiest right now
  • Forecast — pick a country, see actual vs. predicted vs. next-year projection
  • Driver Importance — which indicators the model is actually leaning on
  • Trend Analysis — how indicators move across the full panel over time
  • Export — grab the full scored panel as CSV (this is what feeds Power BI — see reports/powerbi_guide.md)

A look at it

The Executive Country Risk Intelligence view pulls historical indicators, model predictions, risk tiers, top drivers, and the forecast into one screen — built for investment, treasury, and policy calls rather than for digging through raw numbers.

Executive Country Risk Intelligence Dashboard

Executive Country Risk Intelligence — Streamlit

Trend view — how stress has moved for a given country over time, useful for spotting when things started turning.

Economic Stress Trend Analysis

Driver ranking — what's actually pushing the score up or down for a given country-year.

Key Economic Risk Drivers

Forecast — historical vs. predicted, with the one-year-ahead projection layered on.

Forward-Looking Economic Stress Forecast

Portfolio mix — how many countries sit in each risk tier, for a quick exposure check.

Portfolio Risk Distribution

Map view — same thing, laid out geographically.

Global Predicted Country Economic Stress Map

Model results

Four models, trained on a time-based split (train through 2019, test on everything after), 5-fold CV on the training set:

Model Test RMSE Test MAE Test R² CV RMSE (mean ± std)
Linear Regression 6.39 5.18 0.076 5.92 ± 0.37
Random Forest 5.03 4.13 0.427 4.32 ± 0.36
XGBoost 5.19 4.27 0.390 4.39 ± 0.36
LightGBM (selected) 5.03 4.21 0.427 4.38 ± 0.37

(These numbers are from the synthetic dataset that ships with the repo — run python main.py against real data and it'll regenerate reports/model_comparison.json and reports/evaluation_report.json with the real figures.)

LightGBM won on test RMSE and got the nod. On held-out years it's off by about 4.2 points on the stress scale on average, and it accounts for roughly 43% of year-to-year variation. That's good enough to rank countries into risk tiers with confidence — it's not meant to replace an analyst's read on any one country in isolation.

Consistently, political stability, inflation, unemployment, FX reserve coverage, and current account balance come out as the biggest drivers across the panel (full ranking in reports/driver_importance.csv).

Shipping it

Local:

streamlit run dashboard/app.py

Docker:

docker build -t geo-stress-dashboard .
docker run -p 8501:8501 geo-stress-dashboard

Docker Compose (dashboard + MLflow UI together):

docker compose up --build

Streamlit Community Cloud: push to GitHub, connect at share.streamlit.io, point the main file at dashboard/app.py. requirements.txt is already at the repo root.

Render: new Web Service against this repo. Build command: pip install -r requirements.txt && python data/raw/_generate_synthetic_data.py && python main.py Start command: streamlit run dashboard/app.py --server.port $PORT --server.address 0.0.0.0

What's next

  • Swap the naive one-year roll-forward for a proper multi-horizon forecaster (direct multi-step LightGBM or a state-space model) once there's more history to work with
  • Add quarterly indicators so the signal reacts faster
  • Bring in market-based signals — sovereign CDS spreads, bond yields — alongside the fundamentals
  • Move off manual python main.py runs onto scheduled retraining (cron/Airflow)
  • Add drift monitoring in src/monitoring/ so it flags when live indicators start diverging from what the model was trained on
  • Row-level security on the dashboard, if different stakeholder groups end up needing different country subsets

Author

Mr. Shubham Panchal

Data Analytics | Data Science | AI | Machine Learning | Business Intelligence LinkedIn: linkedin.com/in/shubham-panchal-a100282a8

About

An end to end Data Science and Business Intelligence platform for analyzing economic performance, country risk, trends, key drivers, forecasting, and executive decision-making through interactive dashboards

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages