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 identifierspec_id
: Character identifier (‘A’,‘B’,‘C’ and ‘D’) representing the product specs of the model point.product_spec_table
inCashValue_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')