Generating 100K model points#

This notebook generates the sample model points ued by the “3. Memory-Optimized Mutiprocess Example” notebook. A DataFrame of 100,000 model points is generated and saved to an Excel file named model_point_table_100K.xlsx in the current directory. The generated model point file can be loaded back by calling pandas’ read_excel function with index_col=0. The DataFrame can be used with CashValue_ME by setting it to model_point_table in the Projection space.

Index and Columns:

  • point_id(Index): Model point identifier

  • spec_id: Character identifier (‘A’,‘B’,‘C’ and ‘D’) representing the product specs of the model point. product_spec_table in CashValue_ME.Projection defines the product specs for each identifier.

  • age_at_entry: Issue age. The samples are distributed uniformly from 20 to 59.

  • sex: “M” or “F” to indicate policy holder’s sex.

  • policy_term: Policy term in years. The samples are evenly distriubted among 10, 15 and 20.

  • policy_count: The number of policies. Uniformly distributed from 0 to 100.

  • sum_assured: Sum assured. The samples are uniformly distributed from 10,000 to 1,000,000.

  • duration_mth: Months elapsed from the issue til t=0. New business is assumed so 0 for all model points.

  • premium_pp: Premium per policy.

  • av_pp_init: Initial account value per policy for existing policies. 0 for all model points.

Number of model points:

  • 100,000

[5]:
import numpy as np
from numpy.random import default_rng  # Requires NumPy 1.17 or newer

rng = default_rng(12345)

# Number of Model Points
MPCount = 100000

# Issue Age (Integer): 20 - 59 year old
age_at_entry = rng.integers(low=20, high=60, size=MPCount)

# Sex (Char)
Sex = ["M", "F"]

sex = np.fromiter(map(lambda i: Sex[i], rng.integers(low=0, high=len(Sex), size=MPCount)), np.dtype('<U1'))

# Policy Term (Integer, modified later for whole life): 10, 15, 20
policy_term = rng.integers(low=0, high=3, size=MPCount) * 5 + 10


# Sum Assured (Float): 10,000 - 1,000,000
sum_assured = np.round((1_000_000 - 10_000) * rng.random(size=MPCount) + 10_000, -3)


# Policy Count (Integer): 1
policy_count = np.rint(100 * rng.random(size=MPCount)).astype(int)
[6]:
import pandas as pd

attrs = [
    "age_at_entry",
    "sex",
    "policy_term",
    "policy_count",
    "sum_assured"
]

data = [
    age_at_entry,
    sex,
    policy_term,
    policy_count,
    sum_assured
]

model_point_table = pd.DataFrame(dict(zip(attrs, data)), index=range(1, MPCount+1))
model_point_table.index.name = "policy_id"
[7]:
# Spec ID
SpedIDs = "ABCD"

spec_ids = np.fromiter(map(lambda i: SpedIDs[i], rng.integers(low=0, high=len(SpedIDs), size=MPCount)), np.dtype('<U1'))
model_point_table.insert(0, 'spec_id', spec_ids)

whole_life = (model_point_table['spec_id'] == 'C')  | (model_point_table['spec_id'] == 'D')

# Modify Policy Term

model_point_table['policy_term'].mask(whole_life, 9999, inplace=True)

# Set Duration to 0

model_point_table['duration_mth'] = 0

# Premium per Plicy (by adjusting size between single premium(A and B) and level premium(C and D) policies)

premium_pp = np.ceil(model_point_table['sum_assured'] / (80 - model_point_table['age_at_entry']) / 12 / 100) * 100

model_point_table.insert(len(model_point_table.columns), 'premium_pp', model_point_table['sum_assured'])
model_point_table['premium_pp'].mask(whole_life, premium_pp, inplace=True)

# Ininital Account Value per Policy

model_point_table['av_pp_init'] = 0

[8]:
model_point_table
[8]:
spec_id age_at_entry sex policy_term policy_count sum_assured duration_mth premium_pp av_pp_init
policy_id
1 A 47 M 20 22 804000.0 0 804000.0 0
2 C 29 F 9999 75 519000.0 0 900.0 0
3 A 51 F 10 5 409000.0 0 409000.0 0
4 B 32 M 15 60 128000.0 0 128000.0 0
5 D 28 M 9999 45 698000.0 0 1200.0 0
... ... ... ... ... ... ... ... ... ...
99996 A 21 M 10 34 152000.0 0 152000.0 0
99997 D 24 F 9999 53 928000.0 0 1400.0 0
99998 B 46 F 15 72 662000.0 0 662000.0 0
99999 A 46 M 15 36 583000.0 0 583000.0 0
100000 B 35 M 15 3 638000.0 0 638000.0 0

100000 rows × 9 columns

[9]:
model_point_table.to_excel('model_point_table_100K.xlsx')