def test_printer(): print(cl.load_sample('abc'))
""" ========================== Voting Chainladder Example ========================== This example demonstrates how you can can use the Voting Chainladder method. """ import numpy as np import pandas as pd import chainladder as cl # Load the data raa = cl.load_sample('raa') cl_ult = cl.Chainladder().fit(raa).ultimate_ # Chainladder Ultimate apriori = cl_ult * 0 + (float(cl_ult.sum()) / 10) # Mean Chainladder Ultimate # Load estimators to vote between bcl = cl.Chainladder() cc = cl.CapeCod() estimators = [('bcl', bcl), ('cc', cc)] # Fit VotingChainladder using CC after 1987 and a blend of BCL and CC otherwise vot = cl.VotingChainladder( estimators=estimators, weights=lambda origin: (0, 1) if origin.year > 1987 else (0.5, 0.5) ) vot.fit(raa, sample_weight=apriori) # Plotting bcl_ibnr = bcl.fit(raa).ibnr_.to_frame() cc_ibnr = cc.fit(raa, sample_weight=apriori).ibnr_.to_frame()
def mack_p(data, average, est_sigma): return cl.Development(average=average, sigma_interpolation=est_sigma).fit_transform( cl.load_sample(data))
def test_concat(): tri = cl.load_sample('clrd').groupby('LOB').sum() assert cl.concat([tri.loc['wkcomp'], tri.loc['comauto']], axis=0) == \ tri.loc[['wkcomp', 'comauto']]
""" ==================== Clark Residual Plots ==================== This example demonstrates how to recreate the normalized residual plots in Clarks LDF Curve-Fitting paper (2003). """ import chainladder as cl import matplotlib.pyplot as plt # Fit the basic model genins = cl.load_sample('genins') genins = cl.ClarkLDF().fit(genins) # Grab Normalized Residuals as a DataFrame norm_resid = genins.norm_resid_.melt( var_name='Development Age', value_name='Normalized Residual').dropna() # Grab Fitted Incremental values as a DataFrame incremental_fits = genins.incremental_fits_.melt( var_name='Development Age', value_name='Expected Incremental Loss').dropna() # Plot the residuals vs Age and vs Expected Incrementals fig, ((ax0, ax1)) = plt.subplots(ncols=2, figsize=(15, 5)) # Left plot norm_resid.plot(x='Development Age', y='Normalized Residual', kind='scatter', grid=True,
def test_basic_odp_cl(): genins = cl.load_sample('genins') assert abs((cl.Chainladder().fit(genins).ultimate_ - cl.Chainladder().fit( cl.TweedieGLM().fit_transform(genins)).ultimate_) / genins.latest_diagonal).max() < 1e-2
def test_json_subtri(): assert cl.read_json(cl.Chainladder().fit_predict(cl.load_sample('raa')).to_json()).full_triangle_ == \ cl.Chainladder().fit_predict(cl.load_sample('raa')).full_triangle_
def test_valdev3(): a = cl.load_sample('quarterly').grain( 'OYDY').dev_to_val().val_to_dev().values b = cl.load_sample('quarterly').grain('OYDY').values xp = cp.get_array_module(a) xp.testing.assert_array_equal(a, b)
def test_valdev7(): tri = cl.load_sample('quarterly') xp = cp.get_array_module(tri.values) x = cl.Chainladder().fit(tri).full_expectation_ assert xp.sum(x.dev_to_val().val_to_dev().values - x.values) < 1e-5
def test_grain_returns_valid_tri(): tri = cl.load_sample('quarterly') assert tri.grain('OYDY').latest_diagonal == tri.latest_diagonal
def test_grain_increm_arg(): tri = cl.load_sample('quarterly')['incurred'] tri_i = tri.cum_to_incr() np.testing.assert_array_equal( tri_i.grain('OYDY').incr_to_cum(), tri.grain('OYDY'))
def test_quantile_vs_median(): clrd = cl.load_sample('clrd') xp = cp.get_array_module(clrd.values) xp.testing.assert_array_equal( clrd.quantile(.5)['CumPaidLoss'].values, clrd.median()['CumPaidLoss'].values)
def test_shift(): x = cl.load_sample('quarterly').iloc[0, 0] xp = cp.get_array_module(x.values) xp.testing.assert_array_equal(x[x.valuation <= x.valuation_date].values, x.values)
def test_trend(): assert abs((cl.load_sample('abc').trend(0.05).trend((1 / 1.05) - 1) - cl.load_sample('abc')).sum().sum()) < 1e-5
def test_arithmetic_1(): x = cl.load_sample("mortgage") np.testing.assert_array_equal(-(((x / x) + 0) * x), -(+x))
def test_reassignment(): raa = cl.load_sample('clrd') raa['values'] = raa['CumPaidLoss'] raa['values'] = raa['values'] + raa['CumPaidLoss']
def test_arithmetic_2(): x = cl.load_sample("mortgage") np.testing.assert_array_equal(1 - (x / x), 0 * x * 0)
def test_dropna(): clrd = cl.load_sample('clrd') assert clrd.shape == clrd.dropna().shape assert clrd[clrd['LOB'] == 'wkcomp'].iloc[-5]['CumPaidLoss'].dropna().shape == (1, 1, 2, 2)
def test_json_for_val(): x = cl.load_sample('raa').dev_to_val().to_json() assert cl.read_json(x) == cl.load_sample('raa').dev_to_val()
import chainladder as cl import pandas as pd import numpy as np import copy tri = cl.load_sample("clrd") qtr = cl.load_sample("quarterly") raa = cl.load_sample("raa") tri_gt = copy.deepcopy(tri) qtr_gt = copy.deepcopy(qtr) raa_gt = copy.deepcopy(raa) # Test Triangle slicing def test_slice_by_boolean(): assert tri == tri_gt assert ( tri[tri["LOB"] == "ppauto"].loc["Wolverine Mut Ins Co"]["CumPaidLoss"] == tri.loc["Wolverine Mut Ins Co"].loc["ppauto"]["CumPaidLoss"]) def test_slice_by_loc(): assert tri == tri_gt assert tri.loc["Aegis Grp"].loc["comauto"].index.iloc[0, 0] == "comauto" def test_slice_origin(): assert raa == raa_gt assert raa[raa.origin > "1985"].shape == (1, 1, 5, 10)
def test_json_df(): x = cl.MunichAdjustment(paid_to_incurred=('paid', 'incurred')).fit_transform( cl.load_sample('mcl')) assert abs(cl.read_json(x.to_json()).lambda_ - x.lambda_).sum() < 1e-5
def test_assign_existing_col(): qtr = cl.load_sample("quarterly") before = qtr.shape qtr["paid"] = 1 / qtr["paid"] assert qtr.shape == before
""" ================================ Pandas-style slicing of Triangle ================================ This example demonstrates the familiarity of the pandas API applied to a :class:`Triangle` instance. """ import chainladder as cl # The base Triangle Class: cl.Triangle # Load data clrd = cl.load_sample('clrd') # pandas-style Aggregations clrd = clrd.groupby('LOB').sum() # pandas-style value/column slicing clrd = clrd['CumPaidLoss'] # pandas loc-style index slicing clrd = clrd.loc['medmal'] # Plot g = clrd.link_ratio.plot(marker='o', grid=True, title='Medical Malpractice Link Ratios').set( ylabel='Link Ratio', xlabel='Accident Year')
def test_arithmetic_across_keys(): x = cl.load_sample("auto") xp = x.get_array_module() xp.testing.assert_array_equal((x.sum() - x.iloc[0]).values, x.iloc[1].values)
""" ====================== Value at Risk example ====================== This example uses the `BootstrapODPSample` to simulate new triangles that are then used to simulate an IBNR distribution from which we can do Value at Risk percentile lookups. """ import chainladder as cl import matplotlib.pyplot as plt # Load triangle triangle = cl.load_sample('genins') # Create 1000 bootstrap samples of the triangle resampled_triangles = cl.BootstrapODPSample(random_state=42).fit_transform(triangle) # Create 1000 IBNR estimates sim_ibnr = cl.Chainladder().fit(resampled_triangles).ibnr_.sum('origin') # X - mu sim_ibnr = (sim_ibnr - sim_ibnr.mean()).to_frame().sort_values() # Plot data fig, ax = plt.subplots() sim_ibnr.index = [item/1000 for item in range(1000)] (sim_ibnr/1e6).loc[0.90:].plot(kind='area', alpha=0.5, title='Bootstrap VaR (90% and above)', color='red', ax=ax).set( xlabel='Percentile', xlim=(0.899, 1.0), ylabel='Value (Millions)');
def test_printer(): print(cl.load_sample("abc"))
============================ `DevelopmentConstant` takes a dictionary of development factors and stores them in a development estimator. This example demonstrates how a function can be passed into `DevelopmentConstant` rather than a static dictionary of patterns. The function should return development patterns for each element of the Triangle's index. When passing a function to the estimator, it behaves as if calling the pandas `apply` method on the Triangle's index. """ import chainladder as cl import pandas as pd # Sample Data agway = cl.load_sample('clrd').loc['Agway Ins Co', 'CumPaidLoss'] def paid_cdfs(x): """ A function that returns different CDFs depending on a specified LOB """ cdfs = { 'comauto': [3.832, 1.874, 1.386, 1.181, 1.085, 1.043, 1.022, 1.013, 1.007, 1], 'medmal': [24.168, 4.127, 2.103, 1.528, 1.275, 1.161, 1.088, 1.047, 1.018, 1], 'othliab': [10.887, 3.416, 1.957, 1.433, 1.231, 1.119, 1.06, 1.031, 1.011, 1], 'ppauto': [2.559, 1.417, 1.181, 1.084, 1.04, 1.019, 1.009, 1.004, 1.001, 1], 'prodliab': [13.703, 5.613, 2.92, 1.765, 1.385, 1.177, 1.072, 1.034, 1.008, 1],
def test_trend(): assert (abs((cl.load_sample("abc").trend(0.05).trend((1 / 1.05) - 1) - cl.load_sample("abc")).sum().sum()) < 1e-5)
def test_full_slice(): assert (cl.Development().fit_transform( cl.load_sample("GenIns")).ldf_ == cl.Development( n_periods=1000).fit_transform(cl.load_sample("GenIns")).ldf_)
def test_off_cycle_val_date(): assert cl.load_sample('quarterly').valuation_date.strftime( '%Y-%m-%d') == '2006-03-31'