2.4.8. Vectorization: Limit Profiles and Mixed Severity
Prerequisites: Examples use build and qd, and basic Aggregate output.
2.4.8.1. Using a Limit Profile with a Mixed Severity
Limit Profiles and Mixed Severity Distributions can be combined. Each mixed severity is applied to each limit profile component.
sub-components.
Example.
This example combines three limit bands and a severity with two mixture
components. It creates an aggregate with six severities. The report_df
dataframe shows the components (transposed extract shown). The mixture weights apply to claim counts, since exposure is specified by number of expected claims.
In [1]: from aggregate import build, qd
In [2]: a11 = build('agg DecL:11 '
...: '[10 20 30] claims '
...: '[100 200 75] xs [0 50 75] '
...: 'sev lognorm 100 cv [1 2] wts [0.6 0.4] '
...: 'poisson')
...:
In [3]: qd(a11)
E[X] Est E[X] Err E[X] CV(X) Est CV(X) Skew(X) Est Skew(X)
X
Freq 60 0.1291 0.1291
Sev 60.65 60.65 -8.3258e-08 0.76525 0.76525 1.2624 1.2624
Agg 3639 3639 -8.3262e-08 0.16256 0.16256 0.21483 0.21483
log2 = 16, bandwidth = 1/8, validation: not unreasonable.
In [4]: qd(a11.report_df.loc[['limit', 'attachment', 'freq_m',
...: 'agg_m', 'agg_cv']].T.iloc[:-4])
...:
statistic limit attachment freq_m agg_m agg_cv
view
0 100 0 6 406.32 0.44721
1 100 0 4 210.35 0.6055
2 200 50 13.618 984.54 0.35857
3 200 50 6.3822 552.26 0.51379
4 75 75 20.23 969.19 0.25552
5 75 75 9.7703 516.34 0.35838
Example.
We can combine the mixed exponential from Mixed Exponential Distributions with a limits profile.
In [5]: from aggregate import build, qd
In [6]: a12 = build('agg DecL:12 [20 8 4 2] claims [1e6, 2e6 5e6 10e6] xs 0 '
...: 'sev [2.764e3 24.548e3 275.654e3 1.917469e6 10e6] * '
...: 'expon 1 wts [0.824796 0.159065 0.014444 0.001624, 0.000071] fixed',
...: log2=18, bs=500)
...:
In [7]: qd(a12)
E[X] Est E[X] Err E[X] CV(X) Est CV(X) Skew(X) Est Skew(X)
X
Freq 34 0
Sev 11973 11970 -0.00026506 6.328 6.3298 31.665 31.665
Agg 4.0708e+05 4.0697e+05 -0.00026506 1.0852 1.0855 5.4306 5.4305
log2 = 18, bandwidth = 500, validation: fails sev mean, agg mean.
The report_df shows all 20 components: 4 limits x 5 mixture components.
In [8]: qd(a12.report_df.loc[['limit', 'attachment', 'freq_m',
...: 'agg_m', 'agg_cv']].T.iloc[:-4])
...:
statistic limit attachment freq_m agg_m agg_cv
view
0 1e+06 0 16.496 45595 0.24621
1 1e+06 0 3.1813 78095 0.56066
2 1e+06 0 0.28888 77515 1.7165
3 1e+06 0 0.03248 25309 2.3031
4 1e+06 0 0.00142 1351.3 4.8442
5 2e+06 0 6.5984 18238 0.3893
6 2e+06 0 1.2725 31238 0.88648
7 2e+06 0 0.11555 31830 2.9287
8 2e+06 0 0.012992 16133 5.082
9 2e+06 0 0.000568 1029.6 10.827
10 5e+06 0 3.2992 9118.9 0.55055
11 5e+06 0 0.63626 15619 1.2537
12 5e+06 0 0.057776 15926 4.1603
13 5e+06 0 0.006496 11538 10.463
14 5e+06 0 0.000284 1117.5 24.125
15 1e+07 0 1.6496 4559.5 0.7786
16 1e+07 0 0.31813 7809.5 1.773
17 1e+07 0 0.028888 7963.1 5.8836
18 1e+07 0 0.003248 6194.1 17.135
19 1e+07 0 0.000142 897.61 47.664
2.4.8.2. Circumventing Products: Modeling Multiple Units in One Aggregate
When severity weights sum to one, the severity is treated as a mixture and all exposure terms are broadcast against all severity terms in an outer product.
When severity weights are missing or sum to the number of severity components (e.g., are all equal to 1) the result is an item by item combination, circumventing the outer product. There are two cases when this alternative is useful:
Two or more units each with a different severity, but with a shared mixing variable. For example, to model two units with expected losses 100 and 200, one with a gamma mean 10 CV 1 severity and the other lognormal mean 15 CV 1.5 and both share a gamma mixing variable:
agg MixedPremReserve \ [100 200] claims \ sev [gamma lognorm] [10 15] cv [1 1.5] \ mixed gamma 0.4
The result should be the two-way combination, not the four-way exposure and severity product.
Exposures with different limits may have different severity curves. Again, the limit profile and severity curves should all be broadcast together at once, rather than broadcasting limits and severities separately and then taking the outer product:
agg Eg4 \ [10 10 10] claims \ [1000 2000 5000] xs 0 \ sev lognorm [50 100 150] cv [0.1 0.15 0.2] \ poisson
Example.
The next two examples illustrate the different behavior.
Two units with different limits and severities and no weights.
report_dfshows only two components modeled.
In [9]: a13 = build('agg DecL:13 '
...: '[10 20] claims '
...: '[1000 2000] xs 0 '
...: 'sev [gamma lognorm] [10 15] cv [1 1.5] '
...: 'mixed gamma 0.4 ')
...:
In [10]: qd(a13)
E[X] Est E[X] Err E[X] CV(X) Est CV(X) Skew(X) Est Skew(X)
X
Freq 30 0.4397 0.80358
Sev 13.333 13.333 -4.0697e-07 1.4543 1.4543 8.255 8.255
Agg 400 400 -4.0707e-07 0.51365 0.51365 1.014 1.014
log2 = 16, bandwidth = 1/16, validation: not unreasonable.
In [11]: qd(a13.report_df.loc[['limit', 'attachment', 'freq_m',
....: 'agg_m', 'agg_cv']].T.iloc[:-4])
....:
statistic limit attachment freq_m agg_m agg_cv
view
0 1000 0 10 100 0.6
1 2000 0 20 300 0.56778
Adding weights results in a mixed severity, 80% for the gamma and 20% for lognormal. Now
report_dfshows that each limit band is combined with each severity, resulting in four modeled components.
In [12]: a14 = build('agg DecL:14 '
....: '[10 20] claims '
....: '[1000 2000] xs 0 '
....: 'sev [gamma lognorm] [10 15] cv [1 1.5] '
....: 'wts [.8 .2] '
....: 'mixed gamma 0.4 ')
....:
In [13]: qd(a14)
E[X] Est E[X] Err E[X] CV(X) Est CV(X) Skew(X) Est Skew(X)
X
Freq 30 0.4397 0.80358
Sev 11 11 -2.9593e-07 1.2362 1.2362 7.7928 7.7928
Agg 330 330 -2.1305e-06 0.49424 0.49422 0.94603 0.94464
log2 = 16, bandwidth = 1/32, validation: not unreasonable.
In [14]: qd(a14.report_df.loc[['limit', 'attachment', 'freq_m',
....: 'agg_m', 'agg_cv']].T.iloc[:-4])
....:
statistic limit attachment freq_m agg_m agg_cv
view
0 1000 0 8 80 0.64031
1 1000 0 2 29.997 1.3328
2 2000 0 16 160 0.53385
3 2000 0 4 60 0.98584