-
Notifications
You must be signed in to change notification settings - Fork 84
Description
Description
chainladder-python currently lacks a visualization method for loss development patterns expressed as percentage of ultimate. This visualization shows cumulative losses divided by ultimate losses across development periods, commonly used in actuarial analysis to examine emergence patterns and compare individual origins against average development. Such visualization helps identify unusual development patterns and supports validation of development assumptions.
Overall, this capability can be valuable across actuarial applications where understanding development velocity is important, including loss reserving analysis, pattern validation, and benchmarking development assumptions across different lines of business or portfolios.
Is your feature request at odds with the scope of the package?
- Yes, absolutely!
- No, but it's still worth discussing.
- N/A (this request is not a codebase enhancement).
Describe the solution you'd like, or your current workaround.
Add a percentage_of_ultimate()
method to the Triangle class that creates matplotlib visualizations showing:
- Individual origin development curves (observed data only)
- Average development pattern with multiple weighting methods (volume, simple, regression, Zehnwirth & Barnett numeric)
- Configurable display options for origins, averaging methods, and figure sizing
Method signature:
def percentage_of_ultimate(
self,
show_by_origin: bool = True,
show_average_pattern: bool = True,
show_origin_years_in_legend: bool = True,
selected_origins: list = None,
average: str | float = "volume",
figsize: tuple = (12, 8)
) -> Figure
Mathematical approach:
The method calculates percentage of ultimate as Cumulative Losses / Ultimate Losses
for each development period. Ultimate projections are derived using Development() patterns without tail estimation - the calculation extends observed development through the available CDF factors only.
The method supports volume, simple, regression, and Zehnwirth & Barnett numeric averaging methods (e.g., average=1.5
) and works exclusively with raw triangles to provide individual origin analysis.
Key limitations:
- Currently works exclusively with raw triangles (not fitted Development objects or CDF triangles)
- Requires matplotlib for visualization
- Most effective for single triangle analysis
Usage example:
import chainladder as cl
# Load triangle and analyze development patterns
raa = cl.load_sample('raa')
# Basic visualization
fig = raa.percentage_of_ultimate()
# Custom analysis with different averaging
fig = raa.percentage_of_ultimate(
average="simple",
selected_origins=[1985, 1987, 1990],
show_average_pattern=True
)
Plots:
Do you have any additional supporting notes?
Implementation status: Working implementation available.
Technical details:
- Proposed location:
chainladder/core/display.py
(follows existingheatmap()
pattern) - Dependencies: matplotlib (consistent with current visualization methods)
- Backend compatibility: Works with numpy, sparse, cupy, and dask backends
- Breaking changes: None - pure addition to Triangle class
Validation:
- Tested with RAA sample data and quarterly development triangles
- Integration confirmed with existing chainladder workflow