From 165f6b2e41fac54aeeb64c84894858234fb71f33 Mon Sep 17 00:00:00 2001 From: Gene Dan Date: Fri, 4 Sep 2026 16:39:26 -0500 Subject: [PATCH] [FIX] Apply Ruff fix to docs/gallery. --- docs/gallery/plot_advanced_triangle.ipynb | 26 ++++--- docs/gallery/plot_ave_analysis.ipynb | 33 ++++---- docs/gallery/plot_benktander.ipynb | 46 ++++++----- docs/gallery/plot_bondy_sensitivity.ipynb | 30 +++++--- docs/gallery/plot_bootstrap.ipynb | 36 ++++++--- docs/gallery/plot_bootstrap_comparison.ipynb | 35 ++++++--- docs/gallery/plot_capecod.ipynb | 41 ++++++---- docs/gallery/plot_capecod_onlevel.ipynb | 77 ++++++++++++------- docs/gallery/plot_clarkldf_resid.ipynb | 36 ++++++--- docs/gallery/plot_development_periods.ipynb | 27 ++++--- docs/gallery/plot_elrf_resid.ipynb | 70 +++++++++++------ docs/gallery/plot_exposure_triangle.ipynb | 16 ++-- docs/gallery/plot_extrap_period.ipynb | 21 +++-- docs/gallery/plot_loss_development.ipynb | 32 ++++---- docs/gallery/plot_mack.ipynb | 28 ++++--- docs/gallery/plot_munich.ipynb | 42 ++++++---- docs/gallery/plot_munich_resid.ipynb | 59 +++++++++------ docs/gallery/plot_ptf_resid.ipynb | 80 +++++++++++++++----- docs/gallery/plot_stochastic_bornferg.ipynb | 21 +++-- docs/gallery/plot_triangle_from_pandas.ipynb | 36 ++++++--- docs/gallery/plot_value_at_risk.ipynb | 17 +++-- docs/gallery/plot_voting_chainladder.ipynb | 23 +++--- pyproject.toml | 22 ------ 23 files changed, 524 insertions(+), 330 deletions(-) diff --git a/docs/gallery/plot_advanced_triangle.ipynb b/docs/gallery/plot_advanced_triangle.ipynb index dab19acc6..b41af5d64 100644 --- a/docs/gallery/plot_advanced_triangle.ipynb +++ b/docs/gallery/plot_advanced_triangle.ipynb @@ -44,23 +44,23 @@ }, "outputs": [], "source": [ - "clrd = cl.load_sample('clrd')\n", - "clrd = clrd[clrd['LOB']=='comauto']\n", + "clrd = cl.load_sample(\"clrd\")\n", + "clrd = clrd[clrd[\"LOB\"] == \"comauto\"]\n", "\n", "# Create a loss ratio virtual column\n", - "clrd['LossRatio'] = lambda clrd: clrd['IncurLoss'] / clrd['EarnedPremDIR']\n", + "clrd[\"LossRatio\"] = lambda clrd: clrd[\"IncurLoss\"] / clrd[\"EarnedPremDIR\"]\n", "\n", "# Identify the largest companies (by premium) for 1997\n", - "top_10 = clrd['EarnedPremDIR'].groupby('GRNAME').sum().latest_diagonal\n", - "top_10 = top_10.loc[..., '1997', :].to_frame().nlargest(10)\n", + "top_10 = clrd[\"EarnedPremDIR\"].groupby(\"GRNAME\").sum().latest_diagonal\n", + "top_10 = top_10.loc[..., \"1997\", :].to_frame().nlargest(10)\n", "\n", "# Group any companies together that are not in the top 10\n", - "clrd = clrd.groupby(clrd.index['GRNAME'].map(\n", - " lambda x: x if x in top_10.index else 'Remainder')).sum()\n", + "clrd = clrd.groupby(\n", + " clrd.index[\"GRNAME\"].map(lambda x: x if x in top_10.index else \"Remainder\")\n", + ").sum()\n", "\n", "# Sort by company volume, but keep Remainder as last entry\n", - "clrd = clrd.loc[top_10.index.to_list() + ['Remainder']].iloc[::-1]\n", - "\n" + "clrd = clrd.loc[top_10.index.to_list() + [\"Remainder\"]].iloc[::-1]" ] }, { @@ -90,12 +90,14 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "\n", - "ax = clrd.latest_diagonal.sum('origin')['LossRatio'].plot(\n", - " kind='barh', title='Loss Ratio');" + "ax = clrd.latest_diagonal.sum(\"origin\")[\"LossRatio\"].plot(\n", + " kind=\"barh\", title=\"Loss Ratio\"\n", + ");" ] }, { diff --git a/docs/gallery/plot_ave_analysis.ipynb b/docs/gallery/plot_ave_analysis.ipynb index a919c50c4..8955a64d0 100644 --- a/docs/gallery/plot_ave_analysis.ipynb +++ b/docs/gallery/plot_ave_analysis.ipynb @@ -43,8 +43,8 @@ }, "outputs": [], "source": [ - "tri_1997 = cl.load_sample('clrd')\n", - "tri_1997 = tri_1997.groupby('LOB').sum().loc['medmal']['CumPaidLoss']" + "tri_1997 = cl.load_sample(\"clrd\")\n", + "tri_1997 = tri_1997.groupby(\"LOB\").sum().loc[\"medmal\"][\"CumPaidLoss\"]" ] }, { @@ -62,12 +62,12 @@ "outputs": [], "source": [ "# Create a triangle as of the previous valuation and build IBNR model\n", - "tri_1996 = tri_1997[tri_1997.valuation < '1997']\n", + "tri_1996 = tri_1997[tri_1997.valuation < \"1997\"]\n", "model_1996 = cl.Chainladder().fit(cl.TailCurve().fit_transform(tri_1996))\n", "\n", "# Slice the expected losses from the 1997 calendar period of the model\n", "ave = model_1996.full_triangle_.dev_to_val()\n", - "ave = ave[ave.valuation==tri_1997.valuation_date].rename('columns', 'Expected')" + "ave = ave[ave.valuation == tri_1997.valuation_date].rename(\"columns\", \"Expected\")" ] }, { @@ -85,7 +85,7 @@ "outputs": [], "source": [ "# Slice the actual losses from the 1997 calendar period for prior AYs\n", - "ave['Actual'] = tri_1997.latest_diagonal[tri_1997.origin < '1997']\n", + "ave[\"Actual\"] = tri_1997.latest_diagonal[tri_1997.origin < \"1997\"]\n", "df = ave.to_frame().T.iloc[::-1]" ] }, @@ -116,23 +116,26 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plotting\n", "fig, ax = plt.subplots()\n", - "ax.grid(axis='x')\n", + "ax.grid(axis=\"x\")\n", "plt.hlines(\n", - " y=df.index.astype(str), \n", - " xmin=df['Actual'], \n", - " xmax=df['Expected'],\n", - " color='grey', alpha=0.4)\n", - "plt.scatter(df['Actual'], df.index.astype(str), alpha=1, label='Actual')\n", - "plt.scatter(df['Expected'], df.index.astype(str), alpha=0.8 , label='Expected')\n", + " y=df.index.astype(str),\n", + " xmin=df[\"Actual\"],\n", + " xmax=df[\"Expected\"],\n", + " color=\"grey\",\n", + " alpha=0.4,\n", + ")\n", + "plt.scatter(df[\"Actual\"], df.index.astype(str), alpha=1, label=\"Actual\")\n", + "plt.scatter(df[\"Expected\"], df.index.astype(str), alpha=0.8, label=\"Expected\")\n", "plt.legend()\n", "plt.title(\"Actual vs Expected results in 1997\")\n", - "plt.xlabel('Difference')\n", - "plt.ylabel('Origin');" + "plt.xlabel(\"Difference\")\n", + "plt.ylabel(\"Origin\");" ] }, { diff --git a/docs/gallery/plot_benktander.ipynb b/docs/gallery/plot_benktander.ipynb index 8ac4c46eb..d5c91bf87 100644 --- a/docs/gallery/plot_benktander.ipynb +++ b/docs/gallery/plot_benktander.ipynb @@ -46,21 +46,25 @@ "outputs": [], "source": [ "# Load Data\n", - "clrd = cl.load_sample('clrd').groupby('LOB').sum()\n", - "X = clrd.loc['medmal', 'CumPaidLoss']\n", - "sample_weight = clrd.loc['medmal', 'EarnedPremDIR'].latest_diagonal\n", + "clrd = cl.load_sample(\"clrd\").groupby(\"LOB\").sum()\n", + "X = clrd.loc[\"medmal\", \"CumPaidLoss\"]\n", + "sample_weight = clrd.loc[\"medmal\", \"EarnedPremDIR\"].latest_diagonal\n", "\n", "# Specify Model\n", "grid = cl.GridSearch(\n", - " estimator=cl.Pipeline(steps=[\n", - " ('dev', cl.Development()),\n", - " ('tail', cl.TailCurve()),\n", - " ('model', cl.Benktander())]), \n", - " param_grid = dict(\n", - " model__n_iters=list(range(1, 100, 2)),\n", - " model__apriori=[0.50, 0.75, 1.00]), \n", - " scoring={'IBNR': lambda x: x.named_steps.model.ibnr_.sum()},\n", - " n_jobs=-1)" + " estimator=cl.Pipeline(\n", + " steps=[\n", + " (\"dev\", cl.Development()),\n", + " (\"tail\", cl.TailCurve()),\n", + " (\"model\", cl.Benktander()),\n", + " ]\n", + " ),\n", + " param_grid=dict(\n", + " model__n_iters=list(range(1, 100, 2)), model__apriori=[0.50, 0.75, 1.00]\n", + " ),\n", + " scoring={\"IBNR\": lambda x: x.named_steps.model.ibnr_.sum()},\n", + " n_jobs=-1,\n", + ")" ] }, { @@ -120,7 +124,8 @@ ], "source": [ "from sklearn import set_config\n", - "set_config(display='diagram')\n", + "\n", + "set_config(display=\"diagram\")\n", "grid" ] }, @@ -225,9 +230,8 @@ "\n", "# Analyze results\n", "output = grid.results_.pivot(\n", - " index='model__n_iters', \n", - " columns='model__apriori', \n", - " values='IBNR') \n", + " index=\"model__n_iters\", columns=\"model__apriori\", values=\"IBNR\"\n", + ")\n", "output.head()" ] }, @@ -266,13 +270,15 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "ax = (output / 1e6).plot(\n", - " ylabel='IBNR (Millions)',\n", - " xlabel='Number of Iterations',\n", - " title='Benktander convergence to Chainladder');" + " ylabel=\"IBNR (Millions)\",\n", + " xlabel=\"Number of Iterations\",\n", + " title=\"Benktander convergence to Chainladder\",\n", + ");" ] }, { diff --git a/docs/gallery/plot_bondy_sensitivity.ipynb b/docs/gallery/plot_bondy_sensitivity.ipynb index 2a3212831..93902b911 100644 --- a/docs/gallery/plot_bondy_sensitivity.ipynb +++ b/docs/gallery/plot_bondy_sensitivity.ipynb @@ -47,19 +47,19 @@ "outputs": [], "source": [ "# Fit basic development to a triangle\n", - "tri = cl.load_sample('tail_sample')['paid']\n", - "dev = cl.Development(average='simple').fit_transform(tri)\n", + "tri = cl.load_sample(\"tail_sample\")[\"paid\"]\n", + "dev = cl.Development(average=\"simple\").fit_transform(tri)\n", "\n", "# Return both the tail factor and the Bondy exponent in the scoring function\n", "scoring = {\n", - " 'tail_factor': lambda x: x.tail_.values[0,0],\n", - " 'bondy_exponent': lambda x : x.b_.values[0,0]}\n", + " \"tail_factor\": lambda x: x.tail_.values[0, 0],\n", + " \"bondy_exponent\": lambda x: x.b_.values[0, 0],\n", + "}\n", "\n", "# Vary the 'earliest_age' assumption in GridSearch\n", - "param_grid=dict(earliest_age=list(range(12, 120, 12)))\n", + "param_grid = dict(earliest_age=list(range(12, 120, 12)))\n", "grid = cl.GridSearch(cl.TailBondy(), param_grid, scoring)\n", - "results = grid.fit(dev).results_\n", - "\n" + "results = grid.fit(dev).results_" ] }, { @@ -89,13 +89,19 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", - "ax = results.plot(x='earliest_age', y='bondy_exponent',\n", - " title='Bondy Assumption Sensitivity', marker='o')\n", - "results.plot(x='earliest_age', y='tail_factor', grid=True,\n", - " secondary_y=True, ax=ax, marker='o');" + "ax = results.plot(\n", + " x=\"earliest_age\",\n", + " y=\"bondy_exponent\",\n", + " title=\"Bondy Assumption Sensitivity\",\n", + " marker=\"o\",\n", + ")\n", + "results.plot(\n", + " x=\"earliest_age\", y=\"tail_factor\", grid=True, secondary_y=True, ax=ax, marker=\"o\"\n", + ");" ] }, { diff --git a/docs/gallery/plot_bootstrap.ipynb b/docs/gallery/plot_bootstrap.ipynb index bb92e7fd4..a10f64372 100644 --- a/docs/gallery/plot_bootstrap.ipynb +++ b/docs/gallery/plot_bootstrap.ipynb @@ -42,10 +42,8 @@ }, "outputs": [], "source": [ - "import chainladder as cl\n", - "\n", "# Grab a Triangle\n", - "tri = cl.load_sample('genins')\n", + "tri = cl.load_sample(\"genins\")\n", "\n", "# Generate bootstrap samples\n", "sims = cl.BootstrapODPSample(random_state=42).fit_transform(tri)\n", @@ -57,7 +55,7 @@ "plot2 = (sims.sum() / 1000).T / 1e6\n", "plot3a = sim_ldf.T\n", "plot3b = cl.Development().fit(tri).ldf_.drop_duplicates().T\n", - "plot4 = sim_ldf.T.loc['12-24']" + "plot4 = sim_ldf.T.loc[\"12-24\"]" ] }, { @@ -87,27 +85,41 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot the Data\n", - "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(ncols=2, nrows=2, figsize=(10,10))\n", + "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(ncols=2, nrows=2, figsize=(10, 10))\n", "\n", "# Plot 1\n", - "plot1.plot(ax=ax00, title='Raw Data', xlabel='Development', ylabel='Incurred (Millions)')\n", + "plot1.plot(\n", + " ax=ax00, title=\"Raw Data\", xlabel=\"Development\", ylabel=\"Incurred (Millions)\"\n", + ")\n", "\n", "# Plot 2\n", - "plot2.plot(ax=ax01, title='Mean Simulation (Millions)', xlabel='Development')\n", + "plot2.plot(ax=ax01, title=\"Mean Simulation (Millions)\", xlabel=\"Development\")\n", "\n", "# Plot 3\n", - "plot3a.plot(legend=False, color='lightgray', ax=ax10, \n", - " title='Simulated LDF', xlabel='Development', ylabel='LDF')\n", + "plot3a.plot(\n", + " legend=False,\n", + " color=\"lightgray\",\n", + " ax=ax10,\n", + " title=\"Simulated LDF\",\n", + " xlabel=\"Development\",\n", + " ylabel=\"LDF\",\n", + ")\n", "plot3b.plot(legend=False, ax=ax10, grid=True)\n", "\n", "# Plot 4\n", "plot4.plot(\n", - " kind='hist', bins=50, alpha=0.5, ax=ax11,\n", - " title='Age 12-24 LDF Distribution', xlabel='LDF');" + " kind=\"hist\",\n", + " bins=50,\n", + " alpha=0.5,\n", + " ax=ax11,\n", + " title=\"Age 12-24 LDF Distribution\",\n", + " xlabel=\"LDF\",\n", + ");" ] }, { diff --git a/docs/gallery/plot_bootstrap_comparison.ipynb b/docs/gallery/plot_bootstrap_comparison.ipynb index 054accda3..49d967b85 100644 --- a/docs/gallery/plot_bootstrap_comparison.ipynb +++ b/docs/gallery/plot_bootstrap_comparison.ipynb @@ -42,23 +42,29 @@ "outputs": [], "source": [ "# Load triangle\n", - "triangle = cl.load_sample('genins')\n", + "triangle = cl.load_sample(\"genins\")\n", "\n", "# Use bootstrap sampler to get resampled triangles\n", - "s1 = cl.BootstrapODPSample(\n", - " n_sims=5000, random_state=42).fit(triangle).resampled_triangles_\n", + "s1 = (\n", + " cl\n", + " .BootstrapODPSample(n_sims=5000, random_state=42)\n", + " .fit(triangle)\n", + " .resampled_triangles_\n", + ")\n", "\n", - "## Alternatively use fit_transform() to access resampled triangles dropping\n", + "# Alternatively use fit_transform() to access resampled triangles dropping\n", "# outlier link-ratios from resampler\n", "s2 = cl.BootstrapODPSample(\n", - " drop_high=[True] * 5+ [False] * 4, \n", + " drop_high=[True] * 5 + [False] * 4,\n", " drop_low=[True] * 5 + [False] * 4,\n", - " n_sims=5000, random_state=42).fit_transform(triangle)\n", + " n_sims=5000,\n", + " random_state=42,\n", + ").fit_transform(triangle)\n", "\n", "# Summarize results of first model\n", - "results = cl.Chainladder().fit(s1).ibnr_.sum('origin').rename('columns', ['Original'])\n", + "results = cl.Chainladder().fit(s1).ibnr_.sum(\"origin\").rename(\"columns\", [\"Original\"])\n", "# Add another column to triangle with second set of results.\n", - "results['Dropped'] = cl.Chainladder().fit(s2).ibnr_.sum('origin')" + "results[\"Dropped\"] = cl.Chainladder().fit(s2).ibnr_.sum(\"origin\")" ] }, { @@ -88,13 +94,18 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "# Plot both IBNR distributions\n", "ax = results.to_frame().plot(\n", - " kind='hist', bins=50, alpha=0.5, \n", - " grid=True, xlabel='Ultimate',\n", - " title='Reserve Variability')" + " kind=\"hist\",\n", + " bins=50,\n", + " alpha=0.5,\n", + " grid=True,\n", + " xlabel=\"Ultimate\",\n", + " title=\"Reserve Variability\",\n", + ")" ] } ], diff --git a/docs/gallery/plot_capecod.ipynb b/docs/gallery/plot_capecod.ipynb index 2d270dc47..8a90aaaf1 100644 --- a/docs/gallery/plot_capecod.ipynb +++ b/docs/gallery/plot_capecod.ipynb @@ -43,30 +43,39 @@ "outputs": [], "source": [ "# Grab data\n", - "ppauto_loss = cl.load_sample('clrd').groupby('LOB').sum().loc['ppauto', 'CumPaidLoss']\n", - "ppauto_prem = cl.load_sample('clrd').groupby('LOB').sum() \\\n", - " .loc['ppauto']['EarnedPremDIR'].latest_diagonal\n", + "ppauto_loss = cl.load_sample(\"clrd\").groupby(\"LOB\").sum().loc[\"ppauto\", \"CumPaidLoss\"]\n", + "ppauto_prem = (\n", + " cl\n", + " .load_sample(\"clrd\")\n", + " .groupby(\"LOB\")\n", + " .sum()\n", + " .loc[\"ppauto\"][\"EarnedPremDIR\"]\n", + " .latest_diagonal\n", + ")\n", + "\n", "\n", "def get_apriori(decay, trend):\n", - " \"\"\" Function to grab apriori array from cape cod method \"\"\"\n", + " \"\"\"Function to grab apriori array from cape cod method\"\"\"\n", " cc = cl.CapeCod(decay=decay, trend=trend)\n", " cc.fit(ppauto_loss, sample_weight=ppauto_prem)\n", " return cc.detrended_apriori_.to_frame()\n", "\n", + "\n", "def get_plot_data(trend):\n", - " \"\"\" Function to grab plot data \"\"\"\n", + " \"\"\"Function to grab plot data\"\"\"\n", " # Initial apriori DataFrame\n", - " detrended_aprioris = get_apriori(0,trend)\n", - " detrended_aprioris.columns=['decay: 0%']\n", + " detrended_aprioris = get_apriori(0, trend)\n", + " detrended_aprioris.columns = [\"decay: 0%\"]\n", "\n", " # Add columns to apriori DataFrame\n", " for item in [25, 50, 75, 100]:\n", - " detrended_aprioris[f'decay: {item}%'] = get_apriori(item/100, trend)\n", + " detrended_aprioris[f\"decay: {item}%\"] = get_apriori(item / 100, trend)\n", " return detrended_aprioris\n", "\n", + "\n", "# Plot Data\n", "plot1 = get_plot_data(-0.05)\n", - "plot2 = get_plot_data(-.025)\n", + "plot2 = get_plot_data(-0.025)\n", "plot3 = get_plot_data(0)\n", "plot4 = get_plot_data(0.025)" ] @@ -94,16 +103,18 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(\n", - " ncols=2, nrows=2, sharex=True, figsize=(10,10))\n", + " ncols=2, nrows=2, sharex=True, figsize=(10, 10)\n", + ")\n", "fig.suptitle(\"Private Passenger Auto Cape Cod Detrended Aprioris\")\n", - "plot1.plot(ax=ax00, title='Trend: -5.0%')\n", - "plot2.plot(ax=ax01, title='Trend: -2.5%')\n", - "plot3.plot(ax=ax10, title='Trend: 0.0%')\n", - "plot4.plot(ax=ax11, title='Trend: 2.5%');" + "plot1.plot(ax=ax00, title=\"Trend: -5.0%\")\n", + "plot2.plot(ax=ax01, title=\"Trend: -2.5%\")\n", + "plot3.plot(ax=ax10, title=\"Trend: 0.0%\")\n", + "plot4.plot(ax=ax11, title=\"Trend: 2.5%\");" ] }, { diff --git a/docs/gallery/plot_capecod_onlevel.ipynb b/docs/gallery/plot_capecod_onlevel.ipynb index 2d3912953..d21eea146 100644 --- a/docs/gallery/plot_capecod_onlevel.ipynb +++ b/docs/gallery/plot_capecod_onlevel.ipynb @@ -44,54 +44,76 @@ }, "outputs": [], "source": [ - "\n", "# Grab a triangle\n", - "xyz = cl.load_sample('xyz')\n", + "xyz = cl.load_sample(\"xyz\")\n", "\n", "# Premium on-leveling factors\n", "rate_history = pd.DataFrame({\n", - " 'date': ['1/1/1999', '1/1/2000', '1/1/2001', '1/1/2002', '1/1/2003',\n", - " '1/1/2004', '1/1/2005', '1/1/2006', '1/1/2007', '1/1/2008'],\n", - " 'rate_change': [.02, .02, .02, .02, .05, .075, .15, .1, -.2, -.2]\n", + " \"date\": [\n", + " \"1/1/1999\",\n", + " \"1/1/2000\",\n", + " \"1/1/2001\",\n", + " \"1/1/2002\",\n", + " \"1/1/2003\",\n", + " \"1/1/2004\",\n", + " \"1/1/2005\",\n", + " \"1/1/2006\",\n", + " \"1/1/2007\",\n", + " \"1/1/2008\",\n", + " ],\n", + " \"rate_change\": [0.02, 0.02, 0.02, 0.02, 0.05, 0.075, 0.15, 0.1, -0.2, -0.2],\n", "})\n", "\n", "# Loss on-leveling factors\n", "tort_reform = pd.DataFrame({\n", - " 'date': ['1/1/2006', '1/1/2007'],\n", - " 'rate_change': [-0.1067, -.25]\n", + " \"date\": [\"1/1/2006\", \"1/1/2007\"],\n", + " \"rate_change\": [-0.1067, -0.25],\n", "})\n", "\n", "# In addition to development, include onlevel estimator in pipeline for loss\n", - "pipe = cl.Pipeline(steps=[\n", - " ('olf', cl.ParallelogramOLF(tort_reform, change_col='rate_change', date_col='date', vertical_line=True)),\n", - " ('dev', cl.Development(n_periods=2)),\n", - " ('model', cl.CapeCod(trend=0.034))\n", - "])\n", + "pipe = cl.Pipeline(\n", + " steps=[\n", + " (\n", + " \"olf\",\n", + " cl.ParallelogramOLF(\n", + " tort_reform,\n", + " change_col=\"rate_change\",\n", + " date_col=\"date\",\n", + " vertical_line=True,\n", + " ),\n", + " ),\n", + " (\"dev\", cl.Development(n_periods=2)),\n", + " (\"model\", cl.CapeCod(trend=0.034)),\n", + " ]\n", + ")\n", "\n", "# Define X\n", - "X = cl.load_sample('xyz')['Incurred']\n", + "X = cl.load_sample(\"xyz\")[\"Incurred\"]\n", "\n", "# Separately apply on-level factors for premium\n", "sample_weight = cl.ParallelogramOLF(\n", - " rate_history, change_col='rate_change', date_col='date',\n", - " vertical_line=True).fit_transform(xyz['Premium'].latest_diagonal)\n", + " rate_history, change_col=\"rate_change\", date_col=\"date\", vertical_line=True\n", + ").fit_transform(xyz[\"Premium\"].latest_diagonal)\n", "\n", "# Fit Cod Estimator\n", - "pipe.fit(X, sample_weight=sample_weight).named_steps.model.ultimate_\n", + "pipe.fit(X, sample_weight=sample_weight)\n", "\n", "# Create a Cape Cod pipeline without onleveling\n", - "pipe2 = cl.Pipeline(steps=[\n", - " ('dev', cl.Development(n_periods=2)),\n", - " ('model', cl.CapeCod(trend=0.034))\n", - "])\n", + "pipe2 = cl.Pipeline(\n", + " steps=[(\"dev\", cl.Development(n_periods=2)), (\"model\", cl.CapeCod(trend=0.034))]\n", + ")\n", "\n", "# Finally fit Cod Estimator without on-leveling\n", - "pipe2.fit(X, sample_weight=xyz['Premium'].latest_diagonal).named_steps.model.ultimate_\n", + "pipe2.fit(X, sample_weight=xyz[\"Premium\"].latest_diagonal)\n", "\n", "# Plot results\n", - "results = cl.concat((\n", - " pipe.named_steps.model.ultimate_.rename('columns', ['With On-level']),\n", - " pipe2.named_steps.model.ultimate_.rename('columns', ['Without On-level'])), 1).T" + "results = cl.concat(\n", + " (\n", + " pipe.named_steps.model.ultimate_.rename(\"columns\", [\"With On-level\"]),\n", + " pipe2.named_steps.model.ultimate_.rename(\"columns\", [\"Without On-level\"]),\n", + " ),\n", + " 1,\n", + ").T" ] }, { @@ -121,12 +143,13 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "ax = results.plot(\n", - " kind='bar', title='Cape Cod sensitivity to on-leveling', \n", - " subplots=True, legend=False);" + " kind=\"bar\", title=\"Cape Cod sensitivity to on-leveling\", subplots=True, legend=False\n", + ");" ] }, { diff --git a/docs/gallery/plot_clarkldf_resid.ipynb b/docs/gallery/plot_clarkldf_resid.ipynb index 19a154531..13e2e061b 100644 --- a/docs/gallery/plot_clarkldf_resid.ipynb +++ b/docs/gallery/plot_clarkldf_resid.ipynb @@ -42,20 +42,21 @@ "outputs": [], "source": [ "# Fit the basic model\n", - "genins = cl.load_sample('genins')\n", + "genins = cl.load_sample(\"genins\")\n", "genins = cl.ClarkLDF().fit(genins)\n", "\n", "# Grab Normalized Residuals as a DataFrame\n", "norm_resid = genins.norm_resid_.melt(\n", - " var_name='Development Age',\n", - " value_name='Normalized Residual').dropna()\n", + " var_name=\"Development Age\", value_name=\"Normalized Residual\"\n", + ").dropna()\n", "\n", "# Grab Fitted Incremental values as a DataFrame\n", "incremental_fits = genins.incremental_fits_.melt(\n", - " var_name='Development Age',\n", - " value_name='Expected Incremental Loss').dropna()\n", + " var_name=\"Development Age\", value_name=\"Expected Incremental Loss\"\n", + ").dropna()\n", "incremental_fits = incremental_fits.merge(\n", - " norm_resid, how='inner', left_index=True, right_index=True)\n" + " norm_resid, how=\"inner\", left_index=True, right_index=True\n", + ")" ] }, { @@ -85,20 +86,31 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot the residuals vs Age and vs Expected Incrementals\n", - "fig, ((ax0, ax1)) = plt.subplots(ncols=2, figsize=(10,5))\n", + "fig, ((ax0, ax1)) = plt.subplots(ncols=2, figsize=(10, 5))\n", "\n", "# Left plot\n", "norm_resid.plot(\n", - " x='Development Age', y='Normalized Residual',\n", - " kind='scatter', grid=True, ylim=(-4, 4), ax=ax0)\n", + " x=\"Development Age\",\n", + " y=\"Normalized Residual\",\n", + " kind=\"scatter\",\n", + " grid=True,\n", + " ylim=(-4, 4),\n", + " ax=ax0,\n", + ")\n", "# Right plot\n", "incremental_fits.plot(\n", - " x='Expected Incremental Loss', y='Normalized Residual',\n", - " kind='scatter', grid=True, ylim=(-4, 4), ax=ax1)\n", + " x=\"Expected Incremental Loss\",\n", + " y=\"Normalized Residual\",\n", + " kind=\"scatter\",\n", + " grid=True,\n", + " ylim=(-4, 4),\n", + " ax=ax1,\n", + ")\n", "fig.suptitle(\"Clark LDF Normalized Residual Plots\");" ] } diff --git a/docs/gallery/plot_development_periods.ipynb b/docs/gallery/plot_development_periods.ipynb index 91748fbe3..f2ae0c41b 100644 --- a/docs/gallery/plot_development_periods.ipynb +++ b/docs/gallery/plot_development_periods.ipynb @@ -42,12 +42,10 @@ }, "outputs": [], "source": [ - "tri = cl.load_sample('abc')\n", + "tri = cl.load_sample(\"abc\")\n", "\n", "# Set up Pipeline\n", - "pipe = cl.Pipeline(steps=[\n", - " ('dev',cl.Development()),\n", - " ('chainladder',cl.Chainladder())])\n", + "pipe = cl.Pipeline(steps=[(\"dev\", cl.Development()), (\"chainladder\", cl.Chainladder())])\n", "\n", "# Develop scoring function that returns an Ultimate/Incurred Ratio\n", "\n", @@ -55,16 +53,19 @@ "grid = cl.GridSearch(\n", " estimator=pipe,\n", " param_grid=dict(\n", - " dev__n_periods=[item for item in range(2,11)],\n", - " dev__average=['simple', 'volume', 'regression']),\n", + " dev__n_periods=[item for item in range(2, 11)],\n", + " dev__average=[\"simple\", \"volume\", \"regression\"],\n", + " ),\n", " scoring=lambda x: (\n", - " x.named_steps.chainladder.ultimate_.sum() /\n", - " tri.latest_diagonal.sum()))\n", + " x.named_steps.chainladder.ultimate_.sum() / tri.latest_diagonal.sum()\n", + " ),\n", + ")\n", "grid.fit(tri)\n", "\n", "# Plot data\n", - "results = pd.pivot_table(grid.results_, index='dev__n_periods',\n", - " columns='dev__average', values='score')" + "results = pd.pivot_table(\n", + " grid.results_, index=\"dev__n_periods\", columns=\"dev__average\", values=\"score\"\n", + ")" ] }, { @@ -95,6 +96,7 @@ "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", + "\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "fig, ax = plt.subplots()\n", @@ -105,8 +107,9 @@ "ax.set_xticklabels(results.index)\n", "for i in range(len(results.index)):\n", " for j in range(len(results.columns)):\n", - " text = ax.text(i, j, results.round(2).values[i, j],\n", - " ha=\"center\", va=\"center\", color=\"w\")\n", + " text = ax.text(\n", + " i, j, results.round(2).values[i, j], ha=\"center\", va=\"center\", color=\"w\"\n", + " )\n", "ax.set_title(\"Ultimate to Incurred Ratio\")\n", "fig.tight_layout()\n", "plt.show()" diff --git a/docs/gallery/plot_elrf_resid.ipynb b/docs/gallery/plot_elrf_resid.ipynb index a2304ef14..0a014a00d 100644 --- a/docs/gallery/plot_elrf_resid.ipynb +++ b/docs/gallery/plot_elrf_resid.ipynb @@ -58,19 +58,24 @@ } ], "source": [ - "raa = cl.load_sample('raa')\n", + "raa = cl.load_sample(\"raa\")\n", "model = cl.Development().fit(raa)\n", "\n", "plot1a = model.std_residuals_.T\n", - "plot1b = model.std_residuals_.mean('origin').T\n", + "plot1b = model.std_residuals_.mean(\"origin\").T\n", "plot2a = model.std_residuals_\n", - "plot2b = model.std_residuals_.mean('development')\n", + "plot2b = model.std_residuals_.mean(\"development\")\n", "plot3a = model.std_residuals_.dev_to_val().T\n", - "plot3b = model.std_residuals_.dev_to_val().mean('origin').T\n", - "plot4 = pd.concat((\n", - " (raa[raa.valuation < raa.valuation_date] * \n", - " model.ldf_.values).unstack().rename('Fitted Values'),\n", - " model.std_residuals_.unstack().rename('Residual')), axis=1).dropna()" + "plot3b = model.std_residuals_.dev_to_val().mean(\"origin\").T\n", + "plot4 = pd.concat(\n", + " (\n", + " (raa[raa.valuation < raa.valuation_date] * model.ldf_.values)\n", + " .unstack()\n", + " .rename(\"Fitted Values\"),\n", + " model.std_residuals_.unstack().rename(\"Residual\"),\n", + " ),\n", + " axis=1,\n", + ").dropna()" ] }, { @@ -100,28 +105,45 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", - "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(ncols=2, nrows=2, figsize=(13,10))\n", - "fig.suptitle(\"Barnett Zehnwirth\\nStandardized residuals of the Extended Link Ratio Family (ELRF)\\n(Fig 2.6)\");\n", + "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(ncols=2, nrows=2, figsize=(13, 10))\n", + "fig.suptitle(\n", + " \"Barnett Zehnwirth\\nStandardized residuals of the Extended Link Ratio Family (ELRF)\\n(Fig 2.6)\"\n", + ")\n", "\n", "\n", "plot1a.plot(\n", - " style='.', color='gray', legend=False, ax=ax00,\n", - " xlabel='Development Month', ylabel='Weighted Standardized Residuals')\n", - "plot1b.plot(\n", - " color='red', legend=False, ax=ax00)\n", - "plot2a.plot(\n", - " style='.', color='gray', legend=False, ax=ax01, xlabel='Origin Period')\n", - "plot2b.plot(\n", - " color='red', legend=False, ax=ax01)\n", + " style=\".\",\n", + " color=\"gray\",\n", + " legend=False,\n", + " ax=ax00,\n", + " xlabel=\"Development Month\",\n", + " ylabel=\"Weighted Standardized Residuals\",\n", + ")\n", + "plot1b.plot(color=\"red\", legend=False, ax=ax00)\n", + "plot2a.plot(style=\".\", color=\"gray\", legend=False, ax=ax01, xlabel=\"Origin Period\")\n", + "plot2b.plot(color=\"red\", legend=False, ax=ax01)\n", "plot3a.plot(\n", - " style='.', color='gray', legend=False, ax=ax10,\n", - " xlabel='Valuation Date', ylabel='Weighted Standardized Residuals')\n", - "plot3b.plot(color='red', legend=False, grid=True, ax=ax10)\n", - "plot4.plot(kind='scatter', marker='o', color='gray', \n", - " x='Fitted Values', y='Residual', ax=ax11, sharey=True);\n" + " style=\".\",\n", + " color=\"gray\",\n", + " legend=False,\n", + " ax=ax10,\n", + " xlabel=\"Valuation Date\",\n", + " ylabel=\"Weighted Standardized Residuals\",\n", + ")\n", + "plot3b.plot(color=\"red\", legend=False, grid=True, ax=ax10)\n", + "plot4.plot(\n", + " kind=\"scatter\",\n", + " marker=\"o\",\n", + " color=\"gray\",\n", + " x=\"Fitted Values\",\n", + " y=\"Residual\",\n", + " ax=ax11,\n", + " sharey=True,\n", + ");" ] } ], diff --git a/docs/gallery/plot_exposure_triangle.ipynb b/docs/gallery/plot_exposure_triangle.ipynb index c9753914d..22e16b8fb 100644 --- a/docs/gallery/plot_exposure_triangle.ipynb +++ b/docs/gallery/plot_exposure_triangle.ipynb @@ -134,12 +134,13 @@ ], "source": [ "# Raw premium data in pandas\n", - "premium_df = pd.DataFrame(\n", - " {'AccYear':[item for item in range(1977, 1988)],\n", - " 'premium': [3000000]*11})\n", + "premium_df = pd.DataFrame({\n", + " \"AccYear\": [item for item in range(1977, 1988)],\n", + " \"premium\": [3000000] * 11,\n", + "})\n", "\n", "# Create a premium 'triangle' with no development\n", - "premium = cl.Triangle(premium_df, origin='AccYear', columns='premium')\n", + "premium = cl.Triangle(premium_df, origin=\"AccYear\", columns=\"premium\")\n", "premium" ] }, @@ -150,7 +151,7 @@ "outputs": [], "source": [ "# Create some loss triangle\n", - "loss = cl.load_sample('abc')\n", + "loss = cl.load_sample(\"abc\")\n", "ultimate = cl.Chainladder().fit(loss).ultimate_\n", "\n", "loss_ratios = (ultimate / premium).to_frame()" @@ -183,12 +184,13 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "fig, ax = plt.subplots()\n", "plt.stem(loss_ratios.index.astype(str), loss_ratios.iloc[:, 0])\n", - "ax.grid(axis='y')\n", + "ax.grid(axis=\"y\")\n", "for spine in ax.spines:\n", " ax.spines[spine].set_visible(False)\n", "plt.show();" diff --git a/docs/gallery/plot_extrap_period.ipynb b/docs/gallery/plot_extrap_period.ipynb index 90f61739f..1fcd2eeb5 100644 --- a/docs/gallery/plot_extrap_period.ipynb +++ b/docs/gallery/plot_extrap_period.ipynb @@ -43,23 +43,25 @@ }, "outputs": [], "source": [ - "tri = cl.load_sample('clrd').groupby('LOB').sum().loc['medmal', 'CumPaidLoss']\n", + "tri = cl.load_sample(\"clrd\").groupby(\"LOB\").sum().loc[\"medmal\", \"CumPaidLoss\"]\n", + "\n", "\n", "# Create a function to grab the scalar tail value.\n", "def scoring(model):\n", - " \"\"\" Scoring functions must return a scalar \"\"\"\n", + " \"\"\"Scoring functions must return a scalar\"\"\"\n", " return model.tail_.iloc[0, 0]\n", "\n", + "\n", "# Create a grid of scenarios\n", "param_grid = dict(\n", - " extrap_periods=list(range(1, 100, 6)),\n", - " curve=['inverse_power', 'exponential'])\n", + " extrap_periods=list(range(1, 100, 6)), curve=[\"inverse_power\", \"exponential\"]\n", + ")\n", "\n", "# Fit Grid\n", "model = cl.GridSearch(cl.TailCurve(), param_grid=param_grid, scoring=scoring).fit(tri)\n", "\n", "# Plot results\n", - "results = model.results_.pivot(columns='curve', index='extrap_periods', values='score')" + "results = model.results_.pivot(columns=\"curve\", index=\"extrap_periods\", values=\"score\")" ] }, { @@ -89,12 +91,15 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "ax = results.plot(\n", - " ylim=(1,None), ylabel='Tail Factor',\n", - " title='Curve Fit Sensitivity to Extrapolation Period');" + " ylim=(1, None),\n", + " ylabel=\"Tail Factor\",\n", + " title=\"Curve Fit Sensitivity to Extrapolation Period\",\n", + ");" ] } ], diff --git a/docs/gallery/plot_loss_development.ipynb b/docs/gallery/plot_loss_development.ipynb index 3ce1a7b9a..4c81a651a 100644 --- a/docs/gallery/plot_loss_development.ipynb +++ b/docs/gallery/plot_loss_development.ipynb @@ -18,7 +18,8 @@ "import chainladder as cl\n", "import pandas as pd\n", "import warnings\n", - "warnings.filterwarnings('ignore', category=UserWarning, module='chainladder.core.base')" + "\n", + "warnings.filterwarnings(\"ignore\", category=UserWarning, module=\"chainladder.core.base\")" ] }, { @@ -39,11 +40,11 @@ "outputs": [], "source": [ "# Load sample data\n", - "quarterly = cl.load_sample('quarterly')['incurred']\n", + "quarterly = cl.load_sample(\"quarterly\")[\"incurred\"]\n", "\n", "quarterly_dev = cl.Pipeline([\n", " (\"dev\", cl.Development()),\n", - " (\"tail\", cl.TailCurve(projection_period=0)) # neglect tail projection\n", + " (\"tail\", cl.TailCurve(projection_period=0)), # neglect tail projection\n", "]).fit_transform(quarterly)\n", "\n", "# Fit Chainladder estimator\n", @@ -55,8 +56,8 @@ "\n", "# Unify results in a single DataFrame\n", "expected.index = emergence.index\n", - "expected.columns = ['Expected']\n", - "result = pd.concat([emergence, expected], axis=1, keys=['Actual', 'Expected'])" + "expected.columns = [\"Expected\"]\n", + "result = pd.concat([emergence, expected], axis=1, keys=[\"Actual\", \"Expected\"])" ] }, { @@ -87,19 +88,20 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", - "ax = result['Actual'].plot(\n", - " title='Emergence Pattern',\n", - " xlabel='Development', ylabel='% of Ultimate');\n", + "ax = result[\"Actual\"].plot(\n", + " title=\"Emergence Pattern\", xlabel=\"Development\", ylabel=\"% of Ultimate\"\n", + ")\n", "# Plot the average line with specific styling\n", - "ax = result['Expected'].plot(\n", + "ax = result[\"Expected\"].plot(\n", " ax=ax,\n", - " linewidth=3, # Thicker line\n", - " color='black', # Different color\n", - " linestyle='--', # Dashed line\n", - " alpha=0.7 # Slightly transparent\n", - " )\n" + " linewidth=3, # Thicker line\n", + " color=\"black\", # Different color\n", + " linestyle=\"--\", # Dashed line\n", + " alpha=0.7, # Slightly transparent\n", + ")" ] } ], diff --git a/docs/gallery/plot_mack.ipynb b/docs/gallery/plot_mack.ipynb index de1f6792e..cbb0f9467 100644 --- a/docs/gallery/plot_mack.ipynb +++ b/docs/gallery/plot_mack.ipynb @@ -163,12 +163,12 @@ ], "source": [ "# Load the data\n", - "data = cl.load_sample('raa')\n", + "data = cl.load_sample(\"raa\")\n", "\n", "# Compute Mack Chainladder ultimates and Std Err using 'mack' interpolation\n", - "# This recreates the figures from page 130 of Mack (1994) \n", + "# This recreates the figures from page 130 of Mack (1994)\n", "mack = cl.MackChainladder()\n", - "dev = cl.Development(sigma_interpolation = 'mack')\n", + "dev = cl.Development(sigma_interpolation=\"mack\")\n", "mack.fit(dev.fit_transform(data))\n", "\n", "plot_data = mack.summary_.to_frame(origin_as_datetime=False)\n", @@ -202,15 +202,23 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", - "ax = plot_data[['Latest', 'IBNR']].plot(\n", - " kind='bar', stacked=True, ylim=(0, None), grid=True,\n", - " yerr=pd.DataFrame({'latest': plot_data['Mack Std Err']*0,\n", - " 'IBNR': plot_data['Mack Std Err']}),\n", - " title='Mack Chainladder Ultimate',\n", - " xlabel='Accident Year', ylabel='Loss');" + "ax = plot_data[[\"Latest\", \"IBNR\"]].plot(\n", + " kind=\"bar\",\n", + " stacked=True,\n", + " ylim=(0, None),\n", + " grid=True,\n", + " yerr=pd.DataFrame({\n", + " \"latest\": plot_data[\"Mack Std Err\"] * 0,\n", + " \"IBNR\": plot_data[\"Mack Std Err\"],\n", + " }),\n", + " title=\"Mack Chainladder Ultimate\",\n", + " xlabel=\"Accident Year\",\n", + " ylabel=\"Loss\",\n", + ");" ] }, { diff --git a/docs/gallery/plot_munich.ipynb b/docs/gallery/plot_munich.ipynb index 796ce9679..6aa07f976 100644 --- a/docs/gallery/plot_munich.ipynb +++ b/docs/gallery/plot_munich.ipynb @@ -39,23 +39,32 @@ "outputs": [], "source": [ "# Load data\n", - "mcl = cl.load_sample('mcl')\n", + "mcl = cl.load_sample(\"mcl\")\n", "\n", "# Traditional Chainladder\n", "cl_traditional = cl.Chainladder().fit(mcl).ultimate_\n", "\n", "# Munich Adjustment\n", - "dev_munich = cl.MunichAdjustment(paid_to_incurred=('paid', 'incurred')).fit_transform(mcl)\n", + "dev_munich = cl.MunichAdjustment(paid_to_incurred=(\"paid\", \"incurred\")).fit_transform(\n", + " mcl\n", + ")\n", "cl_munich = cl.Chainladder().fit(dev_munich).ultimate_\n", "\n", "plot1_data = cl_munich.to_frame().T.rename(\n", - " {'incurred':'Ultimate Incurred', 'paid': 'Ultimate Paid'}, axis=1)\n", + " {\"incurred\": \"Ultimate Incurred\", \"paid\": \"Ultimate Paid\"}, axis=1\n", + ")\n", "\n", "plot2_data = pd.concat(\n", - " ((cl_munich['paid'] / cl_munich['incurred']).to_frame(origin_as_datetime=False).rename(\n", - " columns={'2261': 'Munich'}),\n", - " (cl_traditional['paid'] / cl_traditional['incurred']).to_frame(origin_as_datetime=False).rename(\n", - " columns={'2261': 'Traditional'})), axis=1)" + " (\n", + " (cl_munich[\"paid\"] / cl_munich[\"incurred\"])\n", + " .to_frame(origin_as_datetime=False)\n", + " .rename(columns={\"2261\": \"Munich\"}),\n", + " (cl_traditional[\"paid\"] / cl_traditional[\"incurred\"])\n", + " .to_frame(origin_as_datetime=False)\n", + " .rename(columns={\"2261\": \"Traditional\"}),\n", + " ),\n", + " axis=1,\n", + ")" ] }, { @@ -93,19 +102,20 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot data\n", - "fig, (ax0, ax1) = plt.subplots(ncols=2, sharex=True, figsize=(10,5))\n", - "plot_kw = dict(kind='bar', alpha=0.7)\n", + "fig, (ax0, ax1) = plt.subplots(ncols=2, sharex=True, figsize=(10, 5))\n", + "plot_kw = dict(kind=\"bar\", alpha=0.7)\n", "\n", - "plot1_data.plot(\n", - " title='Munich Chainladder', ax=ax0, **plot_kw).set(\n", - " ylabel='Ultimate', xlabel='Accident Year')\n", - "plot2_data.plot(\n", - " title='P/I Ratio Comparison', ax=ax1, ylim=(0,1.25), **plot_kw).set(\n", - " ylabel='Paid Ultimate / Incurred Ultimate', xlabel='Accident Year');" + "plot1_data.plot(title=\"Munich Chainladder\", ax=ax0, **plot_kw).set(\n", + " ylabel=\"Ultimate\", xlabel=\"Accident Year\"\n", + ")\n", + "plot2_data.plot(title=\"P/I Ratio Comparison\", ax=ax1, ylim=(0, 1.25), **plot_kw).set(\n", + " ylabel=\"Paid Ultimate / Incurred Ultimate\", xlabel=\"Accident Year\"\n", + ");" ] }, { diff --git a/docs/gallery/plot_munich_resid.ipynb b/docs/gallery/plot_munich_resid.ipynb index b9eb32fd2..b46f7a2b9 100644 --- a/docs/gallery/plot_munich_resid.ipynb +++ b/docs/gallery/plot_munich_resid.ipynb @@ -45,30 +45,38 @@ "outputs": [], "source": [ "# Fit Munich Model\n", - "mcl = cl.load_sample('mcl')\n", - "model = cl.MunichAdjustment([('paid', 'incurred')]).fit(mcl)\n", + "mcl = cl.load_sample(\"mcl\")\n", + "model = cl.MunichAdjustment([(\"paid\", \"incurred\")]).fit(mcl)\n", "\n", "# Paid lambda line\n", - "paid_lambda = pd.DataFrame(\n", - " {'(P/I)': np.linspace(-2,2,2),\n", - " 'P': np.linspace(-2,2,2)*model.lambda_.loc['paid']})\n", + "paid_lambda = pd.DataFrame({\n", + " \"(P/I)\": np.linspace(-2, 2, 2),\n", + " \"P\": np.linspace(-2, 2, 2) * model.lambda_.loc[\"paid\"],\n", + "})\n", "\n", "# Paid scatter\n", "paid_plot = pd.concat(\n", - " (model.resids_['paid'].melt(value_name='P')['P'],\n", - " model.q_resids_['paid'].melt(value_name='(P/I)')['(P/I)']),\n", - " axis=1)\n", + " (\n", + " model.resids_[\"paid\"].melt(value_name=\"P\")[\"P\"],\n", + " model.q_resids_[\"paid\"].melt(value_name=\"(P/I)\")[\"(P/I)\"],\n", + " ),\n", + " axis=1,\n", + ")\n", "\n", "# Incurred lambda line\n", - "inc_lambda = pd.DataFrame(\n", - " {'(I/P)': np.linspace(-2,2,2),\n", - " 'I': np.linspace(-2,2,2)*model.lambda_.loc['incurred']})\n", + "inc_lambda = pd.DataFrame({\n", + " \"(I/P)\": np.linspace(-2, 2, 2),\n", + " \"I\": np.linspace(-2, 2, 2) * model.lambda_.loc[\"incurred\"],\n", + "})\n", "\n", "# Incurred scatter\n", "incurred_plot = pd.concat(\n", - " (model.resids_['incurred'].melt(value_name='I')['I'],\n", - " model.q_resids_['incurred'].melt(value_name='(I/P)')['(I/P)']),\n", - " axis=1)" + " (\n", + " model.resids_[\"incurred\"].melt(value_name=\"I\")[\"I\"],\n", + " model.q_resids_[\"incurred\"].melt(value_name=\"(I/P)\")[\"(I/P)\"],\n", + " ),\n", + " axis=1,\n", + ")" ] }, { @@ -98,21 +106,28 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot Data\n", - "fig, ((ax0, ax1)) = plt.subplots(ncols=2, figsize=(10,5))\n", + "fig, ((ax0, ax1)) = plt.subplots(ncols=2, figsize=(10, 5))\n", "\n", - "paid_lambda.plot(x='(P/I)', y='P', legend=False, ax=ax0)\n", + "paid_lambda.plot(x=\"(P/I)\", y=\"P\", legend=False, ax=ax0)\n", "paid_plot.plot(\n", - " kind='scatter', y='P', x='(P/I)', ax=ax0,\n", - " xlim=(-2,2), ylim=(-2,2), title='Paid')\n", + " kind=\"scatter\", y=\"P\", x=\"(P/I)\", ax=ax0, xlim=(-2, 2), ylim=(-2, 2), title=\"Paid\"\n", + ")\n", "\n", - "inc_lambda.plot(x='(I/P)', y='I', ax=ax1, legend=False);\n", + "inc_lambda.plot(x=\"(I/P)\", y=\"I\", ax=ax1, legend=False)\n", "incurred_plot.plot(\n", - " kind='scatter', y='I', x='(I/P)', ax=ax1,\n", - " xlim=(-2,2), ylim=(-2,2), title='Incurred');\n", + " kind=\"scatter\",\n", + " y=\"I\",\n", + " x=\"(I/P)\",\n", + " ax=ax1,\n", + " xlim=(-2, 2),\n", + " ylim=(-2, 2),\n", + " title=\"Incurred\",\n", + ")\n", "fig.suptitle(\"Munich Chainladder Residual Correlations\");" ] } diff --git a/docs/gallery/plot_ptf_resid.ipynb b/docs/gallery/plot_ptf_resid.ipynb index 694547341..134fae759 100644 --- a/docs/gallery/plot_ptf_resid.ipynb +++ b/docs/gallery/plot_ptf_resid.ipynb @@ -52,9 +52,21 @@ }, "outputs": [], "source": [ - "abc = cl.load_sample('abc')\n", - "exposure = np.array([[2.2], [2.4], [2.2], [2.0], [1.9], [1.6], [1.6], [1.8], [2.2], [2.5], [2.6]])\n", - "model = cl.BarnettZehnwirth(formula='C(origin) + C(development)').fit(abc/exposure)\n", + "abc = cl.load_sample(\"abc\")\n", + "exposure = np.array([\n", + " [2.2],\n", + " [2.4],\n", + " [2.2],\n", + " [2.0],\n", + " [1.9],\n", + " [1.6],\n", + " [1.6],\n", + " [1.8],\n", + " [2.2],\n", + " [2.5],\n", + " [2.6],\n", + "])\n", + "model = cl.BarnettZehnwirth(formula=\"C(origin) + C(development)\").fit(abc / exposure)\n", "\n", "plot1a = model.std_residuals_.T\n", "plot1b = plot1a.T.mean()\n", @@ -63,11 +75,19 @@ "plot2b = plot2a.T.mean()\n", "\n", "plot3a = model.std_residuals_.dev_to_val().T\n", - "plot3b = model.std_residuals_.dev_to_val().mean('origin').T\n", + "plot3b = model.std_residuals_.dev_to_val().mean(\"origin\").T\n", "\n", - "plot4 = pd.concat((\n", - " model.triangle_ml_[model.triangle_ml_.valuation<=abc.valuation_date].log().unstack().rename('Fitted Values'),\n", - " model.std_residuals_.unstack().rename('Residual')), axis=1).dropna()" + "plot4 = pd.concat(\n", + " (\n", + " model\n", + " .triangle_ml_[model.triangle_ml_.valuation <= abc.valuation_date]\n", + " .log()\n", + " .unstack()\n", + " .rename(\"Fitted Values\"),\n", + " model.std_residuals_.unstack().rename(\"Residual\"),\n", + " ),\n", + " axis=1,\n", + ").dropna()" ] }, { @@ -97,26 +117,46 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", - "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(ncols=2, nrows=2, figsize=(14,10))\n", - "fig.suptitle(\"Barnett Zehnwirth\\nStandardized residuals of the statistical chainladder model\\n(Figure 23)\");\n", + "fig, ((ax00, ax01), (ax10, ax11)) = plt.subplots(ncols=2, nrows=2, figsize=(14, 10))\n", + "fig.suptitle(\n", + " \"Barnett Zehnwirth\\nStandardized residuals of the statistical chainladder model\\n(Figure 23)\"\n", + ")\n", "\n", "plot1a.plot(\n", - " style='.', color='gray', legend=False, ax=ax00,\n", - " xlabel='Development Month', ylabel='Weighted Standardized Residuals')\n", - "plot1b.plot(color='red', legend=False, ax=ax00)\n", + " style=\".\",\n", + " color=\"gray\",\n", + " legend=False,\n", + " ax=ax00,\n", + " xlabel=\"Development Month\",\n", + " ylabel=\"Weighted Standardized Residuals\",\n", + ")\n", + "plot1b.plot(color=\"red\", legend=False, ax=ax00)\n", "\n", - "plot2a.plot(style='.', color='gray', legend=False, ax=ax01, xlabel='Origin Period')\n", - "plot2b.plot(color='red', legend=False, ax=ax01,xlim=(6.5,17.5))\n", + "plot2a.plot(style=\".\", color=\"gray\", legend=False, ax=ax01, xlabel=\"Origin Period\")\n", + "plot2b.plot(color=\"red\", legend=False, ax=ax01, xlim=(6.5, 17.5))\n", "plot3a.plot(\n", - " style='.', color='gray', legend=False, ax=ax10,\n", - " xlabel='Valuation Date', ylabel='Weighted Standardized Residuals')\n", - "plot3b.plot(color='red', legend=False, ax=ax10)\n", + " style=\".\",\n", + " color=\"gray\",\n", + " legend=False,\n", + " ax=ax10,\n", + " xlabel=\"Valuation Date\",\n", + " ylabel=\"Weighted Standardized Residuals\",\n", + ")\n", + "plot3b.plot(color=\"red\", legend=False, ax=ax10)\n", "\n", - "plot4.plot(kind='scatter', marker='o', color='gray', \n", - " x='Fitted Values', y='Residual', ax=ax11, sharey=True);" + "plot4.plot(\n", + " kind=\"scatter\",\n", + " marker=\"o\",\n", + " color=\"gray\",\n", + " x=\"Fitted Values\",\n", + " y=\"Residual\",\n", + " ax=ax11,\n", + " sharey=True,\n", + ");" ] }, { diff --git a/docs/gallery/plot_stochastic_bornferg.ipynb b/docs/gallery/plot_stochastic_bornferg.ipynb index a8d2a9384..bdd7b8ba0 100644 --- a/docs/gallery/plot_stochastic_bornferg.ipynb +++ b/docs/gallery/plot_stochastic_bornferg.ipynb @@ -43,14 +43,12 @@ }, "outputs": [], "source": [ - "import chainladder as cl\n", - "\n", "# Simulation parameters\n", "random_state = 42\n", "n_sims = 1000\n", "\n", "# Get data\n", - "loss = cl.load_sample('genins')\n", + "loss = cl.load_sample(\"genins\")\n", "premium = loss.latest_diagonal * 0 + 8e6\n", "\n", "# Simulate loss triangles\n", @@ -66,7 +64,9 @@ "full_triangle = (model.full_triangle_ - model.X_ + loss) / premium\n", "\n", "# Limiting to the current year for plotting\n", - "current_year = full_triangle[full_triangle.origin==full_triangle.origin.max()].to_frame().T" + "current_year = (\n", + " full_triangle[full_triangle.origin == full_triangle.origin.max()].to_frame().T\n", + ")" ] }, { @@ -96,14 +96,19 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot the data\n", "ax = current_year.iloc[:-1, :300].plot(\n", - " legend=False, alpha=0.1, color='red', \n", - " xlabel='Development Age', ylabel='Loss Ratio',\n", - " title='Current Accident Year BornFerg Distribution');" + " legend=False,\n", + " alpha=0.1,\n", + " color=\"red\",\n", + " xlabel=\"Development Age\",\n", + " ylabel=\"Loss Ratio\",\n", + " title=\"Current Accident Year BornFerg Distribution\",\n", + ");" ] } ], diff --git a/docs/gallery/plot_triangle_from_pandas.ipynb b/docs/gallery/plot_triangle_from_pandas.ipynb index 59ce91da8..050771c28 100644 --- a/docs/gallery/plot_triangle_from_pandas.ipynb +++ b/docs/gallery/plot_triangle_from_pandas.ipynb @@ -20,7 +20,7 @@ "outputs": [], "source": [ "import chainladder as cl\n", - "import pandas as pd\n" + "import pandas as pd" ] }, { @@ -205,7 +205,9 @@ ], "source": [ "# Read in the data\n", - "data = pd.read_csv(r'https://raw.githubusercontent.com/casact/chainladder-python/master/chainladder/utils/data/clrd.csv')\n", + "data = pd.read_csv(\n", + " r\"https://raw.githubusercontent.com/casact/chainladder-python/master/chainladder/utils/data/clrd.csv\"\n", + ")\n", "\n", "# Output\n", "data.head()" @@ -277,10 +279,14 @@ "source": [ "# Create a triangle\n", "triangle = cl.Triangle(\n", - " data, origin='AccidentYear', development='DevelopmentYear',\n", - " index=['GRNAME'], columns=['IncurLoss','CumPaidLoss','EarnedPremDIR'])\n", + " data,\n", + " origin=\"AccidentYear\",\n", + " development=\"DevelopmentYear\",\n", + " index=[\"GRNAME\"],\n", + " columns=[\"IncurLoss\", \"CumPaidLoss\", \"EarnedPremDIR\"],\n", + ")\n", "\n", - "triangle\n" + "triangle" ] }, { @@ -461,7 +467,7 @@ } ], "source": [ - "triangle['CumPaidLoss'].sum()\n" + "triangle[\"CumPaidLoss\"].sum()" ] }, { @@ -491,14 +497,22 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot data\n", - "ax = triangle['CumPaidLoss'].sum().T.plot(\n", - " marker='.', grid=True,\n", - " title='CAS Loss Reserve Database: Workers Compensation',\n", - " xlabel='Development Period', ylabel='Cumulative Paid Loss');" + "ax = (\n", + " triangle[\"CumPaidLoss\"]\n", + " .sum()\n", + " .T.plot(\n", + " marker=\".\",\n", + " grid=True,\n", + " title=\"CAS Loss Reserve Database: Workers Compensation\",\n", + " xlabel=\"Development Period\",\n", + " ylabel=\"Cumulative Paid Loss\",\n", + " )\n", + ");" ] }, { diff --git a/docs/gallery/plot_value_at_risk.ipynb b/docs/gallery/plot_value_at_risk.ipynb index 772cfe648..cf8dcf01e 100644 --- a/docs/gallery/plot_value_at_risk.ipynb +++ b/docs/gallery/plot_value_at_risk.ipynb @@ -44,13 +44,13 @@ "outputs": [], "source": [ "# Load triangle\n", - "triangle = cl.load_sample('genins')\n", + "triangle = cl.load_sample(\"genins\")\n", "\n", "# Create 1000 bootstrap samples of the triangle\n", "resampled_triangles = cl.BootstrapODPSample(random_state=42).fit_transform(triangle)\n", "\n", "# Create 1000 IBNR estimates\n", - "sim_ibnr = cl.Chainladder().fit(resampled_triangles).ibnr_.sum('origin')\n", + "sim_ibnr = cl.Chainladder().fit(resampled_triangles).ibnr_.sum(\"origin\")\n", "\n", "# X - mu\n", "sim_ibnr = (sim_ibnr - sim_ibnr.mean()).to_frame().sort_values()" @@ -83,16 +83,17 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "# Plot data\n", "fig, ax = plt.subplots()\n", - "sim_ibnr.index = [item/1000 for item in range(1000)]\n", - "(sim_ibnr/1e6).loc[0.90:].plot(kind='area', alpha=0.5,\n", - " title='Bootstrap VaR (90% and above)', ax=ax).set(\n", - " xlabel='Percentile', xlim=(0.899, 1.0), ylabel='Value (Millions)');\n", - "ax.grid(axis='y')\n", + "sim_ibnr.index = [item / 1000 for item in range(1000)]\n", + "(sim_ibnr / 1e6).loc[0.90:].plot(\n", + " kind=\"area\", alpha=0.5, title=\"Bootstrap VaR (90% and above)\", ax=ax\n", + ").set(xlabel=\"Percentile\", xlim=(0.899, 1.0), ylabel=\"Value (Millions)\")\n", + "ax.grid(axis=\"y\")\n", "for spine in ax.spines:\n", " ax.spines[spine].set_visible(False)" ] diff --git a/docs/gallery/plot_voting_chainladder.ipynb b/docs/gallery/plot_voting_chainladder.ipynb index 1cfa74ba6..5a93bf9ca 100644 --- a/docs/gallery/plot_voting_chainladder.ipynb +++ b/docs/gallery/plot_voting_chainladder.ipynb @@ -20,7 +20,6 @@ "outputs": [], "source": [ "import chainladder as cl\n", - "import numpy as np\n", "import pandas as pd" ] }, @@ -44,20 +43,20 @@ "outputs": [], "source": [ "# Load the data\n", - "raa = cl.load_sample('raa')\n", + "raa = cl.load_sample(\"raa\")\n", "cl_ult = cl.Chainladder().fit(raa).ultimate_ # Chainladder Ultimate\n", "apriori = cl_ult * 0 + (float(cl_ult.sum()) / 10) # Mean Chainladder Ultimate\n", "\n", "# Load estimators to vote between\n", "bcl = cl.Chainladder()\n", "cc = cl.CapeCod()\n", - "estimators = [('bcl', bcl), ('cc', cc)]\n", + "estimators = [(\"bcl\", bcl), (\"cc\", cc)]\n", "\n", "# Fit VotingChainladder using CC after 1987 and a blend of BCL and CC otherwise\n", "vot = cl.VotingChainladder(\n", " estimators=estimators,\n", - " weights=lambda origin: (0, 1) if origin.year > 1987 else (0.5, 0.5)\n", - " )\n", + " weights=lambda origin: (0, 1) if origin.year > 1987 else (0.5, 0.5),\n", + ")\n", "vot.fit(raa, sample_weight=apriori)\n", "\n", "# Plotting\n", @@ -66,7 +65,7 @@ "vot_ibnr = vot.ibnr_.to_frame(origin_as_datetime=False)\n", "\n", "plot_ibnr = pd.concat([bcl_ibnr, vot_ibnr, cc_ibnr], axis=1)\n", - "plot_ibnr.columns = ['BCL', 'Voting', 'CC']" + "plot_ibnr.columns = [\"BCL\", \"Voting\", \"CC\"]" ] }, { @@ -96,14 +95,18 @@ ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.style.use('ggplot')\n", + "\n", + "plt.style.use(\"ggplot\")\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "\n", "ax = plot_ibnr.plot(\n", - " kind='bar', ylim=(0, None), \n", - " title='Voting Chainladder IBNR',\n", - " xlabel='Accident Year', ylabel='Loss');" + " kind=\"bar\",\n", + " ylim=(0, None),\n", + " title=\"Voting Chainladder IBNR\",\n", + " xlabel=\"Accident Year\",\n", + " ylabel=\"Loss\",\n", + ");" ] }, { diff --git a/pyproject.toml b/pyproject.toml index 1b6622a02..95edbfd31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -153,28 +153,6 @@ select = ["E2", "E4", "E7", "E9", "F", "B018", "UP034", "N802"] "docs/friedland/chapter_10.ipynb" = ["E731", "F841"] "docs/friedland/chapter_7_part_2.ipynb" = ["N802"] "docs/friedland/chapter_9.ipynb" = ["E731"] -"docs/gallery/plot_advanced_triangle.ipynb" = ["E225"] -"docs/gallery/plot_ave_analysis.ipynb" = ["E203", "E225"] -"docs/gallery/plot_benktander.ipynb" = ["E251"] -"docs/gallery/plot_bondy_sensitivity.ipynb" = ["E203", "E225", "E231"] -"docs/gallery/plot_bootstrap.ipynb" = ["E231", "F811"] -"docs/gallery/plot_bootstrap_comparison.ipynb" = ["E226", "E266"] -"docs/gallery/plot_capecod.ipynb" = ["E225", "E226", "E231"] -"docs/gallery/plot_capecod_onlevel.ipynb" = ["B018"] -"docs/gallery/plot_clarkldf_resid.ipynb" = ["E231"] -"docs/gallery/plot_development_periods.ipynb" = ["E231"] -"docs/gallery/plot_elrf_resid.ipynb" = ["E231", "E703"] -"docs/gallery/plot_exposure_triangle.ipynb" = ["E226", "E231"] -"docs/gallery/plot_extrap_period.ipynb" = ["E231"] -"docs/gallery/plot_loss_development.ipynb" = ["E261", "E703"] -"docs/gallery/plot_mack.ipynb" = ["E226", "E251"] -"docs/gallery/plot_munich.ipynb" = ["E231"] -"docs/gallery/plot_munich_resid.ipynb" = ["E226", "E231", "E703"] -"docs/gallery/plot_ptf_resid.ipynb" = ["E225", "E226", "E231", "E703"] -"docs/gallery/plot_stochastic_bornferg.ipynb" = ["E225", "E241", "F811"] -"docs/gallery/plot_triangle_from_pandas.ipynb" = ["E231"] -"docs/gallery/plot_value_at_risk.ipynb" = ["E226", "E703"] -"docs/gallery/plot_voting_chainladder.ipynb" = ["F401"] "docs/getting_started/tutorials/stochastic-tutorial.ipynb" = ["E231"] "docs/getting_started/tutorials/tail-tutorial.ipynb" = ["E722", "F401"] "docs/user_guide/adjustments.ipynb" = ["E226", "E231", "E251"]