Les librairies importantes
Importation des données
## CodeGe Age SexeBen DeptBen
## Length:2972487 Min. : 0.00 Length:2972487 Length:2972487
## Class :character 1st Qu.: 50.00 Class :character Class :character
## Mode :character Median : 68.00 Mode :character Mode :character
## Mean : 62.33
## 3rd Qu.: 79.00
## Max. :110.00
## CategorieBen TypeContrat TypePaiement PeriodeSurvenance
## Length:2972487 Length:2972487 Length:2972487 Min. : 1.00
## Class :character Class :character Class :character 1st Qu.: 9.00
## Mode :character Mode :character Mode :character Median :17.00
## Mean :17.72
## 3rd Qu.:27.00
## Max. :36.00
## PeriodePaiement DelaiPaiement RembOam
## Min. : 1.00 Min. : 1.00 Min. : 0.01
## 1st Qu.:10.00 1st Qu.: 5.00 1st Qu.: 9.68
## Median :18.00 Median : 9.00 Median : 20.00
## Mean :18.52 Mean : 23.22 Mean : 54.05
## 3rd Qu.:27.00 3rd Qu.: 21.00 3rd Qu.: 42.64
## Max. :36.00 Max. :1019.00 Max. :60468.80
L’hypothèse d’indépendance entre les années de survenance peut être vérifiée grâce au High and Low Diagonal Test, proposé par Mack en 1993 [@mack1993distribution]. Ce test statistique permet d’évaluer l’indépendance entre les années de survenance, en détectant les effets potentiels d’une année calendaire sur une diagonale spécifique. Mack justifie cette méthode par l’influence qu’une année calendaire peut exercer sur les résultats observés.
\[ \text{Diag}_k = \{ C_{k,0}, C_{k-1,1}, \cdots, C_{1,k-1}, C_{0,k} \}, \quad 0 \leq k \leq n, \]
et, par conséquent, les facteurs individuels
\[ f_{i,j} = \frac{C_{i,j+1}}{C_{i,j}}, \quad \text{pour } i + j \leq n - 1. \]
La technique de construction de la statistique considère le triangle des facteurs de développement individuels et les classe en trois catégories : \(U\) pour “Upper”, \(D\) pour “Down”, et \(N\) pour “Neutre”. Pour chaque colonne de ce triangle, on procède ainsi :
Intuitivement, si l’hypothèse d’indépendance entre les années de survenance est vérifiée, on devrait avoir autant de facteurs dans la catégorie \(U\) que dans la catégorie \(D\) par diagonale. Le nombre de « facteurs bas » (resp. « facteurs élevés ») par diagonale suit alors une loi binomiale \(\mathcal{B}(n, p)\), où \(n\) représente la somme des éléments des catégories \(U\) et \(D\), et \(p\) la probabilité d’observer un « facteur bas » (resp. un « facteur élevé »).
Autrement dit, si l’on désigne par \(D_j\) le nombre de « facteurs bas » et \(U_j\) le nombre de « facteurs élevés » sur une diagonale \(j\), alors \(U_j\) et \(D_j\) suivent une loi binomiale de paramètres \(p = \frac{1}{2}\) et \(n = U_j + D_j\). La moyenne et la variance attendues sont données par :
\[ E(U_j) = E(D_j) = np \quad \text{et} \quad V(U_j) = V(D_j) = np(1-p). \]
Dans sa méthode, Mack propose un test de distribution binomiale basé sur le minimum \(M_j = \min(U_j, D_j)\). En posant \(m\) la partie entière de \(\frac{n-1}{2}\), les caractéristiques de \(M_j\) sont :
\[ E(M_j) = \frac{n}{2} - \frac{n}{2^n} C_n^{m-1} \quad \text{et} \quad V(M_j) = \frac{n(n-1)}{4} - \frac{C_n^{m-1}}{n} \frac{n(n-1)}{2^n} + E(M_j) - (E(M_j))^2. \]
L’hypothèse nulle \(H_0\) consiste à considérer qu’il y a indépendance entre les années de survenance. Sous \(H_0\), les \(M_j\) sont indépendants et on a :
\[ M = \sum_{j=2}^{n-1} M_j, \quad E(M) = \sum_{j=2}^{n-1} E(M_j) \quad \text{et} \quad V(M) = \sum_{j=2}^{n-1} V(M_j). \]
D’après le théorème central limite (TCL), \(M\) suit approximativement une loi normale. Par conséquent, on rejette l’hypothèse \(H_0\) si \(M\) n’appartient pas à l’intervalle de confiance à 95 % suivant :
\[ [E(M) - 1,96 \sqrt{V(M)}, \ E(M) + 1,96 \sqrt{V(M)}]. \]
Triangle = MODELEDURE %>% dplyr::select(RembOam, PeriodePaiement, PeriodeSurvenance) %>%
mutate(PeriodePaiement2 = PeriodePaiement - PeriodeSurvenance + 1) %>%
group_by(PeriodeSurvenance, PeriodePaiement2) %>% summarise(Montants = sum(RembOam))
Triangle_Matrix = matrix(data = 0, ncol = 36, nrow = 36)
for(i in 1:36) {
cumulative_sum = 0
for(j in 1:36) {
if(i + j <= 37) {
subdata <- subset(Triangle, PeriodeSurvenance == i & PeriodePaiement2 == j)
if(nrow(subdata) > 0) {
cumulative_sum = cumulative_sum + subdata$Montants[1] # Ajout de la valeur de Montants
}
Triangle_Matrix[i, j] = cumulative_sum
}
}
}\[ F_j = \frac{C_{i,j+1}}{C_{i,j}}, \quad 0 \leq j \leq n-1 \quad \text{et} \quad 0 \leq i \leq n-1-j \]
Triangle_Matrix_Coefficient = matrix(data = 0, ncol = 35, nrow = 35)
for(i in 1:35) {
for(j in 1:35) {
if(i + j <= 36) {
Triangle_Matrix_Coefficient[i, j] = Triangle_Matrix[i, j+1]/Triangle_Matrix[i, j]
}
}
}Stats_per_row <- apply(Triangle_Matrix_Coefficient, 2, function(row) {
non_zero_values <- row[row != 0]
if (length(non_zero_values) > 0) {
Moyenne <- mean(non_zero_values)
Mediane <- median(non_zero_values)
Ecart_Type <- sd(non_zero_values)
} else {
Moyenne <- NA
Mediane <- NA
Ecart_Type <- NA
}
return(c(Moyenne = Moyenne, Mediane = Mediane, Ecart_Type = Ecart_Type))
})
Stats_per_row <- as.data.frame(t(Stats_per_row))
Stats_per_row## Moyenne Mediane Ecart_Type
## 1 1.705042 1.702191 1.315435e-01
## 2 1.131655 1.123178 4.383289e-02
## 3 1.043290 1.038715 1.864168e-02
## 4 1.019193 1.016847 6.773758e-03
## 5 1.011898 1.009268 6.087354e-03
## 6 1.009641 1.008235 5.258300e-03
## 7 1.005407 1.003978 3.012630e-03
## 8 1.004736 1.003552 3.305999e-03
## 9 1.003549 1.002997 2.703348e-03
## 10 1.002853 1.002225 2.103685e-03
## 11 1.001676 1.001382 1.124604e-03
## 12 1.001665 1.001117 1.339132e-03
## 13 1.001151 1.000728 1.268150e-03
## 14 1.001394 1.000797 1.578124e-03
## 15 1.001198 1.000723 1.126007e-03
## 16 1.001284 1.000539 2.303872e-03
## 17 1.000856 1.000602 8.907398e-04
## 18 1.000475 1.000378 3.150677e-04
## 19 1.000561 1.000415 4.682678e-04
## 20 1.001006 1.000437 1.510862e-03
## 21 1.000511 1.000334 2.733353e-04
## 22 1.000610 1.000364 6.906511e-04
## 23 1.000456 1.000411 2.935030e-04
## 24 1.000581 1.000200 1.106999e-03
## 25 1.000060 1.000010 9.249471e-05
## 26 1.000190 1.000058 3.633155e-04
## 27 1.000382 1.000048 5.776010e-04
## 28 1.000019 1.000007 3.121329e-05
## 29 1.000171 1.000019 3.499892e-04
## 30 1.000043 1.000045 4.236974e-05
## 31 1.000005 1.000000 9.504424e-06
## 32 1.000004 1.000000 7.209786e-06
## 33 1.000216 1.000013 3.634435e-04
## 34 1.000000 1.000000 0.000000e+00
## 35 1.000000 1.000000 NA
Triangle_Reconstructed <- apply(Triangle_Matrix_Coefficient, 2, function(column) {
non_zero_values <- column[column != 0]
if (length(non_zero_values) > 0) {
Mediane <- median(non_zero_values)
} else {
Mediane <- NA
}
column <- ifelse(column == 0, 0,
ifelse(column > Mediane, "U", ifelse(column < Mediane, "D", "N")))
return(column)
})
Triangle_Reconstructed <- as.data.frame(Triangle_Reconstructed)
head(Triangle_Reconstructed,3)## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21
## 1 U U U U U U D U U D U U U U U U U D U U U
## 2 U D D U D D D D D U U U U U U U U U U U D
## 3 D D U D D U U D U U U U U U D U U U N D U
## V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35
## 1 U U D D D D U U D U U U N N
## 2 D D U D D U U U U U N D N 0
## 3 U U U U U U D N U N N N 0 0
\[ E(M_j) = \frac{n}{2} - \frac{n}{2^n} C_n^{m-1} \quad \text{et} \quad V(M_j) = \frac{n(n-1)}{4} - \frac{C_n^{m-1}}{n} \frac{n(n-1)}{2^n} + E(M_j) - (E(M_j))^2. \]
count_anti_diagonals <- function(triangle_matrix) {
n <- nrow(triangle_matrix)
counts <- lapply(2:n, function(k) {
elements <- sapply(1:n, function(i) {
j <- k - i
if (j > 0 && j <= n) triangle_matrix[i, j] else NA
})
elements <- na.omit(elements)
count_D <- sum(elements == "D")
count_U <- sum(elements == "U")
count_N <- sum(elements == "N")
Z <- min(count_D, count_U)
Nn <- count_D + count_U
m <- round((Nn - 1) / 2, 0)
data.frame(
Count_D = count_D,
Count_U = count_U,
Count_N = count_N,
Verif = count_D + count_U + count_N,
Z = Z,
n = Nn,
m = m
)
})
counts_df <- do.call(rbind, counts)
counts_df$E <- with(counts_df, ifelse(n - 1 >= m, n / 2 - n / (2^n) * choose(n - 1, m), NA))
counts_df$V <- with(counts_df, ifelse(
n - 1 >= m,
n * (n - 1) / 4 - n * (n - 1) / (2^n) * choose(n - 1, m) + E - E^2,
NA
))
return(counts_df)
}
AntiDiagonal_Counts <- count_anti_diagonals(Triangle_Reconstructed)
AntiDiagonal_Counts## Count_D Count_U Count_N Verif Z n m E V
## 1 0 1 0 1 0 1 0 0.000000 0.0000000
## 2 0 2 0 2 0 2 0 0.500000 0.2500000
## 3 2 1 0 3 1 3 1 0.750000 0.1875000
## 4 3 1 0 4 1 4 2 1.250000 0.4375000
## 5 0 5 0 5 0 5 2 1.562500 0.3710938
## 6 4 2 0 6 2 6 2 2.062500 0.6210938
## 7 7 0 0 7 0 7 3 2.406250 0.5537109
## 8 4 3 1 8 3 7 3 2.406250 0.5537109
## 9 6 3 0 9 3 9 4 3.269531 0.7359467
## 10 8 2 0 10 2 10 4 3.769531 0.9859467
## 11 1 9 1 11 1 10 4 3.769531 0.9859467
## 12 3 9 0 12 3 12 6 4.646484 1.1679955
## 13 2 11 0 13 2 13 6 5.033691 1.0999391
## 14 6 8 0 14 6 14 6 5.533691 1.3499391
## 15 6 9 0 15 6 15 7 5.928955 1.2818179
## 16 3 13 0 16 3 16 8 6.428955 1.5318179
## 17 7 10 0 17 7 17 8 6.830765 1.4636537
## 18 8 10 0 18 8 18 8 7.330765 1.7136537
## 19 6 13 0 19 6 19 9 7.738029 1.6454599
## 20 5 15 0 20 5 20 10 8.238029 1.8954599
## 21 4 16 1 21 4 20 10 8.238029 1.8954599
## 22 8 14 0 22 8 22 10 9.149931 2.0772445
## 23 6 17 0 23 6 23 11 9.565837 2.0090131
## 24 13 11 0 24 11 24 12 10.065837 2.2590131
## 25 16 7 2 25 7 23 11 9.565837 2.0090131
## 26 10 14 2 26 10 24 12 10.065837 2.2590131
## 27 18 8 1 27 8 26 12 10.985247 2.4407695
## 28 19 9 0 28 9 28 14 11.907756 2.6225162
## 29 12 16 1 29 12 28 14 11.907756 2.6225162
## 30 22 7 1 30 7 29 14 12.333033 2.5542552
## 31 17 12 2 31 12 29 14 12.333033 2.5542552
## 32 17 14 1 32 14 31 15 13.260801 2.7359881
## 33 14 16 3 33 14 30 14 12.833033 2.8042552
## 34 22 8 4 34 8 30 14 12.833033 2.8042552
Moyenne = sum(AntiDiagonal_Counts$E)
Variance = sum(AntiDiagonal_Counts$V)
(M = sum(AntiDiagonal_Counts$m))## [1] 270
InfBorn = Moyenne - 1.96*sqrt(Variance)
SupBorn = Moyenne + 1.96*sqrt(Variance)
print(c(InfBorn, SupBorn))## [1] 220.3017 248.6993
La statistique ne se situe pas dans l’intervalle de confiance, ce qui indique que l’hypothèse d’indépendance entre les années de survenance n’est pas respectée. En conséquence, la valeur observée ne fait pas partie de cet intervalle.
Pour vérifier la corrélation entre \(\frac{C_{i,j+1}}{C_{i,j}}\) et \(\frac{C_{i,j}}{C_{i,j-1}}\), Thomas Mack a proposé, dans son article de 1994 Measuring the Variability of Chain Ladder Reserve Estimates ([Mack 1994]), de réaliser un test de Spearman, comme décrit ci-dessous.
\[ F_j = \frac{C_{i,j+1}}{C_{i,j}}, \quad 0 \leq j \leq n-1 \quad \text{et} \quad 0 \leq i \leq n-1-j \]
Trier \(F_j\) de manière croissante pour \(0 \leq j \leq n-1\).
Calculer le rang \(r_{i,j}\) de \(F_j\) pour chaque ligne, avec \(0 \leq r_{i,j} \leq n-1-j\).
Supprimer le coefficient \(\frac{C_{n-j-1,j+1}}{C_{n-1-j,j}}\) du triangle de départ pour \(0 \leq j \leq n-1\).
Trier à nouveau \(F_j\) de manière croissante.
Calculer le nouveau rang \(s_{i,j}\) des \(F_j\), avec \(0 \leq i \leq n - 1 - j\) et \(1 \leq j \leq n - 2\).
Calculer les coefficients de Spearman \(T_j\) pour chaque colonne \(j\) et le coefficient de corrélation total \(T\) :
\[ T_j = 1 - \frac{6 \sum_{i=0}^{n-1-j} \left( r_{j,i} - s_{j,i} \right)^2}{(n-j)^3 - n + j}, \quad \text{pour} \quad 1 \leq j < n - 2 \]
\[ T = \sum_{j=1}^{n-2} \frac{n - j - 1}{2(n - 1)(n - 2)} T_j \]
\[ T \in \left[ \frac{-0.67}{\sqrt{\frac{(n - 1)(n - 2)}{2}}} , \ \frac{0.67}{\sqrt{\frac{(n - 1)(n - 2)}{2}}} \right] \]
Triangle = MODELEDURE %>% dplyr::select(RembOam, PeriodePaiement, PeriodeSurvenance) %>%
mutate(PeriodePaiement2 = PeriodePaiement - PeriodeSurvenance + 1) %>%
group_by(PeriodeSurvenance, PeriodePaiement2) %>% summarise(Montants = sum(RembOam))
Triangle_Matrix = matrix(data = 0, ncol = 36, nrow = 36)
for(i in 1:36) {
cumulative_sum = 0
for(j in 1:36) {
if(i + j <= 37) {
subdata <- subset(Triangle, PeriodeSurvenance == i & PeriodePaiement2 == j)
if(nrow(subdata) > 0) {
cumulative_sum = cumulative_sum + subdata$Montants[1] # Ajout de la valeur de Montants
}
Triangle_Matrix[i, j] = cumulative_sum
}
}
}\[ F_j = \frac{C_{i,j+1}}{C_{i,j}}, \quad 0 \leq j \leq n-1 \quad \text{et} \quad 0 \leq i \leq n-1-j \]
Triangle_Matrix_Coefficient = matrix(data = 0, ncol = 35, nrow = 35)
for(i in 1:35) {
for(j in 1:35) {
if(i + j <= 36) {
Triangle_Matrix_Coefficient[i, j] = Triangle_Matrix[i, j+1]/Triangle_Matrix[i, j]
}
}
}Rank_Matrix <- matrix(data = 0, ncol = 35, nrow = 35)
for (i in 1:35) {
non_zero_values <- Triangle_Matrix_Coefficient[i, Triangle_Matrix_Coefficient[i, ] != 0]
sorted_positions <- order(non_zero_values)
Rank_Matrix[i, Triangle_Matrix_Coefficient[i, ] != 0] <- sorted_positions
}
head(Rank_Matrix, 3)## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
## [1,] 26 34 35 30 27 25 32 31 28 24 29 18 23 33
## [2,] 32 33 34 26 31 25 28 30 21 22 23 24 18 17
## [3,] 31 32 28 33 29 30 26 25 20 19 23 27 18 15
## [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
## [1,] 17 21 14 19 22 12 10 15 20 11 13 7
## [2,] 16 14 19 29 12 13 27 11 9 15 8 7
## [3,] 24 16 21 22 12 11 8 10 9 17 7 13
## [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35]
## [1,] 8 9 16 6 5 4 3 2 1
## [2,] 10 6 20 5 4 3 2 1 0
## [3,] 14 5 6 4 3 2 1 0 0
Rank_Matrix_S = Rank_Matrix[1:34, 1:34]
for(i in 1:33){
Rank_Matrix_S[35-i, i+1] = 0
}
Rank_Matrix_R = Rank_Matrix_Sfor (i in 1:34) {
non_zero_values <- Rank_Matrix_S[i, Rank_Matrix_S[i, ] != 0]
ranks <- rank(non_zero_values, ties.method = "first")
Rank_Matrix_S[i, Rank_Matrix_S[i, ] != 0] <- ranks
}
head(Rank_Matrix_S, 3)## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
## [1,] 25 33 34 29 26 24 31 30 27 23 28 17 22 32
## [2,] 31 32 33 25 30 24 27 29 20 21 22 23 17 16
## [3,] 30 31 27 32 28 29 25 24 19 18 22 26 17 14
## [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
## [1,] 16 20 13 18 21 11 9 14 19 10 12 6
## [2,] 15 13 18 28 11 12 26 10 8 14 7 6
## [3,] 23 15 20 21 11 10 7 9 8 16 6 12
## [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34]
## [1,] 7 8 15 5 4 3 2 1
## [2,] 9 5 19 4 3 2 1 0
## [3,] 13 4 5 3 2 1 0 0
\[ T_j = 1 - \frac{6 \sum_{i=0}^{n-1-j} \left( r_{j,i} - s_{j,i} \right)^2}{(n-j)^3 - n + j}, \quad \text{pour} \quad 1 \leq j < n - 2 \]
Diff_Matrix <- (Rank_Matrix_R - Rank_Matrix_S) * (Rank_Matrix_R - Rank_Matrix_S)
Sum_By_Row <- rowSums(Diff_Matrix)/((36 - 1:34)^3 - 34 + 1:34)
T_k = 1-6*Sum_By_Row\[ T = \sum_{j=1}^{n-2} \frac{n - j - 1}{2(n - 1)(n - 2)} T_j \]
## [1] 0.2446106
## [1] -0.03884466 0.03884466
L’hypothése n’est pas verifié
Afin de tester l’absence de saisonnalité dans le triangle des données, les étapes suivantes sont réalisées :
Ce test, similaire au premier, permet non seulement de vérifier l’effet de saisonnalité dans les données, mais aussi d’évaluer l’indépendance entre les années d’occurrence. Dans notre cas, les deux hypothèses ne sont pas respectées : nous observons un effet de saisonnalité ainsi qu’une dépendance entre les années d’occurrence.
On peut vérifier l’hypothèse (H3) à l’aide d’un graphique : il s’agit de représenter les résidus \(\frac{C_{i,k+1} - C_{i,k} \hat{f_k}}{\sqrt{C_{i,k}}}\) en fonction des \(C_{i,k}\). L’hypothèse sera vérifiée si les résidus sont aléatoires.
\[ F_j = \frac{\sum_{i=1}^{n-i}C_{i,j+1}}{\sum_{i=1}^{n-i}C_{i,j}}, \quad 0 \leq j \leq n-1 \quad \text{et} \quad 0 \leq i \leq n-1 \]
Triangle_Matrix_A = Triangle_Matrix
C_j = colSums(Triangle_Matrix)
Triangle_Matrix_A[cbind(1:36, 36:1)] = 0
C_j_1 = colSums(Triangle_Matrix_A)
Coef = C_j[2:36]/C_j_1[1:35]Triangle_Matrix_B = Triangle_Matrix
n = ncol(Triangle_Matrix_B)
for(i in 1:35){
Triangle_Matrix_B[n-i+1,] = c(Triangle_Matrix_B[n-i+1,1:i], cumprod(Coef[i:(n-1)])*Triangle_Matrix_B[n-i+1, i])
print(i)
}## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 15
## [1] 16
## [1] 17
## [1] 18
## [1] 19
## [1] 20
## [1] 21
## [1] 22
## [1] 23
## [1] 24
## [1] 25
## [1] 26
## [1] 27
## [1] 28
## [1] 29
## [1] 30
## [1] 31
## [1] 32
## [1] 33
## [1] 34
## [1] 35
Residu = matrix(data = 0, ncol = 35, nrow = 35)
for(i in 1:35){
Residu[1:(35+1-i),i] = (Triangle_Matrix[1:(36-i),i+1]-Triangle_Matrix[1:(36-i),i]*Coef[i])/sqrt(Triangle_Matrix[1:(36-i),i])
}# Tracer chaque colonne dans un graphique séparé (si vous travaillez dans un environnement graphique)
for(i in 1:35) {
plot(Residu[,i], type = "p", col = 1, lty = 1, xlab = "Index", ylab = "Résidu", main = paste("Résidu pour la colonne", i))
Sys.sleep(0.5) # Pause de 0.5 seconde entre les graphiques
}