Mardi prochain, nous aborderons les techniques de segmentation lorsque
les variables discriminantes sont qualitatives. Une très vieille
méthode est dite
de biais minimal.
Pas mal de choses ont été publiées sur ces techniques (e.g.
ici
pour un survol très opérationnel). Car il y en a plusieurs, et il n'y a
pas de consensus sur la meilleure méthode.

L'idée est qu'on dispose, en plus d'une information sur la
sinistralité, de variables sur le conducteur, comme le sexe, ou la région
d'habitation.
> base=read.table("http://freakonometrics.blog.free.fr/public/data/base-biais-minimal.txt",
+ header=TRUE,sep=";")
> head(base)
sexe lieu claims
1 F banlieue 0
2 F banlieue 0
3 H banlieue 0
4 H ville 0
5 H ville 0
6 F campagne 0
On pourrait tarifer en utilisant la prime pure empirique (i.e. la
moyenne empirique)
mais la population semble
relativement hétérogène.
> (POPULATION=table(base$sexe,base$lieu))
banlieue campagne ville
F 250 50 150
H 200 100 300
> SINISTRE=POPULATION
> SINISTRE[1,]=tapply(base[base$sexe==rownames(POPULATION)[1],]$claims,
+ base[base$sexe==rownames(POPULATION)[1],]$lieu,sum)
> SINISTRE[2,]=tapply(base[base$sexe==rownames(POPULATION)[2],]$claims,
+ base[base$sexe==rownames(POPULATION)[2],]$lieu,sum)
> SINISTRE
banlieue campagne ville
F 21 4 12
H 22 9 30
> (FREQUENCE=SINISTRE/POPULATION)
banlieue campagne ville
F 0.084 0.080 0.080
H 0.110 0.090 0.100
Une première piste est complètement non-paramétrique: on utilise ces
fréquences empiriques comme base tarifaire. Mais on se rend compte que
si des sous-groupes sont de taille petite, les fréquences empiriques
seront très volatiles, et pourront passer du simple au double d'une
année sur l'autre. On va donc tenter un modèle paramétrique.
Formalisons un peu. Comme dans notre exemple, on note

la
fréquence empirique observée lorsque la première variable (que l'on
notera

) prend la valeur

(ici

prend deux valeurs,
homme ou
femme) et la second variable

prend
la valeur

(ici

prend trois valeurs,
ville,
banlieue et
campagne). On notera

l'exposition, i.e. ici le nombre d'assurés.
L'estimation de

et de

