Vintage Analysis Tutorial
This guide shows the baseline vintage workflow for comparing smoothing methods, validating them, and optionally projecting incomplete vintage tails.
Use this workflow when
- you have cohort-level loss history by month on book
- you want a fast cumulative-loss workflow without building a transition model
- you need a ranked smoothing comparison as the first success metric
Do not start here if
- your starting object is a portfolio snapshot plus a transition matrix — use Lifetime Loss Forecasting
- your starting object is monthly aggregated rollforward data — use the Rollforward workflow
- your main question is time-to-default or prepayment timing — use Survival Analysis
Inputs
Minimum columns:
vintage_datemonths_on_bookcumulative_loss_rate
Useful segmentation columns:
vintage_nameif you plan to overridevintage_colsegment
If your data uses older labels such as vintage_name and mob, pass them
through run_vintage_analysis_session(..., vintage_col=..., mob_col=...).
For the full contract, see Input Data Contracts.
Code
import numpy as np
import pandas as pd
from cranalytics import run_vintage_analysis_session
rows = []
for vintage_name, max_mob in [("2022-Q1", 12), ("2022-Q2", 9)]:
curve = np.maximum.accumulate(
0.055 * (1.0 - np.exp(-np.arange(1, max_mob + 1) / 6.0))
)
for mob, value in enumerate(curve, start=1):
rows.append(
{
"vintage_date": vintage_name,
"months_on_book": mob,
"cumulative_loss_rate": float(value),
}
)
session = run_vintage_analysis_session(
pd.DataFrame(rows),
min_maturity_months=12,
extrapolate_tails=True,
)
print(session.rankings[["method_name", "score"]])
print(session.validation_summary[["method_name", "train_mse", "test_mse"]])
print(session.tail_projections.tail())
Expected output / first win
Your first win is a vintage analysis session result with method rankings, validation output, and optional projected tails for incomplete vintages.
You should expect:
- a ranked smoothing comparison table
- a validation summary across smoothing methods
- optional
tail_projectionsrows when incomplete vintages are present andextrapolate_tails=True
Visualization
Visualize your vintage curves using the plotting utilities.
from cranalytics.viz import plot_vintage_triangle
import pandas as pd
triangle = pd.DataFrame(
{
1: [0.01, 0.008],
2: [0.02, 0.018],
3: [0.03, 0.027],
},
index=["2022-Q1", "2022-Q2"],
)
fig = plot_vintage_triangle(triangle)
fig.show()
Common mistakes
- passing a wide pivoted table without first reshaping it into long vintage observations
- feeding a non-cumulative loss series into a cumulative-loss workflow
- expecting this workflow to model cashflows, transitions, or dynamic status migration
- jumping straight to a single fitter before checking whether the session boundary already covers comparison, validation, and tail projection
- using Vintage when your real business question is about feature ranking or ML backtesting
Next step
Run the packaged demo end-to-end with:
python -m cranalytics.examples.core_vintage
If you only need one direct parametric curve fit instead of the full analysis
session, use CurveFitter from cranalytics.vintage.
If you need reserve-style portfolio forecasting instead of cohort curve fitting, continue to the Lifetime Loss Forecasting Tutorial.