Unified model governance for UK insurance pricing: PRA SS1/23 validation and model risk management
Project description
insurance-governance
Unified model governance for UK insurance pricing teams. Combines PRA SS1/23 statistical validation and model risk management into one package.
Merged from: insurance-validation (PRA SS1/23 validation reports) and insurance-mrm (model risk management).
The problem this solves: validation tests and MRM governance packs were built separately and had separate installs, separate version pinning, and separate import paths. Pricing teams either installed both and managed the coupling themselves, or skipped one. This package resolves that by providing a single install.
Subpackages
insurance_governance.validation
PRA SS1/23 compliant model validation report generator. Runs statistical tests (Gini, PSI, discrimination checks, Hosmer-Lemeshow, lift charts) and produces self-contained HTML reports.
insurance_governance.mrm
Model risk management framework. ModelCard metadata container, RiskTierScorer (objective 0-100 composite score mapping to Tier 1/2/3), ModelInventory (JSON file registry), GovernanceReport (executive committee pack).
Install
pip install insurance-governance
Quick start
import numpy as np
from insurance_governance import (
ModelValidationReport,
ValidationModelCard,
MRMModelCard,
RiskTierScorer,
ModelInventory,
GovernanceReport,
)
# --- Synthetic model outputs (replace with your real model predictions) ---
rng = np.random.default_rng(42)
n_val = 5_000
y_val = rng.poisson(0.08, n_val).astype(float) # observed claim counts
y_pred_val = np.clip(rng.normal(0.08, 0.02, n_val), 0.001, None) # model predictions
# --- Run statistical validation ---
card = ValidationModelCard(
name="Motor Frequency v3.2",
version="3.2.0",
purpose="Predict claim frequency for UK motor portfolio",
methodology="CatBoost gradient boosting with Poisson objective",
target="claim_count",
features=["age", "vehicle_age", "area", "vehicle_group"],
limitations=["No telematics data"],
owner="Pricing Team",
)
report = ModelValidationReport(model_card=card, y_val=y_val, y_pred_val=y_pred_val)
report.generate("validation_report.html")
# --- MRM governance pack ---
mrm_card = MRMModelCard(
model_id="motor-freq-v3",
model_name="Motor TPPD Frequency",
version="3.2.0",
model_class="pricing",
intended_use="Frequency pricing for private motor.",
)
scorer = RiskTierScorer()
tier = scorer.score(
gwp_impacted=125_000_000,
model_complexity="high",
deployment_status="champion",
regulatory_use=False,
external_data=False,
customer_facing=True,
)
GovernanceReport(card=mrm_card, tier=tier).save_html("mrm_pack.html")
Or import from subpackages directly:
from insurance_governance.validation import ModelValidationReport, ModelCard as ValidationModelCard
from insurance_governance.mrm import ModelCard as MRMModelCard, RiskTierScorer, ModelInventory, GovernanceReport
Note on ModelCard
Both subpackages define a ModelCard class, but they serve different purposes:
insurance_governance.validation.ModelCard(ValidationModelCardat top level) — Pydantic schema, anchors the statistical validation report, captures features, methodology, limitations.insurance_governance.mrm.ModelCard(MRMModelCardat top level) — dataclass, anchors the MRM governance pack, captures assumptions, risk tier, Model Risk Committee metadata.
At the top level they are re-exported as ValidationModelCard and MRMModelCard to avoid ambiguity.
Capabilities Demo
Demonstrated on synthetic motor data: 50,000 UK motor policies, CatBoost Poisson frequency model, 60/20/20 temporal train/validation/test split. Full notebook: notebooks/benchmark.py.
- Runs the full PRA SS1/23 validation suite in a single
ModelValidationReportcall: Gini coefficient with bootstrap 95% CI, 10-band lift chart, A/E by predicted decile with Poisson CI, Hosmer-Lemeshow goodness-of-fit, PSI on score distribution (train vs validation), monitoring plan completeness check — all returningTestResultobjects with a pass/fail flag and human-readable detail - Computes an overall RAG status (Green/Amber/Red) from the worst-severity failure across all tests
- Produces a self-contained HTML validation report and JSON sidecar, print-to-PDF ready, in under one second
- Scores model risk tier via
RiskTierScorer: 6 dimensions (GWP, model complexity, deployment status, regulatory use, external data, customer-facing) mapped to a 0-100 composite with documented rules per point — no subjective judgement required at the MRC presentation - Registers models in
ModelInventory(JSON file, check into git alongside your code); records validation run history linked byrun_id; lists overdue reviews - Generates a
GovernanceReportexecutive committee pack (HTML + JSON) covering model purpose, risk tier rationale, last validation RAG, assumptions register with risk ratings, outstanding issues, approval conditions, and next review date
When to use: You are subject to PRA SS1/23, have 10+ production pricing models, and want consistent, auditable validation and governance output rather than bespoke analyst notebooks that vary by model. Particularly useful before a PRA supervisory visit.
When NOT to use: You need reserving or capital model governance — this package is scoped to pricing models. It also does not replace independent human review of validation results; it automates the tests, not the judgement.
Performance
Benchmarked on synthetic UK motor data — 50,000 policies, CatBoost Poisson frequency model, 60/20/20 temporal split. See notebooks/benchmark.py for the full demo workflow.
| Task | Time |
|---|---|
| Full SS1/23 validation suite (9 tests) | < 5 seconds |
| HTML validation report generation | < 1 second |
| JSON sidecar generation | < 1 second |
| RiskTierScorer.score() | < 1ms |
| ModelInventory.register() | < 10ms |
| GovernanceReport HTML generation | < 1 second |
The computational cost of this library is negligible — it runs statistical tests on pre-computed predictions, not raw data. The bottleneck is always the model fitting that produces y_pred_val, not the governance layer. A team generating quarterly validation reports for 15 models can run the full suite in under 10 minutes of wall clock time, most of which is the CatBoost fits.
The value is not in computation speed but in consistency: every model in the portfolio gets identical tests, identical thresholds, and identical output format. A pricing team relying on bespoke analyst notebooks has no guarantee that the Gini in one report means the same thing as the Gini in another.
Licence
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file insurance_governance-0.1.0.tar.gz.
File metadata
- Download URL: insurance_governance-0.1.0.tar.gz
- Upload date:
- Size: 89.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e4261aadf183f5158e5d96ba23b95d70d0d24400aee39dfb3ddff0f89fd0911
|
|
| MD5 |
4fa65687fec2c874ac4541c437857126
|
|
| BLAKE2b-256 |
780e45ad74edca65fa165309fc620075caeb0c64fa8a0a013005892610d1b10b
|
File details
Details for the file insurance_governance-0.1.0-py3-none-any.whl.
File metadata
- Download URL: insurance_governance-0.1.0-py3-none-any.whl
- Upload date:
- Size: 66.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f81b2a89febc42fe3b50cfb9c8ff39e6a40da6b58e8c5055592718e83666766
|
|
| MD5 |
705163beef8527a9aa461ac071b5f383
|
|
| BLAKE2b-256 |
12d8c31db7b2d279e94eab5b9fa6c2e73b38fb9cf3ec7874463515d23e78f9c4
|