Il y a quelques années, Guillaume Beneteau avait fait son mémoire d'actuariat, en France, sur l'utilisation de données individuelles pour faire du provisionnement (au lieu de travailler sur des donnees aggregées dans des triangles). Dans le même genre d'idées, Ngoc An Dinh et Gilles Chau viennent de soutenir leur mémoire cette semaine à l'ENSAE, encadré par Frédéric Planchet. L'idée était de modéliser les processus de règlements avec deux approches : la première intitulée dynamiques markoviennes qui considère les processus de règlements (avec une certaine dynamique sous-jacente), et une basée sur des modèles linéaires généralisés qui suppose que les règlements appartiennent à une famille de distribution paramétrique et les paramètres dépendent des facteurs liés aux règlements. Le mémoire est en ligne sur le blog, ainsi que le code R.
Tag - IBNR
Friday, June 29 2012
Provisionnement et modélisation individuelle des sinistres
By arthur charpentier on Friday, June 29 2012, 15:21 - Encadrement
Wednesday, June 6 2012
Claims reserving and IBNR with R
By arthur charpentier on Wednesday, June 6 2012, 14:04 - talks and seminars
Following previous posts on life contingencies and longevity and mortality models, I upload additional material for the short course at the 6th R/Rmetrics Meielisalp Workshop & Summer School on Computational Finance and Financial Engineering organized by ETH Zürich, https://www.rmetrics.org/. The third part of the talk (on Actuarial models with R) will be dedicated to IBNR and claims reserving. A complete set of slides can be downloaded from the blog, but again, only some part will be presented. Note that the slides start with a parallel between mortality tables (in life insurance) and payment triangles (in non-life insurance).
Once again, the codes are from a book on actuarial science in R, written with Christophe Dutang and Vincent Goulet (so far in French) that should appear, some day... The code used in the slides above are based on the following datasets,
> source("http://perso.univ-rennes1.fr/arthur.charpentier/ + bases.R")We will built our own functions to derive all quantities. One function used can be found here
> source("http://perso.univ-rennes1.fr/arthur.charpentier/ + merz-wuthrich-triangle.R")Finally, note that most of the code can be found in the following library
> library(ChainLadder)
Wednesday, December 7 2011
ACT2040: tail factor et cloture de la première ligne des triangles de paiements
By arthur charpentier on Wednesday, December 7 2011, 19:43 - ACT2040-2011
La grosse hypothèse que l'on a fait quand on travaillait sur les triangles, était que la première année était close. Et donc, que pour la première ligne de paiements cumulés, le montant final était la charge totale des sinistres survenus cette année là. En fait, en 1999, Thomas Mack avait proposé un modèle relativement simple permettant l'inclusion d'un tail factor. L'idée est que l'on peut supposer que les facteurs de développement dans la méthode Chain Ladder décroissent tranquillement vers 1. Toujours sur le même triangle (mais en utilisant une régression pondérée sans constante - ce qui permet d'éviter les problèmes des valeurs manquantes à n'importe quel endroit dans le triangle), nous avions
> LAMBDA <- rep(NA,nc-1) > for(k in 1:(nc-1)){ + LAMBDA[k]=lm(PAID[,k+1]~0+PAID[,k], + weights=1/PAID[,k])$coefficients} > LAMBDA [1] 1.380933 1.011433 1.004343 1.001858 1.004735
> logL <- log(LAMBDA-1) > tps <- 1:(nc-1) > modele <- lm(logL~tps) > plot(tps,logL,xlim=c(1,20),ylim=c(-30,0),col="red") > abline(modele) > tpsP <- seq(6,1000) > logP <- predict(modele,newdata=data.frame(tps=tpsP)) > points(tpsP,logP ,pch=0,col="blue")


> (facteur <- prod(exp(logP)+1)) [1] 1.000707Autrement dit, il faudrait rajouter 0.07% à la charge ultime. Sans ce facteur ultime, le montant de provisions était
> DIAG <- diag(PAID[,6:1]) > PRODUIT <- c(1,rev(LAMBDA)) > sum((cumprod(PRODUIT)-1)*DIAG) [1] 2426.985
On retrouve ici la même chose que ce qui est obtenu sous R,
> MackChainLadder(PAID,tail=TRUE) MackChainLadder(Triangle = PAID, tail = TRUE) Latest Dev.To.Date Ultimate IBNR Mack.S.E CV(IBNR) 1 4,456 0.999 4,459 3.15 0.299 0.0948 2 4,730 0.995 4,756 25.76 0.712 0.0277 3 5,420 0.993 5,460 39.64 2.528 0.0638 4 6,020 0.988 6,090 70.37 5.064 0.0720 5 6,794 0.977 6,952 157.99 31.357 0.1985 6 5,217 0.708 7,372 2,154.86 68.499 0.0318 Totals Latest: 32,637.00 Dev: 0.93 Ultimate: 35,088.76 IBNR: 2,451.76 Mack S.E.: 79.37 CV(IBNR): 0.0323730538389919
Tuesday, November 29 2011
ACT2040: chain ladder
By arthur charpentier on Tuesday, November 29 2011, 13:24 - ACT2040-2011

