Skip to content
Back to skills

GEO INFER RISK

ASecurity

Geospatial risk modeling including catastrophe models and exposure analysis. Use when assessing spatial risk, building catastrophe models, analyzing exposure/hazard/vulnerability, or computing portfolio risk metrics.

  • 17 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 1, 2026
datapythongoawsapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned September 22, 2026

npx -y skills add ActiveInferenceInstitute/GEO-INFER --skill GEO-INFER-RISK --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of GEO INFER RISK?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for GEO INFER RISK
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/activeinferenceinstitute-geo-infer-risk/badge)](https://www.skillsdirectory.com/skills/activeinferenceinstitute-geo-infer-risk)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: geo-infer-risk
description: Geospatial risk modeling including catastrophe models and exposure analysis. Use when assessing spatial risk, building catastrophe models, analyzing exposure/hazard/vulnerability, or computing portfolio risk metrics.
prerequisites:
  required:
    - geo-infer-space
    - geo-infer-data
  recommended:
    - geo-infer-bayes
    - geo-infer-math
difficulty: advanced
estimated_time: 60min
examples_dir: ../GEO-INFER-EXAMPLES/examples/
---

# GEO-INFER-RISK

## Instructions

### Core Capabilities

- **Catastrophe models**: Spatial correlation and directed multi-hazard interactions
- **Risk engine**: Moran's I, Geary C, Monte Carlo loss calculation
- **Exposure modeling**: `file://` loading of CSV/JSON/Parquet; other source
  schemes (e.g. `api://`) require a configured data connector and are
  explicitly rejected rather than silently faked
- **Hazard modeling**: Spatial hazard assessment and mapping
- **Vulnerability**: Bayesian uncertainty quantification

### Key Imports

```python
from geo_infer_risk.core.risk_engine import EnhancedRiskEngine
from geo_infer_risk.core.catastrophe_models import (
    EnhancedCatastropheModel,
    MultiHazardInteractionMatrix,
)
from geo_infer_risk.core.exposure_model import EnhancedExposureModel
from geo_infer_risk.core.hazard_model import EnhancedHazardModel
```

## Examples

Every snippet below runs against the current API.

Reproducible catastrophe simulation. The seed lives on the config, and all
draws come from the model's own generator, so a run replays exactly and never
disturbs the caller's `numpy.random` stream:

```python
from geo_infer_risk.core.catastrophe_models import (
    CatastropheConfig,
    EnhancedEarthquakeModel,
)

config = CatastropheConfig(
    simulation_years=50, spatial_correlation=False, random_seed=7
)
model = EnhancedEarthquakeModel(config=config)
model.model_parameters = {"mean_depth": 15.0}
events = model.simulate_events(200)
```

Estimate compound annual exceedance along a directed hazard chain. Zero
off-diagonal interaction recovers independent joint exceedance; positive
interaction raises the downstream conditional probability:

```python
from geo_infer_risk.core import MultiHazardInteractionMatrix

interactions = MultiHazardInteractionMatrix(
    ["earthquake", "fire_following", "flood"],
    [[1.0, 0.5, 0.0], [0.0, 1.0, 0.4], [0.0, 0.0, 1.0]],
)
compound_probability = interactions.compound_exceedance_probability(
    {"earthquake": 0.1, "fire_following": 0.2, "flood": 0.3}
)
```

Risk metrics from an event loss table. `exposure_years` is how many years the
table spans; omit it and every per-year figure is inflated (a warning says so):

```python
import pandas as pd
from geo_infer_risk.utils.risk_metrics import (
    calculate_aal,
    calculate_pml,
    calculate_annual_aggregate_exceedance_probability,
)

losses = pd.DataFrame(
    {
        "event_id": [event["event_id"] for event in events],
        "hazard_type": ["earthquake"] * len(events),
        "loss": modelled_losses,  # one loss per event
    }
)

aal = calculate_aal(losses, exposure_years=50.0)["total"]
pml_25 = calculate_pml(losses, return_period=25, exposure_years=50.0)
aep = calculate_annual_aggregate_exceedance_probability(
    losses, threshold=5e6, num_years=20_000, random_seed=7, exposure_years=50.0
)
```

`calculate_pml` warns when the requested return period is longer than the
record can resolve; the value is then clamped to the largest observed loss and
understates the tail.

## Reproducibility

Every stochastic entry point in this module takes a `random_seed` and routes it
through `geo_infer_risk.utils.rng.resolve_rng`, which accepts `None`, an `int`,
a `SeedSequence`, a `BitGenerator`, a `numpy.random.Generator`, or a legacy
`RandomState`, and always returns a `Generator`. Consequences worth knowing:

- Passing an `int` makes a run replayable; `0` is a valid seed.
- Passing a `Generator` threads one stream through a whole pipeline.
- `None` means OS entropy, so results are *not* replayable. Calling
  `np.random.seed(...)` does not make them so: this module never reads the
  process-wide singleton, and never advances it either.
- For independent parallel streams use
  `geo_infer_risk.utils.rng.spawn_rng(seed, n)` rather than `seed`, `seed + 1`,
  ... which carries no independence guarantee.
- At boundaries that accept only an `int` seed, such as scikit-learn's
  `random_state`, use `geo_infer_risk.utils.rng.derive_int_seed`.

## Guidelines

- Production paths require configured data sources and do not fabricate risk inputs.
- Spatial correlation uses Cholesky decomposition
- Directed interaction entries are bounded to `[-1, 1]`; ordered compound
  exceedance uses the configured source-to-target chain
- Risk aggregation uses real Moran's I and Monte Carlo
- Exceedance-probability curves use the Weibull plotting position and
  interpolate loss as a function of exceedance probability; return periods
  beyond the record are clamped, not extrapolated
- Pass `exposure_years` to any per-year metric (AAL, OEP, AEP, and the
  annualized EP curve); the fallback treats the table as spanning one year
- Simplified conversions, stand-in probabilities, and loss-tail multipliers
  are catalogued in the Honest Capability Register below; source sites point
  here instead of re-explaining themselves
- Test: `uv run python GEO-INFER-TEST/run_unified_tests.py --module RISK`

### Integrations

- **BAYES** → Bayesian uncertainty quantification
- **ECON** → Economic loss and insurance modeling
- **CLIMATE** → Climate-driven hazard projections
- **SPACE** → Spatial correlation of hazards
- **AG** → Crop loss risk assessment

## Honest Capability Register

The simplified conversions and multipliers in this module are deliberate
engineering stand-ins, not calibrated geoscience or actuarial models. They are
listed once here; the inline code comments point back to this register.

- **Magnitude → PGA (GMPE stand-ins)** —
  `EnhancedHazardModel._magnitude_to_intensity` (banded step table,
  `core/hazard_model.py`) and `EnhancedEarthquakeModel._magnitude_to_pga`
  (log-distance attenuation, `core/catastrophe_models.py`). Neither is a
  calibrated ground-motion prediction equation; site effects in the
  catastrophe loss path are fixed soil multipliers (soft 1.3, rock 0.8).
- **Secondary perils (liquefaction, landslide)** —
  `EnhancedHazardModel._calculate_liquefaction_probability` and
  `_calculate_landslide_probability` return magnitude-band probability tables;
  they ignore soil conditions, saturation, and slope.
- **Storm surge** — `EnhancedHurricaneModel._calculate_storm_surge` is linear
  in wind speed above 30 m/s with a ±30% random tidal factor; it includes no
  bathymetry, pressure forcing, or track integration.
- **VaR / CVaR multipliers** — `PropertyInsuranceModel.estimate_losses` uses
  Gaussian quantiles (mean + 1.645σ and mean + 2.063σ);
  `CatastropheInsuranceModel.estimate_losses` applies flat 2.0× and 3.0×
  multipliers to total expected loss. Neither is an empirical
  loss-distribution tail, and the catastrophe multipliers ignore per-peril
  aggregation.
- **Model calibration** — only `cross_validation` against a mean-loss
  baseline is implemented (`EnhancedRiskEngine.calibrate_models`); `bayesian`
  and `maximum_likelihood` are rejected with a documented error rather than
  accepted as options that would hard-fail.
- **Catastrophe base-rate tables** — `CatastropheInsuranceModel` premium
  models (`core/insurance_models.py`) price per-peril coverage from
  hand-set latitude-band base rates: hurricane `_hurricane_model`
  (0.02/0.01/0.005 by latitude band), earthquake `_earthquake_model`
  (0.015/0.01/0.005 by |lat| band), flood `_flood_model`
  (0.025/0.015/0.005 by |lat| band), wildfire `_wildfire_model`
  (0.02/0.015/0.005 by |lat| band). None accounts for real exposure
  drivers (elevation, bathymetry, fuel load, fault proximity). Separately,
  `_estimate_catastrophe_loss` applies flat per-peril expected-loss
  fractions (hurricane 0.01, earthquake 0.008, flood 0.012, wildfire
  0.015; other 0.01) of coverage limit, independent of location or the
  premium rate tables.

Files in this skill

  • AGENTS.md1.3 KB
  • README.md944 B
  • SKILL.md5.3 KB
  • config/AGENTS.md1.2 KB
  • config/README.md753 B
  • config/example.yaml11.1 KB
  • config/schema.json17.6 KB
  • docs/AGENTS.md1.1 KB
  • docs/README.md736 B
  • docs/api_schema.yaml55.5 KB
  • examples/AGENTS.md1.2 KB
  • examples/README.md950 B
  • examples/basic_risk_assessment.py4.5 KB
  • examples/comprehensive_risk_assessment.py1.9 KB
  • pyproject.toml3.2 KB
  • requirements.txt106 B
  • setup.py146 B
  • src/AGENTS.md1.1 KB
  • src/README.md734 B
  • src/geo_infer_risk/AGENTS.md1.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.