From f9a23080176dbec6c4cbfc6cf6293179b0a853cd Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Sat, 16 Sep 2023 11:54:42 -0700 Subject: [PATCH 01/10] Fixed solution link at the top --- .../getting_started/online_sandbox/sandbox_workbook_blank.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb b/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb index 47febd44..f5121162 100644 --- a/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb +++ b/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb @@ -6,7 +6,7 @@ "metadata": {}, "source": [ "# Got Stuck?\n", - "Click here for the filled in workbook." + "Click [here](https://nbviewer.org/github/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb) for the filled in workbook. Have questions? Join the [discussion](https://github.com/casact/chainladder-python/discussions) on GitHub." ] }, { From f4cd881ea8b7db4e90062cad611707cad3723121 Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Sat, 16 Sep 2023 11:54:53 -0700 Subject: [PATCH 02/10] Fixed URL --- docs/getting_started/index.md | 7 +++++++ docs/getting_started/online_sandbox/sandbox_intro.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index f28b9198..8fa40d40 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -24,4 +24,11 @@ How to install chainladder. Our beginner tutorials. ::: +:::{grid-item-card} {octicon}`book;2.5em;sd-mr-1` User Guide +:link: user_guide/index +:link-type: doc + +A more comprehensive guide on the capabilities of chainladder. +::: + :::: diff --git a/docs/getting_started/online_sandbox/sandbox_intro.md b/docs/getting_started/online_sandbox/sandbox_intro.md index a31e441a..79897630 100644 --- a/docs/getting_started/online_sandbox/sandbox_intro.md +++ b/docs/getting_started/online_sandbox/sandbox_intro.md @@ -14,4 +14,4 @@ You can open the sandbox tutorial in one of two ways. You may be forced to use o - Open in [Binder](https://mybinder.org/v2/gh/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb) (slower, no sign up required) -Just in case you want a copy of the sandbox tutorial notebook, you can download it [here](https://github.com/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/demo-blank-concurrent.ipynb). +Just in case you want a copy of the sandbox tutorial notebook, you can download it [here](https://github.com/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb). From 6875654bb93e4783e8169ddffd8354baac1f87ee Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Sat, 16 Sep 2023 11:58:48 -0700 Subject: [PATCH 03/10] Links not working --- docs/getting_started/index.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index 8fa40d40..f28b9198 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -24,11 +24,4 @@ How to install chainladder. Our beginner tutorials. ::: -:::{grid-item-card} {octicon}`book;2.5em;sd-mr-1` User Guide -:link: user_guide/index -:link-type: doc - -A more comprehensive guide on the capabilities of chainladder. -::: - :::: From 26995be4492d44ee273be43c7b7e6a077bed6fa8 Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Sat, 16 Sep 2023 12:14:37 -0700 Subject: [PATCH 04/10] File paths --- docs/getting_started/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index f28b9198..b19433bb 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -1,10 +1,10 @@ ## {octicon}`rocket` Getting Started - -::::{grid} + +::::{grid} 1 2 3 4 :gutter: 1 1 1 2 :::{grid-item-card} {octicon}`chevron-right;2.5em;sd-mr-1` Try Online -:link: getting_started/sandbox_intro.md +:link: online_sandbox/sandbox_intro.md :link-type: doc Try chainladder online. From ac68e56250c1f676b89b486b95c9187e8931cb26 Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Sat, 16 Sep 2023 13:30:47 -0700 Subject: [PATCH 05/10] language = "en" since None is deprecated --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f7e71505..8b751dab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -66,7 +66,7 @@ html_title = "Reserving in Python" jupyter_cache = "" jupyter_execute_notebooks = "force" -language = None +language = "en" latex_engine = "pdflatex" myst_enable_extensions = ["colon_fence", "dollarmath", "linkify", "substitution"] myst_url_schemes = ["mailto", "http", "https"] From 4685511c7a279395afb126f114d0da45feb952dd Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Sat, 16 Sep 2023 13:31:16 -0700 Subject: [PATCH 06/10] Working links --- docs/getting_started/index.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index b19433bb..888e9927 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -1,24 +1,26 @@ ## {octicon}`rocket` Getting Started - + +We recommend that you try the sandbox tutorial before installing the package on your machine. There's also the more in-depth onboarding tutorial to give you a slightly more comprehensive view of what the package can do. + ::::{grid} 1 2 3 4 :gutter: 1 1 1 2 :::{grid-item-card} {octicon}`chevron-right;2.5em;sd-mr-1` Try Online -:link: online_sandbox/sandbox_intro.md +:link: online_sandbox/sandbox_intro :link-type: doc Try chainladder online. ::: :::{grid-item-card} {octicon}`desktop-download;2.5em;sd-mr-1` Installation -:link: install.md +:link: install :link-type: doc How to install chainladder. ::: :::{grid-item-card} {octicon}`beaker;2.5em;sd-mr-1` Tutorials -:link: tutorials/index.md +:link: tutorials/index :link-type: doc Our beginner tutorials. From 2d42f39a8aea13349a1c3b67f345cc14cf25f2d5 Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Tue, 19 Sep 2023 18:04:27 -0700 Subject: [PATCH 07/10] Added the sandbox tutorial to the toc --- docs/_toc.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/_toc.yml b/docs/_toc.yml index 76e9a19b..2db37224 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -9,6 +9,8 @@ parts: - file: getting_started/index.md sections: - file: getting_started/online_sandbox/sandbox_intro.md + sections: + - file: getting_started/online_sandbox/sandbox_workbook_blank - file: getting_started/install.md - file: getting_started/tutorials/index.md sections: From 20a546f6a33a51b61552121ab62fce50ed1bb59f Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Tue, 19 Sep 2023 18:04:35 -0700 Subject: [PATCH 08/10] Working binder link --- docs/getting_started/online_sandbox/sandbox_intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started/online_sandbox/sandbox_intro.md b/docs/getting_started/online_sandbox/sandbox_intro.md index 79897630..666b9104 100644 --- a/docs/getting_started/online_sandbox/sandbox_intro.md +++ b/docs/getting_started/online_sandbox/sandbox_intro.md @@ -12,6 +12,6 @@ You can open the sandbox tutorial in one of two ways. You may be forced to use o - Open in [Google Colab](https://githubtocolab.com/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb) (faster, but a free Google Account is required) -- Open in [Binder](https://mybinder.org/v2/gh/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb) (slower, no sign up required) +- Open in [Binder](https://mybinder.org/v2/gh/casact/chainladder-python/master?urlpath=tree/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb) (slower, no sign up required) Just in case you want a copy of the sandbox tutorial notebook, you can download it [here](https://github.com/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb). From a932f5b744a2b259794c869b26e505b1ec072293 Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Tue, 19 Sep 2023 18:04:44 -0700 Subject: [PATCH 09/10] Words --- .../online_sandbox/sandbox_workbook_blank.ipynb | 11 ++++++++--- .../online_sandbox/sandbox_workbook_filled.ipynb | 8 ++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb b/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb index f5121162..bb3b46a9 100644 --- a/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb +++ b/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb @@ -2,11 +2,16 @@ "cells": [ { "cell_type": "markdown", - "id": "ff5ff833-2b83-46c7-994f-12a19ef2a158", + "id": "0f0e5e3b-ac37-4865-8c51-ded927ea9b46", "metadata": {}, "source": [ - "# Got Stuck?\n", - "Click [here](https://nbviewer.org/github/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb) for the filled in workbook. Have questions? Join the [discussion](https://github.com/casact/chainladder-python/discussions) on GitHub." + "# Online Sandbox Tutorial\n", + "\n", + "Welcome! If you've come here to explore the capabilities of the `chainladder-python` package, you've landed in the perfect spot. This online sandbox tutorial is designed to provide you with a glimpse of the package's functionalities. \n", + "\n", + "We recommend setting aside about **one hour** to complete it.\n", + "\n", + "Got Stuck? Click [here](https://nbviewer.org/github/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb) for the filled in workbook. Have questions? Join the [discussion](https://github.com/casact/chainladder-python/discussions) on GitHub." ] }, { diff --git a/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb b/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb index a732a8fa..737d5f2b 100644 --- a/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb +++ b/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "90c5da33-d41d-41a2-9599-3d9e5989fe39", + "metadata": {}, + "source": [ + "# Online Sandbox Tutorial" + ] + }, { "cell_type": "markdown", "id": "d8f38e79-5010-4190-b38c-cbc1d85bde47", From 1cdf87f762407950fb20592b4338db7e490b8bef Mon Sep 17 00:00:00 2001 From: kennethshsu Date: Tue, 19 Sep 2023 21:40:05 -0700 Subject: [PATCH 10/10] Merged from main --- .../sandbox_workbook_blank.ipynb | 1688 ++++++++--------- 1 file changed, 844 insertions(+), 844 deletions(-) diff --git a/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb b/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb index 5c2c4ff0..bb3b46a9 100644 --- a/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb +++ b/docs/getting_started/online_sandbox/sandbox_workbook_blank.ipynb @@ -1,845 +1,845 @@ { - "cells": [ - { - "cell_type": "markdown", - "id": "0f0e5e3b-ac37-4865-8c51-ded927ea9b46", - "metadata": {}, - "source": [ - "# Online Sandbox Tutorial\n", - "\n", - "Welcome! If you've come here to explore the capabilities of the `chainladder-python` package, you've landed in the perfect spot. This online sandbox tutorial is designed to provide you with a glimpse of the package's functionalities. \n", - "\n", - "We recommend setting aside about **one hour** to complete it.\n", - "\n", - "Got Stuck? Click [here](https://nbviewer.org/github/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb) for the filled in workbook. Have questions? Join the [discussion](https://github.com/casact/chainladder-python/discussions) on GitHub." - ] - }, - { - "cell_type": "markdown", - "id": "d8f38e79-5010-4190-b38c-cbc1d85bde47", - "metadata": { - "tags": [] - }, - "source": [ - "# Setting Up\n", - "We will first need to install the package, as Google Colab's default environment doesn't have the chainladder package pre-installed. \n", - "\n", - "Simply execute `pip install chainladder`, Colab is smart enough to know that this is not a piece of python code, but to execute it in shell. FYI, `pip` stands for \"Package Installer for Python\". You will need to run this step using your terminal instead of using a python notebook when you are ready to install the package on your machine." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be51a379-5efe-420e-b689-3bf93b96ebc8", - "metadata": {}, - "outputs": [], - "source": [ - "pip install __fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "3d2bde34-d9e8-436d-8819-675e2ece7bc9", - "metadata": {}, - "source": [ - "`%load_ext lab_black` is a linter, it makes code prettier, you may ignore this line." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "882cc191-5849-471e-8e13-65fdf3e01419", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext lab_black" - ] - }, - { - "cell_type": "markdown", - "id": "011ee825-ca6d-4efc-b782-5e6f2a14bead", - "metadata": {}, - "source": [ - "Other commonly used packages, such as `numpy`, `pandas`, and `matplotlib` are already pre-installed, we just need to load them into our environment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "03fdf8fd-ecd1-4df4-b9cf-a4bf01d978f0", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "import chainladder as cl\n", - "\n", - "print(\"chainladder\", cl.__version__)" - ] - }, - { - "cell_type": "markdown", - "id": "42e0f37f-6d82-46ed-9f80-647cc7233046", - "metadata": {}, - "source": [ - "# Your Journey Begins" - ] - }, - { - "cell_type": "markdown", - "id": "c9a3a636-979a-4205-9762-469e8afb7e46", - "metadata": {}, - "source": [ - "Let's begin by looking at a sample dataset, called `xyz`, which is hosted on https://raw.githubusercontent.com/casact/chainladder-python/master/chainladder/utils/data/xyz.csv.\n", - "\n", - "Let's load the dataset into the memory with `pandas`, then inspect its \"`head`\"." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa2c95b8-86b4-4846-b950-12c402477ec1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "xyz_df = pd.read_csv(\n", - " __fill_in_code__\n", - ")\n", - "xyz_df.head()" - ] - }, - { - "cell_type": "markdown", - "id": "996795b6-9361-4b5c-a00d-d9b6391b115f", - "metadata": {}, - "source": [ - "Can you list all of the unique accident years?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c11052c-291e-439f-ac0f-6736bb2b0b68", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_df[__fill_in_code__].unique()" - ] - }, - { - "cell_type": "markdown", - "id": "3d5be56c-1432-4ba2-85bc-16412fee1d66", - "metadata": {}, - "source": [ - "How many are there?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfeca5a6-366f-4abb-b3e9-51c91e7b9336", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_df[__fill_in_code__].nunique()" - ] - }, - { - "cell_type": "markdown", - "id": "8f870f4f-117c-467d-b3d7-d2941f964f23", - "metadata": {}, - "source": [ - "# Triangle Basics" - ] - }, - { - "cell_type": "markdown", - "id": "4d4ebbf6-bcdc-4c4f-be8c-168c4e7883ea", - "metadata": {}, - "source": [ - "Let's load the data into the chainladder triangle format. And let's call it `xyz_tri`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b51e0b6-c1d3-4976-8866-4800b15d27ec", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri = cl.Triangle(\n", - " data=__fill_in_code__,\n", - " origin=\"AccidentYear\",\n", - " development=\"DevelopmentYear\",\n", - " columns=[\"Incurred\", \"Paid\", \"Reported\", \"Closed\", \"Premium\"],\n", - " cumulative=True,\n", - ")\n", - "xyz_tri" - ] - }, - { - "cell_type": "markdown", - "id": "2c404d26-4418-43b8-8687-58be1b6423f1", - "metadata": {}, - "source": [ - "What does the incurred triangle look like?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe9309fe-2744-4e4d-beff-0a36c1182386", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[__fill_in_code__]" - ] - }, - { - "cell_type": "markdown", - "id": "ed9811e6-5761-4258-9942-19a620540361", - "metadata": {}, - "source": [ - "How about paid?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "278856cf-6d84-4fa6-ac57-4f57755580b8", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[__fill_in_code__]" - ] - }, - { - "cell_type": "markdown", - "id": "04114ff8-107a-4c56-ab9a-8c36f53553df", - "metadata": {}, - "source": [ - "# Pandas-like Operations" - ] - }, - { - "cell_type": "markdown", - "id": "433b8ae8-1968-4dfc-a176-c8a8c93c5f97", - "metadata": {}, - "source": [ - "Let's see how `.iloc[...]` and `.loc[...]` similarly to pandas. They take 4 parameters: [index, column, origin, valuation]." - ] - }, - { - "cell_type": "markdown", - "id": "f0452527-796d-4185-929a-97241329b377", - "metadata": {}, - "source": [ - "What if we want the row from AY 1998 Incurred data?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a13a157b-3fe9-4254-bc72-11d4e1705f29", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri.iloc[__fill_in_code__, __fill_in_code__, __fill_in_code__, __fill_in_code__]" - ] - }, - { - "cell_type": "markdown", - "id": "08b8557c-66fe-4a25-a8bf-5413ca1c1fbb", - "metadata": {}, - "source": [ - "What if you only want the valuation at age 60?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fb20eda1-4e4a-431d-8c8a-21cc87b8c472", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri.iloc[__fill_in_code__, __fill_in_code__, __fill_in_code__, __fill_in_code__]" - ] - }, - { - "cell_type": "markdown", - "id": "56683ffb-01ef-4e18-ba27-1b8ab31b9ae7", - "metadata": {}, - "source": [ - "Let's use `.loc[...]` to get the incurred triangle." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b8116ded-c788-483c-b2af-fde45b72ee4a", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri.iloc[__fill_in_code__, __fill_in_code__, __fill_in_code__, __fill_in_code__]" - ] - }, - { - "cell_type": "markdown", - "id": "c9d515b7-c9a3-4045-ad79-78af1574be8a", - "metadata": {}, - "source": [ - "How do we get the latest Incurred diagonal only?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5bce08b8-bf34-418e-ac3b-db253db44898", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[\"Incurred\"].__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "31b56210-cbcd-4bbb-af9f-063a3788867a", - "metadata": {}, - "source": [ - "Very often, we want incremental triangles instead. Let's convert the Incurred triangle to the incremental form." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2766e7b-b1e6-4574-bfa7-fd70ccd556d7", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[\"Incurred\"].__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "6235668f-9025-4108-b987-f867f93c8ce6", - "metadata": {}, - "source": [ - "We can also convert the triangle to the valuation format, what we often see on Schedule Ps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72487c9a-4438-4ab7-8a24-245485d4c637", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[\"Incurred\"].__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "6e404747-8e22-42c0-a1b5-45c95d702730", - "metadata": {}, - "source": [ - "Another function that is often useful is the `.heatmap()` method. Let's inspect the incurred amount and see if there are trends." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f20ed887-e5b1-40f7-81b5-14bd840cca23", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[\"Incurred\"].__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "27d110d2-ee73-4bb5-a411-3d27c0dd7673", - "metadata": {}, - "source": [ - "# Development" - ] - }, - { - "cell_type": "markdown", - "id": "a0d0950f-bec7-406d-b253-4cf1bfd925dd", - "metadata": {}, - "source": [ - "How can we get the incurred link ratios?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ec16d0fd-ac17-4280-aabf-ad5795114d5f", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[\"Incurred\"].__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "c74c5352-a95b-4403-8322-962ded312e39", - "metadata": {}, - "source": [ - "We can also apply a `.heatmap()` to make it too, to help us visulize the highs and lows." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "172c70be-2324-472f-b89c-29963695179a", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri[\"Incurred\"].__fill_in_code__.__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "f5f212b0-3769-49cd-b7cc-b484f2877aa2", - "metadata": {}, - "source": [ - "Let's get a volume-weighted average LDFs for our Incurred triangle." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ba0b96cb-77eb-472c-84fd-c5c8c5c11e10", - "metadata": {}, - "outputs": [], - "source": [ - "cl.Development(average=\"simple\").fit(__fill_in_code__).ldf_" - ] - }, - { - "cell_type": "markdown", - "id": "0c4baafd-e141-4566-a4ae-2f0a44ef828e", - "metadata": {}, - "source": [ - "How about the CDFs?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b156f84b-dd0d-49d6-8eec-070d0143f40c", - "metadata": {}, - "outputs": [], - "source": [ - "cl.Development(average=\"simple\").fit(__fill_in_code__).__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "d51e5664-3106-41d1-b77f-8afa9ee94ff7", - "metadata": {}, - "source": [ - "We can also use only the latest 3 periods in the calculation of CDFs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de88fdad-5d89-4cc2-adb0-bbeb7c77bbcb", - "metadata": {}, - "outputs": [], - "source": [ - "cl.Development(average=\"simple\", n_periods=__fill_in_code__).fit(xyz_tri[\"Incurred\"]).cdf_" - ] - }, - { - "cell_type": "markdown", - "id": "b018bae9-6070-4795-8af6-b5e196aa1af1", - "metadata": {}, - "source": [ - "# Deterministic Models" - ] - }, - { - "cell_type": "markdown", - "id": "e7c7b88e-205d-45c8-b9e6-4586f29041a4", - "metadata": {}, - "source": [ - "Before we can build any models, we need to use `fit_transform()`, so that the object is actually modified with our selected development pattern(s).\n", - "\n", - "Set the development of the triangle to use only 3 periods." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9e5136d2-0c3c-44da-8440-57ca3cfbbb9d", - "metadata": {}, - "outputs": [], - "source": [ - "cl.Development(__fill_in_code__).fit_transform(__fill_in_code__)" - ] - }, - { - "cell_type": "markdown", - "id": "1bd89481-e5c7-4a84-b2cc-a2e386ccdb15", - "metadata": {}, - "source": [ - "Let's fit a chainladder model to our Incurred triangle." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "022e22e9-92a8-427c-bf5c-cf352df1437c", - "metadata": {}, - "outputs": [], - "source": [ - "cl_mod = cl.Chainladder().fit(__fill_in_code__)\n", - "cl_mod" - ] - }, - { - "cell_type": "markdown", - "id": "7b710342-5f86-408e-bf7e-76382b37f2d1", - "metadata": {}, - "source": [ - "How can we get the model's ultimate estimate?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "69f18923-73b1-4b80-9148-60a7bab5b118", - "metadata": {}, - "outputs": [], - "source": [ - "cl_mod.__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "b416a404-8d0f-46fc-a3e7-f5b5b884b4b4", - "metadata": {}, - "source": [ - "How about just the IBNR?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5fad3aa0-03bc-4f84-a8b7-1a00dbdebe8d", - "metadata": {}, - "outputs": [], - "source": [ - "cl_mod.__fill_in_code__" - ] - }, - { - "cell_type": "markdown", - "id": "70d8c018-21ca-4f2c-a764-433e310bb44a", - "metadata": {}, - "source": [ - "Let's fit an Expected Loss model, with an aprior of 90% on Premium, and get its ultimates." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22eba9fa-1890-4f6f-8a10-281142d2d58d", - "metadata": {}, - "outputs": [], - "source": [ - "cl.ExpectedLoss(apriori=0.90).fit(\n", - " __fill_in_code__, sample_weight=xyz_tri[\"Premium\"].latest_diagonal\n", - ").ultimate_" - ] - }, - { - "cell_type": "markdown", - "id": "eb20b72a-4e49-4eaa-b8e8-d3801833e2d3", - "metadata": {}, - "source": [ - "Try it on the Paid triangle, do you get the same ultimate?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "411f48b0-8b86-4175-80f2-f5f4a19e6c46", - "metadata": {}, - "outputs": [], - "source": [ - "cl.ExpectedLoss(apriori=0.90).fit(\n", - " __fill_in_code__, sample_weight=__fill_in_code__\n", - ").ultimate_" - ] - }, - { - "cell_type": "markdown", - "id": "fb1d7eda-f4c6-4990-9488-47235492001a", - "metadata": {}, - "source": [ - "How about a Bornhuetter-Ferguson model?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d66c7c9a-71eb-4d56-beea-f275da062fc0", - "metadata": {}, - "outputs": [], - "source": [ - "cl.BornhuetterFerguson(apriori=0.90).fit(\n", - " __fill_in_code__, sample_weight=__fill_in_code__\n", - ").ultimate_" - ] - }, - { - "cell_type": "markdown", - "id": "5564ead9-d059-4d2c-839a-f988238e50ee", - "metadata": {}, - "source": [ - "How about Benktander, with 1 iteration, which is the same as BF?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d504e48d-1f5d-4fd6-975b-155235ffb577", - "metadata": {}, - "outputs": [], - "source": [ - "cl.Benktander(apriori=0.90, n_iters=__fill_in_code__).fit(\n", - " __fill_in_code__, sample_weight=__fill_in_code__\n", - ").ultimate_" - ] - }, - { - "cell_type": "markdown", - "id": "002a76c2-7989-46ba-954b-d84c09b4675a", - "metadata": {}, - "source": [ - "How about Cape Cod?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7089ea42-ad28-4edc-9e83-723a7bc25443", - "metadata": {}, - "outputs": [], - "source": [ - "cl.CapeCod().fit(\n", - " __fill_in_code__, sample_weight=__fill_in_code__\n", - ").ultimate_" - ] - }, - { - "cell_type": "markdown", - "id": "5a0d73a2-0e05-4be2-91f0-9ef1ef56a7be", - "metadata": {}, - "source": [ - "Let's store the Cape Cod model as `cc_result`. We can also use `.to_frame()` to leave `chainladder` and go to a `DataFrame`. Let's make a bar chart over origin years to see what they look like." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f2cd9f8c-454d-4b9f-b936-a2f39e8fefde", - "metadata": {}, - "outputs": [], - "source": [ - "cc_result = (\n", - " cl.CapeCod()\n", - " .fit(xyz_tri[\"Incurred\"], sample_weight=xyz_tri[\"Premium\"].latest_diagonal)\n", - " .ultimate_\n", - ")\n", - "plt.plot(\n", - " __fill_in_code__, \n", - " __fill_in_code__,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "3f9e62f8-225b-4046-8847-a6e8d971e14d", - "metadata": {}, - "source": [ - "# Stochastic Models" - ] - }, - { - "cell_type": "markdown", - "id": "36105614-e317-4a87-a42d-282f59b1d339", - "metadata": {}, - "source": [ - "The Mack's Chainladder model is available." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e008ebdb-243d-4ed0-9256-86331df1070a", - "metadata": {}, - "outputs": [], - "source": [ - "mcl_mod = cl.MackChainladder().fit(__fill_in_code__)\n", - "mcl_mod" - ] - }, - { - "cell_type": "markdown", - "id": "3298c63c-5356-4d69-afa3-058b68daf777", - "metadata": {}, - "source": [ - "There are many attributes that are available, such as `full_std_err_`, `total_process_risk_`, `total_parameter_risk_`, `mack_std_err_` and `total_mack_std_err_`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "67f5d99b-7a5e-4640-a6e0-f8b654e6ce27", - "metadata": {}, - "outputs": [], - "source": [ - "__fill_in_code__.full_std_err_" - ] - }, - { - "cell_type": "markdown", - "id": "bdb08c81-5921-4c41-ad63-96168ffd48b7", - "metadata": {}, - "source": [ - "MackChainladder also has a `summary_` attribute." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "81fc38c1-d5b7-4262-94ae-bce5c7ac17e1", - "metadata": {}, - "outputs": [], - "source": [ - "__fill_in_code__.summary_" - ] - }, - { - "cell_type": "markdown", - "id": "0e285585-62b6-48e4-8b1d-c5824ae5df46", - "metadata": {}, - "source": [ - "Let's make a graph, that shows the Reported and IBNR as stacked bars, and error bars showing Mack Standard Errors." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e615b86e-a907-4445-9e95-645090719f76", - "metadata": {}, - "outputs": [], - "source": [ - "plt.bar(\n", - " mcl_mod.summary_.to_frame(origin_as_datetime=True).index.year,\n", - " mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", - " label=\"Paid\",\n", - ")\n", - "plt.bar(\n", - " mcl_mod.summary_.to_frame(origin_as_datetime=True).index.year,\n", - " mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", - " bottom=mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", - " yerr=mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", - " label=\"Reserves\",\n", - ")\n", - "plt.legend(loc=\"upper left\")" - ] - }, - { - "cell_type": "markdown", - "id": "785120ad-03cf-48a7-90d8-d1d56a75ef88", - "metadata": {}, - "source": [ - "ODP Bootstrap is also available. Let's build sample 10,000 Incurred triangles." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "859e19f3-d526-435c-a845-4845a7a3956d", - "metadata": {}, - "outputs": [], - "source": [ - "xyz_tri_sampled = (\n", - " cl.BootstrapODPSample(n_sims=__fill_in_code__).fit(__fill_in_code__).resampled_triangles_\n", - ")\n", - "xyz_tri_sampled" - ] - }, - { - "cell_type": "markdown", - "id": "4391f730-5309-49b2-9c19-0801e3e66c7c", - "metadata": {}, - "source": [ - "We can fit a basic chainladder to all sampled triangles. We now have 10,000 simulated chainladder models, all (most) with unique LDFs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe6dbe70-1b2a-4fb0-aa6b-56380534704f", - "metadata": {}, - "outputs": [], - "source": [ - "cl_mod_bootstrapped = cl.Chainladder().fit(xyz_tri_sampled)\n", - "cl_mod_bootstrapped" - ] - }, - { - "cell_type": "markdown", - "id": "bb3d7c32-9e75-4ae4-ab23-0ca3f2a436b5", - "metadata": {}, - "source": [ - "Let's make another graph." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "edeba1db-97e6-43df-b1c0-590c2d7cd098", - "metadata": {}, - "outputs": [], - "source": [ - "plt.bar(\n", - " cl_mod_bootstrapped.ultimate_.mean().to_frame(origin_as_datetime=True).index.year,\n", - " cl_mod_bootstrapped.ultimate_.mean().to_frame(origin_as_datetime=True)[\"2261\"],\n", - " yerr=cl_mod_bootstrapped.ultimate_.std().to_frame(origin_as_datetime=True)[\"2261\"],\n", - ")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file + "cells": [ + { + "cell_type": "markdown", + "id": "0f0e5e3b-ac37-4865-8c51-ded927ea9b46", + "metadata": {}, + "source": [ + "# Online Sandbox Tutorial\n", + "\n", + "Welcome! If you've come here to explore the capabilities of the `chainladder-python` package, you've landed in the perfect spot. This online sandbox tutorial is designed to provide you with a glimpse of the package's functionalities. \n", + "\n", + "We recommend setting aside about **one hour** to complete it.\n", + "\n", + "Got Stuck? Click [here](https://nbviewer.org/github/casact/chainladder-python/blob/master/docs/getting_started/online_sandbox/sandbox_workbook_filled.ipynb) for the filled in workbook. Have questions? Join the [discussion](https://github.com/casact/chainladder-python/discussions) on GitHub." + ] + }, + { + "cell_type": "markdown", + "id": "d8f38e79-5010-4190-b38c-cbc1d85bde47", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting Up\n", + "We will first need to install the package, as Google Colab's default environment doesn't have the chainladder package pre-installed. \n", + "\n", + "Simply execute `pip install chainladder`, Colab is smart enough to know that this is not a piece of python code, but to execute it in shell. FYI, `pip` stands for \"Package Installer for Python\". You will need to run this step using your terminal instead of using a python notebook when you are ready to install the package on your machine." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "be51a379-5efe-420e-b689-3bf93b96ebc8", + "metadata": {}, + "outputs": [], + "source": [ + "pip install __fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "3d2bde34-d9e8-436d-8819-675e2ece7bc9", + "metadata": {}, + "source": [ + "`%load_ext lab_black` is a linter, it makes code prettier, you may ignore this line." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "882cc191-5849-471e-8e13-65fdf3e01419", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext lab_black" + ] + }, + { + "cell_type": "markdown", + "id": "011ee825-ca6d-4efc-b782-5e6f2a14bead", + "metadata": {}, + "source": [ + "Other commonly used packages, such as `numpy`, `pandas`, and `matplotlib` are already pre-installed, we just need to load them into our environment." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03fdf8fd-ecd1-4df4-b9cf-a4bf01d978f0", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import chainladder as cl\n", + "\n", + "print(\"chainladder\", cl.__version__)" + ] + }, + { + "cell_type": "markdown", + "id": "42e0f37f-6d82-46ed-9f80-647cc7233046", + "metadata": {}, + "source": [ + "# Your Journey Begins" + ] + }, + { + "cell_type": "markdown", + "id": "c9a3a636-979a-4205-9762-469e8afb7e46", + "metadata": {}, + "source": [ + "Let's begin by looking at a sample dataset, called `xyz`, which is hosted on https://raw.githubusercontent.com/casact/chainladder-python/master/chainladder/utils/data/xyz.csv.\n", + "\n", + "Let's load the dataset into the memory with `pandas`, then inspect its \"`head`\"." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa2c95b8-86b4-4846-b950-12c402477ec1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "xyz_df = pd.read_csv(\n", + " __fill_in_code__\n", + ")\n", + "xyz_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "996795b6-9361-4b5c-a00d-d9b6391b115f", + "metadata": {}, + "source": [ + "Can you list all of the unique accident years?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c11052c-291e-439f-ac0f-6736bb2b0b68", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_df[__fill_in_code__].unique()" + ] + }, + { + "cell_type": "markdown", + "id": "3d5be56c-1432-4ba2-85bc-16412fee1d66", + "metadata": {}, + "source": [ + "How many are there?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfeca5a6-366f-4abb-b3e9-51c91e7b9336", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_df[__fill_in_code__].nunique()" + ] + }, + { + "cell_type": "markdown", + "id": "8f870f4f-117c-467d-b3d7-d2941f964f23", + "metadata": {}, + "source": [ + "# Triangle Basics" + ] + }, + { + "cell_type": "markdown", + "id": "4d4ebbf6-bcdc-4c4f-be8c-168c4e7883ea", + "metadata": {}, + "source": [ + "Let's load the data into the chainladder triangle format. And let's call it `xyz_tri`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b51e0b6-c1d3-4976-8866-4800b15d27ec", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri = cl.Triangle(\n", + " data=__fill_in_code__,\n", + " origin=\"AccidentYear\",\n", + " development=\"DevelopmentYear\",\n", + " columns=[\"Incurred\", \"Paid\", \"Reported\", \"Closed\", \"Premium\"],\n", + " cumulative=True,\n", + ")\n", + "xyz_tri" + ] + }, + { + "cell_type": "markdown", + "id": "2c404d26-4418-43b8-8687-58be1b6423f1", + "metadata": {}, + "source": [ + "What does the incurred triangle look like?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe9309fe-2744-4e4d-beff-0a36c1182386", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[__fill_in_code__]" + ] + }, + { + "cell_type": "markdown", + "id": "ed9811e6-5761-4258-9942-19a620540361", + "metadata": {}, + "source": [ + "How about paid?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "278856cf-6d84-4fa6-ac57-4f57755580b8", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[__fill_in_code__]" + ] + }, + { + "cell_type": "markdown", + "id": "04114ff8-107a-4c56-ab9a-8c36f53553df", + "metadata": {}, + "source": [ + "# Pandas-like Operations" + ] + }, + { + "cell_type": "markdown", + "id": "433b8ae8-1968-4dfc-a176-c8a8c93c5f97", + "metadata": {}, + "source": [ + "Let's see how `.iloc[...]` and `.loc[...]` similarly to pandas. They take 4 parameters: [index, column, origin, valuation]." + ] + }, + { + "cell_type": "markdown", + "id": "f0452527-796d-4185-929a-97241329b377", + "metadata": {}, + "source": [ + "What if we want the row from AY 1998 Incurred data?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a13a157b-3fe9-4254-bc72-11d4e1705f29", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri.iloc[__fill_in_code__, __fill_in_code__, __fill_in_code__, __fill_in_code__]" + ] + }, + { + "cell_type": "markdown", + "id": "08b8557c-66fe-4a25-a8bf-5413ca1c1fbb", + "metadata": {}, + "source": [ + "What if you only want the valuation at age 60?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb20eda1-4e4a-431d-8c8a-21cc87b8c472", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri.iloc[__fill_in_code__, __fill_in_code__, __fill_in_code__, __fill_in_code__]" + ] + }, + { + "cell_type": "markdown", + "id": "56683ffb-01ef-4e18-ba27-1b8ab31b9ae7", + "metadata": {}, + "source": [ + "Let's use `.loc[...]` to get the incurred triangle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8116ded-c788-483c-b2af-fde45b72ee4a", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri.iloc[__fill_in_code__, __fill_in_code__, __fill_in_code__, __fill_in_code__]" + ] + }, + { + "cell_type": "markdown", + "id": "c9d515b7-c9a3-4045-ad79-78af1574be8a", + "metadata": {}, + "source": [ + "How do we get the latest Incurred diagonal only?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5bce08b8-bf34-418e-ac3b-db253db44898", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[\"Incurred\"].__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "31b56210-cbcd-4bbb-af9f-063a3788867a", + "metadata": {}, + "source": [ + "Very often, we want incremental triangles instead. Let's convert the Incurred triangle to the incremental form." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2766e7b-b1e6-4574-bfa7-fd70ccd556d7", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[\"Incurred\"].__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "6235668f-9025-4108-b987-f867f93c8ce6", + "metadata": {}, + "source": [ + "We can also convert the triangle to the valuation format, what we often see on Schedule Ps." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72487c9a-4438-4ab7-8a24-245485d4c637", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[\"Incurred\"].__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "6e404747-8e22-42c0-a1b5-45c95d702730", + "metadata": {}, + "source": [ + "Another function that is often useful is the `.heatmap()` method. Let's inspect the incurred amount and see if there are trends." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f20ed887-e5b1-40f7-81b5-14bd840cca23", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[\"Incurred\"].__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "27d110d2-ee73-4bb5-a411-3d27c0dd7673", + "metadata": {}, + "source": [ + "# Development" + ] + }, + { + "cell_type": "markdown", + "id": "a0d0950f-bec7-406d-b253-4cf1bfd925dd", + "metadata": {}, + "source": [ + "How can we get the incurred link ratios?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec16d0fd-ac17-4280-aabf-ad5795114d5f", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[\"Incurred\"].__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "c74c5352-a95b-4403-8322-962ded312e39", + "metadata": {}, + "source": [ + "We can also apply a `.heatmap()` to make it too, to help us visulize the highs and lows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "172c70be-2324-472f-b89c-29963695179a", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri[\"Incurred\"].__fill_in_code__.__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "f5f212b0-3769-49cd-b7cc-b484f2877aa2", + "metadata": {}, + "source": [ + "Let's get a volume-weighted average LDFs for our Incurred triangle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba0b96cb-77eb-472c-84fd-c5c8c5c11e10", + "metadata": {}, + "outputs": [], + "source": [ + "cl.Development(average=\"simple\").fit(__fill_in_code__).ldf_" + ] + }, + { + "cell_type": "markdown", + "id": "0c4baafd-e141-4566-a4ae-2f0a44ef828e", + "metadata": {}, + "source": [ + "How about the CDFs?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b156f84b-dd0d-49d6-8eec-070d0143f40c", + "metadata": {}, + "outputs": [], + "source": [ + "cl.Development(average=\"simple\").fit(__fill_in_code__).__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "d51e5664-3106-41d1-b77f-8afa9ee94ff7", + "metadata": {}, + "source": [ + "We can also use only the latest 3 periods in the calculation of CDFs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de88fdad-5d89-4cc2-adb0-bbeb7c77bbcb", + "metadata": {}, + "outputs": [], + "source": [ + "cl.Development(average=\"simple\", n_periods=__fill_in_code__).fit(xyz_tri[\"Incurred\"]).cdf_" + ] + }, + { + "cell_type": "markdown", + "id": "b018bae9-6070-4795-8af6-b5e196aa1af1", + "metadata": {}, + "source": [ + "# Deterministic Models" + ] + }, + { + "cell_type": "markdown", + "id": "e7c7b88e-205d-45c8-b9e6-4586f29041a4", + "metadata": {}, + "source": [ + "Before we can build any models, we need to use `fit_transform()`, so that the object is actually modified with our selected development pattern(s).\n", + "\n", + "Set the development of the triangle to use only 3 periods." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e5136d2-0c3c-44da-8440-57ca3cfbbb9d", + "metadata": {}, + "outputs": [], + "source": [ + "cl.Development(__fill_in_code__).fit_transform(__fill_in_code__)" + ] + }, + { + "cell_type": "markdown", + "id": "1bd89481-e5c7-4a84-b2cc-a2e386ccdb15", + "metadata": {}, + "source": [ + "Let's fit a chainladder model to our Incurred triangle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "022e22e9-92a8-427c-bf5c-cf352df1437c", + "metadata": {}, + "outputs": [], + "source": [ + "cl_mod = cl.Chainladder().fit(__fill_in_code__)\n", + "cl_mod" + ] + }, + { + "cell_type": "markdown", + "id": "7b710342-5f86-408e-bf7e-76382b37f2d1", + "metadata": {}, + "source": [ + "How can we get the model's ultimate estimate?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69f18923-73b1-4b80-9148-60a7bab5b118", + "metadata": {}, + "outputs": [], + "source": [ + "cl_mod.__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "b416a404-8d0f-46fc-a3e7-f5b5b884b4b4", + "metadata": {}, + "source": [ + "How about just the IBNR?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5fad3aa0-03bc-4f84-a8b7-1a00dbdebe8d", + "metadata": {}, + "outputs": [], + "source": [ + "cl_mod.__fill_in_code__" + ] + }, + { + "cell_type": "markdown", + "id": "70d8c018-21ca-4f2c-a764-433e310bb44a", + "metadata": {}, + "source": [ + "Let's fit an Expected Loss model, with an aprior of 90% on Premium, and get its ultimates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22eba9fa-1890-4f6f-8a10-281142d2d58d", + "metadata": {}, + "outputs": [], + "source": [ + "cl.ExpectedLoss(apriori=0.90).fit(\n", + " __fill_in_code__, sample_weight=xyz_tri[\"Premium\"].latest_diagonal\n", + ").ultimate_" + ] + }, + { + "cell_type": "markdown", + "id": "eb20b72a-4e49-4eaa-b8e8-d3801833e2d3", + "metadata": {}, + "source": [ + "Try it on the Paid triangle, do you get the same ultimate?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "411f48b0-8b86-4175-80f2-f5f4a19e6c46", + "metadata": {}, + "outputs": [], + "source": [ + "cl.ExpectedLoss(apriori=0.90).fit(\n", + " __fill_in_code__, sample_weight=__fill_in_code__\n", + ").ultimate_" + ] + }, + { + "cell_type": "markdown", + "id": "fb1d7eda-f4c6-4990-9488-47235492001a", + "metadata": {}, + "source": [ + "How about a Bornhuetter-Ferguson model?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d66c7c9a-71eb-4d56-beea-f275da062fc0", + "metadata": {}, + "outputs": [], + "source": [ + "cl.BornhuetterFerguson(apriori=0.90).fit(\n", + " __fill_in_code__, sample_weight=__fill_in_code__\n", + ").ultimate_" + ] + }, + { + "cell_type": "markdown", + "id": "5564ead9-d059-4d2c-839a-f988238e50ee", + "metadata": {}, + "source": [ + "How about Benktander, with 1 iteration, which is the same as BF?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d504e48d-1f5d-4fd6-975b-155235ffb577", + "metadata": {}, + "outputs": [], + "source": [ + "cl.Benktander(apriori=0.90, n_iters=__fill_in_code__).fit(\n", + " __fill_in_code__, sample_weight=__fill_in_code__\n", + ").ultimate_" + ] + }, + { + "cell_type": "markdown", + "id": "002a76c2-7989-46ba-954b-d84c09b4675a", + "metadata": {}, + "source": [ + "How about Cape Cod?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7089ea42-ad28-4edc-9e83-723a7bc25443", + "metadata": {}, + "outputs": [], + "source": [ + "cl.CapeCod().fit(\n", + " __fill_in_code__, sample_weight=__fill_in_code__\n", + ").ultimate_" + ] + }, + { + "cell_type": "markdown", + "id": "5a0d73a2-0e05-4be2-91f0-9ef1ef56a7be", + "metadata": {}, + "source": [ + "Let's store the Cape Cod model as `cc_result`. We can also use `.to_frame()` to leave `chainladder` and go to a `DataFrame`. Let's make a bar chart over origin years to see what they look like." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2cd9f8c-454d-4b9f-b936-a2f39e8fefde", + "metadata": {}, + "outputs": [], + "source": [ + "cc_result = (\n", + " cl.CapeCod()\n", + " .fit(xyz_tri[\"Incurred\"], sample_weight=xyz_tri[\"Premium\"].latest_diagonal)\n", + " .ultimate_\n", + ")\n", + "plt.plot(\n", + " __fill_in_code__, \n", + " __fill_in_code__,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "3f9e62f8-225b-4046-8847-a6e8d971e14d", + "metadata": {}, + "source": [ + "# Stochastic Models" + ] + }, + { + "cell_type": "markdown", + "id": "36105614-e317-4a87-a42d-282f59b1d339", + "metadata": {}, + "source": [ + "The Mack's Chainladder model is available." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e008ebdb-243d-4ed0-9256-86331df1070a", + "metadata": {}, + "outputs": [], + "source": [ + "mcl_mod = cl.MackChainladder().fit(__fill_in_code__)\n", + "mcl_mod" + ] + }, + { + "cell_type": "markdown", + "id": "3298c63c-5356-4d69-afa3-058b68daf777", + "metadata": {}, + "source": [ + "There are many attributes that are available, such as `full_std_err_`, `total_process_risk_`, `total_parameter_risk_`, `mack_std_err_` and `total_mack_std_err_`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67f5d99b-7a5e-4640-a6e0-f8b654e6ce27", + "metadata": {}, + "outputs": [], + "source": [ + "__fill_in_code__.full_std_err_" + ] + }, + { + "cell_type": "markdown", + "id": "bdb08c81-5921-4c41-ad63-96168ffd48b7", + "metadata": {}, + "source": [ + "MackChainladder also has a `summary_` attribute." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81fc38c1-d5b7-4262-94ae-bce5c7ac17e1", + "metadata": {}, + "outputs": [], + "source": [ + "__fill_in_code__.summary_" + ] + }, + { + "cell_type": "markdown", + "id": "0e285585-62b6-48e4-8b1d-c5824ae5df46", + "metadata": {}, + "source": [ + "Let's make a graph, that shows the Reported and IBNR as stacked bars, and error bars showing Mack Standard Errors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e615b86e-a907-4445-9e95-645090719f76", + "metadata": {}, + "outputs": [], + "source": [ + "plt.bar(\n", + " mcl_mod.summary_.to_frame(origin_as_datetime=True).index.year,\n", + " mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", + " label=\"Paid\",\n", + ")\n", + "plt.bar(\n", + " mcl_mod.summary_.to_frame(origin_as_datetime=True).index.year,\n", + " mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", + " bottom=mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", + " yerr=mcl_mod.summary_.to_frame(origin_as_datetime=True)[__fill_in_code__],\n", + " label=\"Reserves\",\n", + ")\n", + "plt.legend(loc=\"upper left\")" + ] + }, + { + "cell_type": "markdown", + "id": "785120ad-03cf-48a7-90d8-d1d56a75ef88", + "metadata": {}, + "source": [ + "ODP Bootstrap is also available. Let's build sample 10,000 Incurred triangles." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "859e19f3-d526-435c-a845-4845a7a3956d", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_tri_sampled = (\n", + " cl.BootstrapODPSample(n_sims=__fill_in_code__).fit(__fill_in_code__).resampled_triangles_\n", + ")\n", + "xyz_tri_sampled" + ] + }, + { + "cell_type": "markdown", + "id": "4391f730-5309-49b2-9c19-0801e3e66c7c", + "metadata": {}, + "source": [ + "We can fit a basic chainladder to all sampled triangles. We now have 10,000 simulated chainladder models, all (most) with unique LDFs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe6dbe70-1b2a-4fb0-aa6b-56380534704f", + "metadata": {}, + "outputs": [], + "source": [ + "cl_mod_bootstrapped = cl.Chainladder().fit(xyz_tri_sampled)\n", + "cl_mod_bootstrapped" + ] + }, + { + "cell_type": "markdown", + "id": "bb3d7c32-9e75-4ae4-ab23-0ca3f2a436b5", + "metadata": {}, + "source": [ + "Let's make another graph." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edeba1db-97e6-43df-b1c0-590c2d7cd098", + "metadata": {}, + "outputs": [], + "source": [ + "plt.bar(\n", + " cl_mod_bootstrapped.ultimate_.mean().to_frame(origin_as_datetime=True).index.year,\n", + " cl_mod_bootstrapped.ultimate_.mean().to_frame(origin_as_datetime=True)[\"2261\"],\n", + " yerr=cl_mod_bootstrapped.ultimate_.std().to_frame(origin_as_datetime=True)[\"2261\"],\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}