se fait
généralement de trois manières. Par
moindres carrés, i.e. en cherchant a minimiser
La condition du premier ordre donne ici
soit
L'autre condition du premier ordre donne
On résout alors ce petit système de manière itérative (car il n'y a pas de solution analytique simple).
> L=matrix(NA,100,2);C=matrix(NA,100,3)
> L[1,]=c(1,1);colnames(L)=rownames(POPULATION)
> C[1,]=c(1,1,1);colnames(C)=colnames(POPULATION)
> for(j in 2:100){
+ L[j,1]=sum(SINISTRE[1,]*C[j-1,])/sum(POPULATION[1,]*C[j-1,]^2)
+ L[j,2]=sum(SINISTRE[2,]*C[j-1,])/sum(POPULATION[2,]*C[j-1,]^2)
+ C[j,1]=sum(SINISTRE[,1]*L[j,])/sum(POPULATION[,1]*L[j,]^2)
+ C[j,2]=sum(SINISTRE[,2]*L[j,])/sum(POPULATION[,2]*L[j,]^2)
+ C[j,3]=sum(SINISTRE[,3]*L[j,])/sum(POPULATION[,3]*L[j,]^2)
+ }
> L[c(1:5,98:100),]
F H
[1,] 1.00000000 1.0000000
[2,] 0.08222222 0.1016667
[3,] 0.08099202 0.1024439
[4,] 0.08092684 0.1024843
[5,] 0.08092343 0.1024864
[6,] 0.08092324 0.1024865
[7,] 0.08092324 0.1024865
[8,] 0.08092324 0.1024865
> C[c(1:5,98:100),]
banlieue campagne ville
[1,] 1.000000 1.0000000 1.0000000
[2,] 1.054823 0.9068653 0.9809860
[3,] 1.057697 0.9045362 0.9789077
[4,] 1.057847 0.9044141 0.9787988
[5,] 1.057854 0.9044077 0.9787931
[6,] 1.057855 0.9044074 0.9787928
[7,] 1.057855 0.9044074 0.9787928
[8,] 1.057855 0.9044074 0.9787928
> PREDICTION1=SINISTRE
> PREDICTION1[1,]=L[100,1]*C[100,]
> PREDICTION1[2,]=L[100,2]*C[100,]
> PREDICTION1
banlieue campagne ville
F 0.08560504 0.07318758 0.07920709
H 0.10841583 0.09268954 0.10031304
On note que l'itération converge très vite, même en partant de n'importe quelle valeur (ici 1 partout, mais on aurait pu être plus malin, et prendre la moyenne empirique sur la population entière, par exemple).
Une seconde idée est d'utiliser un "
principe de balancement": on veut que, par modalité, les prédictions coïncident avec les valeurs empiriques. Formellement, on veut
en somment sur la ligne i, ou sur la colonne j
La première équation donne
et la seconde

}
La encore, une méthode itérative permet de calculer numériquement les solutions de ces équations.
> L=matrix(NA,100,2);C=matrix(NA,100,3)
> L[1,]=c(1,1);colnames(L)=rownames(POPULATION)
> C[1,]=c(1,1,1);colnames(C)=colnames(POPULATION)
> for(j in 2:100){
+ L[j,1]=sum(SINISTRE[1,])/sum(POPULATION[1,]*C[j-1,])
+ L[j,2]=sum(SINISTRE[2,])/sum(POPULATION[2,]*C[j-1,])
+ C[j,1]=sum(SINISTRE[,1])/sum(POPULATION[,1]*L[j,])
+ C[j,2]=sum(SINISTRE[,2])/sum(POPULATION[,2]*L[j,])
+ C[j,3]=sum(SINISTRE[,3])/sum(POPULATION[,3]*L[j,])
+ }
> PREDICTION2=SINISTRE
> PREDICTION2[1,]=L[100,1]*C[100,]
> PREDICTION2[2,]=L[100,2]*C[100,]
> PREDICTION2
banlieue campagne ville
F 0.08558024 0.07376881 0.07944334
H 0.10802471 0.09311559 0.10027833
On peut d'ailleurs vérifier que les conditions de balancement sont vérifiées
> sum(PREDICTION2[1,]*POPULATION[1,])
[1] 37
> sum(SINISTRE[1,])
[1] 37
> sum(PREDICTION2[2,]*POPULATION[2,])
[1] 61
> sum(SINISTRE[2,])
[1] 61
> sum(PREDICTION2[,1]*POPULATION[,1])
[1] 43
> sum(SINISTRE[,1])
[1] 43
> sum(PREDICTION2[,2]*POPULATION[,2])
[1] 13
> sum(SINISTRE[,2])
[1] 13
> sum(PREDICTION2[,3]*POPULATION[,3])
[1] 42
> sum(SINISTRE[,3])
[1] 42
Enfin, la dernière solution que l'on verra peut-être d'utiliser un
critère de type chi-deux. On cherche alors a minimiser
La encore on utilise les conditions du premier ordre, et on obtient
et une expression du même genre pour

