| Title: | Machine Learning Models for Predicting Claim Counts |
|---|---|
| Description: | Prediction of claim counts using the feature based development factors introduced in the manuscript Hiabu M., Hofman E. and Pittarello G. (2023) <doi:10.48550/arXiv.2312.14549>. Implementation of Neural Networks, Extreme Gradient Boosting, and Cox model with splines to optimise the partial log-likelihood of proportional hazard models. |
| Authors: | Emil Hofman [aut, cre, cph], Gabriele Pittarello [aut, cph] (ORCID: <https://orcid.org/0000-0003-3360-5826>), Munir Hiabu [aut, cph] (ORCID: <https://orcid.org/0000-0001-5846-667X>) |
| Maintainer: | Emil Hofman <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 1.1.0 |
| Built: | 2026-10-15 09:10:32 UTC |
| Source: | https://github.com/edhofman/resurv |
This function generates individual claims data on the requested time scale
using the SynthETIC package.
This simple function allows to simulate from a sand-box to test out the ReSurv approach.
Some parameters of the simulation can be changed.
data_generator( ref_claim = 2e+05, time_unit = 1/360, years = 4, random_seed = 1964, period_exposure = 200, period_frequency = 0.2, scenario = 1 )data_generator( ref_claim = 2e+05, time_unit = 1/360, years = 4, random_seed = 1964, period_exposure = 200, period_frequency = 0.2, scenario = 1 )
ref_claim |
|
time_unit |
Numeric, fraction of a year per output period, for example 1/360 (the default) for days, 1/12 for months, or 1 for years. |
years |
|
random_seed |
|
period_exposure |
|
period_frequency |
|
scenario |
|
Individual claims data. It contains the following columns:
claim_number: Policy ID.
claim_type: Type of claim (0 or 1) in scenarios alpha through epsilon.
Zeta instead includes age, property_value, and
business_use; eta includes business_use.
AP: Accident period
RP: Reporting period.
Avanzi, B., Taylor, G., Wang, M., & Wong, B. (2021). SynthETIC: an individual insurance claim simulator with feature control. Insurance: Mathematics and Economics, 100, 296-308.
Hiabu, M., Hofman, E., & Pittarello, G. (2023). A machine learning approach based on survival analysis for IBNR frequencies in non-life reserving. arXiv preprint arXiv:2312.14549.
input_data_0 <- data_generator( random_seed = 1964, scenario = "alpha", time_unit = 1, years = 2, period_exposure = 100)input_data_0 <- data_generator( random_seed = 1964, scenario = "alpha", time_unit = 1, years = 2, period_exposure = 100)
This function pre-processes the data for the application of a ReSurv model.
IndividualDataPP( data, id = NULL, continuous_features = NULL, categorical_features = NULL, accident_period, calendar_period, input_time_granularity = "months", output_time_granularity = "quarters", years = NULL, calendar_period_extrapolation = FALSE, continuous_features_spline = NULL, degrees_cf = 3, degrees_of_freedom_cf = 4, degrees_cp = 3, degrees_of_freedom_cp = 4 )IndividualDataPP( data, id = NULL, continuous_features = NULL, categorical_features = NULL, accident_period, calendar_period, input_time_granularity = "months", output_time_granularity = "quarters", years = NULL, calendar_period_extrapolation = FALSE, continuous_features_spline = NULL, degrees_cf = 3, degrees_of_freedom_cf = 4, degrees_cp = 3, degrees_of_freedom_cp = 4 )
data |
|
id |
|
continuous_features |
|
categorical_features |
|
accident_period |
|
calendar_period |
|
input_time_granularity |
Default to |
output_time_granularity |
The output granularity must be equal to or coarser than the input granularity.
Also, the output granularity must be consistent with the input granularity, meaning that the time conversion must be possible.
E.g., it is possible to group quarters to years. Quarters can also be grouped to semesters.
Default to |
years |
|
calendar_period_extrapolation |
|
continuous_features_spline |
|
degrees_cf |
|
degrees_of_freedom_cf |
|
degrees_cp |
|
degrees_of_freedom_cp |
|
Accident and reporting periods are indexed from one. Development time is
DP_i = RP_i - AP_i + 1; reverse development time is
DP_rev_i = DP_max - DP_i + 1, and truncation time is
TR_i = AP_i - 1. Training retains observed rows with
DP_rev_i > TR_i.
The conversion factor is the input time unit divided by the output time unit (for example, 1/3 for months to quarters). Accident and calendar periods are grouped using ceiling; development periods also account for the position of the accident period within each output period. Days use a 360-day year for the development horizon.
An IndividualDataPP list containing training.data
(observed rows), full.data (all encoded rows), and
data_information (conversion factor, input/output formulas,
feature names, time units, horizon, and original column names).
After pre-processing, we provide a standard encoding for the time components. This regards the output in training.data.
In the ReSurv notation:
AP_i: Input granularity accident period.
AP_o: Output granularity accident period.
DP_i: Input granularity development period in forward time.
DP_rev_i: Input granularity development period in reverse time.
DP_rev_o: Output granularity development period in reverse time.
TR_i: Input granularity truncation time.
TR_o: Output granularity truncation time.
I: event indicator, under this framework is equal to one for each entry.
Hiabu, M., Hofman, E., & Pittarello, G. (2023). A machine learning approach based on survival analysis for IBNR frequencies in non-life reserving. arXiv preprint arXiv:2312.14549.
input_data_0 <- data_generator( random_seed = 1964, scenario = "alpha", time_unit = 1, years = 2, period_exposure = 100) individual_data <- IndividualDataPP(data = input_data_0, categorical_features = "claim_type", continuous_features = "AP", accident_period = "AP", calendar_period = "RP", input_time_granularity = "years", output_time_granularity = "years", years = 2)input_data_0 <- data_generator( random_seed = 1964, scenario = "alpha", time_unit = 1, years = 2, period_exposure = 100) individual_data <- IndividualDataPP(data = input_data_0, categorical_features = "claim_type", continuous_features = "AP", accident_period = "AP", calendar_period = "RP", input_time_granularity = "years", output_time_granularity = "years", years = 2)
Plots the development factors by group code.
## S3 method for class 'ReSurvPredict' plot( x, granularity = "input", group_code = 1, color_par = "royalblue", linewidth_par = 2.5, ylim_par = NULL, ticks_by_par = NULL, base_size_par = NULL, title_par = NULL, x_text_par = NULL, plot.title.size_par = NULL, ... )## S3 method for class 'ReSurvPredict' plot( x, granularity = "input", group_code = 1, color_par = "royalblue", linewidth_par = 2.5, ylim_par = NULL, ticks_by_par = NULL, base_size_par = NULL, title_par = NULL, x_text_par = NULL, plot.title.size_par = NULL, ... )
x |
"ReSurvPredict" object specifying hazard and development factors. |
granularity |
|
group_code |
|
color_par |
|
linewidth_par |
|
ylim_par |
|
ticks_by_par |
|
base_size_par |
|
title_par |
|
x_text_par |
|
plot.title.size_par |
|
... |
Other arguments to be passed to Plot. Optional. |
ggplot2 of the development factors
This function predicts the results from the ReSurv fits.
## S3 method for class 'ReSurvFit' predict( object, newdata = NULL, lower_triangular_output = FALSE, minimal_output = FALSE, check_value = 1.85, ... )## S3 method for class 'ReSurvFit' predict( object, newdata = NULL, lower_triangular_output = FALSE, minimal_output = FALSE, check_value = 1.85, ... )
object |
A fitted |
newdata |
An optional |
lower_triangular_output |
|
minimal_output |
|
check_value |
Retained for compatibility; currently ignored. |
... |
Additional arguments to pass to the predict function. |
A ReSurvPredict object with fitted predictions, long triangle outputs, predicted counts, and optional lower-triangle outputs.
Predict deterministic reserve table
Predict deterministic reserve table from a ReSurvFit object
predictReserve(object, ...) ## S3 method for class 'ReSurvFit' predictReserve(object, granularity = c("output", "input"), ...)predictReserve(object, ...) ## S3 method for class 'ReSurvFit' predictReserve(object, granularity = c("output", "input"), ...)
object |
A ReSurvFit object. |
... |
Additional arguments passed to predict.ReSurvFit(). |
granularity |
Character. Either "output" or "input". |
A data.table with accident period AP, development
period DP, calendar period CP, and predicted claim count
IBNR. These are claim counts, not monetary reserves.
A data.table with columns AP, DP, CP, IBNR.
Print method for ReSurvCV objects
## S3 method for class 'ReSurvCV' print(x, ...)## S3 method for class 'ReSurvCV' print(x, ...)
x |
An object of class |
... |
Additional arguments, currently ignored. |
Gives overview of IBNr predictions
## S3 method for class 'summaryReSurvPredict' print(x, digits = max(3L, getOption("digits") - 3L), ...)## S3 method for class 'summaryReSurvPredict' print(x, digits = max(3L, getOption("digits") - 3L), ...)
x |
"ReSurvPredict" object specifying hazard and development factors. |
digits |
|
... |
Other arguments to be passed to print. |
print of summary of predictions
ReSurv models on the individual data.This function fits and computes the reserves for the ReSurv models
ReSurv( IndividualDataPP, hazard_model = "COX", tie = "efron", baseline = "spline", continuous_features_scaling_method = "minmax", random_seed = 1, hparameters = list(), percentage_data_training = 0.8, grouping_method = "exposure", check_value = 1.85, eta = 0.5, simplifier = TRUE ) ## Default S3 method: ReSurv( IndividualDataPP, hazard_model = "COX", tie = "efron", baseline = "spline", continuous_features_scaling_method = "minmax", random_seed = 1, hparameters = list(), percentage_data_training = 0.8, grouping_method = "exposure", check_value = 1.85, eta = 0.5, simplifier = TRUE ) ## S3 method for class 'IndividualDataPP' ReSurv( IndividualDataPP, hazard_model = "COX", tie = "efron", baseline = "spline", continuous_features_scaling_method = "minmax", random_seed = 1, hparameters = list(), percentage_data_training = 0.8, grouping_method = "exposure", check_value = 1.85, eta = 0.5, simplifier = TRUE )ReSurv( IndividualDataPP, hazard_model = "COX", tie = "efron", baseline = "spline", continuous_features_scaling_method = "minmax", random_seed = 1, hparameters = list(), percentage_data_training = 0.8, grouping_method = "exposure", check_value = 1.85, eta = 0.5, simplifier = TRUE ) ## Default S3 method: ReSurv( IndividualDataPP, hazard_model = "COX", tie = "efron", baseline = "spline", continuous_features_scaling_method = "minmax", random_seed = 1, hparameters = list(), percentage_data_training = 0.8, grouping_method = "exposure", check_value = 1.85, eta = 0.5, simplifier = TRUE ) ## S3 method for class 'IndividualDataPP' ReSurv( IndividualDataPP, hazard_model = "COX", tie = "efron", baseline = "spline", continuous_features_scaling_method = "minmax", random_seed = 1, hparameters = list(), percentage_data_training = 0.8, grouping_method = "exposure", check_value = 1.85, eta = 0.5, simplifier = TRUE )
IndividualDataPP |
IndividualDataPP object to use for the |
hazard_model |
|
tie |
Handling of ties in the Cox fit, passed to
|
baseline |
Retained for compatibility. The baseline is estimated from
the risk sets using the specified |
continuous_features_scaling_method |
Scaling method: |
random_seed |
|
hparameters |
|
percentage_data_training |
|
grouping_method |
Retained for compatibility; currently ignored. |
check_value |
Retained for compatibility; currently ignored. |
eta |
Numeric in [0, 1], controlling the baseline estimate and hazard-to-development-factor conversion. Default is 0.5. |
simplifier |
|
The model fit uses the theoretical framework of Hiabu et al. (2023), that relies on the correspondence between hazard models and development factors:
Neural networks use the native R torch backend. Install its runtime with
torch::install_torch() before fitting a neural network.
The ReSurv package assumes proportional hazard models.
Given an i.i.d. sample the individual hazard at time is:
Composed of a baseline and a proportional effect .
Currently, the implementation allows to optimize the partial likelihood (concerning the proportional effects) using one of the following statistical learning approaches:
A ReSurvFit list containing model.out (design matrix
and fitted backend model), hazard_frame (risk scores, baseline,
hazards, development factors and survival probabilities),
data_information (preprocessing and reserving metadata), and
fit_information (model name, training loss is_lkh,
validation loss os_lkh, and eta). Use predict()
or predictReserve() to obtain claim-count predictions.
Hiabu, M., Hofman, E., & Pittarello, G. (2023). A machine learning approach based on survival analysis for IBNR frequencies in non-life reserving. arXiv preprint arXiv:2312.14549.
Therneau, T. M., & Lumley, T. (2015). Package ‘survival’. R Top Doc, 128(10), 28-33.
Katzman, J. L., Shaham, U., Cloninger, A., Bates, J., Jiang, T., & Kluger, Y. (2018). DeepSurv: personalized treatment recommender system using a Cox proportional hazards deep neural network. BMC medical research methodology, 18(1), 1-12.
Chen, T., He, T., Benesty, M., & Khotilovich, V. (2019). Package ‘xgboost’. R version, 90, 1-66.
input_data_0 <- data_generator( random_seed = 1964, scenario = "alpha", time_unit = 1, years = 4, period_exposure = 100) individual_data <- IndividualDataPP(data = input_data_0, categorical_features = "claim_type", continuous_features = "AP", accident_period = "AP", calendar_period = "RP", input_time_granularity = "years", output_time_granularity = "years", years=4) resurv_fit_cox <- ReSurv(individual_data, hazard_model = "COX", eta = 0)input_data_0 <- data_generator( random_seed = 1964, scenario = "alpha", time_unit = 1, years = 4, period_exposure = 100) individual_data <- IndividualDataPP(data = input_data_0, categorical_features = "claim_type", continuous_features = "AP", accident_period = "AP", calendar_period = "RP", input_time_granularity = "years", output_time_granularity = "years", years=4) resurv_fit_cox <- ReSurv(individual_data, hazard_model = "COX", eta = 0)
K-fold cross-validation of a ReSurv model
ReSurvCV( IndividualDataPP, model, hparameters_grid, folds, random_seed, continuous_features_scaling_method = "minmax", print_every_n = 1L, nrounds = NULL, early_stopping_rounds = NULL, epochs = 1, parallel = FALSE, ncores = 1, num_workers = 0, verbose = FALSE, verbose.cv = FALSE, cv_data_subsample = 1 )ReSurvCV( IndividualDataPP, model, hparameters_grid, folds, random_seed, continuous_features_scaling_method = "minmax", print_every_n = 1L, nrounds = NULL, early_stopping_rounds = NULL, epochs = 1, parallel = FALSE, ncores = 1, num_workers = 0, verbose = FALSE, verbose.cv = FALSE, cv_data_subsample = 1 )
IndividualDataPP |
An object of class |
model |
Character. Either |
hparameters_grid |
Named list defining the hyperparameter grid. |
folds |
Integer. Number of folds. |
random_seed |
Integer. Random seed. |
continuous_features_scaling_method |
Character. Scaling method for continuous features. |
print_every_n |
Integer. Passed to XGBoost. |
nrounds |
Integer. Number of XGBoost boosting rounds. |
early_stopping_rounds |
Integer. XGBoost early stopping. |
epochs |
Integer. Number of NN epochs. |
parallel |
Logical. Retained for compatibility; execution is sequential and setting this to TRUE produces a warning. |
ncores |
Integer. Retained for compatibility; currently ignored. |
num_workers |
Deprecated for the native torch backend. Ignored. |
verbose |
Logical. Print model fitting output. |
verbose.cv |
Logical. Print CV progress. |
cv_data_subsample |
Fraction of training rows used for cross-validation, in (0, 1]. Values greater than 1 and at most 100 are interpreted as percentages. The default 1 uses all rows; use 0.01 for one percent. |
An object of class ReSurvCV containing out.cv
(all combinations and mean training and validation losses),
out.cv.best.oos (the row with smallest validation loss), and
hparameters.best, suitable for the hparameters argument
of ReSurv(). Cross-validation does not refit the final model.
Compare predictions with realized claim counts in the lower triangle.
Score_Reserving( models, newdata, scoring_metrics = c("EI", "R-tot", "R-cell-wise", "R-cal-wise"), granularity = c("output", "input"), chain_ladder = TRUE, clmplus_benchmark = NULL, ... )Score_Reserving( models, newdata, scoring_metrics = c("EI", "R-tot", "R-cell-wise", "R-cal-wise"), granularity = c("output", "input"), chain_ladder = TRUE, clmplus_benchmark = NULL, ... )
models |
A fitted |
newdata |
Realized claims, either individual data with the accident and
reporting columns used for fitting, or an aggregate table with |
scoring_metrics |
Character vector selecting |
granularity |
Time scale for scoring: |
chain_ladder |
Logical; include the aggregate chain-ladder benchmark. |
clmplus_benchmark |
Optional character vector containing any of '"ac"' or '"apc"'. Requested models are fitted with the 'clmplus' package to the same aggregate triangle as the chain-ladder benchmark. 'NULL' (the default) disables these benchmarks. |
... |
Additional arguments passed to |
A list of score tables, one per requested metric, with class
Score_Reserving and a granularity attribute.
Gives overview of IBNR predictions
## S3 method for class 'ReSurvPredict' summary(object, granularity = "input", ...)## S3 method for class 'ReSurvPredict' summary(object, granularity = "input", ...)
object |
"ReSurvPredict" object specifying hazard and development factors. |
granularity |
Default is |
... |
Other arguments to be passed to summary. |
Summary of predictions