diff --git a/chainladder/core/base.py b/chainladder/core/base.py index 24824577..f196b298 100644 --- a/chainladder/core/base.py +++ b/chainladder/core/base.py @@ -369,7 +369,7 @@ def nan_triangle(self): This becomes useful when managing array arithmetic. """ xp = self.get_array_module() - if self.is_pattern or self.is_ultimate: + if self.is_ultimate: return xp.ones(self.values.shape[2:], dtype="float16") val_array = np.array(self.valuation).reshape(self.shape[-2:], order="f") nan_triangle = np.array(pd.DataFrame(val_array) > self.valuation_date) @@ -601,6 +601,9 @@ def _drop_subtriangles(self): del self.sigma_ if "std_err_" in sub_tris: del self.std_err_ + #w_ is currently stored as an ndarray + if hasattr(self, "w_"): + del self.w_ @property def subtriangles(self): diff --git a/chainladder/core/triangle.py b/chainladder/core/triangle.py index bd5e710e..cd94e689 100644 --- a/chainladder/core/triangle.py +++ b/chainladder/core/triangle.py @@ -109,7 +109,7 @@ class Triangle(TriangleBase): link_ratio, age_to_age: Triangle Displays age-to-age ratios for the triangle. disposal_rate_tri: Triangle - Displays actual disposal rates by origin and development; must have ultimate_ + Displays actual disposal rates by origin and development; must have ``ultimate_`` valuation_date : date The latest valuation date of the data loc: Triangle diff --git a/chainladder/utils/data/_manifest.py b/chainladder/utils/data/_manifest.py index fa336b13..5b30d9bc 100644 --- a/chainladder/utils/data/_manifest.py +++ b/chainladder/utils/data/_manifest.py @@ -148,6 +148,7 @@ "Reported Claim Counts", "Disposal Rate", "Paid Claims", + "Reported Claims", ], "cumulative": True, }, @@ -277,13 +278,6 @@ "columns": ["Paid Claims", "Reported Claims", "Closed Claim Counts", "Reported Claim Counts", "Case Outstanding", "Reported Severities", "Earned Premium"], "cumulative": True, }, - "friedland_xyz_disp": { - "origin": "Accident Year", - "development": "Calendar Year", - "index": None, - "columns": ["Disposal Rate", "Closed Claim Counts", "Paid Claims"], - "cumulative": True, - }, "genins": { "origin": "origin", "development": "development", diff --git a/chainladder/utils/data/friedland_auto_freq_sev.csv b/chainladder/utils/data/friedland_auto_freq_sev.csv index bd91893c..6a22a655 100644 --- a/chainladder/utils/data/friedland_auto_freq_sev.csv +++ b/chainladder/utils/data/friedland_auto_freq_sev.csv @@ -1,56 +1,56 @@ -Accident Half-Year,Calendar Half-Year,Closed Claim Counts,Reported Claim Counts,Reported Claims,Reported Severity,Paid Claims -2003-07,2003-07,2547,3556,14235000,4003, -2003-07,2004-01,3262,3314,14960000,4514, -2003-07,2004-07,3287,3301,14921000,4520, -2003-07,2005-01,3291,3299,14911000,4520, -2003-07,2005-07,3292,3295,14926000,4530, -2003-07,2006-01,3292,3294,14864000,4512, -2003-07,2006-07,3292,3293,14860000,4513, -2003-07,2007-01,3292,3293,14854000,4511, -2003-07,2007-07,3292,3293,14850000,4510, -2003-07,2008-01,3292,3292,14847000,4510,14846000 -2004-01,2004-01,2791,3492,14548000,4166, -2004-01,2004-07,3217,3262,14674000,4498, -2004-01,2005-01,3240,3250,14643000,4506, -2004-01,2005-07,3242,3247,14626000,4505, -2004-01,2006-01,3243,3247,14621000,4503, -2004-01,2006-07,3243,3245,14610000,4502, -2004-01,2007-01,3243,3245,14610000,4502, -2004-01,2007-07,3243,3244,14611000,4504, -2004-01,2008-01,3242,3243,14617000,4507,14614000 -2004-07,2004-07,2099,2980,12129000,4070, -2004-07,2005-01,2677,2712,12576000,4637, -2004-07,2005-07,2695,2704,12541000,4638, -2004-07,2006-01,2697,2702,12531000,4638, -2004-07,2006-07,2697,2700,12523000,4683, -2004-07,2007-01,2698,2700,12523000,4638, -2004-07,2007-07,2698,2699,12510000,4635, -2004-07,2008-01,2698,2699,12502000,4632,12502000 -2005-01,2005-01,2370,2896,11980000,4137, -2005-01,2005-07,2735,2768,11921000,4307, -2005-01,2006-01,2751,2761,11882000,4304, -2005-01,2006-07,2754,2758,11862000,4301, -2005-01,2007-01,2755,2758,11854000,4298, -2005-01,2007-07,2755,2758,11844000,4294, -2005-01,2008-01,2756,2757,11841000,4295,11840000 -2005-07,2005-07,1966,2814,11283000,4010, -2005-07,2006-01,2609,2650,11843000,4469, -2005-07,2006-07,2630,2640,11805000,4472, -2005-07,2007-01,2634,2639,11789000,4467, -2005-07,2007-07,2634,2638,11772000,4462, -2005-07,2008-01,2634,2636,11770000,4465,11765000 -2006-01,2006-01,2261,2808,11947000,4254, -2006-01,2006-07,2671,2712,11856000,4372, -2006-01,2007-01,2694,2704,11820000,4371, -2006-01,2007-07,2696,2701,11772000,4359, -2006-01,2008-01,2697,2700,11760000,4356,11755000 -2006-07,2006-07,1949,2799,12503000,4467, -2006-07,2007-01,2637,2675,12762000,4771, -2006-07,2007-07,2659,2670,12706000,4759, -2006-07,2008-01,2662,2668,12697000,4759,12679000 -2007-01,2007-01,2059,2578,11662000,4524, -2007-01,2007-07,2496,2533,11523000,4549, -2007-01,2008-01,2520,2529,11492000,4544,11406000 -2007-07,2007-07,2083,2791,12647000,4531, -2007-07,2008-01,2732,2778,12854000,4627,12648000 -2008-01,2008-01,2533,3139,14071000,4483,11833000 +Accident Half-Year,Calendar Half-Year,Closed Claim Counts,Reported Claim Counts,Reported Claims,Reported Severity,Paid Claims +2003-07,2003-07,2547,3556,14234668,4003, +2003-07,2004-01,3262,3314,14959396,4514, +2003-07,2004-07,3287,3301,14920520,4520, +2003-07,2005-01,3291,3299,14911480,4520, +2003-07,2005-07,3292,3295,14926350,4530, +2003-07,2006-01,3292,3294,14862528,4512, +2003-07,2006-07,3292,3293,14861309,4513, +2003-07,2007-01,3292,3293,14854723,4511, +2003-07,2007-07,3292,3293,14851430,4510, +2003-07,2008-01,3292,3292,14846920,4510,14846000 +2004-01,2004-01,2791,3492,14547672,4166, +2004-01,2004-07,3217,3262,14672476,4498, +2004-01,2005-01,3240,3250,14644500,4506, +2004-01,2005-07,3242,3247,14627735,4505, +2004-01,2006-01,3243,3247,14621241,4503, +2004-01,2006-07,3243,3245,14608990,4502, +2004-01,2007-01,3243,3245,14608990,4502, +2004-01,2007-07,3243,3244,14610976,4504, +2004-01,2008-01,3242,3243,14616201,4507,14614000 +2004-07,2004-07,2099,2980,12128600,4070, +2004-07,2005-01,2677,2712,12575544,4637, +2004-07,2005-07,2695,2704,12541152,4638, +2004-07,2006-01,2697,2702,12531876,4638, +2004-07,2006-07,2697,2700,12522600,4683, +2004-07,2007-01,2698,2700,12522600,4638, +2004-07,2007-07,2698,2699,12509865,4635, +2004-07,2008-01,2698,2699,12501768,4632,12502000 +2005-01,2005-01,2370,2896,11980752,4137, +2005-01,2005-07,2735,2768,11921776,4307, +2005-01,2006-01,2751,2761,11883344,4304, +2005-01,2006-07,2754,2758,11862158,4301, +2005-01,2007-01,2755,2758,11853884,4298, +2005-01,2007-07,2755,2758,11842852,4294, +2005-01,2008-01,2756,2757,11841315,4295,11840000 +2005-07,2005-07,1966,2814,11284140,4010, +2005-07,2006-01,2609,2650,11842850,4469, +2005-07,2006-07,2630,2640,11806080,4472, +2005-07,2007-01,2634,2639,11788413,4467, +2005-07,2007-07,2634,2638,11770756,4462, +2005-07,2008-01,2634,2636,11769740,4465,11765000 +2006-01,2006-01,2261,2808,11945232,4254, +2006-01,2006-07,2671,2712,11856864,4372, +2006-01,2007-01,2694,2704,11819184,4371, +2006-01,2007-07,2696,2701,11773659,4359, +2006-01,2008-01,2697,2700,11761200,4356,11755000 +2006-07,2006-07,1949,2799,12503133,4467, +2006-07,2007-01,2637,2675,12762425,4771, +2006-07,2007-07,2659,2670,12706530,4759, +2006-07,2008-01,2662,2668,12697012,4759,12679000 +2007-01,2007-01,2059,2578,11662872,4524, +2007-01,2007-07,2496,2533,11522617,4549, +2007-01,2008-01,2520,2529,11491776,4544,11406000 +2007-07,2007-07,2083,2791,12646021,4531, +2007-07,2008-01,2732,2778,12853806,4627,12648000 +2008-01,2008-01,2533,3139,14072137,4483,11833000 diff --git a/chainladder/utils/data/friedland_gl_insurer.csv b/chainladder/utils/data/friedland_gl_insurer.csv index 66804cda..b4bb7434 100644 --- a/chainladder/utils/data/friedland_gl_insurer.csv +++ b/chainladder/utils/data/friedland_gl_insurer.csv @@ -1,37 +1,37 @@ -Accident Year,Calendar Year,Closed Claim Counts,Reported Claim Counts,Disposal Rate,Paid Claims -2001,2001,195,1299,0.223,1119962 -2001,2002,375,1077,0.43,4373268 -2001,2003,510,1057,0.584,8398345 -2001,2004,625,965,0.716,13490793 -2001,2005,702,930,0.804,17372233 -2001,2006,752,917,0.862,22052662 -2001,2007,780,864,0.894,27359691 -2001,2008,796,870,0.912,29901361 -2002,2002,199,847,0.277,1411957 -2002,2003,349,945,0.485,6287005 -2002,2004,445,864,0.618,11443820 -2002,2005,508,787,0.706,15520552 -2002,2006,563,784,0.782,21295572 -2002,2007,594,743,0.826,28410418 -2002,2008,626,731,0.87,32468911 -2003,2003,106,800,0.169,984748 -2003,2004,294,831,0.47,6128957 -2003,2005,383,762,0.612,10470758 -2003,2006,453,704,0.724,14604684 -2003,2007,499,669,0.797,21936647 -2003,2008,542,636,0.866,23942499 -2004,2004,126,823,0.2,1158659 -2004,2005,281,862,0.447,5811172 -2004,2006,377,797,0.599,10497504 -2004,2007,445,728,0.707,15087416 -2004,2008,494,684,0.785,18242570 -2005,2005,114,828,0.194,1198767 -2005,2006,249,850,0.423,5103837 -2005,2007,315,765,0.536,9042134 -2005,2008,403,687,0.685,15443929 -2006,2006,114,824,0.206,1220778 -2006,2007,229,809,0.414,4594746 -2006,2008,300,734,0.543,8983864 -2007,2007,79,604,0.18,796774 -2007,2008,188,620,0.429,4233641 -2008,2008,127,812,0.209,1445365 +Accident Year,Calendar Year,Closed Claim Counts,Reported Claim Counts,Disposal Rate,Paid Claims,Reported Claims +2001,2001,195,1299,0.223,1119962, +2001,2002,375,1077,0.43,4373268, +2001,2003,510,1057,0.584,8398345, +2001,2004,625,965,0.716,13490793, +2001,2005,702,930,0.804,17372233, +2001,2006,752,917,0.862,22052662, +2001,2007,780,864,0.894,27359691, +2001,2008,796,870,0.912,29901361,35592000 +2002,2002,199,847,0.277,1411957, +2002,2003,349,945,0.485,6287005, +2002,2004,445,864,0.618,11443820, +2002,2005,508,787,0.706,15520552, +2002,2006,563,784,0.782,21295572, +2002,2007,594,743,0.826,28410418, +2002,2008,626,731,0.87,32468911,36330000 +2003,2003,106,800,0.169,984748, +2003,2004,294,831,0.47,6128957, +2003,2005,383,762,0.612,10470758, +2003,2006,453,704,0.724,14604684, +2003,2007,499,669,0.797,21936647, +2003,2008,542,636,0.866,23942499,31900000 +2004,2004,126,823,0.2,1158659, +2004,2005,281,862,0.447,5811172, +2004,2006,377,797,0.599,10497504, +2004,2007,445,728,0.707,15087416, +2004,2008,494,684,0.785,18242570,39716000 +2005,2005,114,828,0.194,1198767, +2005,2006,249,850,0.423,5103837, +2005,2007,315,765,0.536,9042134, +2005,2008,403,687,0.685,15443929,32667000 +2006,2006,114,824,0.206,1220778, +2006,2007,229,809,0.414,4594746, +2006,2008,300,734,0.543,8983864,27774000 +2007,2007,79,604,0.18,796774, +2007,2008,188,620,0.429,4233641,16246000 +2008,2008,127,812,0.209,1445365,8216000 diff --git a/chainladder/utils/data/friedland_xyz_auto_bi.csv b/chainladder/utils/data/friedland_xyz_auto_bi.csv index 4f4753c3..a9863903 100644 --- a/chainladder/utils/data/friedland_xyz_auto_bi.csv +++ b/chainladder/utils/data/friedland_xyz_auto_bi.csv @@ -1,67 +1,67 @@ -Accident Year,Calendar Year,Paid Claims,Reported Claims,Closed Claim Counts,Reported Claim Counts,Case Outstanding,Reported Severities,Earned Premium -1998,1998,,,,,,,20000 -1998,1999,,,,,,,20000 -1998,2000,6309,11171,,,4861,,20000 -1998,2001,8521,12380,510,634,3859,19526,20000 -1998,2002,10082,13216,547,635,3134,20813,20000 -1998,2003,11620,14067,575,635,2447,22152,20000 -1998,2004,13242,14688,598,637,1446,23058,20000 -1998,2005,14419,16366,612,637,1947,25692,20000 -1998,2006,15311,16163,620,637,853,25374,20000 -1998,2007,15764,15835,635,637,71,24859,20000 -1998,2008,15822,15822,637,637,0,24839,20000 -1999,1999,,,,,,,31500 -1999,2000,4666,13255,,,8589,,31500 -1999,2001,9861,16405,686,1026,6544,15989,31500 -1999,2002,13971,19639,819,1039,5668,18902,31500 -1999,2003,18127,22473,910,1047,4347,21464,31500 -1999,2004,22032,23764,980,1050,1732,22632,31500 -1999,2005,23511,25094,1007,1053,1583,23831,31500 -1999,2006,24146,24795,1036,1047,649,23682,31500 -1999,2007,24592,25071,1039,1047,479,23946,31500 -1999,2008,24817,25107,1044,1047,290,23980,31500 -2000,2000,1302,15676,,,14374,,45000 -2000,2001,6513,18749,650,1354,12237,13847,45000 -2000,2002,12139,21900,932,1397,9760,15676,45000 -2000,2003,17828,27144,1095,1411,9316,19237,45000 -2000,2004,24030,29488,1216,1410,5458,20914,45000 -2000,2005,28853,34458,1292,1408,5605,24473,45000 -2000,2006,33222,36949,1367,1408,3727,26242,45000 -2000,2007,35902,37505,1391,1408,1603,26637,45000 -2000,2008,36782,37246,1402,1408,465,26453,45000 -2001,2001,1539,11827,304,1305,10288,9063,50000 -2001,2002,5952,16004,681,1421,10052,11262,50000 -2001,2003,12319,21022,936,1449,8703,14508,50000 -2001,2004,18609,26578,1092,1458,7969,18229,50000 -2001,2005,24387,34205,1225,1458,9818,23460,50000 -2001,2006,31090,37136,1357,1455,6046,25523,50000 -2001,2007,37070,38541,1432,1455,1471,26489,50000 -2001,2008,38519,38798,1446,1455,278,26665,50000 -2002,2002,2318,12811,203,1342,10494,9546,61183 -2002,2003,7932,20370,607,1514,12439,13455,61183 -2002,2004,13822,26656,841,1548,12833,17219,61183 -2002,2005,22095,37667,1089,1557,15572,24192,61183 -2002,2006,31945,44414,1327,1549,12469,28673,61183 -2002,2007,40629,48701,1464,1552,8072,31379,61183 -2002,2008,44437,48169,1523,1554,3731,30997,61183 -2003,2003,1743,9651,181,1373,7908,7029,69175 -2003,2004,6240,16995,614,1616,10755,10517,69175 -2003,2005,12683,30354,941,1630,17671,18622,69175 -2003,2006,22892,40594,1263,1626,17702,24966,69175 -2003,2007,34505,44231,1507,1629,9726,27152,69175 -2003,2008,39320,44373,1568,1629,5052,27239,69175 -2004,2004,2221,16995,235,1932,14774,8796,99322 -2004,2005,9898,40180,848,2168,30281,18533,99322 -2004,2006,25950,58866,1442,2234,32916,26350,99322 -2004,2007,43439,71707,1852,2249,28268,31884,99322 -2004,2008,52811,70288,2029,2258,17477,31129,99322 -2005,2005,3043,28674,295,2067,25631,13872,138151 -2005,2006,12219,47432,1119,2293,35213,20686,138151 -2005,2007,27073,70340,1664,2367,43268,29717,138151 -2005,2008,40026,70655,1946,2390,30629,29563,138151 -2006,2006,3531,27066,307,1473,23535,18375,107578 -2006,2007,11778,46783,906,1645,35005,28440,107578 -2006,2008,22819,48804,1201,1657,25985,29453,107578 -2007,2007,3529,19477,329,1192,15948,16340,62438 -2007,2008,11865,31732,791,1264,19867,25104,62438 -2008,2008,3409,18632,276,1036,15223,17985,47797 +Accident Year,Calendar Year,Paid Claims,Reported Claims,Closed Claim Counts,Reported Claim Counts,Case Outstanding,Reported Severities,Earned Premium +1998,1998,,,,,,,20000 +1998,1999,,,,,,,20000 +1998,2000,6309,11171,,,4861,,20000 +1998,2001,8521,12380,510,634,3859,19526,20000 +1998,2002,10082,13216,547,635,3134,20813,20000 +1998,2003,11620,14067,575,635,2447,22152,20000 +1998,2004,13242,14688,598,637,1446,23058,20000 +1998,2005,14419,16366,612,637,1947,25692,20000 +1998,2006,15311,16163,620,637,853,25374,20000 +1998,2007,15764,15835,635,637,71,24859,20000 +1998,2008,15822,15822,637,637,0,24839,20000 +1999,1999,,,,,,,31500 +1999,2000,4666,13255,,,8589,,31500 +1999,2001,9861,16405,686,1026,6544,15989,31500 +1999,2002,13971,19639,819,1039,5668,18902,31500 +1999,2003,18127,22473,910,1047,4347,21464,31500 +1999,2004,22032,23764,980,1050,1732,22632,31500 +1999,2005,23511,25094,1007,1053,1583,23831,31500 +1999,2006,24146,24795,1036,1047,649,23682,31500 +1999,2007,24592,25071,1039,1047,479,23946,31500 +1999,2008,24817,25107,1044,1047,290,23980,31500 +2000,2000,1302,15676,,,14374,,45000 +2000,2001,6513,18749,650,1354,12237,13847,45000 +2000,2002,12139,21900,932,1397,9760,15676,45000 +2000,2003,17828,27144,1095,1411,9316,19237,45000 +2000,2004,24030,29488,1216,1410,5458,20914,45000 +2000,2005,28853,34458,1292,1408,5605,24473,45000 +2000,2006,33222,36949,1367,1408,3727,26242,45000 +2000,2007,35902,37505,1391,1408,1603,26637,45000 +2000,2008,36782,37246,1402,1408,465,26453,45000 +2001,2001,1539.456,11827,304,1305,10288,9063,50000 +2001,2002,5952.241,16004,681,1421,10052,11262,50000 +2001,2003,12319.336,21022,936,1449,8703,14508,50000 +2001,2004,18608.788,26578,1092,1458,7969,18229,50000 +2001,2005,24386.973,34205,1225,1458,9818,23460,50000 +2001,2006,31090.065,37136,1357,1455,6046,25523,50000 +2001,2007,37069.815,38541,1432,1455,1471,26489,50000 +2001,2008,38519.529,38798,1446,1455,278,26665,50000 +2002,2002,2317.651,12811,203,1342,10494,9546,61183 +2002,2003,7931.635,20370,607,1514,12439,13455,61183 +2002,2004,13822.585,26656,841,1548,12833,17219,61183 +2002,2005,22095.617,37667,1089,1557,15572,24192,61183 +2002,2006,31945.485,44414,1327,1549,12469,28673,61183 +2002,2007,40628.819,48701,1464,1552,8072,31379,61183 +2002,2008,44437.623,48169,1523,1554,3731,30997,61183 +2003,2003,1743.211,9651,181,1373,7908,7029,69175 +2003,2004,6240.349,16995,614,1616,10755,10517,69175 +2003,2005,12683.23,30354,941,1630,17671,18622,69175 +2003,2006,22892.562,40594,1263,1626,17702,24966,69175 +2003,2007,34505.01,44231,1507,1629,9726,27152,69175 +2003,2008,39320.472,44373,1568,1629,5052,27239,69175 +2004,2004,2221.22,16995,235,1932,14774,8796,99322 +2004,2005,9898.432,40180,848,2168,30281,18533,99322 +2004,2006,25950.094,58866,1442,2234,32916,26350,99322 +2004,2007,43439.464,71707,1852,2249,28268,31884,99322 +2004,2008,52811.083,70288,2029,2258,17477,31129,99322 +2005,2005,3042.925,28674,295,2067,25631,13872,138151 +2005,2006,12218.989,47432,1119,2293,35213,20686,138151 +2005,2007,27072.964,70340,1664,2367,43268,29717,138151 +2005,2008,40026.352,70655,1946,2390,30629,29563,138151 +2006,2006,3531.114,27066,307,1473,23535,18375,107578 +2006,2007,11778.146,46783,906,1645,35005,28440,107578 +2006,2008,22819.111,48804,1201,1657,25985,29453,107578 +2007,2007,3528.854,19477,329,1192,15948,16340,62438 +2007,2008,11864.72,31732,791,1264,19867,25104,62438 +2008,2008,3408.876,18632,276,1036,15223,17985,47797 diff --git a/chainladder/utils/data/friedland_xyz_disp.csv b/chainladder/utils/data/friedland_xyz_disp.csv deleted file mode 100644 index 8f9607ef..00000000 --- a/chainladder/utils/data/friedland_xyz_disp.csv +++ /dev/null @@ -1,37 +0,0 @@ -Accident Year,Calendar Year,Disposal Rate,Closed Claim Counts,Paid Claims -2001,2001,0.209,304,1539 -2001,2002,0.468,681,5952 -2001,2003,0.643,936,12319 -2001,2004,0.751,1092,18609 -2001,2005,0.842,1225,24387 -2001,2006,0.933,1357,31090 -2001,2007,0.984,1432,37070 -2001,2008,0.994,1446,38519 -2002,2002,0.131,203,2318 -2002,2003,0.391,607,7932 -2002,2004,0.541,841,13822 -2002,2005,0.701,1089,22095 -2002,2006,0.854,1327,31945 -2002,2007,0.842,1464,40629 -2002,2008,0.98,1523,44437 -2003,2003,0.111,181,1743 -2003,2004,0.377,614,6240 -2003,2005,0.577,941,12683 -2003,2006,0.775,1263,22892 -2003,2007,0.924,1507,34505 -2003,2008,0.962,1568,39320 -2004,2004,0.104,235,2221 -2004,2005,0.375,848,9898 -2004,2006,0.637,1442,25950 -2004,2007,0.819,1852,43439 -2004,2008,0.897,2029,52811 -2005,2005,0.123,295,3043 -2005,2006,0.466,1119,12219 -2005,2007,0.693,1664,27073 -2005,2008,0.81,1946,40026 -2006,2006,0.183,307,3531 -2006,2007,0.54,906,11778 -2006,2008,0.716,1201,22819 -2007,2007,0.251,329,3529 -2007,2008,0.605,791,11865 -2008,2008,0.236,276,3409 diff --git a/chainladder/utils/tests/test_utilities.py b/chainladder/utils/tests/test_utilities.py index 9c4615b2..1e516922 100644 --- a/chainladder/utils/tests/test_utilities.py +++ b/chainladder/utils/tests/test_utilities.py @@ -1242,3 +1242,33 @@ def test_describe_option_invalid_regex() -> None: """ with pytest.raises(ValueError, match="not a valid regular expression"): cl.options.describe_option('[') + + +def test_triangleweight_drop_valuation_all(raa: Triangle) -> None: + ''' + Testing error raising from dropping too many valuations + ''' + with pytest.raises(Exception): + _ = cl.TriangleWeight( + drop_valuation=[ + '1981', + '1982', + '1983', + '1984', + '1985', + '1986', + '1987', + '1988', + '1989', + '1990', + ] + ).fit(raa) + +def test_triangleweight_full_triangle(raa: Triangle) -> None: + ''' + Testing new path that allows weights on full triangles + ''' + ult = cl.Chainladder().fit(raa) + tw = cl.TriangleWeight(n_periods = 4).fit(raa) + tw_full = cl.TriangleWeight(n_periods = 4).fit(ult.full_triangle_) + assert tw.w_.iloc[:,:,:,0] == tw_full.w_.iloc[:,:,:,0] \ No newline at end of file diff --git a/chainladder/utils/triangle_weight.py b/chainladder/utils/triangle_weight.py index a0ebbfae..7399c741 100644 --- a/chainladder/utils/triangle_weight.py +++ b/chainladder/utils/triangle_weight.py @@ -15,7 +15,9 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from chainladder.core.typing import TriangleLike + from chainladder import Triangle + from chainladder.core.typing import TriangleProtocol + class TriangleWeight(BaseEstimator,TransformerMixin): """ @@ -84,7 +86,7 @@ def __init__( 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_valuation: str | list[str] | None = None, drop_above: float = np.inf, drop_below: float = 0.00, ): @@ -97,7 +99,7 @@ def __init__( self.drop_below = drop_below self.drop = drop - def fit(self, X: TriangleLike, y: None = None, sample_weight: None = None): + def fit(self, X: TriangleProtocol, y: None = None, sample_weight: None = None): """ Fit the model with X. @@ -115,17 +117,16 @@ def fit(self, X: TriangleLike, y: None = None, sample_weight: None = None): self : object Returns the instance itself. """ - self.w_ = self._set_weight_func(X=X,secondary_rank=sample_weight) return self - def transform(self, X: TriangleLike): + def transform(self, X: TriangleProtocol) -> Triangle: """If X and self are of different shapes, align self to X, else return self. Parameters ---------- - X : Triangle + X : TriangleProtocol The triangle to be transformed Returns @@ -175,9 +176,9 @@ def _cascade_param( def _set_weight_func( self, - X: TriangleLike, - secondary_rank: TriangleLike | None = None - ) -> TriangleLike: + X: TriangleProtocol, + secondary_rank: TriangleProtocol | None = None + ) -> Triangle: """ Combines weights from all parameters @@ -212,18 +213,18 @@ def _set_weight_func( return w_tri - def _assign_n_periods_weight_func(self, X: TriangleLike) -> TriangleLike: + def _assign_n_periods_weight_func(self, X: TriangleProtocol) -> np.ndarray: """ Generates weights for the `n_periods` parameter Parameters ---------- - X: TriangleLike + X: TriangleProtocol Triangle of values to be weighted Returns ------- - A Triangle of weights + numpy array of weights """ # cascading n_periods across all columns @@ -242,11 +243,16 @@ def _assign_n_periods_weight_int(X, n_periods): if n_periods < 1 or n_periods >= X.shape[-2]: return X.values * 0 + 1 else: - val_date_min = X.valuation[X.valuation <= X.valuation_date] - val_date_min = val_date_min.drop_duplicates().sort_values() z = -n_periods * val_offset[X.development_grain][X.origin_grain] - val_date_min = val_date_min[z] - w = X[X.valuation >= val_date_min] + #adding new path to handle full triangle (e.g. full_triangle_, ultimate_, et.c) + if X.is_full: + w = X.copy() + w.values[:,:,:z,:] = np.nan + else: + val_date_min = X.valuation[X.valuation <= X.valuation_date] + val_date_min = val_date_min.drop_duplicates().sort_values() + val_date_min = val_date_min[z] + w = X[X.valuation >= val_date_min] return xp.nan_to_num((w / w).values) * X.nan_triangle xp = X.get_array_module() @@ -265,9 +271,9 @@ def _assign_n_periods_weight_int(X, n_periods): def _drop_n_func( self, - X: TriangleLike, - secondary_rank: TriangleLike | None = None - ) -> TriangleLike: + X: TriangleProtocol, + secondary_rank: TriangleProtocol | None = None + ) -> np.ndarray: """ Generates weights for the `drop_high` and `drop_low` parameter @@ -280,7 +286,7 @@ def _drop_n_func( Returns ------- - A Triangle of weights + numpy array of weights """ # Preparing to set up 3D array for drop_n parameters @@ -362,7 +368,7 @@ def _drop_n_func( return w.astype(float) - def _drop_func(self, X: TriangleLike) -> TriangleLike: + def _drop_func(self, X: TriangleProtocol) -> np.ndarray: """ Generates weights for the `drop` parameter @@ -373,7 +379,7 @@ def _drop_func(self, X: TriangleLike) -> TriangleLike: Returns ------- - A Triangle of weights + numpy array of weights """ # get the appropriate backend for nan_to_num @@ -399,7 +405,7 @@ def _drop_func(self, X: TriangleLike) -> TriangleLike: w[(origin_ind, dev_ind)] = 0 return xp.nan_to_num(w)[None, None] - def _drop_valuation_func(self, X: TriangleLike) -> TriangleLike: + def _drop_valuation_func(self, X: TriangleProtocol) -> np.ndarray: """ Generates weights for the `drop` parameter @@ -410,7 +416,7 @@ def _drop_valuation_func(self, X: TriangleLike) -> TriangleLike: Returns ------- - A Triangle of weights + numpy array of weights """ # get the appropriate backend for nan_to_num @@ -434,7 +440,7 @@ def _drop_valuation_func(self, X: TriangleLike) -> TriangleLike: raise Exception("The entire triangle has been dropped via drop_valuation.") return w - def _drop_x_func(self, X: TriangleLike) -> TriangleLike: + def _drop_x_func(self, X: TriangleProtocol) -> np.ndarray: """ Generates weights for the `drop_above` and `drop_below` parameters @@ -445,7 +451,7 @@ def _drop_x_func(self, X: TriangleLike) -> TriangleLike: Returns ------- - A Triangle of weights + numpy array of weights """ # Preparing to set up 3D array for drop_x parameters diff --git a/chainladder/utils/weighted_regression.py b/chainladder/utils/weighted_regression.py index 925ac5d6..cc375af3 100644 --- a/chainladder/utils/weighted_regression.py +++ b/chainladder/utils/weighted_regression.py @@ -144,17 +144,29 @@ def _fit_OLS(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) + x_mean = xp.nansum(w * x, axis) / xp.nansum(w, axis) + y_mean = xp.nansum(y * w, axis) / xp.nansum(w, axis) slope = num_to_nan( - xp.nansum(w * x * y, axis) - - xp.nansum(x * w, axis) * xp.nanmean(y, axis) + xp.nansum(w * x * y, axis) - xp.nansum(x * w, axis) * y_mean ) / num_to_nan( - xp.nansum(w * x * x, axis) - - xp.nanmean(x, axis) * xp.nansum(w * x, axis) + xp.nansum(w * x * x, axis) - xp.nansum(x * w, axis) * x_mean ) - intercept = xp.nanmean(y, axis) - slope * xp.nanmean(x, axis) + intercept = y_mean - slope * x_mean + + fitted_value = xp.repeat(xp.expand_dims(slope, axis), x.shape[axis], axis) + fitted_value = fitted_value * x * (y * 0 + 1) + xp.repeat(xp.expand_dims(intercept, axis), x.shape[axis], axis) + + residual = (y - fitted_value) + + wss_residual = xp.nansum(residual ** 2 * w, axis) + + r2 = 1 - wss_residual / num_to_nan( + xp.nansum(w * y * y, axis) - xp.nansum(y * w, axis) * y_mean + ) self.slope_ = slope[..., None] self.intercept_ = intercept[..., None] + self.rsq_ = r2[..., None] return self diff --git a/docs/_toc.yml b/docs/_toc.yml index 87f3af4d..05681b7f 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -35,6 +35,7 @@ parts: sections: - file: friedland/chapter_6.rst - file: friedland/chapter_7.rst + - file: friedland/chapter_11.ipynb - chapters: - file: gallery/index.md - chapters: diff --git a/docs/friedland/chapter_11.ipynb b/docs/friedland/chapter_11.ipynb new file mode 100644 index 00000000..bf82fb9e --- /dev/null +++ b/docs/friedland/chapter_11.ipynb @@ -0,0 +1,3358 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "24730109-b724-4a80-817b-c11900453da4", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "# Chapter 11 - Frequency-Severity Techniques\n", + "\n", + "On this page, we will recreating Chapter 11 of Friendland. There is not a dedicated ``FrequencySeverity`` method in the package. Instead, we will chain together existing methods and use ``Triangle`` arithmetic to calculate the utimate. \n", + "\n", + "We will begin by import packages and setting up some helper functions." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "ff40a83c-496e-4345-8d03-5dbc368f6ba0", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import chainladder as cl\n", + "from IPython.display import display as nb_display\n", + "\n", + "#create reported/paid summary exhibit\n", + "def summary_exh(reported_tri:cl.Triangle,paid_tri:cl.Triangle,ult:cl.Triangle) -> pd.DataFrame:\n", + " output = reported_tri.latest_diagonal.to_frame()\n", + " output.columns = ['Reported']\n", + " output['Paid'] = paid_tri.latest_diagonal.to_frame()\n", + " #using floating point offset to achieve standard rounding\n", + " output['Ult Claims'] = (ult.latest_diagonal + 1e-9).round(0).to_frame()\n", + " output['Case Outstanding'] = output[\"Reported\"] - output[\"Paid\"]\n", + " output['IBNR'] = output[\"Ult Claims\"] - output[\"Reported\"]\n", + " output['Unpaid'] = output[\"Ult Claims\"] - output[\"Paid\"]\n", + " return output.round(0)\n", + "\n", + "#create a dict of developed triangles for each of the selection assumptions on a given page\n", + "def average_dev(tri: cl.Triangle, avg_params: dict[str,int]) -> dict[cl.Triangle]:\n", + " return {k:cl.Development(**v).fit_transform(tri) for k,v in avg_params.items()}\n", + "\n", + "#combine a dict of triangles into a singla triangle\n", + "def combine_tri(devs: dict[cl.Triangle]) -> cl.Triangle:\n", + " avgs = [v.rename('index',k) for k,v in devs.items()]\n", + " return cl.concat(avgs,axis=0)\n", + "\n", + "#combine the ldf_ of a dict of triangles into a singla triangle\n", + "def combine_ldf(devs: dict[cl.Triangle]) -> cl.Triangle:\n", + " return combine_tri({k:v.ldf_ for k,v in devs.items()})\n", + "\n", + "#create a dict of DisposalRate estimators for each of the selection assumptions on a given page\n", + "def average_dr(tri: cl.Triangle, w:cl.Triangle, avg_params: dict[str,int]) -> dict[cl.DisposalRate]:\n", + " return {k:cl.DisposalRate(**v).fit(X=tri,sample_weight = w) for k,v in avg_params.items()}\n", + "\n", + "#combine the disposal_rate_ of a dict of triangles into a singla triangle\n", + "def combine_disposal(devs: dict[cl.Triangle]) -> cl.Triangle:\n", + " return combine_tri({k:v.disposal_rate_ for k,v in devs.items()})\n", + "\n", + "#create a dict of weighted regression objects for each of the selection assumptions on a given page\n", + "def regs(tri: cl.Triangle, avg_params: dict[str,int]) -> dict[cl.WeightedRegression]:\n", + " return {k:cl.WeightedRegression(\n", + " axis=2,\n", + " thru_orig=False,\n", + " xp=tri.get_array_module()\n", + " ).fit(\n", + " np.ones(tri.shape) * tri.origin.year.values[None,None,:,None],\n", + " np.log(tri.values),\n", + " cl.TriangleWeight(**v).fit(tri).w_.values\n", + " ) for k,v in avg_params.items()}\n", + "\n", + "#combine all the trends and r-squared values into pandas DataFrame\n", + "def reg_outputs(regs: dict[cl.WeightedRegression],devs:pd.Series) -> pd.DataFrame:\n", + " trend = {k:(np.exp(v.slope_)-1).flatten() for k,v in regs.items()}\n", + " trend = pd.DataFrame.from_dict(trend,orient='index')\n", + " trend.columns = devs\n", + " rsq = {k:v.rsq_.flatten() for k,v in regs.items()}\n", + " rsq = pd.DataFrame.from_dict(rsq,orient='index')\n", + " rsq.columns = devs\n", + " return trend,rsq\n", + "\n", + "#create a dict of weighted regression objects for each of the selection assumptions on a given page\n", + "def average_sev(tri: cl.Triangle, avg_params: dict[str,int]) -> dict[cl.Triangle]:\n", + " output = {}\n", + " for k,v in avg_params.items():\n", + " w = cl.TriangleWeight(**v).fit(tri)\n", + " weighted_tri = tri * w.w_.values\n", + " output[k] = weighted_tri.mean()\n", + " return output" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "1f3f99fd-cb60-4901-807f-71273d213005", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Analysis\n", + "\n", + "Displaying all the triangles and dataframes take up quite a bit of code. We will distill the core analysis code at the top of each exhibit. \n", + "\n", + "Exhibit I follows Approach 1. Count and Severity are developed separately and multiplied together. " + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "68273ff4-16dd-4239-842e-e4c602ca6e08", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#loading data and assumptions\n", + "e1_tri = cl.load_sample('friedland_auto_freq_sev')\n", + "e1_cnt_assumptions = {}\n", + "e1_cnt_assumptions['simple_5'] = {'n_periods':5, 'average':'simple'}\n", + "e1_cnt_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e1_cnt_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e1_cnt_assumptions['volume_5'] = {'n_periods':5, 'average':'volume'}\n", + "e1_cnt_assumptions['volume_3'] = {'n_periods':3, 'average':'volume'}\n", + "e1_sev_assumptions = {}\n", + "e1_sev_assumptions['simple_5'] = {'n_periods':5, 'average':'simple'}\n", + "e1_sev_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e1_sev_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "\n", + "#developing closed claim counts\n", + "e1_ccc_devs = average_dev(e1_tri['Closed Claim Counts'],e1_cnt_assumptions)\n", + "e1_ccc_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e1_ccc_devs['simple_3'])\n", + "e1_ccc_selected.ldf_ = e1_ccc_selected.ldf_.round(3)\n", + "\n", + "#developing reported claim counts\n", + "e1_rcc_devs = average_dev(e1_tri['Reported Claim Counts'],e1_cnt_assumptions)\n", + "e1_rcc_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e1_rcc_devs['simple_3'])\n", + "e1_rcc_selected.ldf_ = e1_rcc_selected.ldf_.round(3)\n", + "\n", + "#combining closed and reported claim counts\n", + "e1_ccc_cl = cl.Chainladder().fit(e1_ccc_selected)\n", + "e1_rcc_cl = cl.Chainladder().fit(e1_rcc_selected)\n", + "e1_cc_ult = (e1_ccc_cl.ultimate_ + e1_rcc_cl.ultimate_)/2\n", + "e1_cc_ult.iloc[:,:,-1,:] = e1_rcc_cl.ultimate_.iloc[:,:,-1,:]\n", + "\n", + "#calculating and developing reported severity\n", + "e1_rsev = e1_tri['Reported Claims'] / e1_tri['Reported Claim Counts']\n", + "e1_rsev_devs = average_dev(e1_rsev,e1_sev_assumptions)\n", + "e1_rsev_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e1_rsev_devs['medial_5x1'])\n", + "e1_rsev_selected.ldf_ = e1_rsev_selected.ldf_.round(3)\n", + "e1_rsev_cl = cl.Chainladder().fit(e1_rsev_selected)\n", + "\n", + "#combining developed count and severity\n", + "e1_ult = e1_rsev_cl.ultimate_ * e1_cc_ult / 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "65209fce-b487-4443-92bc-17da6ca31835", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 1" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "1762546d-c6e0-4fa7-8f27-a780fad04a77", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e1_tri['Closed Claim Counts'])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e1_tri['Closed Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e1_ccc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e1_ccc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e1_ccc_selected.cdf_.round(3))\n", + "print('Percent Closed')\n", + "nb_display(1/e1_ccc_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d91cc78f-5868-4711-a5a0-d49a9b331ec9", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 2" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "b76a2ed5-adf7-4ca3-900d-757daf1b730c", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e1_tri['Reported Claim Counts'])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e1_tri['Reported Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e1_rcc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e1_rcc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e1_rcc_selected.cdf_.round(3))\n", + "print('Percent Reported')\n", + "nb_display(1/e1_rcc_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "10316a34-7ae5-41f6-b266-70fdda592cd6", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 3" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d5ebe00f-0b16-47dc-94a5-41a188939fb1", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e1_ccc_df = cl.model_diagnostics(e1_ccc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e1_rcc_df = cl.model_diagnostics(e1_rcc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e1_s3 = e1_ccc_df[['development','Latest','CDF','Ultimate']].rename(columns={'Latest':'Closed Claim Counts','CDF':'Closed CDF','Ultimate':'Ult Count Using CCC'})\n", + "e1_s3[['Reported Claim Counts','Reported CDF','Ult Count Using RCC']] = e1_rcc_df[['Latest','CDF','Ultimate']]\n", + "e1_s3[\"Selected Ult CC\"] = e1_cc_ult.latest_diagonal.to_frame()\n", + "e1_s3[['Closed CDF','Reported CDF']] = e1_s3[['Closed CDF','Reported CDF']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e1_s3[['Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']] = (e1_s3[['Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']] + 1e-9).round(0)\n", + "e1_s3[['development','Closed Claim Counts','Reported Claim Counts','Closed CDF','Reported CDF','Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "a8b310a4-5622-4d1a-8217-7fac37ac21c4", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 4" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "114ad9f1-ac4f-49a0-ba34-cd5abbf598b9", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "(e1_tri['Closed Claim Counts']/e1_tri['Reported Claim Counts']).round(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "b876aa8e-280f-4e37-9b2b-0d83ebaf86e1", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 5" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "6f4ad9ef-4ff1-4939-b282-702b7312d298", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "nb_display(e1_tri['Reported Claims']/1000)\n", + "nb_display(e1_rsev)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "090cd8df-b99a-438a-b727-80d208b93a6d", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 6" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "33761774-ce20-472f-9f3f-fe94fa470f0f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e1_rsev)\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e1_rsev.age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factors')\n", + "nb_display(combine_ldf(e1_rsev_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "nb_display(e1_rsev_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e1_rsev_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "16ae37e3-32c6-44c0-9d8f-6a9295b0d113", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 7" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "900d666c-de59-444c-b9d2-47d547895f00", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e1_rsev_ult_df = cl.model_diagnostics(e1_rsev_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e1_s7 = e1_rsev_ult_df[['development','Latest','CDF','Ultimate']].rename(columns={'Latest':'Reported Severity','Ultimate':'Ult Severity'})\n", + "e1_s7['Selected Ult CC'] = e1_s3['Selected Ult CC']\n", + "e1_s7[\"Ult Claims\"] = e1_ult.latest_diagonal.to_frame()\n", + "e1_s7['CDF'] = e1_s7['CDF'].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e1_s7[['Reported Severity','Ult Severity','Ult Claims']] = (e1_s7[['Reported Severity','Ult Severity','Ult Claims']]+1e-9).round(0)\n", + "e1_s7" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "3135d7a1-01f8-46aa-bf62-3cd6e0953696", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit I Sheet 8" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5e3ea0bc-d45c-4d62-9864-0497606a78f0", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "summary_exh(e1_tri['Reported Claims']/1000,e1_tri['Paid Claims']/1000,e1_ult)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": {}, + "inputWidgets": {}, + "nuid": "2caf8e32-c2a4-4552-bd8d-03f2790fcf26", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "At the end of each exhibit, we reconcile to hardcoded figures from Friedland using a series of ``assert`` statemenets. When any of these statements errors out, we know some bug has been introduced into the package. " + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "79910de8-366a-45a5-8706-704fccdf4a6c", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#Exhibit I Sheet 1\n", + "assert np.all(e1_ccc_selected.cdf_.round(3).values == np.array([1.305, 1.010, 1.001, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000]))\n", + "#Exhibit I Sheet 2\n", + "assert np.all(e1_rcc_selected.cdf_.round(3).values == np.array([0.975, 0.997, 0.999, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000]))\n", + "#Exhibit I Sheet 3\n", + "assert np.allclose(\n", + " e1_s3['Selected Ult CC'].values,\n", + " np.array([3292, 3243, 2699, 2757, 2635, 2699, 2665, 2524, 2764, 3061]),\n", + " atol=1\n", + ")\n", + "#Exhibit I Sheet 6\n", + "assert np.all(e1_rsev_selected.cdf_.round(3).values == np.array([1.036, 0.997, 0.998, 0.999, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000]))\n", + "#Exhibit I Sheet 7\n", + "assert np.allclose(\n", + " e1_s7['Ult Severity'].values,\n", + " np.array([4510, 4507, 4632, 4295, 4465, 4356, 4754, 4535, 4613, 4644]),\n", + " atol=1\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "dd3aa676-954a-470b-b812-3f9c1492ed66", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit II Analysis\n", + "\n", + "Exhibit II also follows Approach 1, and is largely similar to Exhibit I. " + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "a36cd4db-3d8d-481b-b702-a58cd3b36f8a", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#loading data and assumptions\n", + "e2_tri = cl.load_sample('friedland_xyz_auto_bi')\n", + "e2_cnt_assumptions = {}\n", + "e2_cnt_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e2_cnt_assumptions['simple_2'] = {'n_periods':2, 'average':'simple'}\n", + "e2_cnt_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e2_cnt_assumptions['volume_3'] = {'n_periods':3, 'average':'volume'}\n", + "e2_cnt_assumptions['volume_2'] = {'n_periods':2, 'average':'volume'}\n", + "e2_sev_assumptions = {}\n", + "e2_sev_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e2_sev_assumptions['simple_2'] = {'n_periods':2, 'average':'simple'}\n", + "e2_sev_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "\n", + "#developing closed claim counts\n", + "e2_ccc_devs = average_dev(e2_tri['Closed Claim Counts'],e2_cnt_assumptions)\n", + "e2_ccc_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e2_ccc_devs['volume_2'])\n", + "e2_ccc_selected.ldf_ = e2_ccc_selected.ldf_.round(3)\n", + "\n", + "#developing reported claim counts\n", + "e2_rcc_devs = average_dev(e2_tri['Reported Claim Counts'],e2_cnt_assumptions)\n", + "e2_rcc_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e2_rcc_devs['volume_2'])\n", + "e2_rcc_selected.ldf_ = e2_rcc_selected.ldf_.round(3)\n", + "\n", + "#combining closed and reported claim counts\n", + "e2_ccc_cl = cl.Chainladder().fit(e2_ccc_selected)\n", + "e2_rcc_cl = cl.Chainladder().fit(e2_rcc_selected)\n", + "e2_cc_ult = (e2_ccc_cl.ultimate_ + e2_rcc_cl.ultimate_)/2\n", + "\n", + "#calculating and developing reported severity\n", + "e2_rsev = e2_tri['Reported Claims'] / e2_tri['Reported Claim Counts'] * 1000\n", + "e2_rsev_devs = average_dev(e2_rsev,e2_sev_assumptions)\n", + "e2_rsev_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e2_rsev_devs['simple_2'])\n", + "e2_rsev_selected.ldf_ = e2_rsev_selected.ldf_.round(3)\n", + "e2_rsev_cl = cl.Chainladder().fit(e2_rsev_selected)\n", + "\n", + "#combining developed count and severity\n", + "e2_ult = e2_rsev_cl.ultimate_ * e2_cc_ult / 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "c2e97f2e-16f7-4b58-ab54-ac46fb34f31c", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 1" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 1" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5f470719-d2a6-4f85-a907-653d6fe0b9f2", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e2_tri['Closed Claim Counts'])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e2_tri['Closed Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e2_ccc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e2_ccc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e2_ccc_selected.cdf_.round(3))\n", + "print('Percent Closed')\n", + "nb_display(1/e2_ccc_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5a9022d4-50c6-4f97-bfa3-1ce4d122a2a1", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 2" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 2" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "8795f064-01d3-440d-846f-7b402e560c40", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e2_tri['Reported Claim Counts'])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e2_tri['Reported Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e2_rcc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e2_rcc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e2_rcc_selected.cdf_.round(3))\n", + "print('Percent Reported')\n", + "nb_display(1/e2_rcc_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "ff41fe54-f723-4bfa-a166-73ff106e63d1", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 3" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 3" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "e44a01bd-add3-43b6-9d16-e2d8c4303e1e", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e2_ccc_df = cl.model_diagnostics(e2_ccc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e2_rcc_df = cl.model_diagnostics(e2_rcc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e2_s3 = e2_ccc_df[['development','Latest','CDF','Ultimate']].rename(columns={'Latest':'Closed Claim Counts','CDF':'Closed CDF','Ultimate':'Ult Count Using CCC'})\n", + "e2_s3[['Reported Claim Counts','Reported CDF','Ult Count Using RCC']] = e2_rcc_df[['Latest','CDF','Ultimate']]\n", + "e2_s3[\"Selected Ult CC\"] = e2_cc_ult.latest_diagonal.to_frame()\n", + "e2_s3[['Closed CDF','Reported CDF']] = e2_s3[['Closed CDF','Reported CDF']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e2_s3[['Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']] = (e2_s3[['Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']] + 1e-9).round(0)\n", + "e2_s3[['development','Closed Claim Counts','Reported Claim Counts','Closed CDF','Reported CDF','Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "0f7e73e8-737b-4909-87a6-c68d0f621dbf", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 4" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 4" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "0e4dd781-cb17-4cb6-b5df-c86854361fd4", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "nb_display(e2_tri['Reported Claims'])\n", + "nb_display(e2_rsev)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "be51ed2d-bf1e-4ca4-8b6a-cb891adda7ff", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 5" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 5" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f2a1fda4-9392-4509-863e-77bc09c6cc46", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e2_rsev)\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e2_rsev.age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factors')\n", + "nb_display(combine_ldf(e2_rsev_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "nb_display(e2_rsev_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e2_rsev_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d1006396-3dfd-46b2-a0a4-96461ba2d5f2", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 6" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 6" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "710aef82-31e7-4990-b66b-6913dd2671a9", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e2_rsev_df = cl.model_diagnostics(e2_rsev_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e2_s6 = e2_rsev_df[['development','Latest','CDF','Ultimate']].rename(columns={'Latest':'Reported Severity','Ultimate':'Ult Severity'})\n", + "e2_s6['Selected Ult CC'] = e2_s3['Selected Ult CC']\n", + "e2_s6[\"Ult Claims\"] = e2_ult.latest_diagonal.to_frame()\n", + "e2_s6['CDF'] = e2_s6['CDF'].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e2_s6[['Reported Severity','Ult Severity','Ult Claims']] = (e2_s6[['Reported Severity','Ult Severity','Ult Claims']]+1e-9).round(0)\n", + "e2_s6" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "fb3533d3-36e4-4971-8f9a-49e76ec75d43", + "showTitle": true, + "tableResultSettingsMap": {}, + "title": "Exhibit II Sheet 7" + } + }, + "source": [ + " \n", + "## Exhibit II Sheet 7" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "0375e545-7922-488a-a798-47d95b6a14d5", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "summary_exh(e2_tri['Reported Claims'],e2_tri['Paid Claims'],e2_ult)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "bb21e80c-521d-4fbd-a68b-ac2b7e7b6035", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#Exhibit II Sheet 1\n", + "assert np.all(e2_ccc_selected.cdf_.round(3).values == np.array([6.085, 2.281, 1.612, 1.318, 1.161, 1.085, 1.035, 1.021, 1.015, 1.003, 1.000]))\n", + "#Exhibit II Sheet 2\n", + "assert np.all(e2_rcc_selected.cdf_.round(3).values == np.array([1.131, 1.035, 1.013, 1.005, 1.002, 1.001, 1.000, 1.000, 1.000, 1.000, 1.000]))\n", + "#Exhibit II Sheet 3\n", + "assert np.allclose(\n", + " e2_s3['Selected Ult CC'].values,\n", + " np.array([637, 1047, 1416, 1466, 1565, 1666, 2309, 2483, 1807, 1556, 1426]),\n", + " atol=1\n", + ")\n", + "#Exhibit II Sheet 5\n", + "assert np.all(e2_rsev_selected.cdf_.round(3).values == np.array([2.310, 1.498, 1.212, 1.100, 1.066, 1.016, 1.003, 0.992, 0.990, 0.999, 1.000]))\n", + "#Exhibit II Sheet 6\n", + "assert np.allclose(\n", + " e2_s6['Ult Severity'].values,\n", + " np.array([24839, 23956, 26189, 26452, 31090, 27675, 33183, 32519, 35697, 37606, 41544]),\n", + " rtol=0.001\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "e9c5436c-4e87-448f-bc10-72e08932caf9", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Analysis\n", + "\n", + "Exhibit III follows Approach 2, which adds explicit selections for the most recent frequency and severity. To calculate various averages for frequency and severity, we use the ``TriangleWeight`` utility class, and supply ``n_periods`` and ``drop_high`` as we would with ``Development``. We also leverage the ``Trend`` adjustment method. " + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "67dad577-b2db-4d73-be35-e13bbb176e56", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#loading data and assumptions\n", + "e3_tri = cl.load_sample('friedland_wc_self_insurer')\n", + "e3_cnt_assumptions = {}\n", + "e3_cnt_assumptions['simple_5'] = {'n_periods':5, 'average':'simple'}\n", + "e3_cnt_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e3_cnt_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e3_cnt_assumptions['volume_5'] = {'n_periods':5, 'average':'volume'}\n", + "e3_cnt_assumptions['volume_3'] = {'n_periods':3, 'average':'volume'}\n", + "e3_sev_assumptions = {}\n", + "e3_sev_assumptions['simple_5'] = {'n_periods':5, 'average':'simple'}\n", + "e3_sev_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e3_sev_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e3_sevavg_assumptions = {}\n", + "e3_sevavg_assumptions['all_years'] = {}\n", + "e3_sevavg_assumptions['all_years_excl_hilo'] = {'drop_high':1, 'drop_low':1}\n", + "e3_sevavg_assumptions['latest_3'] = {'n_periods':3}\n", + "\n", + "#developing closed claim counts\n", + "#There is a typo in the text. We will use a tail of 1.002 to match the 84-ult factor'\n", + "e3_ccc_devs = average_dev(e3_tri['Closed Claim Counts'],e3_cnt_assumptions)\n", + "e3_ccc_selected = cl.TailConstant(tail = 1.002, projection_period = 0).fit_transform(e3_ccc_devs['volume_5'])\n", + "e3_ccc_selected.ldf_ = e3_ccc_selected.ldf_.round(3)\n", + "\n", + "#developing reported claim counts\n", + "e3_rcc_devs = average_dev(e3_tri['Reported Claim Counts'],e3_cnt_assumptions)\n", + "e3_rcc_selected = cl.TailConstant(tail = 1.000, projection_period = 0).fit_transform(e3_rcc_devs['volume_5'])\n", + "e3_rcc_selected.ldf_ = e3_rcc_selected.ldf_.round(3)\n", + "\n", + "#combining closed and reported claim counts\n", + "e3_ccc_cl = cl.Chainladder().fit(e3_ccc_selected)\n", + "e3_rcc_cl = cl.Chainladder().fit(e3_rcc_selected)\n", + "e3_cc_ult = (e3_ccc_cl.ultimate_ + e3_rcc_cl.ultimate_)/2\n", + "\n", + "#calculating trended frequency\n", + "e3_freq_trend = cl.Trend(-.01).fit(e3_tri['Reported Claim Counts']).trend_\n", + "e3_payroll_trend = cl.Trend(.025).fit(e3_tri['Payroll']).trend_\n", + "e3_freq_2008 = .0036\n", + "e3_freq_2007 = e3_freq_2008 / e3_freq_trend.values[0,0,-2,0] * e3_payroll_trend.latest_diagonal.values[0,0,-2,0]\n", + "\n", + "#calculating and developing paid severity\n", + "e3_psev = e3_tri[\"Paid Claims\"] / e3_tri['Closed Claim Counts']\n", + "e3_psev_devs = average_dev(e3_psev,e3_sev_assumptions)\n", + "e3_psev_selected = cl.TailConstant(tail = 1.150, projection_period = 0).fit_transform(e3_psev_devs['medial_5x1'])\n", + "e3_psev_selected.ldf_ = e3_psev_selected.ldf_.round(3)\n", + "\n", + "#calculating and developing reported severity\n", + "e3_rsev = e3_tri[\"Reported Claims\"] / e3_tri['Reported Claim Counts']\n", + "e3_rsev_devs = average_dev(e3_rsev,e3_sev_assumptions)\n", + "e3_rsev_selected = cl.TailConstant(tail = 1.025, projection_period = 0).fit_transform(e3_rsev_devs['medial_5x1'])\n", + "e3_rsev_selected.ldf_ = e3_rsev_selected.ldf_.round(3)\n", + "\n", + "#combining developed count and severity\n", + "e3_psev_cl = cl.Chainladder().fit(e3_psev_selected)\n", + "e3_resv_cl = cl.Chainladder().fit(e3_rsev_selected)\n", + "e3_sev_ult = (e3_psev_cl.ultimate_ + e3_resv_cl.ultimate_)/2\n", + "\n", + "#calculated trended severity\n", + "e3_sev_trend = cl.Trend(.075).fit(e3_tri['Reported Claims']).trend_\n", + "e3_sev_ult_trended = e3_sev_ult * e3_sev_trend.latest_diagonal.values\n", + "#prep ult severity for average calculations\n", + "e3_sev_ult_trended_2006 = e3_sev_ult_trended[e3_sev_ult_trended.origin<='2006']\n", + "e3_sevs = average_sev(e3_sev_ult_trended_2006,e3_sevavg_assumptions)\n", + "#calculate selected severities\n", + "e3_sev_2008 = 7100.\n", + "e3_sev_2007 = e3_sev_2008 / e3_sev_trend.values[0,0,-2,0]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "b8b09c7a-0457-4e83-8be5-30b2082ee425", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 1" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "0e9d7db4-9db5-407e-9a4f-59b3facc0025", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e3_tri[\"Closed Claim Counts\"])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e3_tri['Closed Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e3_ccc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e3_ccc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e3_ccc_selected.cdf_.round(3))\n", + "print('Percent Closed')\n", + "nb_display((1/e3_ccc_selected.cdf_).round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "80da84e0-c7d8-4dd9-930c-6956ac1bcb3b", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 2" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "b915789e-e2ee-4d57-b770-3dff07a10c8c", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e3_tri[\"Reported Claim Counts\"])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e3_tri['Reported Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e3_rcc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "nb_display(e3_rcc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e3_rcc_selected.cdf_.round(3))\n", + "print('Percent Reported')\n", + "nb_display((1/e3_rcc_selected.cdf_).round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "efa10e00-52c8-4fd8-87ac-acd7e3358960", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 3" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "23e54b21-3bea-43fb-a86f-d3f3358a303f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e3_ccc_df = cl.model_diagnostics(e3_ccc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e3_rcc_df = cl.model_diagnostics(e3_rcc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e3_s3 = e3_ccc_df[['development','Latest','CDF','Ultimate']].rename(columns={'Latest':'Closed Claim Counts','CDF':'Closed CDF','Ultimate':'Ult Count Using CCC'})\n", + "e3_s3[['Reported Claim Counts','Reported CDF','Ult Count Using RCC']] = e3_rcc_df[['Latest','CDF','Ultimate']]\n", + "e3_s3[\"Selected Ult CC\"] = e3_cc_ult.latest_diagonal.to_frame()\n", + "e3_s3[['Closed CDF','Reported CDF']] = e3_s3[['Closed CDF','Reported CDF']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e3_s3[['Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']] = (e3_s3[['Ult Count Using CCC','Ult Count Using RCC','Selected Ult CC']] + 1e-9).round(0)\n", + "e3_s3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "7a7c251e-b567-464c-bc82-597c2836ccdb", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 4" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "93b3d0d0-418d-475e-bbc9-89e5965122dc", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e3_s4 = e3_s3[['Selected Ult CC']].copy()\n", + "e3_s4['CC Trend'] = e3_freq_trend.latest_diagonal.to_frame()\n", + "e3_s4['Trended Ult CC'] = e3_s4['Selected Ult CC'] * e3_s4['CC Trend']\n", + "e3_s4['Payroll'] = e3_tri['Payroll'].latest_diagonal.to_frame()\n", + "e3_s4['Payroll Trend'] = e3_payroll_trend.latest_diagonal.to_frame()\n", + "e3_s4['Trended Payroll'] = e3_s4['Payroll'] * e3_s4['Payroll Trend']\n", + "e3_s4['Trended Ultimate Freq'] = e3_s4['Trended Ult CC'] / e3_s4['Trended Payroll']\n", + "e3_s4[['CC Trend','Payroll Trend']] = e3_s4[['CC Trend','Payroll Trend']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e3_s4[['Trended Ult CC','Trended Payroll']] = (e3_s4[['Trended Ult CC','Trended Payroll']] + 1e-9).round(0)\n", + "e3_s4['Trended Ultimate Freq'] = e3_s4[\"Trended Ultimate Freq\"].map(\"{:.2%}\".format)\n", + "nb_display(e3_s4)\n", + "print(f\"Selected Frequency at 2008 level {e3_freq_2008:.2%}\")\n", + "print(f\"Selected Frequency at 2007 level {float(e3_freq_2007):.2%}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f3e4e3fe-5297-4079-bb12-103c43e28820", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 5" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "2cb73994-4108-48d0-8c33-d4d4d6eb3972", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Paid Claims')\n", + "nb_display(e3_tri[\"Paid Claims\"])\n", + "print('Paid Severities')\n", + "nb_display(e3_psev)\n", + "print('Reported Claims')\n", + "nb_display(e3_tri[\"Reported Claims\"])\n", + "print('Reported Severities')\n", + "nb_display(e3_rsev)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d28ce8b5-8add-43d5-9609-6dac464d77ac", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 6" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "6d0d24ec-90ae-4eec-9092-a9ff7542ae12", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e3_psev)\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e3_psev.age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e3_psev_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e3_psev_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e3_psev_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f9f3d551-9208-4773-8059-8ee160821d09", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 7" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "364d734d-6b08-46ae-a5fd-862d8ae25267", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e3_rsev)\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e3_rsev.age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e3_rsev_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e3_rsev_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e3_rsev_selected.cdf_.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "3dda605a-2dd1-472a-bd42-ef193c95c1b1", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 8" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5540a4e8-848b-447e-aa4d-13c7bf2983ca", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e3_psev_df = cl.model_diagnostics(e3_psev_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e3_resv_df = cl.model_diagnostics(e3_resv_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e3_s8 = e3_psev_df[['development','Latest','CDF','Ultimate']].rename(columns={'Latest':'Paid Sev','CDF':'Paid CDF','Ultimate':'Ult Paid Sev'})\n", + "e3_s8[['Reported Sev','Reported CDF','Ult Reported Sev']] = e3_resv_df[['Latest','CDF','Ultimate']]\n", + "e3_s8[\"Selected Ult Sev\"] = e3_sev_ult.latest_diagonal.to_frame()\n", + "e3_s8[['Paid CDF','Reported CDF']] = e3_s8[['Paid CDF','Reported CDF']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e3_s8[['Paid Sev','Reported Sev','Ult Paid Sev','Ult Reported Sev','Selected Ult Sev']] = (e3_s8[['Paid Sev','Reported Sev','Ult Paid Sev','Ult Reported Sev','Selected Ult Sev']] + 1e-9).round(0)\n", + "e3_s8.iloc[:-2,:][['development','Paid Sev','Reported Sev','Paid CDF','Reported CDF','Ult Paid Sev','Ult Reported Sev','Selected Ult Sev']]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "781252e1-a9d8-4a65-b502-ba78541d132e", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 9" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "88faaca5-a479-4753-9020-c4f7c269aa7b", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e3_s9 = e3_s8[['Selected Ult Sev']].copy()\n", + "e3_s9['Sev Trend'] = e3_sev_trend.latest_diagonal.to_frame()\n", + "e3_s9['Trended Ult Sev'] = e3_sev_ult_trended.latest_diagonal.to_frame()\n", + "e3_s9[['Sev Trend']] = e3_s9[['Sev Trend']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e3_s9[['Trended Ult Sev']] = (e3_s9[['Trended Ult Sev']] + 1e-9).round(0)\n", + "nb_display(e3_s9.iloc[:-2,:])\n", + "print('Average Trended Severity at 2008 Cost Level')\n", + "for k,v in e3_sevs.items():\n", + " print(f\"\\t{k:<20} \\t{v.round(0)}\")\n", + "print(f\"Selected 2008 Severity \\t\\t{e3_sev_2008:.0f}\")\n", + "print(f\"Estimated 2007 Severity \\t{e3_sev_2007:.0f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "0d86dcac-eb94-4810-910d-8207388ffff6", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit III Sheet 10" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "e4d1cc6d-027b-4ad3-8f66-8f519f0f8f01", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e3_s10 = e3_s4[['Payroll']].copy()[-2:]\n", + "e3_s10['Selected Frequency'] = [e3_freq_2007,e3_freq_2008]\n", + "e3_s10['Ult CC'] = e3_s10['Payroll'] * e3_s10['Selected Frequency']\n", + "e3_s10['Selected Severity'] = [e3_sev_2007,e3_sev_2008]\n", + "e3_s10['Ult Claims'] = e3_s10['Ult CC'] * e3_s10['Selected Severity']\n", + "e3_s10['Reported Claims'] = e3_tri['Reported Claims'].latest_diagonal.to_frame()\n", + "e3_s10['Paid Claims'] = e3_tri['Paid Claims'].latest_diagonal.to_frame()\n", + "e3_s10['Case Outstanding'] = e3_s10['Reported Claims'] - e3_s10['Paid Claims']\n", + "e3_s10['IBNR'] = e3_s10['Ult Claims'] - e3_s10['Reported Claims']\n", + "e3_s10['Unpaid'] = e3_s10['IBNR'] + e3_s10['Case Outstanding']\n", + "e3_s10.T" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "20f78f9f-0bc0-4d12-9c6b-659fcccb0c37", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#Exhibit III Sheet 1\n", + "assert np.all(e3_ccc_selected.cdf_.round(3).values[...,:7] == np.array([1.698, 1.133, 1.071, 1.034, 1.018, 1.014, 1.010]))\n", + "#Exhibit III Sheet 2\n", + "assert np.all(e3_rcc_selected.cdf_.round(3).values == np.array([1.094, 1.022, 1.007, 1.002, 1.000, 1.000, 1.000, 1.000]))\n", + "#Exhibit III Sheet 3\n", + "assert np.allclose(\n", + " e3_s3['Selected Ult CC'].values[...,1:],\n", + " np.array([1700, 1774, 1749, 1651, 2982, 2909, 2658]),\n", + " atol=1\n", + ")\n", + "#Exhibit III Sheet 4\n", + "assert np.all(e3_s4['Trended Ultimate Freq'].values[...,1:] == np.array(['0.53%', '0.53%', '0.54%', '0.43%', '0.35%', '0.36%', '0.36%']))\n", + "#Exhibit III Sheet 6\n", + "assert np.allclose(\n", + " e3_psev_selected.ldf_.round(3).values,\n", + " np.array([1.447, 1.249, 1.108, 1.066, 1.038, 1.037, 1.021, 1.150]),\n", + " atol=.001\n", + ")\n", + "#Exhibit III Sheet 7\n", + "assert np.all(e3_rsev_selected.cdf_.round(3).values == np.array([1.679, 1.314, 1.189, 1.130, 1.092, 1.065, 1.043, 1.025]))\n", + "#Exhibit III Sheet 8\n", + "assert np.allclose(\n", + " e3_s8['Selected Ult Sev'].values[:-2],\n", + " np.array([4371, 4587, 4963, 5242, 5635, 6169]),\n", + " atol=1\n", + ")\n", + "#Exhibit III Sheet 9\n", + "assert np.allclose(\n", + " e3_s9['Trended Ult Sev'].values[:-2],\n", + " np.array([7251, 7079, 7125, 7000, 7001, 7129]),\n", + " rtol=0.001\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "fb822f26-db0f-4035-aa8c-4511509cb6af", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit IV Analysis\n", + "\n", + "Exhibit IV continues to follow Approach 2. We demonstrate two separate ways in the package to achievement the on-leveling and law-change adjustments. Also, there are no full-size triangles in this exhibit. This gives us an opportunity to demontrate utilizing `columns` in `Triangle`, as if we were in Pandas." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "85c7cc4a-a1ae-48d4-a707-f613ab3087b0", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#loading data and assumptions\n", + "xyz_tort_data = pd.DataFrame({\n", + " \"EffDate\": [\"2006-01-01\", \"2007-01-01\"],\n", + " \"RateChange\": [(0.67/0.75) - 1, 0.75-1]\n", + "})\n", + "xyz_tort_adjustment = cl.ParallelogramOLF(\n", + " rate_history=xyz_tort_data,\n", + " change_col=\"RateChange\",\n", + " date_col=\"EffDate\",\n", + " vertical_line=True\n", + ")\n", + "#Both Chapter 6 and Chapter 8 contain the code to derive these on-level factors from underlying rate changes. We will simply use the factors as given\n", + "olf = cl.Triangle(\n", + " data = {\n", + " 'origin':[1998,2002,2003,2004,2005,2006,2007,2008],\n", + " 'valuation':[2008,2008,2008,2008,2008,2008,2008,2008],\n", + " 'On-Level Adjustment':[0,.914,.87,.81,.704,.64,.8,1],\n", + " },\n", + " origin='origin',\n", + " development='valuation',\n", + " columns='On-Level Adjustment'\n", + ")\n", + "e4_freq_assumptions = {}\n", + "e4_freq_assumptions['all_years'] = {}\n", + "e4_freq_assumptions['all_years_excl_hilo'] = {'drop_high':1, 'drop_low':1}\n", + "e4_freq_assumptions['latest_2'] = {'n_periods':2}\n", + "e4_sev_assumptions = {}\n", + "e4_sev_assumptions['latest_5_years'] = {'n_periods':5}\n", + "e4_sev_assumptions['latest_5_years_excl_hilo'] = {'n_periods':5,'drop_high':1, 'drop_low':1}\n", + "e4_sev_assumptions['latest_3'] = {'n_periods':3}\n", + "\n", + "# In Exhibit II, the selected ultimate was actually the average of reported and closed ultimates.\n", + "e4_s1_tri = e2_rcc_cl.ultimate_.copy()\n", + "e4_s1_tri = e4_s1_tri.rename(axis='columns',value='Ult CC')\n", + "e4_s1_tri['CC Trend'] = cl.Trend(-.015,dates=('2008-12-31','2002-01-01')).fit(e4_s1_tri).trend_\n", + "e4_s1_tri['Trended Ult CC'] = e4_s1_tri['CC Trend'] * e4_s1_tri['Ult CC']\n", + "e4_s1_tri['Earned Premium'] = e2_tri['Earned Premium'].latest_diagonal\n", + "e4_s1_tri['On-Level Adjustment'] = olf['On-Level Adjustment']\n", + "e4_s1_tri['On-Level Premium'] = e4_s1_tri['On-Level Adjustment'] * e4_s1_tri['Earned Premium']\n", + "e4_s1_tri['Trended Ult Freq'] = e4_s1_tri['Trended Ult CC'] / e4_s1_tri['On-Level Premium']\n", + "e4_s1_tri_2006 = e4_s1_tri.iloc[:,:,4:9,:]\n", + "#calculate average frequencies\n", + "e4_freq = average_sev(e4_s1_tri_2006['Trended Ult Freq'],e4_freq_assumptions)\n", + "#calculate selected frequencies\n", + "e4_freq_2008 = e4_freq['latest_2'].round(4)\n", + "e4_freq_2007 = e4_freq_2008 / e4_s1_tri['CC Trend'].values[0,0,-2,0] * e4_s1_tri['On-Level Adjustment'].values[0,0,-2,0]\n", + "e4_freq_2007 = e4_freq_2007.round(4)\n", + "\n", + "e4_s2_tri = e2_rsev_cl.ultimate_.copy()\n", + "e4_s2_tri = e4_s2_tri.rename(axis='columns',value='Ult Sev')\n", + "e4_s2_tri['Sev Trend'] = cl.Trend(.05,dates=('2008-12-31','1998-01-01')).fit(e4_s2_tri).trend_.round(3)\n", + "#from Chapter 8 Exhibit III sheet 1\n", + "e4_s2_tri['Tort Reform Factors'] = xyz_tort_adjustment.fit(e4_s2_tri['Ult Sev']).olf_\n", + "e4_s2_tri['Trended Ult Sev'] = e4_s2_tri['Ult Sev'] * e4_s2_tri['Sev Trend'] * e4_s2_tri['Tort Reform Factors']\n", + "e4_s2_tri_2006 = e4_s2_tri[e4_s2_tri.origin <= '2006']\n", + "#calculate average severities\n", + "e4_sev = average_sev(e4_s2_tri_2006['Trended Ult Sev'],e4_sev_assumptions)\n", + "#calculate selected severities\n", + "e4_sev_2008 = e4_sev['latest_5_years_excl_hilo'].round(0)\n", + "e4_sev_2007 = e4_sev_2008 / e4_s2_tri['Sev Trend'].values[0,0,-2,0] / e4_s2_tri['Tort Reform Factors'].values[0,0,-2,0]\n", + "e4_sev_2007 = e4_sev_2007.round(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "cca2c635-f303-4d44-9dd3-de27a63faa4b", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit IV Sheet 1" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d2bf3b32-f70b-489c-a4ea-130eca08c6ec", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e4_s1 = e4_s1_tri.to_frame().T\n", + "e4_s1[['CC Trend','On-Level Adjustment']] = e4_s1[['CC Trend','On-Level Adjustment']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e4_s1[['Trended Ult CC','On-Level Premium']] = (e4_s1[['Trended Ult CC','On-Level Premium']] + 1e-9).round(0)\n", + "e4_s1['Trended Ult Freq'] = e4_s1[\"Trended Ult Freq\"].map(\"{:.2%}\".format)\n", + "nb_display(e4_s1.iloc[4:9])\n", + "print('Average Trended Frequency at 2008 Cost Level')\n", + "for k,v in e4_freq.items():\n", + " print(f\"\\t{k:<20} \\t{v:.2%}\")\n", + "print(f\"Selected 2008 Frequency \\t{e4_freq_2008:.2%}\")\n", + "print(f\"Estimated 2007 Frequency \\t{e4_freq_2007:.2%}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "6111c76b-a5be-4a64-ab78-a6bea6a931a9", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit IV Sheet 2" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "2cdf6c3d-7ad5-4d64-ad79-169375ec9daa", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e4_s2 = e4_s2_tri.to_frame().T\n", + "e4_s2[['Sev Trend','Tort Reform Factors']] = e4_s2[['Sev Trend','Tort Reform Factors']].round(3)\n", + "#using floating point offset to achieve standard rounding\n", + "e4_s2[['Trended Ult Sev','Ult Sev']] = (e4_s2[['Trended Ult Sev','Ult Sev']] + 1e-9).round(0)\n", + "nb_display(e4_s2.iloc[:9])\n", + "print('Average Trended Severity at 2008 Cost Level')\n", + "for k,v in e4_sev.items():\n", + " print(f\"\\t{k:<25} \\t{v.round(0)}\")\n", + "print(f\"Selected 2008 Severity \\t\\t\\t{e4_sev_2008}\")\n", + "print(f\"Estimated 2007 Severity \\t\\t{e4_sev_2007}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f01f14d6-2449-46e0-87e3-2215d2fcf7e7", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit IV Sheet 3" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "9101f7e8-27d6-4575-9da8-ceef012553cc", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e4_s3 = e4_s1_tri['Earned Premium'].to_frame(keepdims=True).set_index('origin').iloc[-2:][['Earned Premium']]\n", + "e4_s3['Selected Frequency'] = [e4_freq_2007,e4_freq_2008]\n", + "e4_s3['Ult CC'] = e4_s3['Earned Premium'] * e4_s3['Selected Frequency']\n", + "e4_s3['Selected Severity'] = [e4_sev_2007,e4_sev_2008]\n", + "e4_s3['Ult Claims'] = e4_s3['Ult CC'] * e4_s3['Selected Severity']\n", + "e4_s3['Reported Claims'] = (e2_tri['Reported Claims']*1000).latest_diagonal.to_frame()\n", + "e4_s3['Paid Claims'] = (e2_tri['Paid Claims']*1000).latest_diagonal.to_frame()\n", + "e4_s3['Case Outstanding'] = e4_s3['Reported Claims'] - e4_s3['Paid Claims']\n", + "e4_s3['IBNR'] = e4_s3['Ult Claims'] - e4_s3['Reported Claims']\n", + "e4_s3['Unpaid'] = e4_s3['IBNR'] + e4_s3['Case Outstanding']\n", + "e4_s3.T" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "2ab9589d-8c3a-4023-977a-2fd18373b46a", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#Exhibit IV Sheet 1\n", + "assert np.all(e4_s1.iloc[4:9]['Trended Ult Freq'].values == np.array(['2.54%', '2.51%', '2.65%', '2.36%', '2.37%']))\n", + "#Exhibit IV Sheet 2\n", + "assert np.allclose(\n", + " list(e4_sev.values()),\n", + " np.array([26669., 26720., 27254.]),\n", + " rtol=0.001\n", + ")\n", + "#Exhibit IV Sheet 3\n", + "assert np.allclose(\n", + " e4_s3.iloc[:,4].values,\n", + " np.array([30512152., 30140260.]),\n", + " rtol=0.001\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5b49ffa0-f939-4d71-917d-1ab1ee88c000", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Analysis\n", + "\n", + "Exhibit V follows Approach 3, which uses full incremental closed count and paid triangles to estimate the ultimate. Full incremental closed count triangle is estimated after first estimating ultimate count using reported count. We use the ``DisposalRate`` adjustment method to perform this calculation. Full incremental paid severity triangle is estimated through trending. " + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "c5398a7e-ddf9-4f84-be70-b57d1e6cde23", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#loading data and assumptions\n", + "e5_tri = cl.load_sample('friedland_gl_insurer')\n", + "e5_cnt_assumptions = {}\n", + "e5_cnt_assumptions['simple_5'] = {'n_periods':5, 'average':'simple'}\n", + "e5_cnt_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e5_cnt_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e5_cnt_assumptions['volume_5'] = {'n_periods':5, 'average':'volume'}\n", + "e5_cnt_assumptions['volume_3'] = {'n_periods':3, 'average':'volume'}\n", + "e5_disp_assumptions = {}\n", + "e5_disp_assumptions['simple_5'] = {'n_periods':5, 'average':'simple'}\n", + "e5_disp_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e5_disp_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e5_trend_assumptions = {}\n", + "e5_trend_assumptions['all_years'] = {}\n", + "e5_trend_assumptions['latest_6'] = {'n_periods':6}\n", + "e5_trend_assumptions['latest_4'] = {'n_periods':4}\n", + "e5_sev_assumptions = {}\n", + "e5_sev_assumptions['simple_5'] = {'n_periods':5}\n", + "e5_sev_assumptions['simple_3'] = {'n_periods':3}\n", + "e5_sev_assumptions['medial_5x1'] = {'n_periods':5,'drop_high':1, 'drop_low':1}\n", + "\n", + "#developing closed claim counts\n", + "e5_ccc_devs = average_dev(e5_tri['Closed Claim Counts'],e5_cnt_assumptions)\n", + "e5_ccc_selected = cl.TailConstant(tail = 1.100, projection_period = 0).fit_transform(e5_ccc_devs['volume_3'])\n", + "e5_ccc_selected.ldf_ = e5_ccc_selected.ldf_.round(3)\n", + "\n", + "#developing reported claim counts\n", + "e5_rcc_devs = average_dev(e5_tri['Reported Claim Counts'],e5_cnt_assumptions)\n", + "e5_rcc_selected = cl.TailConstant(tail = 1.0, projection_period = 0).fit_transform(e5_rcc_devs['volume_3'])\n", + "e5_rcc_selected.ldf_ = e5_rcc_selected.ldf_.round(3)\n", + "\n", + "#combining closed and reported claim counts\n", + "e5_ccc_cl = cl.Chainladder().fit(e5_ccc_selected)\n", + "e5_rcc_cl = cl.Chainladder().fit(e5_rcc_selected)\n", + "e5_cc_ult = ((e5_ccc_cl.ultimate_ + e5_rcc_cl.ultimate_)/2)\n", + "\n", + "#calculating disposal rate and complete the closed count triangle\n", + "e5_drs = average_dr(e5_tri['Closed Claim Counts'],e5_cc_ult,e5_disp_assumptions)\n", + "e5_dr_selected = e5_drs['medial_5x1']\n", + "e5_dr_selected.disposal_rate_ = e5_dr_selected.disposal_rate_.round(3)\n", + "e5_dr_tri = e5_dr_selected.transform(e5_tri['Closed Claim Counts'],sample_weight = e5_cc_ult)\n", + "\n", + "#calculate and select incremental paid severity\n", + "e5_ipsev = e5_tri[\"Paid Claims\"].cum_to_incr() / e5_tri[\"Closed Claim Counts\"].cum_to_incr()\n", + "e5_regs = regs(e5_ipsev,e5_trend_assumptions)\n", + "e5_trend,e5_rsq = reg_outputs(e5_regs,e5_ipsev.development)\n", + "e5_regs_ex2001 = regs(e5_ipsev[e5_ipsev.origin>'2001'],{'all_years_ex_2001':{}})\n", + "e5_trend_ex2001,e5_rsq_ex2001 = reg_outputs(e5_regs_ex2001,e5_ipsev.development)\n", + "e5_sevs = average_sev(e5_ipsev.trend(0.05),e5_sev_assumptions)\n", + "e5_sevs_sel = e5_sevs['simple_3'].copy()\n", + "e5_sevs_sel.origin = ['2008']\n", + "\n", + "#calculate and select tail paid severity\n", + "e5_incr_ccc = e5_tri[\"Closed Claim Counts\"].cum_to_incr()\n", + "e5_incr_paid = e5_tri[\"Paid Claims\"].cum_to_incr()\n", + "e5_incr_paid_trended = e5_incr_paid.trend(0.05)\n", + "\n", + "#complete the incremental paid severity triangle\n", + "e5_ipsev_full = e5_ipsev.copy()\n", + "#extending the severity triangle to 108 months\n", + "e5_ipsev_full = cl.concat((e5_ipsev_full,e5_ipsev_full.latest_diagonal.rename(\"development\",[9999])),axis=3)\n", + "#setting the before 60 months to selected incremental\n", + "e5_ipsev_full.iloc[:,:,:,:5] = e5_sevs_sel.iloc[:,:,:,:5]\n", + "#setting the after 72 months to selected tail\n", + "e5_ipsev_full.iloc[:,:,:,5:] = (\n", + " e5_incr_paid_trended[e5_incr_paid_trended.development >= 72].sum().sum()\n", + " /\n", + " e5_incr_ccc[e5_incr_ccc.development >= 72].sum().sum() \n", + ")\n", + "#setting the valuation_date to the future\n", + "e5_ipsev_full.valuation_date = pd.to_datetime(cl.options.ULT_VAL)\n", + "#trending back from latest accident year\n", + "e5_ipsev_full_detrended = e5_ipsev_full.trend(1/1.05-1,start='2008-12-31',end='2001-01-01')\n", + "#compositing the actual incremental severities with dtrended selected to complete the incremental paid severity triangle\n", + "e5_ipsev_full_complete = e5_ipsev[e5_ipsev.valuation <= e5_ipsev.valuation_date] + e5_ipsev_full_detrended[e5_ipsev_full_detrended.valuation > e5_ipsev.valuation_date]\n", + "\n", + "#complete the incremental paid triangle\n", + "e5_s11_ccc = e5_dr_tri.full_triangle_.cum_to_incr()\n", + "e5_s11_ip = e5_s11_ccc * e5_ipsev_full_complete\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "905e7cd2-2188-4bb0-a656-d0cec6558dd8", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 1" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "8a85abd3-ff5f-4ac7-bc5e-82bf9214ecce", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e5_tri['Closed Claim Counts'])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e5_tri['Closed Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e5_ccc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "print('Selected')\n", + "nb_display(e5_ccc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e5_ccc_selected.cdf_.round(3))\n", + "print('Percent Closed')\n", + "nb_display((1/e5_ccc_selected.cdf_).round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f105d40b-944b-4c23-b2aa-b335748d5855", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 2" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "04a8e098-1264-40c4-bb0a-47a928a3a396", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('PART 1 - Data Triangle')\n", + "nb_display(e5_tri['Reported Claim Counts'])\n", + "print('PART 2 - Age-to-Age Factors')\n", + "nb_display(e5_tri['Reported Claim Counts'].age_to_age.round(3))\n", + "print('PART 3 - Average Age-to-Age Factor')\n", + "nb_display(combine_ldf(e5_rcc_devs).round(3).to_frame())\n", + "print('PART 4 - Selected Age-to-Age Factors')\n", + "nb_display(e5_rcc_selected.ldf_)\n", + "print('CDF to Ultimate')\n", + "nb_display(e5_rcc_selected.cdf_.round(3))\n", + "print('Percent Reported')\n", + "nb_display((1/e5_rcc_selected.cdf_).round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "6a8888f3-14e0-4fcf-ad12-2531b7e9e244", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 3" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f83ec473-543a-45c5-8b53-22ac543d4877", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e5_ccc_df = cl.model_diagnostics(e5_ccc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e5_rcc_df = cl.model_diagnostics(e5_rcc_cl).to_frame(keepdims=True,implicit_axis=True).set_index('origin')\n", + "e5_s3 = e5_ccc_df[['development','Latest','Ultimate']].rename(columns={'Latest':'Closed Claim Counts','Ultimate':'Ult Count Using CCC'})\n", + "e5_s3[['Reported Claim Counts','Ult Count Using RCC']] = e5_rcc_df[['Latest','Ultimate']]\n", + "e5_s3[\"Selected Ult CC\"] = e5_cc_ult.round(0).latest_diagonal.to_frame()\n", + "e5_s3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "7f896e42-0389-4483-878e-2b6e4ede5d4f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 4" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "39ffb70b-472b-4bff-b428-0d3a2238908b", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Part 1 - Disposal Rate Triangle')\n", + "nb_display(cl.DisposalRate().fit_transform(e5_tri['Closed Claim Counts'],sample_weight = e5_cc_ult).disposal_rate_tri.round(3))\n", + "print('PART 2 - Average Disposal Rate Factors')\n", + "nb_display(combine_disposal(e5_drs).round(3).to_frame())\n", + "print('PART 3 - Selected Disposal Rate Factors')\n", + "nb_display(e5_dr_selected.disposal_rate_)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "c8d9acc3-9ee7-4390-b017-5e54a8a2d15f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 5" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "bd6b314e-832d-4b19-aa73-003c91bd567f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Closed Claim Counts')\n", + "nb_display(e5_tri['Closed Claim Counts'])\n", + "print('Projected Incremental Closed Claim Counts')\n", + "nb_display(e5_dr_tri.full_triangle_.cum_to_incr().round(0))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5431abfc-5da3-4fe1-9d75-1d33c25e237b", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 6" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "babf6982-d9e2-4840-9888-d43181813d79", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Paid Claims')\n", + "nb_display(e5_tri[\"Paid Claims\"])\n", + "print('Incremental Paid CLaims')\n", + "nb_display(e5_tri[\"Paid Claims\"].cum_to_incr())\n", + "print('Incremental Closed Claim Counts')\n", + "nb_display(e5_tri[\"Closed Claim Counts\"].cum_to_incr())\n", + "print('Incremental Paid Severities')\n", + "nb_display(e5_ipsev)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "c783393d-2550-4d5b-8163-0d84f31204cf", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 7" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "c1f6f621-0582-48ee-807b-8eceb4e6309a", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Incremental Paid Severities')\n", + "nb_display(e5_ipsev)\n", + "print('Annual Change based on Exponential Regression')\n", + "nb_display(pd.concat([e5_trend.round(3),e5_trend_ex2001.round(3)]))\n", + "print('Goodness of Fit Test of Exponential Regression (R-Squared)')\n", + "nb_display(pd.concat([e5_rsq.round(3),e5_rsq_ex2001.round(3)]))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "1aa1d6f7-c11f-4cc5-aa18-6787929851f2", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 8" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "8a8b31e9-22af-4bb8-9f95-17e15c836ff6", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Incremental Paid Severities')\n", + "nb_display(e5_ipsev)\n", + "print('Trended Incremental Paid Severities Assuming 5% Annual Trend')\n", + "nb_display(e5_ipsev.trend(0.05))\n", + "print('Average Trended Incremental Paid Severities')\n", + "nb_display(combine_tri(e5_sevs).round(0).to_frame())\n", + "print('Selected Incremental Paid Severities')\n", + "nb_display(e5_sevs_sel[e5_sevs_sel.development<=60])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d1042988-724d-44ea-8d13-9df69dd70f04", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 9" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "cd014e1e-b5f1-41c8-96be-52fabeb53f5d", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e5_s9 = pd.DataFrame(\n", + " data = [[\n", + " e5_incr_ccc[e5_incr_ccc.development >= 60].sum().sum(), \n", + " e5_incr_ccc[e5_incr_ccc.development >= 72].sum().sum()\n", + " ]],\n", + " index = ['Total Closed Claim Counts'],\n", + " columns = ['Age 60 & Older','Age 72 & Older']\n", + ")\n", + "e5_s9.loc['Total Trended Paid Claims'] = [\n", + " e5_incr_paid_trended[e5_incr_paid_trended.development >= 60].sum().sum(), \n", + " e5_incr_paid_trended[e5_incr_paid_trended.development >= 72].sum().sum()\n", + " ]\n", + "e5_s9.loc['Estimated Trended Tail Severity'] = e5_s9.iloc[1] / e5_s9.iloc[0]\n", + "e5_s9.loc['Estimated Incremental Trended Tail Severity'] = e5_sevs_sel.iloc[:,:,:,4:6].values.flatten()\n", + "e5_s9.loc['Selected Trended Paid Severity'] = e5_ipsev_full.values[0,0,-1,4:6]\n", + "print('Incremental Closed Claim Counts')\n", + "nb_display(e5_incr_ccc[e5_incr_ccc.development >= 60][e5_incr_ccc.origin <= '2004'])\n", + "print('Incremental Paid CLaims')\n", + "nb_display(e5_incr_paid[e5_incr_paid.development >= 60][e5_incr_paid.origin <= '2004'])\n", + "print('Trended Incremental Paid Severities')\n", + "nb_display(e5_incr_paid_trended[e5_incr_paid_trended.development >= 60][e5_incr_paid_trended.origin <= '2004'])\n", + "nb_display(e5_s9)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "7473207a-ed4d-441d-869d-9043a338bae2", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 10" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "5724e17c-ed8e-40b8-8b78-d47af30118e0", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Incremental Paid Severities')\n", + "nb_display(e5_ipsev)\n", + "print('Selected Incremental Paid Severities')\n", + "nb_display(e5_ipsev_full[e5_ipsev_full.origin == '2008'])\n", + "print('Incremental Paid Severities Adjusted to Cost Level of Accident Year Assuming 5% Annual Trend Rate')\n", + "nb_display(e5_ipsev_full_complete)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "0b84f3d7-71f8-4a5f-8113-186020db4f0f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 11" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "e5789b39-1bb9-4dac-b5bf-5f646cf49352", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Projected Incremental Closed Claim Counts')\n", + "nb_display(e5_s11_ccc.round(0))\n", + "print('Incremental Paid Severities Adjusted to Cost Level of Accident Year Assuming 5% Annual Trend Rate')\n", + "nb_display(e5_ipsev_full_complete)\n", + "print('Projected Incremental Paid Claims')\n", + "nb_display(e5_s11_ip)\n", + "print('Projected Cumulative Paid Claims')\n", + "nb_display(e5_s11_ip.incr_to_cum())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "9fb3d9d7-1038-4615-a512-c088f2ac3f34", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit V Sheet 12" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f1d08176-4f1b-46f7-bdff-1b565b5cdee6", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "summary_exh(\n", + " e5_tri['Reported Claims']/1000,\n", + " e5_tri['Paid Claims']/1000,\n", + " e5_s11_ip.incr_to_cum()/1000\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "9742a88e-12f9-423f-96d8-4a24264bc5b0", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "e5_dr_selected.disposal_rate_" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "2a46eef8-f279-4172-b5e1-a23f079ad80e", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#Exhibit V Sheet 1\n", + "assert np.all(e5_ccc_selected.cdf_.round(3).values == np.array([4.769, 2.199, 1.682, 1.390, 1.256, 1.174, 1.123, 1.100]))\n", + "#Exhibit V Sheet 2\n", + "assert np.all(e5_rcc_selected.cdf_.round(3).values == np.array([0.753, 0.746, 0.818, 0.897, 0.932, 0.968, 1.007, 1.000]))\n", + "#Exhibit V Sheet 3\n", + "assert np.all(e5_s3['Selected Ult CC'].values==np.array([873., 720., 626., 629., 588., 553, 438., 609.]))\n", + "#Exhibit V Sheet 4\n", + "assert np.all(e5_dr_selected.disposal_rate_.values == np.array([0.200, 0.433, 0.585, 0.710, 0.791, 0.862, 0.882, 0.912, 1.000]))\n", + "#Exhibit V Sheet 5\n", + "lhs = (e5_dr_tri.full_triangle_.cum_to_incr()-e5_tri['Closed Claim Counts'].cum_to_incr()).values.flatten()\n", + "rhs = np.array([\n", + " 77., \n", + " 24., 70., \n", + " 12., 18., 54., \n", + " 46., 13., 19., 57., \n", + " 52., 45., 13., 19., 56., \n", + " 76., 49., 43., 12., 18., 54., \n", + " 67., 55., 36., 31., 9., 13., 39., \n", + "140., 91., 75., 49., 43., 12., 18., 53.\n", + "])\n", + "assert np.all(abs(lhs[~np.isnan(lhs)] - rhs) < 1)\n", + "#Exhibit V Sheet 7\n", + "assert np.all(e5_trend.loc['latest_4'].values[:7].round(3) == np.array([0.018, 0.016, 0.095, 0.050, 0.122, -0.294, -0.331]))\n", + "assert np.all(e5_rsq.loc['latest_6'].values[:7].round(3) == np.array([0.704, 0.000, 0.644, 0.722, 0.084, 0.190, 1.000]))\n", + "#Exhibit V Sheet 8\n", + "assert np.all(e5_sevs_sel.values[...,:5].round(0) == np.array([11259., 32980., 65523., 80544., 140802.]))\n", + "#Exhibit V Sheet 9\n", + "assert np.all(e5_s9.iloc[2].values.round(0) == np.array([144160., 175816.]))\n", + "#Exhibit V Sheet 10\n", + "lhs = e5_ipsev_full_detrended[e5_ipsev_full_detrended.valuation > e5_ipsev.valuation_date].round(0).values.flatten()\n", + "rhs = np.array([\n", + " 124949.,\n", + " 131196.,131196.,\n", + " 137756.,137756.,137756.,\n", + " 144644.,144644.,144644.,144644.,\n", + " 121630.,151876.,151876.,151876.,151876.,\n", + " 73056.,\t127711.,159470.,159470.,159470.,159470.,\n", + " 62403.,\t76709.,\t134097.,167443.,167443.,167443.,167443.,\n", + "32980., 65523.,\t80544.,\t140802.,175816.,175816.,175816.,175816.,\n", + "])\n", + "assert np.all(lhs[~np.isnan(lhs)] == rhs)\n", + "#Exhibit V Sheet 11\n", + "assert np.allclose(\n", + " e5_s11_ip.incr_to_cum().iloc[:,:,:,-1].values.round(0).flatten(),\n", + " np.array([39497433., 44743308., 35510981., 37766027., 42007442., 41113459., 32859080., 47109641.]),\n", + " rtol = .001\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "9c887dd3-d12f-4f0d-b9a1-75dbe3f4b79f", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "205c41a2-9f0f-4de1-b184-17a50daa2b30", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#loading data and assumptions\n", + "e6_tri = e2_tri[e2_tri.origin >= '2001'][e2_tri.development <= 96]\n", + "e6_disp_assumptions = {}\n", + "e6_disp_assumptions['simple_3'] = {'n_periods':3, 'average':'simple'}\n", + "e6_disp_assumptions['simple_2'] = {'n_periods':2, 'average':'simple'}\n", + "e6_disp_assumptions['medial_5x1'] = {'n_periods':5, 'average':'simple','drop_high':1, 'drop_low':1}\n", + "e6_sev_assumptions = {}\n", + "e6_sev_assumptions['simple_3'] = {'n_periods':3}\n", + "e6_sev_assumptions['simple_2'] = {'n_periods':2}\n", + "e6_sev_assumptions['medial_5x1'] = {'n_periods':5,'drop_high':1, 'drop_low':1}\n", + "\n", + "#calculating disposal rate and complete the closed count triangle\n", + "e6_rcc_ult = e2_rcc_cl.ultimate_[e2_rcc_cl.ultimate_.origin >= '2001']\n", + "e6_drs = average_dr(e6_tri['Closed Claim Counts'],e6_rcc_ult,e6_disp_assumptions)\n", + "e6_dr_selected = e6_drs['simple_2']\n", + "e6_dr_selected.disposal_rate_ = e6_dr_selected.disposal_rate_.round(3)\n", + "e6_dr_tri = e6_dr_selected.transform(e6_tri['Closed Claim Counts'],sample_weight = e6_rcc_ult)\n", + "\n", + "#calculate and select incremental paid severity\n", + "e6_ipsev = e6_tri[\"Paid Claims\"].cum_to_incr() / e6_tri[\"Closed Claim Counts\"].cum_to_incr() * 1000\n", + "e6_ipsev_adj = e6_ipsev.trend(0.05) * xyz_tort_adjustment.fit(e6_ipsev).olf_.values\n", + "e6_sevs = average_sev(e6_ipsev_adj,e6_sev_assumptions)\n", + "e6_sevs_sel = e6_sevs['simple_2'].copy()\n", + "e6_sevs_sel.origin = ['2008']\n", + "\n", + "#calculate and select tail paid severity\n", + "e6_incr_ccc = e6_tri[\"Closed Claim Counts\"].cum_to_incr()\n", + "e6_incr_paid = e6_tri[\"Paid Claims\"].cum_to_incr() * 1000\n", + "e6_incr_paid_trended = e6_ipsev_adj * e6_incr_ccc\n", + "\n", + "e6_ipsev_full = e6_ipsev_adj.copy()\n", + "#extending the severity triangle to 108 months\n", + "e6_ipsev_full = cl.concat((e6_ipsev_full,e6_ipsev_full.latest_diagonal.rename(\"development\",[9999])),axis=3)\n", + "#setting the before 72 months to selected incremental\n", + "e6_ipsev_full.iloc[:,:,:,:6] = e6_sevs_sel.iloc[:,:,:,:6]\n", + "#setting the after 86 months to selected tail\n", + "e6_ipsev_full.iloc[:,:,:,6:] = (\n", + " e6_incr_paid_trended[e6_incr_paid_trended.development >= 84].sum().sum()\n", + " /\n", + " e6_incr_ccc[e6_incr_ccc.development >= 84].sum().sum() \n", + ")\n", + "#setting the valuation_date to the future\n", + "e6_ipsev_full.valuation_date = pd.to_datetime(cl.options.ULT_VAL)\n", + "#trending back from latest accident year\n", + "e6_ipsev_full_detrended = e6_ipsev_full.trend(1/1.05-1,start='2008-12-31',end='2001-01-01') / xyz_tort_adjustment.fit(e6_ipsev).olf_.values\n", + "#compositing the actual incremental severities with dtrended selected\n", + "e6_ipsev_full_complete = e6_ipsev[e6_ipsev.valuation <= e6_ipsev.valuation_date] + e6_ipsev_full_detrended[e6_ipsev_full_detrended.valuation > e6_ipsev.valuation_date]\n", + "\n", + "#complete the incremental paid triangle\n", + "e6_s7_ccc = e6_dr_tri.full_triangle_.cum_to_incr()\n", + "e6_s7_ip = e6_s7_ccc * e6_ipsev_full_complete / 1000\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "8c663ba3-5416-4bc7-a4bd-c6b6fd456f52", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 1" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "a35f5d52-f6da-410b-8066-2326407fe0be", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Part 1 - Disposal Rate Triangle')\n", + "nb_display(cl.DisposalRate().fit_transform(e6_tri['Closed Claim Counts'],sample_weight = e6_rcc_ult).disposal_rate_tri.round(3))\n", + "\n", + "print('PART 2 - Average Disposal Rate Factors')\n", + "nb_display(combine_disposal(e6_drs).round(3).to_frame())\n", + "\n", + "print('PART 3 - Selected Disposal Rate Factors')\n", + "nb_display(e6_dr_selected.disposal_rate_)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "3cea4559-9ad7-4d0d-80c9-4275bc3f6749", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 2" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "7e65b816-1c9f-4aa3-be14-4ecfe68e3643", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Closed Claim Counts')\n", + "nb_display(e6_tri['Closed Claim Counts'])\n", + "print('Projected Incremental Closed Claim Counts')\n", + "nb_display(e6_dr_tri.full_triangle_.cum_to_incr().round(0))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d82ad2af-f1b4-4723-8f59-d8c8c8e18651", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 3" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "644ce450-62db-4c07-8f8a-b8a40f0057e8", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Paid Claims')\n", + "nb_display(e6_tri[\"Paid Claims\"])\n", + "print('Incremental Paid CLaims')\n", + "nb_display(e6_tri[\"Paid Claims\"].cum_to_incr())\n", + "print('Incremental Closed Claim Counts')\n", + "nb_display(e6_tri[\"Closed Claim Counts\"].cum_to_incr())\n", + "print('Incremental Paid Severities')\n", + "nb_display(e6_ipsev)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "c513183d-95a5-48b6-a956-5d9b5361b1f2", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 4" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "77cd2e1a-89bd-4f73-8944-614b98453ac7", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Incremental Paid Severities')\n", + "nb_display(e6_ipsev)\n", + "print('Trended Incremental Paid Severities Assuming 5% Annual Trend and Adjusted for Tort Reform')\n", + "nb_display(e6_ipsev_adj)\n", + "print('Average Trended Incremental Paid Severities')\n", + "nb_display(combine_tri(e6_sevs).round(0).to_frame())\n", + "print('Selected Incremental Paid Severities')\n", + "nb_display(e6_sevs_sel[e6_sevs_sel.development<=72])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "a58fc306-7907-45c7-ae2b-9a6ad2b4e5cc", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 5" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "f3366d2a-55dd-44db-b92e-0337841fe391", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Incremental Closed Claim Counts')\n", + "nb_display(e6_incr_ccc[e6_incr_ccc.development >= 72][e6_incr_ccc.origin <= '2003'])\n", + "print('Incremental Paid CLaims')\n", + "nb_display(e6_incr_paid[e6_incr_paid.development >= 72][e6_incr_paid.origin <= '2003'])\n", + "print('Trended Incremental Paid Severities')\n", + "nb_display(e6_incr_paid_trended[e6_incr_paid_trended.development >= 72][e6_incr_paid_trended.origin <= '2003'])\n", + "e6_s5 = pd.DataFrame(\n", + " data = [[\n", + " e6_incr_ccc[e6_incr_ccc.development >= 72].sum().sum(), \n", + " e6_incr_ccc[e6_incr_ccc.development >= 84].sum().sum()\n", + " ]],\n", + " index = ['Total Closed Claim Counts'],\n", + " columns = ['Age 72 & Older','Age 84 & Older']\n", + ")\n", + "e6_s5.loc['Total Trended Paid Claims'] = [\n", + " e6_incr_paid_trended[e6_incr_paid_trended.development >= 72].sum().sum(), \n", + " e6_incr_paid_trended[e6_incr_paid_trended.development >= 84].sum().sum()\n", + " ]\n", + "e6_s5.loc['Estimated Trended Tail Severity'] = e6_s5.iloc[1] / e6_s5.iloc[0]\n", + "e6_s5.loc['Estimated Incremental Trended Tail Severity'] = e6_sevs_sel.iloc[:,:,:,5:7].values.flatten()\n", + "e6_s5.loc['Selected Trended Paid Severity'] = e6_ipsev_full.values[0,0,-1,5:7]\n", + "nb_display(e6_s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "cec56e19-6976-43e9-862d-b866a49fbd84", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 6" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "266fee5b-ccab-4936-a652-a352177cc829", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Incremental Paid Severities')\n", + "nb_display(e6_ipsev)\n", + "print('Selected Incremental Paid Severities')\n", + "nb_display(e6_ipsev_full[e6_ipsev_full.origin == '2008'])\n", + "print('Incremental Paid Severities Adjusted to Cost Level of Accident Year Assuming 5% Annual Trend Rate and Tort Reform Adjustment')\n", + "nb_display(e6_ipsev_full_complete)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "b9a1663c-421e-4f69-bedc-b59dd431dda1", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 7" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "a96a03cd-6c86-4a61-9118-4d3744c1a709", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "print('Projected Incremental Closed Claim Counts')\n", + "nb_display(e6_s7_ccc.round(0))\n", + "print('Incremental Paid Severities Adjusted to Cost Level of Accident Year Assuming 5% Annual Trend Rate and Tort Reform Adjustment')\n", + "nb_display(e6_ipsev_full_complete)\n", + "print('Projected Incremental Paid Claims')\n", + "nb_display(e6_s7_ip)\n", + "print('Projected Cumulative Paid Claims')\n", + "nb_display(e6_s7_ip.incr_to_cum())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "d60ebfc1-1517-4d32-85e1-fd79fda6785e", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "source": [ + "## Exhibit VI Sheet 8" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "27234f18-968a-4e23-8b29-19698845193d", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "summary_exh(\n", + " e6_tri['Reported Claims'],\n", + " e6_tri['Paid Claims'],\n", + " e6_s7_ip.incr_to_cum()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "application/vnd.databricks.v1+cell": { + "cellMetadata": { + "byteLimit": 2048000, + "rowLimit": 10000 + }, + "inputWidgets": {}, + "nuid": "e03f91fe-ff00-47ee-9994-3caf56a38ab1", + "showTitle": false, + "tableResultSettingsMap": {}, + "title": "" + } + }, + "outputs": [], + "source": [ + "#Exhibit VI Sheet 1\n", + "assert np.all(e6_dr_selected.disposal_rate_.values == np.array([0.244, 0.572, 0.704, 0.814, 0.910, 0.952, 0.982, 0.994, 1.000]))\n", + "#Exhibit VI Sheet 2\n", + "lhs = (e6_dr_tri.full_triangle_.cum_to_incr()-e6_tri['Closed Claim Counts'].cum_to_incr()).values.flatten()\n", + "rhs = np.array([\n", + " 9., \n", + " 21., 10., \n", + " 39., 16., 8., \n", + " 109., 78., 31., 16., \n", + " 235., 103., 74., 29., 15., \n", + " 177., 155., 68., 48., 19., 10., \n", + " 160., 133., 116., 51., 36., 15., 7., \n", + "389., 156., 130., 114., 50., 36., 14., 7.\n", + "])\n", + "assert np.all(abs(lhs[~np.isnan(lhs)] - rhs) < 1)\n", + "#Exhibit VI Sheet 4\n", + "assert np.all(e6_sevs_sel.values[...,:6].round(0) == np.array([11807.,15165.,26043.,35183.,41908.,62206.]))\n", + "#Exhibit VI Sheet 5\n", + "assert np.all(e6_s5.iloc[4].values.round(0) == np.array([62206.,70432.]))\n", + "#Exhibit VI Sheet 6\n", + "lhs = e6_ipsev_full_detrended[e6_ipsev_full_detrended.valuation > e6_ipsev.valuation_date].values.flatten()\n", + "rhs = np.array([\n", + " 74709., \n", + " 78444., 78444., \n", + " 82367., 82367., 82367., \n", + " 76384., 86485., 86485., 86485., \n", + " 54032., 80203., 90809., 90809., 90809., \n", + " 42549., 50682., 75230., 85179., 85179., 85179., \n", + " 24803., 33508., 39912., 59244., 67079., 67079., 67079., \n", + "15165., 26043., 35183., 41908., 62206., 70432., 70432., 70432., \n", + "])\n", + "assert np.allclose(lhs[~np.isnan(lhs)], rhs, atol=1)\n", + "#Exhibit VI Sheet 7\n", + "assert np.allclose(\n", + " e6_s7_ip.incr_to_cum().iloc[:,:,:,-1].values.round(0).flatten(),\n", + " np.array([39192.,46869.,44479.,71906.,71684.,49913.,31805.,29828.]),\n", + " rtol = .001\n", + ")\n" + ] + } + ], + "metadata": { + "application/vnd.databricks.v1+notebook": { + "computePreferences": { + "hardware": { + "accelerator": null, + "gpuPoolId": null, + "memory": null + }, + "software": null + }, + "dashboards": [], + "environmentMetadata": { + "base_environment": "", + "environment_version": "5" + }, + "inputWidgetPreferences": null, + "language": "python", + "notebookMetadata": { + "mostRecentlyExecutedCommandWithImplicitDF": { + "commandId": 8042421325130824, + "dataframes": [ + "_sqldf" + ] + }, + "pythonIndentUnit": 4 + }, + "notebookName": "Chapter 11", + "widgets": {} + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/friedland/chapter_6.rst b/docs/friedland/chapter_6.rst index 6af1648a..95a4f2f0 100644 --- a/docs/friedland/chapter_6.rst +++ b/docs/friedland/chapter_6.rst @@ -87,14 +87,14 @@ Table 3 - Paid Claim Development Triangle .. doctest:: >>> tri['Paid Claims'] - 12 24 36 48 60 72 84 - 2002 2318.0 7932.0 13822.0 22095.0 31945.0 40629.0 44437.0 - 2003 1743.0 6240.0 12683.0 22892.0 34505.0 39320.0 NaN - 2004 2221.0 9898.0 25950.0 43439.0 52811.0 NaN NaN - 2005 3043.0 12219.0 27073.0 40026.0 NaN NaN NaN - 2006 3531.0 11778.0 22819.0 NaN NaN NaN NaN - 2007 3529.0 11865.0 NaN NaN NaN NaN NaN - 2008 3409.0 NaN NaN NaN NaN NaN NaN + 12 24 36 48 60 72 84 + 2002 2317.651 7931.635 13822.585 22095.617 31945.485 40628.819 44437.623 + 2003 1743.211 6240.349 12683.230 22892.562 34505.010 39320.472 NaN + 2004 2221.220 9898.432 25950.094 43439.464 52811.083 NaN NaN + 2005 3042.925 12218.989 27072.964 40026.352 NaN NaN NaN + 2006 3531.114 11778.146 22819.111 NaN NaN NaN NaN + 2007 3528.854 11864.720 NaN NaN NaN NaN NaN + 2008 3408.876 NaN NaN NaN NaN NaN NaN Table 4 - Ratio of Reported Claims to Earned Premium ####################################################### @@ -188,7 +188,7 @@ Table 6 - Ratio of Paid Claims-to-Reported Claims 2002 0.181 0.389 0.519 0.587 0.719 0.834 0.923 2003 0.181 0.367 0.418 0.564 0.780 0.886 NaN 2004 0.131 0.246 0.441 0.606 0.751 NaN NaN - 2005 0.106 0.258 0.385 0.566 NaN NaN NaN + 2005 0.106 0.258 0.385 0.567 NaN NaN NaN 2006 0.130 0.252 0.468 NaN NaN NaN NaN 2007 0.181 0.374 NaN NaN NaN NaN NaN 2008 0.183 NaN NaN NaN NaN NaN NaN @@ -279,10 +279,10 @@ Table 13 – Average Paid Claim Development Triangle >>> (tri["Paid Claims"] / tri["Closed Claim Counts"] * 1000).round(decimals=0) 12 24 36 48 60 72 84 - 2002 11419.0 13068.0 16435.0 20289.0 24073.0 27752.0 29177.0 - 2003 9630.0 10163.0 13478.0 18125.0 22896.0 25077.0 NaN - 2004 9451.0 11672.0 17996.0 23455.0 26028.0 NaN NaN - 2005 10315.0 10920.0 16270.0 20568.0 NaN NaN NaN + 2002 11417.0 13067.0 16436.0 20290.0 24073.0 27752.0 29178.0 + 2003 9631.0 10163.0 13478.0 18126.0 22896.0 25077.0 NaN + 2004 9452.0 11673.0 17996.0 23455.0 26028.0 NaN NaN + 2005 10315.0 10920.0 16270.0 20569.0 NaN NaN NaN 2006 11502.0 13000.0 19000.0 NaN NaN NaN NaN 2007 10726.0 15000.0 NaN NaN NaN NaN NaN 2008 12351.0 NaN NaN NaN NaN NaN NaN @@ -294,10 +294,10 @@ Table 14 – Average Case Outstanding Development Triangle >>> ((tri["Reported Claims"] - tri["Paid Claims"]) / (tri["Reported Claim Counts"] - tri["Closed Claim Counts"]) * 1000).round(decimals=0) 12 24 36 48 60 72 84 - 2002 9212.0 13713.0 18153.0 33274.0 56167.0 91727.0 120387.0 - 2003 6634.0 10734.0 25647.0 48766.0 79721.0 82836.0 NaN - 2004 8706.0 22941.0 41561.0 71204.0 76319.0 NaN NaN - 2005 14464.0 29994.0 61546.0 68984.0 NaN NaN NaN - 2006 20184.0 47368.0 56985.0 NaN NaN NaN NaN - 2007 18480.0 42002.0 NaN NaN NaN NaN NaN + 2002 9213.0 13714.0 18152.0 33272.0 56164.0 91729.0 120367.0 + 2003 6634.0 10733.0 25647.0 48764.0 79721.0 82828.0 NaN + 2004 8706.0 22941.0 41560.0 71203.0 76318.0 NaN NaN + 2005 14464.0 29994.0 61546.0 68983.0 NaN NaN NaN + 2006 20184.0 47368.0 56984.0 NaN NaN NaN NaN + 2007 18480.0 42003.0 NaN NaN NaN NaN NaN 2008 20030.0 NaN NaN NaN NaN NaN NaN diff --git a/docs/friedland/chapter_7.rst b/docs/friedland/chapter_7.rst index 9b2630a8..63c7110c 100644 --- a/docs/friedland/chapter_7.rst +++ b/docs/friedland/chapter_7.rst @@ -494,35 +494,35 @@ Exhibit II Sheet 2 p111 >>> paid_devs = dev_exhibit(tri['Paid Claims'],assumptions,'volume_2',1.01) PART 1 - Data Triangle - 12 24 36 48 60 72 84 96 108 120 132 - 1998 NaN NaN 6309.0 8521.0 10082.0 11620.0 13242.0 14419.0 15311.0 15764.0 15822.0 - 1999 NaN 4666.0 9861.0 13971.0 18127.0 22032.0 23511.0 24146.0 24592.0 24817.0 NaN - 2000 1302.0 6513.0 12139.0 17828.0 24030.0 28853.0 33222.0 35902.0 36782.0 NaN NaN - 2001 1539.0 5952.0 12319.0 18609.0 24387.0 31090.0 37070.0 38519.0 NaN NaN NaN - 2002 2318.0 7932.0 13822.0 22095.0 31945.0 40629.0 44437.0 NaN NaN NaN NaN - 2003 1743.0 6240.0 12683.0 22892.0 34505.0 39320.0 NaN NaN NaN NaN NaN - 2004 2221.0 9898.0 25950.0 43439.0 52811.0 NaN NaN NaN NaN NaN NaN - 2005 3043.0 12219.0 27073.0 40026.0 NaN NaN NaN NaN NaN NaN NaN - 2006 3531.0 11778.0 22819.0 NaN NaN NaN NaN NaN NaN NaN NaN - 2007 3529.0 11865.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN - 2008 3409.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN + 12 24 36 48 60 72 84 96 108 120 132 + 1998 NaN NaN 6309.000 8521.000 10082.000 11620.000 13242.000 14419.000 15311.0 15764.0 15822.0 + 1999 NaN 4666.000 9861.000 13971.000 18127.000 22032.000 23511.000 24146.000 24592.0 24817.0 NaN + 2000 1302.000 6513.000 12139.000 17828.000 24030.000 28853.000 33222.000 35902.000 36782.0 NaN NaN + 2001 1539.456 5952.241 12319.336 18608.788 24386.973 31090.065 37069.815 38519.529 NaN NaN NaN + 2002 2317.651 7931.635 13822.585 22095.617 31945.485 40628.819 44437.623 NaN NaN NaN NaN + 2003 1743.211 6240.349 12683.230 22892.562 34505.010 39320.472 NaN NaN NaN NaN NaN + 2004 2221.220 9898.432 25950.094 43439.464 52811.083 NaN NaN NaN NaN NaN NaN + 2005 3042.925 12218.989 27072.964 40026.352 NaN NaN NaN NaN NaN NaN NaN + 2006 3531.114 11778.146 22819.111 NaN NaN NaN NaN NaN NaN NaN NaN + 2007 3528.854 11864.720 NaN NaN NaN NaN NaN NaN NaN NaN NaN + 2008 3408.876 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN PART 2 - Age-to-Age Factors 12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 1998 NaN NaN 1.350610 1.183194 1.152549 1.139587 1.088884 1.061863 1.029587 1.003679 1999 NaN 2.113373 1.416793 1.297473 1.215425 1.067130 1.027009 1.018471 1.009149 NaN 2000 5.002304 1.863811 1.468655 1.347880 1.200707 1.151423 1.080669 1.024511 NaN NaN - 2001 3.867446 2.069724 1.510593 1.310495 1.274860 1.192345 1.039088 NaN NaN NaN - 2002 3.421915 1.742562 1.598539 1.445802 1.271842 1.093726 NaN NaN NaN NaN - 2003 3.580034 2.032532 1.804936 1.507295 1.139545 NaN NaN NaN NaN NaN - 2004 4.456551 2.621742 1.673950 1.215751 NaN NaN NaN NaN NaN NaN - 2005 4.015445 2.215648 1.478447 NaN NaN NaN NaN NaN NaN NaN - 2006 3.335599 1.937426 NaN NaN NaN NaN NaN NaN NaN NaN - 2007 3.362142 NaN NaN NaN NaN NaN NaN NaN NaN NaN + 2001 3.866457 2.069697 1.510535 1.310508 1.274864 1.192336 1.039108 NaN NaN NaN + 2002 3.422273 1.742716 1.598516 1.445784 1.271817 1.093746 NaN NaN NaN NaN + 2003 3.579801 2.032455 1.804947 1.507259 1.139558 NaN NaN NaN NaN NaN + 2004 4.456304 2.621637 1.673962 1.215740 NaN NaN NaN NaN NaN NaN + 2005 4.015541 2.215647 1.478462 NaN NaN NaN NaN NaN NaN NaN + 2006 3.335533 1.937411 NaN NaN NaN NaN NaN NaN NaN NaN + 2007 3.362202 NaN NaN NaN NaN NaN NaN NaN NaN NaN PART 3 - Average Age-to-Age Factor 12-24 24-36 36-48 48-60 60-72 72-84 84-96 96-108 108-120 120-132 simple_5 3.750 2.110 1.613 1.365 1.220 1.129 1.059 1.035 1.019 1.004 simple_3 3.571 2.258 1.652 1.390 1.229 1.146 1.049 1.035 1.019 1.004 - simple_2 3.349 2.077 1.576 1.362 1.206 1.143 1.060 1.021 1.019 1.004 + simple_2 3.349 2.077 1.576 1.361 1.206 1.143 1.060 1.021 1.019 1.004 volume_4 3.713 2.206 1.615 1.342 1.218 1.128 1.056 1.030 1.017 1.004 volume_3 3.550 2.238 1.619 1.349 1.222 1.141 1.051 1.030 1.017 1.004 volume_2 3.349 2.079 1.574 1.316 1.203 1.136 1.059 1.022 1.017 1.004 @@ -543,17 +543,17 @@ Exhibit II Sheet 3 p112 >>> exhibit = rounded_development_summary(reported_devs["Selected"],paid_devs["Selected"]) >>> exhibit Age Reported Claims Paid Claims Reported CDF Paid CDF Reported Ultimate Paid Ultimate - 1998 132 15822.0 15822.0 1.000 1.010 15822.0 15980.0 - 1999 120 25107.0 24817.0 0.999 1.014 25082.0 25164.0 - 2000 108 37246.0 36782.0 0.992 1.031 36948.0 37922.0 - 2001 96 38798.0 38519.0 0.992 1.054 38488.0 40599.0 - 2002 84 48169.0 44437.0 1.003 1.116 48314.0 49592.0 - 2003 72 44373.0 39320.0 1.013 1.268 44950.0 49858.0 - 2004 60 70288.0 52811.0 1.064 1.525 74786.0 80537.0 - 2005 48 70655.0 40026.0 1.085 2.007 76661.0 80332.0 - 2006 36 48804.0 22819.0 1.196 3.160 58370.0 72108.0 - 2007 24 31732.0 11865.0 1.512 6.569 47979.0 77941.0 - 2008 12 18632.0 3409.0 2.551 21.999 47530.0 74995.0 + 1998 132 15822.0 15822.000 1.000 1.010 15822.0 15980.0 + 1999 120 25107.0 24817.000 0.999 1.014 25082.0 25164.0 + 2000 108 37246.0 36782.000 0.992 1.031 36948.0 37922.0 + 2001 96 38798.0 38519.529 0.992 1.054 38488.0 40600.0 + 2002 84 48169.0 44437.623 1.003 1.116 48314.0 49592.0 + 2003 72 44373.0 39320.472 1.013 1.268 44950.0 49858.0 + 2004 60 70288.0 52811.083 1.064 1.525 74786.0 80537.0 + 2005 48 70655.0 40026.352 1.085 2.007 76661.0 80333.0 + 2006 36 48804.0 22819.111 1.196 3.160 58370.0 72108.0 + 2007 24 31732.0 11864.720 1.512 6.569 47979.0 77939.0 + 2008 12 18632.0 3408.876 2.551 21.999 47530.0 74992.0 Exhibit II Sheet 4 p113 ########################## @@ -563,17 +563,17 @@ Exhibit II Sheet 4 p113 >>> unpaid_exhibit = unpaid_summary(exhibit) >>> unpaid_exhibit[['Case Outstanding','Reported Method IBNR','Paid Method IBNR','Reported Method Unpaid','Paid Method Unpaid']] Case Outstanding Reported Method IBNR Paid Method IBNR Reported Method Unpaid Paid Method Unpaid - 1998 0.0 0.0 158.0 0.0 158.0 - 1999 290.0 -25.0 57.0 265.0 347.0 - 2000 464.0 -298.0 676.0 166.0 1140.0 - 2001 279.0 -310.0 1801.0 -31.0 2080.0 - 2002 3732.0 145.0 1423.0 3877.0 5155.0 - 2003 5053.0 577.0 5485.0 5630.0 10538.0 - 2004 17477.0 4498.0 10249.0 21975.0 27726.0 - 2005 30629.0 6006.0 9677.0 36635.0 40306.0 - 2006 25985.0 9566.0 23304.0 35551.0 49289.0 - 2007 19867.0 16247.0 46209.0 36114.0 66076.0 - 2008 15223.0 28898.0 56363.0 44121.0 71586.0 + 1998 0.000 0.0 158.0 0.000 158.000 + 1999 290.000 -25.0 57.0 265.000 347.000 + 2000 464.000 -298.0 676.0 166.000 1140.000 + 2001 278.471 -310.0 1802.0 -31.529 2080.471 + 2002 3731.377 145.0 1423.0 3876.377 5154.377 + 2003 5052.528 577.0 5485.0 5629.528 10537.528 + 2004 17476.917 4498.0 10249.0 21974.917 27725.917 + 2005 30628.648 6006.0 9678.0 36634.648 40306.648 + 2006 25984.889 9566.0 23304.0 35550.889 49288.889 + 2007 19867.280 16247.0 46207.0 36114.280 66074.280 + 2008 15223.124 28898.0 56360.0 44121.124 71583.124 Exhibit III Sheet 1 p114 ##########################