.
> L=matrix(NA,100,2);C=matrix(NA,100,3)
> L[1,]=c(1,1);colnames(L)=rownames(POPULATION)
> C[1,]=c(1,1,1);colnames(C)=colnames(POPULATION)
> for(j in 2:100){
+ L[j,1]=sqrt(sum(POPULATION[1,]*FREQUENCE[1,]^2/C[j-1,])/sum(POPULATION[1,]*C[j-1,]))
+ L[j,2]=sqrt(sum(POPULATION[2,]*FREQUENCE[2,]^2/C[j-1,])/sum(POPULATION[2,]*C[j-1,]))
+ C[j,1]=sqrt(sum(POPULATION[,1]*FREQUENCE[,1]^2/L[j,])/sum(POPULATION[,1]*L[j,]))
+ C[j,2]=sqrt(sum(POPULATION[,2]*FREQUENCE[,2]^2/L[j,])/sum(POPULATION[,2]*L[j,]))
+ C[j,3]=sqrt(sum(POPULATION[,3]*FREQUENCE[,3]^2/L[j,])/sum(POPULATION[,3]*L[j,]))
+ }
> PREDICTION3=SINISTRE
> PREDICTION3[1,]=L[100,1]*C[100,]
> PREDICTION3[2,]=L[100,2]*C[100,]
> PREDICTION3
banlieue campagne ville
F 0.08561009 0.07389097 0.07946408
H 0.10802438 0.09323697 0.10026923
On peut d'ailleurs visuellement confirmer l'intuition que les trois
méthodes donnent des résultats relativement proches (avec les femmes a gauche et les hommes a droite)
Pour aller un peu plus loin, il existe des liens avec les GLM (comme
évoqués en détails
ici
ou
la,
par exemple). En fait, formellement, la première méthode fait penser au modèle linéaire (c'est a dire un modèle Gaussien), sauf que le modèle
est ici multiplicatif, c'est a dire avec un lien logarithmique. En
faisant une régression GLM gaussienne avec un lien log, on retrouve des
prédictions par classes très très proches,
> reggauslog=glm(claims~lieu+sexe,data=base,
+ family=gaussian(link="log"),start=c(1,1,1,1))
> summary(reggauslog)
Call:
glm(formula = claims ~ lieu + sexe, family = gaussian(link = "log"),
data = base, start = c(1, 1, 1, 1))
Deviance Residuals:
Min 1Q Median 3Q Max
-0.10842 -0.10031 -0.09269 -0.07921 0.92681
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.45801 0.18441 -13.329 <2e-16 ***
lieucampagne -0.15671 0.31194 -0.502 0.615
lieuville -0.07768 0.20844 -0.373 0.709
sexeH 0.23623 0.20850 1.133 0.257
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for gaussian family taken to be 0.08483775)
Null deviance: 88.853 on 1049 degrees of freedom
Residual deviance: 88.730 on 1046 degrees of freedom
AIC: 395.28
Number of Fisher Scoring iterations: 9
> base0=data.frame(sexe=factor(rep(rownames(FREQUENCE),3)),
+ lieu=factor(rep(colnames(FREQUENCE),each=2)))
> matrix(predict(reggauslog,newdata=base0,type="response"),2,3)
[,1] [,2] [,3]
[1,] 0.08560498 0.07318789 0.07920718
[2,] 0.10841564 0.09268984 0.10031306
Par contre le second coïncide avec la régression de Poisson (avec
toujours un lien log, pour garder la structure multiplicative). Ce
résultat était évoqué sur ce blog
ici (la méthode de balancement étant parfois connue sous le nom de "
méthode des marges").
> regpoislog=glm(claims~lieu+sexe,data=base,
+ family=poisson(link="log"),start=c(1,1,1,1))
> summary(regpoislog)
Call:
glm(formula = claims ~ lieu + sexe, family = poisson(link = "log"),
data = base, start = c(1, 1, 1, 1))
Deviance Residuals:
Min 1Q Median 3Q Max
-0.4648 -0.4478 -0.4315 -0.3986 1.8334
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -2.45830 0.18646 -13.184 <2e-16 ***
lieucampagne -0.14852 0.31978 -0.464 0.642
lieuville -0.07441 0.22170 -0.336 0.737
sexeH 0.23291 0.21355 1.091 0.275
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for poisson family taken to be 1)
Null deviance: 464.83 on 1049 degrees of freedom
Residual deviance: 463.52 on 1046 degrees of freedom
AIC: 667.52
Number of Fisher Scoring iterations: 9
> matrix(predict(regpoislog,newdata=base0,type="response"),2,3)
[,1] [,2] [,3]
[1,] 0.08558023 0.07376881 0.07944334
[2,] 0.10802471 0.09311559 0.10027833
Bref, on rediscutera des méthodes de biais minimal, avant de revenir
sur des rappels de probabilités et de statistiques, et de commencer
l'étude des GLM.