Pour la fin du cours, on a commencé à voir le méthode dit Chain Ladder. Pour cela, rappelons que l'on dispose du jeu de données suivants, de paiements cumulés,
> source("http://perso.univ-rennes1.fr/ arthur.charpentier/bases.R") > PAID [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372 4411 4428 4435 4456 [2,] 3367 4659 4696 4720 4730 NA [3,] 3871 5345 5398 5420 NA NA [4,] 4239 5917 6020 NA NA NA [5,] 4929 6794 NA NA NA NA [6,] 5217 NA NA NA NA NA > PAID/PREMIUM [,1] [,2] [,3] [,4] [,5] [,6] [1,] 0.6989 0.9522 0.9607 0.9644 0.9660 0.9705 [2,] 0.7206 0.9972 1.0051 1.0102 1.0124 NA [3,] 0.7960 1.0991 1.1100 1.1145 NA NA [4,] 0.8191 1.1433 1.1632 NA NA NA [5,] 0.8688 1.1976 NA NA NA NA [6,] 0.8112 NA NA NA NA NA
si on visualise l'évolution du ratio sinistre/primes. On peut visualiser les facteurs de transition dans le tableau ci-dessous,
> PAID[,2:6]/PAID[,1:5] [,1] [,2] [,3] [,4] [,5] [1,] 1.362418 1.008920 1.003854 1.001581 1.004735 [2,] 1.383724 1.007942 1.005111 1.002119 NA [3,] 1.380780 1.009916 1.004076 NA NA [4,] 1.395848 1.017407 NA NA NA [5,] 1.378373 NA NA NA NA [6,] NA NA NA NA NA
Toutefois, pour faire le ratio moyen, on ne fait pas la moyenne des ratios, ou alors à condition de pondérer correctement, par exemple pour passer de la première à la seconde ligne du tableau,
> k=1 > weighted.mean(x=PAID[,k+1]/PAID[,k],w=PAID[,k],na.rm=TRUE) [1] 1.380933 > sum(PAID[1:(6-k),k+1])/sum(PAID[1:(6-k),k]) [1] 1.380933
> lambda=rep(NA,5) > for(k in 1:5){ + lambda[k]=(sum(PAID[1:(6-k),k+1])/sum(PAID[1:(6-k),k]))} > lambda [1] 1.380933 1.011433 1.004343 1.001858 1.004735
> PROJECTION=PAID > for(k in 1:5){ + PROJECTION[((7-k):6),k+1]=PROJECTION[((7-k):6),k]*lambda[k] + print(PROJECTION)} [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372.000 4411 4428 4435 4456 [2,] 3367 4659.000 4696 4720 4730 NA [3,] 3871 5345.000 5398 5420 NA NA [4,] 4239 5917.000 6020 NA NA NA [5,] 4929 6794.000 NA NA NA NA [6,] 5217 7204.327 NA NA NA NA [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372.000 4411.000 4428 4435 4456 [2,] 3367 4659.000 4696.000 4720 4730 NA [3,] 3871 5345.000 5398.000 5420 NA NA [4,] 4239 5917.000 6020.000 NA NA NA [5,] 4929 6794.000 6871.672 NA NA NA [6,] 5217 7204.327 7286.691 NA NA NA [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372.000 4411.000 4428.000 4435 4456 [2,] 3367 4659.000 4696.000 4720.000 4730 NA [3,] 3871 5345.000 5398.000 5420.000 NA NA [4,] 4239 5917.000 6020.000 6046.147 NA NA [5,] 4929 6794.000 6871.672 6901.518 NA NA [6,] 5217 7204.327 7286.691 7318.339 NA NA [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372.000 4411.000 4428.000 4435.000 4456 [2,] 3367 4659.000 4696.000 4720.000 4730.000 NA [3,] 3871 5345.000 5398.000 5420.000 5430.072 NA [4,] 4239 5917.000 6020.000 6046.147 6057.383 NA [5,] 4929 6794.000 6871.672 6901.518 6914.344 NA [6,] 5217 7204.327 7286.691 7318.339 7331.939 NA [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372.000 4411.000 4428.000 4435.000 4456.000 [2,] 3367 4659.000 4696.000 4720.000 4730.000 4752.397 [3,] 3871 5345.000 5398.000 5420.000 5430.072 5455.784 [4,] 4239 5917.000 6020.000 6046.147 6057.383 6086.065 [5,] 4929 6794.000 6871.672 6901.518 6914.344 6947.084 [6,] 5217 7204.327 7286.691 7318.339 7331.939 7366.656où on visualise, étape par étape, le remplissage de la partie inférieure de la matrice. La dernière colonne contient des prédictions des charges ultimes, par année de survenance, et sur la diagonale, on a toujours le montant de paiements déjà effectués par année de survenance. Le montant de provision est alors la différence entre ce que l'on pense payer, et ce que l'on a déjà payé.
> PROJECTION[,6]-diag(PAID[,6:1]) [1] 0.00 22.3968 35.7838 66.0646 153.0835 2149.6564 > sum(PROJECTION[,6]-diag(PAID[,6:1])) [1] 2426.985
Friday, November 25 2011
ACT2040: provisionnement, introduction et devoir maison no2
By arthur charpentier on Friday, November 25 2011, 10:30 - ACT2040-2011
Mardi, nous commençons la dernière partie du cours, sur le provisionnement (pour sinistres à payer) en assurance IARD. Nous commencerons par évoquer le développement des paiements des sinistres dans le temps (à partir de données réelles). Les graphiques sont en ligne sur le blog. Par exemple l'assurance automobile de particuliers,



Mais on peut aussi regarder les risques d'entreprise, avec par exemple l'assurance risque industriel,




> source("http://perso.univ-rennes1.fr/arthur.charpentier/bases.R") > PAID [,1] [,2] [,3] [,4] [,5] [,6] [1,] 3209 4372 4411 4428 4435 4456 [2,] 3367 4659 4696 4720 4730 NA [3,] 3871 5345 5398 5420 NA NA [4,] 4239 5917 6020 NA NA NA [5,] 4929 6794 NA NA NA NA [6,] 5217 NA NA NA NA NA > NUMBER [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1043.4 1045.5 1047.5 1047.7 1047.7 1047.7 [2,] 1043.0 1027.1 1028.7 1028.9 1028.7 NA [3,] 965.1 967.9 967.8 970.1 NA NA [4,] 977.0 984.7 986.8 NA NA NA [5,] 1099.0 1118.5 NA NA NA NA [6,] 1076.3 NA NA NA NA NA
> PREMIUM [1] 4591 4672 4863 5175 5673 6431
library(RODBC) LOC="http://freakonometrics.blog.free.fr/public/data/act2040triangle.xls" fichier = odbcConnectExcel(LOC) TRIANGLE = sqlQuery(fichier, "select * from [triangle1$B2:Q17]") odbcCloseAll()
à condition que le code tourne (ce que je n'ai pas réussit à faire sans Windows). Une alternative est la suivante
> library(gdata) > read.xls("http://freakonometrics.blog.free.fr/ public/data/act2040triangle.xls", sheet = 10) essai de l'URL 'http://freakonometrics.blog.free.fr/ public/data/act2040triangle.xls' Content type 'application/octet-stream' length 454656 bytes (444 Kb) URL ouverte ================================================== downloaded 444 Kb Year X12 X24 X36 X48 X60 X72 X84 X96 X108 X120 X132 1 1995 1340 3188 5072 6973 8677 10008 11802 12606 13174 13596 14033 2 1996 1857 4297 6864 9438 11820 13594 14783 15710 16439 16972 NA 3 1997 2024 4891 7790 10733 13792 16071 17695 18886 19735 NA NA 4 1998 2781 6655 10671 14738 18022 20795 23179 24597 NA NA NA 5 1999 3439 8272 13325 18551 23386 26861 29409 NA NA NA NA 6 2000 3714 9039 14638 20326 26117 30643 NA NA NA NA NA 7 2001 4652 11236 18109 25239 31250 NA NA NA NA NA NA 8 2002 5292 12974 21106 29611 NA NA NA NA NA NA NA 9 2003 6818 16984 27677 NA NA NA NA NA NA NA NA 10 2004 9337 23263 NA NA NA NA NA NA NA NA NA 11 2005 15073 NA NA NA NA NA NA NA NA NA NA
(il est toutefois préférable de télécharger le fichier sur son disque dur afin de renommer certains noms de variables, les symboles comme + ayant du mal à passer). Pour les personnes normales, il est possible d'utiliser une méthode plus laborieuse, mais qui marche toujours, à savoir sauver la feuille dans un format texte (ou CSV, avec un séparateur de colonnes), puis d'utiliser classiquement
TRIANGLE=read.table("triangle1.csv",header=TRUE,sep=";")
Wednesday, November 17 2010
Course on risk, insurance, and uncertainty
By arthur charpentier on Wednesday, November 17 2010, 05:19 - cours divers

Tuesday, November 9 2010
Bornhuetter-Ferguson and claims reserving, STT6705V part 10
By arthur charpentier on Tuesday, November 9 2010, 15:18 - actuariat 10/11 STT6705V
In several posts on this blog, I have mentioned Chain Ladder, Mack's view of Chain Ladder, and the Overdispersed Poisson model for incremental payments. But there is also one important model used when modeling IBNR: the so-called Bornhuetter-Ferguson model (from that paper). The slides for tomorrow can be downloaded here,
Here is also a link to the slides presented by William Panning in 2006. And here and there, it is possible to find papers (or slides) discussing uncertainty in Bornhuetter-Ferguson's model.
Reserving techniques will probably take us half of the course. We will finally discuss mortality models. The dataset we will use can be downloaded from here (with population data here and death data there). I have converted them in csv files, and the R code to use them is the following,
tabB=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/tabB.csv",
sep=";",header=FALSE)
ANNEE=tabB[,1]
BASEB=tabB[,seq(2,246,by=2)]
BASEB=BASEB[,1:100]
tabC=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/tabC.csv",
sep=";",header=FALSE)
BASEC=tabC[,2:101]
BASEC=BASEC[-c(16,23,43,48,51,53),]
BASEC=BASEC[1:nrow(BASEB),] AGE=0:99
(I will upload soon the code for claims reserving techniques...)
Wednesday, October 6 2010
Incertitude dans les triangles de provisionnement
By arthur charpentier on Wednesday, October 6 2010, 03:50 - talks and seminars
Comme je l'avais annoncé ici, la numéro 83 de la revue Risques vient de sortir, avec un article coécrit avec Laurent Devineau et Jean Marie Nessi, essayant de vulgariser la notion d'incertitude (et d'incertitude à un an) dans les triangles de liquidation, en assurance dommage. L'article, intitulé "mesurer le risque lors du calcul des provisions pour sinistres à payer", est en ligne ici. Je ne mets pas de code cette fois-ci car il viendra dans les semaines à venir (nous attaquons précisément le calcul des provisions dans le cours de statistique de l'assurance).

Tuesday, October 5 2010
Statistique de l'assurance STT6705V, partie 6
By arthur charpentier on Tuesday, October 5 2010, 22:48 - actuariat 10/11 STT6705V
Avec le cours de mercredi, nous attaquerons la partie sur la modélisation de la dynamique des sinistres, et le calcul des provisions pour sinistres à payer. Les transparents sont en ligne ici. Je peux renvoyer vers un billet que j'avais mis en ligne l'an dernier sur le sujet, ici. Sinon pour compléter les références, la CAS a publié l'an dernier un très joli ouvrage (ici), Estimating Unpaid Claims Using Basic Techniques. Je peux aussi renvoyer vers un article de Swiss Re sur le sujet, ici, ou sur le site du GIRO, là. Sinon l'ouvrage de référence pour cette section est le le livre de Mario Wüthrich et Michael Merz, stochastic claims reserving methods in insurance.
Le code pour récuper les bases de données (triangles) est simplementsuivant
> source("http://perso.univ-rennes1.fr/arthur.charpentier/bases.R")
Sinon, j'ai mis en ligne, ici
la base des paiements cumulés sous le
format excel (ancienne version).
Pour l'importer, sous R, si le fichier a été sauvé sur D:, il suffit d(utiliser
la requête sql suivante
> library(RODBC)
> fichier = odbcConnectExcel("D:\\triangle.xls")
> BASE = sqlQuery(fichier, "select * from [Feuil1$D9:I15]")
> odbcCloseAll()
> (TRIANGLE = as.matrix(BASE) )
F1 F2 F3 F4 F5 F6
1 3209 4372 4411 4428 4435 4456
2 3367 4659 4696 4720 4730 NA
3 3871 5345 5398 5420 NA NA
4 4239 5917 6020 NA NA NA
5 4929 6794 NA NA NA NA
6 5217 NA NA NA NA NA
Wednesday, March 31 2010
Présentation sur le risque de réserve dans Solvabilité II
By arthur charpentier on Wednesday, March 31 2010, 11:46 - talks and seminars
Mercredi matin, participation à un petit déjeuner sur "Solvabilité II : Problématiques et enjeux des nouvelles exigences réglementaires pour les assureurs non-vie".
Les slides seront bientôt disponibles ici. J'interviendrais
principalement sur le risque de réserve, afin d'essayer d'apporter
quelques éclaircissements sur la formule standard.
Rappelons que dans
le modèle de Mack (qui est celui qui est retenu par Merz &
Wüthrich), on suppose que les paiements vérifie

sont des variables indépendantes et de même loi. En supposant de plus
que les années de survenance sont indépendantes, alors Mack a montré que

Si on regarde maintenant la formule obtenue par Mez & Wüthrich,

Tout cela est sujets aux fautes de typo, et je renvoie aux articles de Mack (ici) et de Merz & Wüthrich (là) pour ceux qui veulent tout programmer.
Sinon je reviendrais par la suite sur les travaux que nous menons avec Laurent sur le sujet, au plus tard lors de l'école d'été qui se tiendra à l'ISFA en juillet.
Triangles multiples et dépendance
By arthur charpentier on Wednesday, March 31 2010, 03:15 - insurance
Parmi les problèmes qui ont connu leur heure de gloire il y a quelques années, il y a eu le sujet des triangles multivariés, ou plutôt de la dépendance qui pourrait exister entre des triangles de paiements. Considérons les deux triangles suivants, obtenus auprès d'un même assureur, pour des sinistres en auto matériel entre 1994 et 2003, i.e.


- Comparaison des prédictions par la méthode de Mack (i.e. chain-ladder)

alors les deux premiers moments vérifient




> P.corp=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/auto-corporel.csv",
+ header=FALSE,sep=";",na.strings = "NA",dec=",")
> P.corp=as.matrix(P.corp)
> n=nrow(P.corp)
> P.mat =read.table("http://perso.univ-rennes1.fr/arthur.charpentier/auto-materiel.csv",
+ header=FALSE,sep=";",na.strings = "NA",dec=",")
> P.mat=as.matrix(P.mat)
> P.mat=P.mat[1:n,1:n]
> P.mat = P.mat[2:10,1:9]
> P.corp= P.corp[2:10,1:9]
> n=9
> P.tot = P.mat + P.corp
> library(ChainLadder)
> V=MackChainLadder(P.tot)$Total.Mack.S.E
> E=sum(MackChainLadder(P.tot)$FullTriangle[,n]-
+ diag(MackChainLadder(P.tot)$FullTriangle[n:1,]))
> mu = log(E) - .5*log(1+V^2/E^2)
> sigma2 = log(1+V^2/E^2)
Les trois distributions sont alors les suivantes (sous hypothèse de lognormalité)

> library(distr)
> V=MackChainLadder(P.mat)$Total.Mack.S.E
> E=sum(MackChainLadder(P.mat)$FullTriangle[,n]-
+-diag(MackChainLadder(P.mat)$FullTriangle[n:1,]))
> mu = log(E) - .5*log(1+V^2/E^2)
> sigma2 = log(1+V^2/E^2)
> LM = Lnorm(meanlog=mu,sdlog=sqrt(sigma2))
> V=MackChainLadder(P.corp)$Total.Mack.S.E
> E=sum(MackChainLadder(P.corp)$FullTriangle[,n]-
+ diag(MackChainLadder(P.corp)$FullTriangle[n:1,]))
> mu = log(E) - .5*log(1+V^2/E^2)
> sigma2 = log(1+V^2/E^2)
> LC = Lnorm(meanlog=mu,sdlog=sqrt(sigma2))
> LT=LM+LC
On peut alors tracer les densités
> u=seq(0,qlnorm(.95,mu,sqrt(sigma2)),length=1000)
> vtotal=dlnorm(u,mu,sqrt(sigma2))
> vconvol=d(LT)(u)

> q(LT)(.9)
[1] 271463.7
> qlnorm(.9,mu,sqrt(sigma2))
[1] 365395.1
Autrement dit, on a le choix sur l'interprétation,
- travailler sur les triangles agrégés apporte beaucoup trop d'incertitudes,
- supposer les triangles matériels et corporels indépendants est une hypothèse trop forte.
> qlnorm(.9,mu,sqrt(sigma2))
[1] 64262.87
> qlnorm(.9,mu,sqrt(sigma2))
[1] 230645
dont la somme fait
[1] 294907.9
qu'il faudrait comparer à
> qlnorm(.9,mu,sqrt(sigma2))
[1] 365395.1
Bref, supposer les risques comontones ne suffit manifestement pas (je renvoie ici pour un billet expliquant que le quantile d'une somme est un objet assez complexe).
- Approche par les GLM
> an <- n; ligne = rep(1:an, each=an); colonne = rep(1:an, an)
> passe = (ligne + colonne - 1)<=an; n = sum(passe)
> PAID=P.corp; INC=PAID
> INC[,2:an]=PAID[,2:an]-PAID[,1:(an-1)]
> I.corp = INC
> PAID=P.mat; INC=PAID
> INC[,2:an]=PAID[,2:an]-PAID[,1:(an-1)]
> I.mat = INC
> Ym = as.vector(I.mat)
> Ym[Ym<0]=0
> Yc = as.vector(I.corp)
> lig = as.factor(ligne)
> col = as.factor(colonne)
> base = data.frame(Ym,Yc,col,lig)
> regm=glm(Ym~col+lig,data=base,family="poisson")
Il y a eu 35 avis (utilisez warnings() pour les visionner)
> regc=glm(Yc~col+lig,data=base,family="poisson")
Il y a eu 38 avis (utilisez warnings() pour les visionner)
> MackChainLadder(P.mat)
MackChainLadder(Triangle = P.mat)
Latest Dev.To.Date Ultimate IBNR Mack.S.E CV(IBNR)
1 2,897,694 1.000 2,897,694 0.00 0.00 NaN
2 353,866 1.000 353,873 6.96 4.52 0.649
3 358,922 1.000 358,926 3.97 21.89 5.515
4 342,988 1.000 343,020 32.27 47.55 1.473
5 288,867 1.000 288,920 52.64 52.77 1.002
6 297,708 1.000 297,775 66.67 371.73 5.576
7 270,537 0.999 270,891 354.26 820.88 2.317
8 290,748 0.997 291,570 822.22 1,180.80 1.436
9 276,447 0.993 278,320 1,872.75 2,486.60 1.328
10 224,499 0.896 250,571 26,071.84 39,252.98 1.506
Totals
Latest: 5,602,275.93
Ultimate: 5,631,559.51
IBNR: 29,283.58
Mack S.E.: 39,374.90
CV(IBNR): 1.34
> sum(exp(predict(regm,newdata=base))[passe!=TRUE])
[1] 29669.72
> MackChainLadder(P.corp)
MackChainLadder(Triangle = P.corp)
Latest Dev.To.Date Ultimate IBNR Mack.S.E CV(IBNR)
1 2,231,325 1.000 2,231,325 0 0 NaN
2 182,004 0.991 183,683 1,678 1,060 0.632
3 196,756 0.981 200,589 3,833 2,731 0.712
4 205,591 0.964 213,166 7,575 4,534 0.599
5 176,427 0.943 187,096 10,669 6,128 0.574
6 156,175 0.912 171,227 15,053 9,091 0.604
7 138,483 0.867 159,709 21,226 12,717 0.599
8 109,483 0.803 136,359 26,876 17,557 0.653
9 73,108 0.704 103,835 30,727 29,956 0.975
10 24,322 0.532 45,723 21,401 59,465 2.779
Totals
Latest: 3,493,676.24
Ultimate: 3,632,713.12
IBNR: 139,036.88
Mack S.E.: 72,058.66
CV(IBNR): 0.52
> sum(exp(predict(regc,newdata=base))[passe!=TRUE])
[1] 139036.9
Mais le point important est que l'on peut récupérer les résidus, et étudier leur structure de dépendance,
> plot(residuals(regc,type="pearson"),
+ residuals(regm,type="pearson"),pch=19,col="blue")

> plot(rank(residuals(regc,type="pearson"))/56,
+ rank(residuals(regm,type="pearson"))/56,pch=19,col="green")


et une dépendance également très différente,

> u=rank(residuals(regc,type="pearson"))/46
> v=rank(residuals(regm,type="pearson"))/46
> cor(u,v)
[1] 0.3051383
On peut alors tenter de faire du boostrap en tirant les paires de résidus à chaque fois, ce qui permet de prendre en compte cette dépendance qui semble exister entre les triangles.
Dans un second temps, on peut aussi introduire de la dépendance sur les scenarios à venir. Lors des tirages des lois normales (évoqués ici), on peut très bien considérer un vecteur Gaussien bivarié, avec une corrélation arbitrairement fixée. La fonction de simulation dans la méthode Chain-Ladder devient alors,
> CLboot2=function(triangle1,l1,s1,triangle2,l2,s2,rho){
+ m=nrow(triangle1)
+ for(i in 2:m){
+ for(j in (m-i+2):m){
+ E=rmnorm(1, mean=c(triangle1[j,i-1]*l1[i-1],
+ triangle2[j,i-1]*l2[i-1]),
+ varcov=matrix(c(triangle1[j,i-1]*s1[i-1]^2,
+ rho*sqrt(triangle1[j,i-1]*triangle2[j,i-1])*
+ s1[i-1]*s2[i-1],
+ rho*sqrt(triangle1[j,i-1]*triangle2[j,i-1])*
+ s1[i-1]*s2[i-1],triangle2[j,i-1]*s2[i-1]^2),2,2))
+ triangle1[j,i]=E[1,1]
+ triangle2[j,i]=E[1,2]
+ }}
+ ULT1=triangle1[,m]
+ DIAG1=diag(triangle1[,m:1])
+ ULT2=triangle2[,m]
+ DIAG2=diag(triangle2[,m:1])
+ return(c(sum(ULT1-DIAG1),sum(ULT2-DIAG2)))
+ }
(le code est sûrement loin d'être optimal, mais au moins on comprend ce qui se passe). En prenant un peu de temps, on peut alors faire tourner différents scenarios, avec des dépendances plus ou moins fortes,
> regm=glm(Ym~col+lig,data=base,family="poisson")
> regc=glm(Yc~col+lig,data=base,family="poisson")
> Ec=residuals(regc,type="pearson")
> Em=residuals(regm,type="pearson")
> YPc=predict(regc,newdata=base)
> YPm=predict(regm,newdata=base)
> n=9
> base=data.frame(YPc,YPm,lig,col)
> nsim=50000
> PROVISION=rep(NA,nsim)
> PROVISIONm=rep(NA,nsim)
> PROVISIONc=rep(NA,nsim)
> PROVISIONc2=rep(NA,nsim)
> PROVISION2=rep(NA,nsim)
> for(k in 1:nsim){
+ I=sample(1:45,size=n^2,replace=TRUE)
+ simEm = Em[I]
+ simEc = Ec[I]
+ I=sample(1:45,size=n^2,replace=TRUE)
+ simEc2= Ec[I]
+
+ bruitm=simEm*sqrt(exp(YPm))
+ bruitc=simEc*sqrt(exp(YPc))
+ bruitc2=simEc2*sqrt(exp(YPc))
+ INCsm=exp(YPm)+bruitm
+ INCsc=exp(YPc)+bruitc
+ INCsc2=exp(YPc)+bruitc2
+ INCMm=matrix(INCsm,n,n)
+ INCMc=matrix(INCsc,n,n)
+ INCMc2=matrix(INCsc2,n,n)
+ CUMMm=INCMm
+ CUMMc=INCMc
+ CUMMc2=INCMc2
+ for(j in 2:n){CUMMm[,j]=CUMMm[,j-1]+INCMm[,j]
+ CUMMc[,j]=CUMMc[,j-1]+INCMc[,j]
+ CUMMc2[,j]=CUMMc2[,j-1]+INCMc2[,j]}
+
+ PROVISIONm[k]=CLb(CUMMm,lambdam,sigmam)
+ PROVISIONc[k]=CLb(CUMMc,lambdac,sigmac)
+ PROVISIONc2[k]=CLb(CUMMc2,lambdac,sigmac)
+ PROVISION[k]=sum(CLb2(CUMMm,lambdam,sigmam,CUMMc,lambdac,sigmac,0.8))
+ PROVISION2[k]=CLb(CUMMm,lambdam,sigmam)+CLb(CUMMc2,lambdac,sigmac)}
où l'on récupère les prédictions marginales (y compris en générant des scénarios indépendants dans la procédure de bootstrap). Ensuite, on regarde la somme des triangles, tout d'abord en tirant les paires d'erreurs obtenus par GLM, puis en tirant un vecteur Gaussien lors des prédiction, et enfin dans le cas complémentement indépendant. On peut commencer par comparer aux montants Chain Ladder obtenu intialement,
> sum(MackChainLadder(P.mat)$FullTriangle[,n]
+ -diag(MackChainLadder(P.mat)$FullTriangle[n:1,]))
[1] 63895.45
> sum(MackChainLadder(P.corp)$FullTriangle[,n]
+ -diag(MackChainLadder(P.corp)$FullTriangle[n:1,]))
[1] 324070.2
Bref, marginalement, on est sur des choses comparables. Si on regarde maintenant au niveau agrégé,
> sum(MackChainLadder(P.tot)$FullTriangle[,n]
+ -diag(MackChainLadder(P.tot)$FullTriangle[n:1,]))
[1] 415998.4
> mean(PROVISION)
[1] 387822.1
> mean(PROVISION2)
[1] 387989.9
Autrement dit, on retrouve la fait que la dépendance n'influence pas le best estimate (ce qui est rassurant), mais il devrait influcer l'erreur,
> plot(density(PROVISION),col="red")
> lines(density(PROVISION2),col="orange")

> quantile(PROVISION,.995)
99.5%
464792.2
> quantile(PROVISION2,.995)
99.5%
452022.6
Bref, on obtient un quantile plus élevé que ce que nous avions en supposant l'indépendance (ce qui nous conforte dans la justesse de notre algorithme). Comme la distribution semble plutôt Gaussienne, et pas trop lognormale, j'ai rajouté la "distribution" obtenue par Mack en supposant la normalité des provisions sur le triangle cumulé, en bleu, en trait plein, et en pointillé le cas log-normal.

Tuesday, December 15 2009
Chain Ladder dans les triangles incomplets
By arthur charpentier on Tuesday, December 15 2009, 15:37 - general insurance
Suite du billet (ici) sur le provisionnement en assurance dommage. On sait depuis le papier d'England et Verrall (1994) que la régression log-Poisson coïncide avec la méthode Chain-Ladder, en tous les cas en moyenne (on peut aller jeter un oeil ici pour les arguments théoriques). Pour les sceptiques, je renvoie au code suivant.
> library(ChainLadder)
> an <- 10; ligne = rep(1:an, each=an); colonne = rep(1:an, an)
> passe = (ligne + colonne - 1)<=an; n = sum(passe)
> PAID=GenIns; INC=PAID
> INC[,2:an]=PAID[,2:an]-PAID[,1:(an-1)]
> Y = as.vector(INC)
> lig = as.factor(ligne)
> col = as.factor(colonne)
> base = data.frame(Y,col,lig)
> reg=glm(Y~col+lig,data=base,family="poisson")
> sum(exp(predict(reg,newdata=base))[passe!=TRUE])
[1] 18680856
On peut vérifier avec la fonction MackChainLadder de library(ChainLadder), i.e.
> MackChainLadder(GenIns)
MackChainLadder(Triangle = GenIns)
Latest Dev.To.Date Ultimate IBNR Mack.S.E CV(IBNR)
1 3,901,463 1.0000 3,901,463 0 0 NaN
2 5,339,085 0.9826 5,433,719 94,634 71,835 0.759
3 4,909,315 0.9127 5,378,826 469,511 119,474 0.254
4 4,588,268 0.8661 5,297,906 709,638 131,573 0.185
5 3,873,311 0.7973 4,858,200 984,889 260,530 0.265
6 3,691,712 0.7223 5,111,171 1,419,459 410,407 0.289
7 3,483,130 0.6153 5,660,771 2,177,641 557,796 0.256
8 2,864,498 0.4222 6,784,799 3,920,301 874,882 0.223
9 1,363,294 0.2416 5,642,266 4,278,972 970,960 0.227
10 344,014 0.0692 4,969,825 4,625,811 1,362,981 0.295
Totals
Latest: 34,358,090.00
Ultimate: 53,038,945.61
IBNR: 18,680,855.61
Mack S.E.: 2,441,364.13
CV(IBNR): 0.13
Bref, les deux coïncident. Tout en étant fondamentalement très différents, comme l'avait noté Mack et Venter (2000). Mais que se passe-t-il si on ne dispose pas d'un triangle de données, mais d'un losange (par exemple en enlevant les 6 données du coin en haut à gauche).
> M=GenIns
> M[1,1:3]=NA
> M[2,1:2]=NA
> M[3,1]=NA
> an <- 10; ligne = rep(1:an, each=an); colonne = rep(1:an, an)
> passe = (ligne + colonne - 1)<=an; n = sum(passe)
> PAID=M; INC=PAID
> INC[,2:an]=PAID[,2:an]-PAID[,1:(an-1)]
> Y = as.vector(INC)
> lig = as.factor(ligne)
> col = as.factor(colonne)
> base = data.frame(Y,col,lig)
> reg=glm(Y~col+lig,data=base,family="poisson")
> sum(exp(predict(reg,newdata=base))[passe!=TRUE])
[1] 17810100
Le montant de provision est ici inférieur au montant obtenu par Chain Ladder (et qui est correct pour avoir refait les calculs),
> MackChainLadder(M)
MackChainLadder(Triangle = M)
Latest Dev.To.Date Ultimate IBNR Mack.S.E CV(IBNR)
1 3,901,463 1.0000 3,901,463 0 0 NaN
2 5,339,085 0.9826 5,433,719 94,634 69,796 0.738
3 4,909,315 0.9127 5,378,826 469,511 118,278 0.252
4 4,588,268 0.8661 5,297,906 709,638 130,514 0.184
5 3,873,311 0.7973 4,858,200 984,889 260,065 0.264
6 3,691,712 0.7223 5,111,171 1,419,459 410,087 0.289
7 3,483,130 0.6153 5,660,771 2,177,641 557,519 0.256
8 2,864,498 0.4155 6,893,493 4,028,995 861,372 0.214
9 1,363,294 0.2341 5,824,117 4,460,823 998,750 0.224
10 344,014 0.0684 5,028,331 4,684,317 1,492,354 0.319
Totals
Latest: 34,358,090.00
Ultimate: 53,387,997.33
IBNR: 19,029,907.33
Mack S.E.: 2,533,277.54
CV(IBNR): 0.13
Bref, si l'on ne dispose que de données incomplètes, il faut faire attention quand on fait une régression log-Poisson...
Incertitude et boni-mali en provisionnement
By arthur charpentier on Tuesday, December 15 2009, 14:31 - formation continue
Yannnick Appert Raulin "provisionnement et solvabilité II" [slides ici]- Arthur Charpentier "modélisation des boni-mali" [slides ici]
- Jérémie Payen "modéles GLM en provisionnement" [slides ici]
- Arnaud Lacoume "le risque à un an" [slides ici] (malheureusement cloué au lit à cause de la grippe et que j'ai remplacé autant que fait se pu)



Il existe aussi une étude menée auprès d'assureurs que je trouve un trop peu uniforme, dans le rapport dit AISAM-ACME (ici)


Mais j'attends toujours des réactions concrètes d'assureurs qui auraient essayé de mettre en oeuvre ces nouvelles résolutions. Pour ma part, je pense que certains auront la mauvaise surprise d'être loins des "gains" annoncés par le rapport AISAM-ACME... Mais comme le faisaient remarquer des participants à la formation, je suis mauvaise langue à vouloir voir le mal partout (ce que j'admet entièrement).
Remarque: histoire de me faire râler davantage, je vais reprendre un passage du rapport AISAM-ACME. Après m'être emporté sur les annologies simplistes liant VaR et TVaR (ici), voilà qu'on nous explique que les aspects temporels ne jouent pas vraiment... Si j'ai le temps de travailler sur ce point, je ferais un billet !
Tuesday, May 5 2009
GAM and claims reserving
By arthur charpentier on Tuesday, May 5 2009, 04:35 - insurance
Yesterday I posted a note on generalized additive models with R (here). I finally decided to mention the application on run-off triangle.I consider here the run-off triangle from table 4 in
Distribution-free Calculation of the
Standard Error of Chain Ladder Reserve Estimates by Thomas Mack (here, ASTIN Bulletin 23, 213-225).
The
standard log-Poisson model (glm) is based on the regression of
incremental payments on 2 kinds of factors: origin year, and
development. Hence, on this 9 year triangle, there is the intercept,
plus 8 coefficients for origin years, and 8 for development years. This
yield a 17 coefficient model, with - only - 45 observations.
An alternative is to consider a log-Poisson gam, where smoothed transforms of origin and developments years are considered. First, we consider splines functions as nonparametric
smoothing terms, with respectively 4 and 8 knots.
It is also possible (instead of spline regressions) some loess smoth terms,







