Development#
- class chainladder.Development(n_periods: int = -1, average: Literal['volume', 'simple', 'regression', 'geometric'] = 'volume', sigma_interpolation: Literal['log-linear', 'mack'] = 'log-linear', drop: tuple | list[tuple] | None = None, drop_high: bool | int | list[bool] | list[int] | None = None, drop_low: bool | int | list[bool] | list[int] | None = None, preserve: int = 1, drop_valuation: str | list[str] = None, drop_above: float = inf, drop_below: float = 0.0, fillna: float | None = None, groupby: Callable | list | str | Series = None)[source]#
A Transformer that allows for basic loss development pattern selection.
- Parameters:
- n_periods: integer, optional (default = -1)
number of origin periods to be used in the ldf average calculation. For all origin periods, set n_periods = -1
- average: literal (or list of literals), or float, optional (default = ‘volume’)
type of averaging to use for ldf average calculation. Options include ‘volume’, ‘simple’, ‘regression’, and ‘geometric’. If numeric values are supplied, then (2-average) in the style of Zehnwirth & Barnett is used for the exponent of the regression weights.
- sigma_interpolation: string optional (default = ‘log-linear’)
Options include ‘log-linear’ and ‘mack’
- drop: tuple or list of tuples
Drops specific origin/development combination(s). See order of operations below when combined with multiple drop parameters.
- drop_high: bool, int, list of bools, or list of ints (default = None)
Drops highest (by rank) link ratio(s) from LDF calculation If a boolean variable is passed, drop_high is set to 1, dropping only the highest value. Protected by
preserve. See order of operations below when combined with multiple drop parameters.- drop_low: bool, int, list of bools, or list of ints (default = None)
Drops lowest (by rank) link ratio(s) from LDF calculation If a boolean variable is passed, drop_low is set to 1, dropping only the lowest value. Protected by
preserve. See order of operations below when combined with multiple drop parameters.- drop_above: float or list of floats (default = numpy.inf)
Drops all link ratio(s) above the given parameter from the LDF calculation. Protected by
preserve. See order of operations below when combined with multiple drop parameters.- drop_below: float or list of floats (default = 0.00)
Drops all link ratio(s) below the given parameter from the LDF calculation. Protected by
preserve. See order of operations below when combined with multiple drop parameters.- preserve: int (default = 1)
The minimum number of link ratio(s) required for LDF calculation. See order of operations below when combined with multiple drop parameters.
- drop_valuation: str or list of str (default = None)
Drops specific valuation periods. str must be date convertible. See order of operations below when combined with multiple drop parameters.
- fillna: float, (default = None)
Used to fill in zero or nan values of an triangle with some non-zero amount. When an link-ratio has zero as its denominator, it is automatically excluded from the
ldf_calculation. For the specific case of ‘volume’ averaging in a deterministic method, this may be reasonable. For all other averages and stochastic methods, this assumption should be avoided.- groupby: Callable, list, str, Series (default = None)
An option to group levels of the triangle index together for the purposes of estimating patterns. If omitted, each level of the triangle index will receive its own patterns.
Note
(Order of Drop Operations)
When multiple drop parameters are used together, the weights are built in this order:
n_periods— limit to the most recent origin periods.drop— remove specific origin/development cells.drop_valuation— remove entire valuation diagonal in the triangle.drop_high/drop_low— remove highest/lowest link ratios by rank (eligible factors fromn_periodsare used; protected bypreserve, which may relax exclusions from this step if too few ratios would remain then this step is skipped).drop_above/drop_below— remove link ratios outside a range (Protected by``preserve``, which may relax exclusions from this step if too few ratios would remain then this step is skipped).Calculate the loss development factors using
averagemethod.
- Attributes:
- ldf_: Triangle
The estimated loss development patterns
- cdf_: Triangle
The estimated cumulative development patterns
- sigma_: Triangle
Sigma of the ldf regression
- std_err_: Triangle
Std_err of the ldf regression
- std_residuals_: Triangle
A Triangle representing the weighted standardized residuals of the estimator as described in Barnett and Zehnwirth.
Examples
There are lots of parameters to control the development pattern selection. One should exercise caution when multiple drop parameters are used together.
Let’s start with a triangle and inspect its link ratios.
tri = cl.load_sample("xyz") print(tri["Incurred"].link_ratio)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 1998 NaN NaN 1.108227 1.067528 1.064392 1.044146 1.114243 0.987596 0.979707 0.999179 1999 NaN 1.237646 1.197135 1.144305 1.057447 1.055967 0.988085 1.011131 1.001436 NaN 2000 1.196032 1.168062 1.239452 1.086354 1.168543 1.072291 1.015048 0.993094 NaN NaN 2001 1.353175 1.313547 1.264295 1.286967 1.085689 1.037834 1.006668 NaN NaN NaN 2002 1.590040 1.308591 1.413078 1.179122 1.096524 0.989076 NaN NaN NaN NaN 2003 1.760957 1.786055 1.337353 1.089595 1.003210 NaN NaN NaN NaN NaN 2004 2.364225 1.465057 1.218140 0.980211 NaN NaN NaN NaN NaN NaN 2005 1.654181 1.482965 1.004478 NaN NaN NaN NaN NaN NaN NaN 2006 1.728479 1.043199 NaN NaN NaN NaN NaN NaN NaN NaN 2007 1.629204 NaN NaN NaN NaN NaN NaN NaN NaN NaN
We can drop a specific origin/development combination by passing a tuple to the drop parameter. By using the fit_transform method, we can see the link ratios after the drop.
print(cl.Development(drop=("2004", 12)).fit_transform(tri["Incurred"]).link_ratio)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 1998 NaN NaN 1.108227 1.067528 1.064392 1.044146 1.114243 0.987596 0.979707 0.999179 1999 NaN 1.237646 1.197135 1.144305 1.057447 1.055967 0.988085 1.011131 1.001436 NaN 2000 1.196032 1.168062 1.239452 1.086354 1.168543 1.072291 1.015048 0.993094 NaN NaN 2001 1.353175 1.313547 1.264295 1.286967 1.085689 1.037834 1.006668 NaN NaN NaN 2002 1.590040 1.308591 1.413078 1.179122 1.096524 0.989076 NaN NaN NaN NaN 2003 1.760957 1.786055 1.337353 1.089595 1.003210 NaN NaN NaN NaN NaN 2004 NaN 1.465057 1.218140 0.980211 NaN NaN NaN NaN NaN NaN 2005 1.654181 1.482965 1.004478 NaN NaN NaN NaN NaN NaN NaN 2006 1.728479 1.043199 NaN NaN NaN NaN NaN NaN NaN NaN 2007 1.629204 NaN NaN NaN NaN NaN NaN NaN NaN NaN
We can also inspect the LDFs with the ldf_ property.
ldf = cl.Development(drop=("2004", 12)).fit(tri["Incurred"]).ldf_ print(ldf)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 (All) 1.582216 1.339353 1.193406 1.095906 1.076968 1.033612 1.019016 0.997636 0.992918 0.999179
We can also drop all link ratio(s) above the given parameter by passing a list of floats to the drop_above parameter. Let’s inspect the link ratios after the drop.
tri = cl.load_sample("xyz") print( cl.Development(drop_above=[2.0, 1.5, 1.3, 1.2, 1.1, 1.07, 1.05, 1.03, 1.01, 1.00]) .fit_transform(tri["Incurred"]) .link_ratio )
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 1998 NaN NaN 1.108227 1.067528 1.064392 1.044146 NaN 0.987596 0.979707 0.999179 1999 NaN 1.237646 1.197135 1.144305 1.057447 1.055967 0.988085 1.011131 1.001436 NaN 2000 1.196032 1.168062 1.239452 1.086354 NaN NaN 1.015048 0.993094 NaN NaN 2001 1.353175 1.313547 1.264295 NaN 1.085689 1.037834 1.006668 NaN NaN NaN 2002 1.590040 1.308591 NaN 1.179122 1.096524 0.989076 NaN NaN NaN NaN 2003 1.760957 NaN NaN 1.089595 1.003210 NaN NaN NaN NaN NaN 2004 NaN 1.465057 1.218140 0.980211 NaN NaN NaN NaN NaN NaN 2005 1.654181 1.482965 1.004478 NaN NaN NaN NaN NaN NaN NaN 2006 1.728479 1.043199 NaN NaN NaN NaN NaN NaN NaN NaN 2007 1.629204 NaN NaN NaN NaN NaN NaN NaN NaN NaN
Then, let the LDFs.
tri = cl.load_sample("xyz") ldf = ( cl.Development(drop_above=[2.0, 1.5, 1.3, 1.2, 1.1, 1.07, 1.05, 1.03, 1.01, 1.00]) .fit(tri["Incurred"]) .ldf_ ) print(ldf)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 (All) 1.582216 1.301914 1.142205 1.071625 1.059935 1.022835 1.00511 0.997636 0.992918 0.999179
We can also use multiple drop parameters together. Let’s say, we want to drop all link ratio(s) above 1.25 and below 1.0, but only drop these link ratios when there are 3 or more link ratios remaining.
tri = cl.load_sample("xyz") print( cl.Development(drop_above=1.25, drop_below=1.0, preserve=3) .fit_transform(tri["Incurred"]) .link_ratio )
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 1998 NaN NaN 1.108227 1.067528 1.064392 1.044146 1.114243 0.987596 0.979707 0.999179 1999 NaN 1.237646 1.197135 1.144305 1.057447 1.055967 NaN 1.011131 1.001436 NaN 2000 1.196032 1.168062 1.239452 1.086354 1.168543 1.072291 1.015048 0.993094 NaN NaN 2001 1.353175 NaN NaN NaN 1.085689 1.037834 1.006668 NaN NaN NaN 2002 1.590040 NaN NaN 1.179122 1.096524 NaN NaN NaN NaN NaN 2003 1.760957 NaN NaN 1.089595 1.003210 NaN NaN NaN NaN NaN 2004 2.364225 NaN 1.218140 NaN NaN NaN NaN NaN NaN NaN 2005 1.654181 NaN 1.004478 NaN NaN NaN NaN NaN NaN NaN 2006 1.728479 1.043199 NaN NaN NaN NaN NaN NaN NaN NaN 2007 1.629204 NaN NaN NaN NaN NaN NaN NaN NaN NaN
Notice that the link ratios above 1.25 and below 1.0 are not dropped, unless there are 3 or more link ratios remaining. For example, the 12-24 link ratio is not dropped because there are 2 valid non-NaN link ratios remaining after removing all link ratios above 1.25 and below 1.0. While the 24-36 link ratio is dropped because there are still 3 valid non-NaN link ratios remaining after removing all link ratios above 1.25 and below 1.0.
Let’s inspect the LDFs.
ldf = ( cl.Development(drop_above=1.25, drop_below=1.0, preserve=3) .fit(tri["Incurred"]) .ldf_ ) print(ldf)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 (All) 1.675693 1.105627 1.127842 1.119324 1.076968 1.053434 1.027623 0.997636 0.992918 0.999179
Using other average methods, we can see that the loss development factors are different.
tri = cl.load_sample("xyz") ldf = ( cl.Development(average="simple").fit(tri["Incurred"]).ldf_ ) print(ldf)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 (All) 1.659537 1.35064 1.22277 1.119155 1.079301 1.039863 1.031011 0.997274 0.990571 0.999179
Inherited Methods
|
Fit to data, then transform it. |
|
Get metadata routing of this object. |
|
Get parameters for this estimator. |
|
|
|
Converts triangle array_backend. |
|
Set output container. |
|
Set the parameters of this estimator. |
|
Serializes triangle object to json format |
|
Serializes triangle object to pickle. |