TailCurve#
- class chainladder.TailCurve(curve='exponential', fit_period=(None, None), extrap_periods=100, errors='ignore', attachment_age=None, reg_threshold=(1.00001, None), projection_period=12)[source]#
Allows for extraploation of LDFs to form a tail factor.
- Parameters:
- curvestr (‘exponential’, ‘inverse_power’)
The type of curve extrapolation you’d like to use
- fit_periodtuple (start, stop) or list(bool)
A tuple representing the range of ldfs to use in the curve fit. The use of
Nonewill use the edge of the triangle. For example, (48, None) will use development factors for age 48 and beyond. Alternatively, passing a list of booleans [True, False, …] will allow for excluding (False) any development patterns from fitting.- extrap_periodsint
Then number of development periods from attachment point to extrapolate the fit.
- errorsstr (‘raise’ or ‘ignore’)
Whether to raise an error or ignore observations that violate the distribution being fit. The most common is ldfs < 1.0 will not work in either the
exponentialorinverse_powerfits.- attachment_age: int (default=None)
The age at which to attach the fitted curve. If None, then the latest age is used. Measures of variability from original
ldf_are retained when being used in conjunction with the MackChainladder method.- reg_thresholdtuple (lower, upper)
A tuple representing the lower and upper thresholds for the ldfs to be considered in the log regression of the tail fitting. Default lower threshold set to 1.00001 to avoid distortion caused by ldfs close to 1. Upper threshold can be used as an alternative to the fit_period start, to make the selection value based rather then period based.
- projection_periodint
The number of months beyond the latest available development age the ldf_ and cdf_ vectors should extend.
- Attributes:
- ldf_Triangle
ldf with tail applied.
- cdf_Triangle
cdf with tail applied.
- tail_DataFrame
Point estimate of tail at latest maturity available in the Triangle.
slope_DataFrameDoes not work with munich
- interceptDataFrame
Intercept parameter of the curve fit.
Examples
Suppose a reserving actuary has credible development factors through age 120, but the line is clearly still developing at the oldest observed ages, so a tail factor must be appended.
TailCurveextrapolates one by regressing the observed development factors against age and extending the fitted curve beyond the edge of the triangle. The two main curve families encode very different assumptions about how quickly the remaining development decays:exponentialregressesln(ldf - 1)against age, so the development portion of each factor decays geometrically. This yields a light tail that converges quickly, appropriate when development is expected to run off within a few periods of the triangle edge.inverse_powerregressesln(ldf - 1)against the log of age, giving a power-law decay. Development persists much longer, producing a heavier and more conservative tail suited to long-tailed lines. Because it approaches its asymptote slowly, it is also far more sensitive to theextrap_periodsparameter than the exponential curve.
dev = cl.Development().fit_transform(cl.load_sample("tail_sample")["paid"]) exp = cl.TailCurve(curve="exponential").fit(dev) inv = cl.TailCurve(curve="inverse_power").fit(dev) print(exp.ldf_) print(inv.ldf_)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 132-144 (All) 2.026309 1.559087 1.320123 1.184491 1.107264 1.074001 1.046207 1.032158 1.023925 1.012067 1.020099 12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 132-144 (All) 2.026309 1.559087 1.320123 1.184491 1.107264 1.074001 1.046207 1.032158 1.023925 1.027083 1.325559The same nine observed factors support either a 3.2% tail under exponential decay (
1.012067 * 1.020099) or a 36.1% tail under the inverse power curve (1.027083 * 1.325559). To judge which family the data actually supports, attach each fitted curve at an early age and compare the smoothed factors against the observed ones over the ages where data exists:print(dev.ldf_) print(cl.TailCurve(curve="exponential", attachment_age=24).fit(dev).ldf_) print(cl.TailCurve(curve="inverse_power", attachment_age=24).fit(dev).ldf_)
12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 (All) 2.026309 1.559087 1.320123 1.184491 1.107264 1.074001 1.046207 1.032158 1.023925 12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 132-144 (All) 2.026309 1.531333 1.331052 1.206265 1.128515 1.080073 1.04989 1.031084 1.019367 1.012067 1.020099 12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 132-144 (All) 2.026309 1.466969 1.227905 1.136998 1.092314 1.066862 1.050903 1.040192 1.032632 1.027083 1.325559The exponential curve tracks the observed decay closely at every age. The inverse power curve understates development at the middle ages and overstates it at the oldest ages, and that overstatement at the oldest ages is exactly what compounds into its 36.1% tail. On this data the lighter exponential tail is the better supported selection; booking the inverse power tail instead would require external support, such as industry benchmarks for an unusually long-tailed line.
Inherited Methods
|
Fit to data, then transform it. |
|
Get metadata routing of this object. |
|
Get parameters for this estimator. |
|
Apply |
|
Converts triangle array_backend. |
|
Set output container. |
|
Set the parameters of this estimator. |
|
Serializes triangle object to json format |
|
Serializes triangle object to pickle. |
|
If X and self are of different shapes, align self to X, else return self. |