1. Getting Started

1.1. Installation

To install from PyPI

pip install aggregate

See https://pypi.org/project/aggregate/.

1.2. Source Code

The source code is hosted on GitHub, https://github.com/mynl/aggregate.

1.3. Prerequisites

This help assumes you know how to program in Python, understand probability, and are familiar with the concept of an aggregate distribution. Awareness of insurance terminology such as limit, attachment and deductible, and the material covered in SOA exam STAM, CAS exam MAS I, or IFOA CS-2 is helpful.

1.4. License

BSD 3.

1.5. Dependencies

See pyproject.toml. Requirements are split between those needed to run the project, and a larger set needed to build the documentation.

Apart from sly and titlecase, all run-dependencies are standard.

1.6. Help Parameters and Examples

Warning

All parameters are fabrications. They try to be realistic (or at least not materially unrealistic) but are not intended to be applied to real-world pricing. They are for educational purposes only.

1.7. Help Structure

This help is structured around access, application, theory, and implementation. There are six parts.

  1. Getting Started (this document).

  2. User Guides, explaining how to access functionality and practical guides explaining how to apply it.

  3. API Reference: all functions, classes, methods, and properties.

  4. Dec Language Reference: syntax and grammar.

  5. Technical Guides, covering the underlying theory and its specific implementation.

  6. Design and Development, giving some history, the design philosophy, and ideas for future development.

There is also a Bibliography.

1.8. Help Coding Conventions

Throughout the help, you will see input code inside code blocks such as:

import pandas as pd
pd.DataFrame({'A': [1, 2, 3]})

or:

In [1]: import pandas as pd

In [2]: pd.DataFrame({'A': [1, 2, 3]})
Out[2]: 
   A
0  1
1  2
2  3

The first block is a standard Python input, while in the second the In [1]: indicates the input is inside a notebook. In Jupyter Notebooks the last line is printed and plots are shown inline.

For example:

In [3]: a = 1

In [4]: a
Out[4]: 1

is equivalent to:

a = 1
print(a)

The Python line continuation \ is used to create compact input.

1.9. Numbers and Units

You can choose your own units. The examples include numbers interpreted in ones, thousands, and millions. Amounts are broadly calibrated to make sense in USD, EUR, and GBP.

1.10. aggregate Hello World

The only object you need to import to get started is build. The quick display function qd is a nice-to-have utility function that handles printing with sensible defaults. It is used extensively throughout.

In [5]: from aggregate import build, qd

In [6]: build
Out[6]: 
underwriter        Rory
version            0.23.0
knowledge          145 programs
update             True
log2               16
debug              False
validation_eps     0.0001
site dir           ~/aggregate/databases
default dir        ~/checkouts/readthedocs.org/user_builds/aggregate/checkouts/latest/aggregate/agg

help
build.knowledge    list of all programs
build.qshow(pat)   show programs matching pattern
build.show(pat)    build and display matching pattern

build is a Underwriter object. It allows you to create all other objects and includes a library of examples, called the knowledge.

Using build you can create an Aggregate object using an DecL program. For example, the program:

agg Eg1 dfreq [1:5] dsev [1:3]

creates an aggregate distribution called Eg1. The frequency distribution is 1, 2, 3, 4, or 5, all equally likely, and the severity is 1, 2, or 3, also equally likely. The mean frequency is 3, the mean severity 2, and hence the aggregate has a mean of 6. It is built and displayed like so:

In [7]: a = build('agg Eg1 dfreq [1:5] dsev [1:3]')

In [8]: qd(a)

      E[X] Est E[X]   Err E[X]   CV(X) Est CV(X)    Skew(X) Est Skew(X)
X                                                                      
Freq     3                      0.4714                    0            
Sev      2        2          0 0.40825   0.40825 6.5268e-15  3.2634e-15
Agg      6        6 -9.992e-16 0.52705   0.52705    0.25298     0.25298
log2 = 5, bandwidth = 1, validation: fails sev skew.

The DecL program:

agg Eg2 5 claims 1000 xs 0 sev lognorm 50 cv 4 poisson

creates a realistic insurance portfolio, with 5 expected claims, severity sampled from a 1000 xs 0 layer of a lognormal with mean 50 and CV 4 and Poisson frequency.

Aggregate objects act like a discrete probability distribution. There are properties for the mean, standard deviation, coefficient of variation (cv), and skewness.

In [9]: a.agg_m, a.agg_sd, a.agg_cv, a.agg_skew
Out[9]: (6.0, 3.1622776601683795, 0.5270462766947299, 0.2529822128134703)

They have probability mass, cumulative distribution, survival, and quantile (inverse of distribution) functions.

In [10]: a.pmf(6), a.cdf(5), a.sf(6), a.q(a.cdf(6)), a.q(0.5)
Out[10]: (0.102880658436214, 0.4650205761316873, 0.4320987654320987, 6.0, 6.0)

It is easy to check some of these calculations. The probability of the minimum outcome of one equals 1/15 (1/5 for a frequency of 1 and 1/3 for a severity of 1) and the maximum outcome of 15 equals 1/1215 (1/5 for a frequency of 5 and (1/3)**5 to draw severity of 3 on each). The object returns the correct values.

In [11]: a.pmf(1), 1/15, a.pmf(15), 1/5/3**5, 5*3**5
Out[11]: 
(0.06666666666666668,
 0.06666666666666667,
 0.0008230452674897143,
 0.000823045267489712,
 1215)

Creating an object automatically adds its specification to the knowledge, with name Eg1. Use build.knowledge to view the knowledge dataframe.

In [12]: qd(build.knowledge.head(), line_width=73, max_colwidth=50, justify='left')

              program                                             \
kind name                                                          
agg  A.Dice00  agg A.Dice00 dfreq  [1:6]  dsev  [1]  note{The...   
     A.Dice01  agg A.Dice01 dfreq  [1]  dsev  [1:6]  note{Sam...   
     A.Dice02  agg A.Dice02 dfreq  [2]  dsev  [1:6]  note{Sum...   
     A.Dice03  agg A.Dice03 dfreq  [5]  dsev  [1:6]  note{Sum...   
     A.Dice04  agg A.Dice04 dfreq  [1:6]  dsev  [1:6]  note{S...   

              spec                                                
kind name                                                         
agg  A.Dice00  {'name': 'A.Dice00', 'freq_name': 'empirical',...  
     A.Dice01  {'name': 'A.Dice01', 'freq_name': 'empirical',...  
     A.Dice02  {'name': 'A.Dice02', 'freq_name': 'empirical',...  
     A.Dice03  {'name': 'A.Dice03', 'freq_name': 'empirical',...  
     A.Dice04  {'name': 'A.Dice04', 'freq_name': 'empirical',...  

In [13]: qd(build.knowledge.query('name == "Eg1"'), line_width=73, max_colwidth=50, justify='left')

          program                             \
kind name                                      
agg  Eg1   agg Eg1 dfreq  [1:5]  dsev  [1:3]   

          spec                                                
kind name                                                     
agg  Eg1   {'name': 'Eg1', 'freq_name': 'empirical', 'fre...  

The User Guides contain more details and examples.