Digital resources in the Social Sciences and Humanities OpenEdition Our platforms OpenEdition Books OpenEdition Journals Hypotheses Calenda Libraries OpenEdition Freemium Follow us

Il y a des jours avec, et des jours sans

Je ne sais pas si ça vous est déjà arrivé, mais quand on fait des crêpes, la probabilité d’en réussir une est proportionnelle à la probabilité que l’on vient de réussir les dernières. Autrement dit si j’ai réussi les premières, je suis dans un bon jour, et je réussi davantage celles qui suivent. Alors que si je commence par rater les premières, je suis dans un mauvais jour, et je les rate toutes (pour les sportifs, il est aussi possible de noter que, par exemple, au tennis, la probabilité de réussir son service est d’autant plus forte que j’ai réussi les derniers: c’est pareil).

  • Une première formalisation du problème

Supposons que sur les http://freakonometrics.blog.free.fr/public/perso3/crepes-01.gif premiers essais (qui servent d’étalonnage), http://freakonometrics.blog.free.fr/public/perso3/crepes-02.gif fois j’ai réussi ma crêpe, et http://freakonometrics.blog.free.fr/public/perso3/crepes-03.gif fois, je l’ai ratée (trop de trous, trop irrégulière, trop cuite, que sais-je encore). Mon a priori sur la probabilité de ne pas avoir de chance (et de rater ma crêpe) est http://freakonometrics.blog.free.fr/public/perso3/crepes-04.gif. Supposons que la probabilité de réussir à l’instant http://freakonometrics.blog.free.fr/public/perso3/crepes-06.gif (on commence à compter après les http://freakonometrics.blog.free.fr/public/perso3/crepes-01.gif premiers essais) soit la fréquence empirique observée sur le passé. Autrement dit

http://freakonometrics.blog.free.fr/public/perso3/crepes-05.gif

http://freakonometrics.blog.free.fr/public/perso3/crepees-07.gif est le nombre de succès. En particulier http://freakonometrics.blog.free.fr/public/perso3/crepes-09.gif. On retrouve ici le fait que plus j’en ai raté, plus j’ai de chances de rater les prochaines… c’est la mauvaise main en quelque sorte.
Afin de mieux comprendre, supposons http://freakonometrics.blog.free.fr/public/perso3/crepes-10.gif. Autrement dit, sur mes deux premiers essais (qui ne servent qu’à étalonner), j’ai raté et réussi une fois. Juste avant l’instant 1, j’ai deux possibilité: réussir ou rater, avec la probabilité http://freakonometrics.blog.free.fr/public/perso3/crepes-11.gif. I.e.

http://freakonometrics.blog.free.fr/public/perso3/crepes-12.gif

Si on se place une crêpe plus loin, et que l’on regarde les probabilités conditionnelles

http://freakonometrics.blog.free.fr/public/perso3/crepes-13b.gif

avec quelque-chose de similaire si on conditionne par l’autre événement,

http://freakonometrics.blog.free.fr/public/perso3/crepes-14.gif

Et donc la probabilité non conditionnelle s’écrit

http://freakonometrics.blog.free.fr/public/perso3/crepes-15.gif

i.e.

http://freakonometrics.blog.free.fr/public/perso3/crepes-16.gif
http://freakonometrics.blog.free.fr/public/perso3/crepes-18.gif

et

http://freakonometrics.blog.free.fr/public/perso3/crepes-19.gif

Moralité

http://freakonometrics.blog.free.fr/public/perso3/crepes-20.gif

Autrement dit, on poursuivant la récurrence, on a que http://freakonometrics.blog.free.fr/public/perso3/crepees-07.gif est uniformément distribué sur http://freakonometrics.blog.free.fr/public/perso3/crepes-21.gif
Étonnant, non ? Autrement dit, si j’ai commencé par un échec et une réussite, la probabilité d’avoir 50 réussites sur 100 essais sera très exactement http://freakonometrics.blog.free.fr/public/perso3/crepes-23.gif. Qui est la même probabilité que d’avoir 1 réussite, ou 99 !
On a aussi que

http://freakonometrics.blog.free.fr/public/perso3/crepes-22.gif

Mais que se passe-t-il si http://freakonometrics.blog.free.fr/public/perso3/crepes-02.gif et http://freakonometrics.blog.free.fr/public/perso3/crepes-03.gif ne sont plus égaux à 1 ?

  • Lien avec l’approche bayésienne et la théorie de la crédibilité

Ce qui est amusant, c’est que la probabilité

http://freakonometrics.blog.free.fr/public/perso3/crepes-05.gif

est bien connue par les personnes qui connaissent l’assurance et la théorie de la crédibilité. Supposons que je note http://freakonometrics.blog.free.fr/public/perso3/crepes-24.gif la variable indicatrice correspondant à une réussite ou un succès au http://freakonometrics.blog.free.fr/public/perso3/crepes-26.gifème essai (avec probabilité http://freakonometrics.blog.free.fr/public/perso3/crepes-25.gif). D’un point de vu bayésien, la loi conjuguée de la loi binomiale (on va compter les réussites sur n essais) est une loi Beta. Rappelons que la loi Beta http://freakonometrics.blog.free.fr/public/perso3/crepes-27.gif a pour densité

http://freakonometrics.blog.free.fr/public/perso3/crepes-28.gif

sur http://freakonometrics.blog.free.fr/public/perso3/crepes-29.gif, et que l’espérance de cette variable est http://freakonometrics.blog.free.fr/public/perso3/crepes-30.gif, i.e. http://freakonometrics.blog.free.fr/public/perso3/crepes-31.gif. Donc cette modélisation devrait parfaitement convenir à notre problème. Ce qui est intéressant, c’est que comme on travaille avec la loi conjuguée, la loi ex post est encore une loi Beta. Autrement dit, ici, si je suppose que http://freakonometrics.blog.free.fr/public/perso2/testic-07.gif suit a priori une loi Beta http://freakonometrics.blog.free.fr/public/perso3/crepes-27.gif, et que la loi de http://freakonometrics.blog.free.fr/public/perso3/crepees-07.gif sachant http://freakonometrics.blog.free.fr/public/perso2/testic-07.gif suit une loi binomiale http://freakonometrics.blog.free.fr/public/perso3/crepes-32.gif, alors la loi a posteriori de http://freakonometrics.blog.free.fr/public/perso2/testic-07.gif sachant http://freakonometrics.blog.free.fr/public/perso3/crepes-33.gif est une loi http://freakonometrics.blog.free.fr/public/perso3/crepes-34.gif (c’est ce que l’on avait vu ici). Et en particulier

http://freakonometrics.blog.free.fr/public/perso3/crepes-35.gif

Autrement dit on obtient une combinaison convexe entre la moyenne de la loi a priori (à gauche) et la fréquence empirique (à droite).
On retrouve ici ce que nous avions noté auparavant, en notant que http://freakonometrics.blog.free.fr/public/perso3/crepes-36.gif, et http://freakonometrics.blog.free.fr/public/perso3/crepes-37.gif.
On peut toutefois se demander si le résultat que l’on avait obtenu sur la loi de S_n reste valide ici…
Notons que

http://freakonometrics.blog.free.fr/public/perso3/crepes-38.gif

i.e. (moyennant quelques calculs)

http://freakonometrics.blog.free.fr/public/perso3/crepes-40.gif

Dans le cas où http://freakonometrics.blog.free.fr/public/perso3/crepes-10.gif, en réécrivant aussi le premier terme, on a

http://freakonometrics.blog.free.fr/public/perso3/crepes-41.gif

i.e.

http://freakonometrics.blog.free.fr/public/perso3/crepes-42.gif

On retrouve bien la formule obtenue auparavant… Ce qui est intéressant aussi, c’est que si on note que

http://freakonometrics.blog.free.fr/public/perso3/crepes-43.gif

or

http://freakonometrics.blog.free.fr/public/perso3/crepes-44.gif

et donc

http://freakonometrics.blog.free.fr/public/perso3/crepes-45.gif

et par récurrence, on obtient que

http://freakonometrics.blog.free.fr/public/perso3/crepes-46.gif

et que de plus

http://freakonometrics.blog.free.fr/public/perso3/crepes-47.gif

Autrement dit, effectivement, si j’en ai raté beaucoup au début, ma probabilité d’en rater beaucoup est grande (et elle est d’ailleurs constante). Certains parleraient de no-free lunch.

Découpage équitable de la pizza avec des olives

mais non papa, tu comprends jamais rien ! ok, c’est bien si on a autant de pizza tous les deux… mais on veut aussi avoir autant d’olives tous les deux ! et autant de morceaux d’ananas !”. Ouais, bon, on n’est pas couché là !

On va quand même essayer de la couper cette pizza (avant qu’elle ne refroidisse) !

  • Partage de la pizza et des olives

Commençons par supposer que seules les olives soient importantes. La première idée que j’aurais serait de faire une régression médiane, qui va découper le nuage de points (les olives) en deux…

Sous R (oui, j’ai installé R sur la table de la cuisine), c’est assez facile à mettre en œuvre… Pour des raisons de symétrie, je vais faire les régressions de l’abscisse sur l’ordonnée, et réciproquement…

> library(quantreg)
> lq=rq(y ~ x, tau = 0.5, data=D)
> abline(lq,lwd=5,col="red")
> sum(y0>predict(lq))
[1] 22
> sum(y0<=predict(lq))
[1] 22
>
> lq=rq(x ~ y, tau = 0.5, data=D)
> abline(b=1/lq$coefficients[2],
+ a=-lq$coefficients[1]/lq$coefficients[2],lwd=5,col="red")
> sum(x0>predict(lq))
[1] 22
> sum(x0<=predict(lq))
[1] 22

Le soucis est que si la régression n’est pas contrainte, il y a une répartition 50-50 des olives, mais les parts ne sont pas équitables,

> library(quantreg)
> lq=rq(y ~ 0+x, tau = 0.5, data=D)
> abline(lq,lwd=5,col="red")
> sum(y0>predict(lq))
[1] 20
> sum(y0<=predict(lq))
[1] 24
>
> lq=rq(x ~ 0+y, tau = 0.5, data=D)
> abline(b=1/lq$coefficients,a=0,lwd=5,col="red")
> sum(x0>predict(lq))
[1] 25
> sum(x0<=predict(lq))
[1] 19

et si je supprime la constante les parts sont équitables (la régression passe par le centre la pizza), mais le partage des olives n’est pas équilibré…

On peut aussi calculer pour tous les angles possibles ce que donnerait des partages de la pizza (qui passent par le centre). C’est ce que représente la courbe rouge ci-dessous: l’extérieur du disque le ratio des olives dépasse 1, à l’intérieur il est inférieur à 1. Les découpages optimaux correspondent au cas où le ratio vaut précisément 1… ce qui est possible si on coupe comme indiqué ci-dessous, à droite,

Je pense qu’on doit pouvoir montrer qu’il est toujours possible de couper la pizza en deux, de manière équitable, avec autant d’olives de part et d’autre (s’il y a un nombre pair d’olives).
oui mais papa… tu nous avais dit que tu savais pas couper en passant par le centre…”. Ah oui, c’est vrai ! Damned…. bon, utilisons la méthode décrite dans le billet précédant (ici), a priori ça doit être possible de trouver un sommet pour lequel le partage des olives est équitable. En fait, on pourrait aussi tirer au hasard des points dans la pizza, et compter les olives en faisant la répartition de manière alternée,

> sommet=matrix(NA,500000,3)
> for(s in 1:nrow(sommet)){
+ a0=runif(10)*2-1; b0=runif(10)*2-1
+ if(a0^2+b0^2)<=1){
+ slope1=(y0-b0)/(x0-a0)
+ I1=((slope1>0)&(slope1<1))|((slope1<(-1)))
+ sommet[s,]=c(sum(I1),a0,b0)
}}

On a alors en rouge l’ensemble des points à partir desquels on peut faire des découpages en 8, avec des pointes à 45° (en commençant par couper horizontalement)

Et ça semble marcher !

oui mais papa… tu as oublié les ananas…”.

  • Partage de la pizza et des olives et des ananas

En utilisant la méthode précédente, rien de plus simple ! En plus de compter la répartition des olives, on va compter la répartition des ananas…! Sur le dessin à gauche on a les olives et les ananas. A droite, les points rouges correspondent à des répartitions équitables des olives, et les bleus des répartitions équitables des ananas… Reste à trouver des points à la fois rouges et bleus,

ce sont finalement les points violets ci-dessous ! On a alors une méthode pour couper la pizza en deux parts de même taille, avec autant d’olives et autant d’ananas de part et d’autres !

Découpage équitable de la pizza

Bon, maintenant que l’année scolaire est passée, je vais arrêter un peu les billets sérieux pour revenir pour mes mésaventures à la maison. Par exemple, hier soir, c’était pizza. Et mes enfants aiment partager à deux une pizza (sur laquelle on a rajouté plein de choses qu’ils aiment, genre des olives, ou des morceaux d’ananas). Mais il faut un découpage équitable. Les enfants ne veulent pas un partage juste, mais un partage moitié-moitié.

Classiquement, je coupe la pizza en deux (cf figure ci-contre, avec un côté en bleu pour mon fils, et un en rouge pour ma fille, histoire de simplifier un peu). Mais comme me l’a fait noté mon fils, si mon couteau ne passe pas par le centre de la pizza (on va dire le centre du cercle parce qu’il va falloir faire des maths… pour les recettes de cuisine, il faut changer de site, genre ici).
Donc pour faire simple, la proba d’avoir deux parts rigoureusement égale est très très faible… car il faut couper suivant une droite qui passe exactement au centre (sinon, il y a quelqu’un qui est défavorisé, alors on tire au sort… a prioric’est juste juste, mais ex-post, il y en a toujours un ou une qui trouve le système injuste et qui veut qu’on retire au hasard…)
Fort heureusement, il existe une technique simple, et rigoureusement juste, permettant d’avoir des parts équitables…
L’idée est la suivante: on commence par couper horizontalement, n’importe où. Ensuite, on coupe verticalement (à angle droit, en prenant son équerre) de manière à récupérer 4 parts. Au point d’intersection,  on coupe à 45° direction nord-est, et 45° direction nord-ouest…. Une fois le découpage effectué, on réparti les parts, à tour de rôle, les parts bleues pour mon fils, et celles en rouges pour ma fille,

Car le truc génial est que le découpage – en plus d’être fort élégant – est parfaitement équitable ! Comme les enfants sont toujours sceptiques, il faut bien sûr leur prouver que oui, ils en auront exactement pareil. Pour ça on reprend le couteau…

Si on recoupe les parts suivant les traits-ci-dessus, chaque part bleue pourra être superposée à une part rouge (la preuve mathématique repose sur des simple notions de symétrie…). Génial non ? On a même le théorème du mardi soir, à savoir que “si on coupe une pizza en 8 parts, avec des pointes à 45° partir d’un point choisi arbitrairement dans la pizza, alors la somme alternée des parts sera égale” (cf ici). En 1967, Upton a posé ce problème,

Larry Carter et Stan Wagon affirmaient que ce résultat resterait vrai si on coupait en 12 ou 16 parts (avec des angles égaux pour les pointes), mais pas pour 6, 10, 14 ou 18 par exemple. Le blog du chou romanesco (ici et ) prétend que c’est vrai pour les découpages en un nombres pairs. En fait, Rick Mabry et Paul Deiermann ont un théorème assez général ( pour la version complète) et qui généralise aussi en dimension 3 (pour une calzone en quelque sorte). Mais je sens que ça n’intéresse plus trop les enfants, qui ont déjà fini la pizza….

Les plus curieux peuvent aussi consulter le court article ci-dessous,

Comment parle un président français le 31 décembre ?

Il y a pas mal d’agitation présidentielle sur les blogs (français) cette semaine, que ce soit au sujet des 30 ans de l’élection de François Mitterrand, ou l’annonce de la date de la prochaine élection présidentielle (et probablement d’autres raisons). Un peu naïvement je me suis demandé si les présidents étaient vraiment si différents que ça ? Ou plus précisément, est-ce qu’une fois investis par la fonction, tous ces hommes ne se comporteraient-ils pas – finalement – tous pareils ?

Pour cela je me suis simplement demandé si on pouvait distinguer les discours des différents Présidents. J’ai donc pris quelques discours entendus les 31 décembre, lors de vœux retransmis à la télévision (en ligne ici, en excluant les discours aux forces armées, qui me semblaient biaiser un peu mon échantillon). On commence par récupérer la liste de tous les mots prononcés (les fichiers csv sont en ligne ici)

setwd("/home/arthur/Documents/r-data/voeux/")
FILES=list.files()
library(tau)
BASE=scan(FILES[1],what="character")
WORD=fixEncoding(BASE,latin1=TRUE)
 for(i in 2:length(FILES)){
BASE=scan(FILES[i],what="character")
 WORD=c(WORD,fixEncoding(BASE,latin1=TRUE))
 }

Ensuite on regarde le top 500 (j’exclue les mots communs genre le ou la, mais je garde les pronoms, comme mon ou notre),

> WORD=toupper(WORD)
> LW=rev(sort(table(WORD)))
> LISTE=names(LW[1:500])
> LISTE=LISTE[-c(1,2,3,4,5,6,7,8,9,10,11,14,15,18,19,20,21,22,23,25,
               27,43,40,36,41,60)]
> LISTE[1:25]
 [1] "NOUS"   "JE"     "VOUS"   "NOTRE"  "PLUS"   "FRANCE" "PAS"    "NOS"   
 [9] "EST"    "AVEC"   "SE"     "MES"    "CEUX"   "MAIS"   "SONT"   "OU"    
[17] "CETTE"  "AUSSI"  "TOUS"   "SUR"    "SI"     "PAYS"   "LEUR"   "FAIRE" 
[25] "VOTRE"

et créer une base de décompte, par discours,

ANNEE=as.numeric(substr(FILES,6,7))
AN=1900+ANNEE*(ANNEE>15)+(100+ANNEE)*(ANNEE<15)
PRES=c("CHIRAC","CHIRAC","CHIRAC","SARKOZY","SARKOZY",
"SARKOZY","VGE","VGE","VGE","MITTERRAND","MITTERRAND",
"MITTERRAND","MITTERRAND","MITTERRAND")
NOM=paste(PRES,AN,sep="-")
COMPTE=matrix(NA,length(FILES),length(LISTE))
for(i in 1:length(FILES)){
BASE=scan(FILES[i],what="character")
WORD=toupper(fixEncoding(BASE,latin1=TRUE))
for(j in 1:length(LISTE)){
COMPTE[i,j]=sum(WORD==LISTE[j])
}}
colnames(COMPTE)=LISTE
rownames(COMPTE)=NOM

On peut alors faire tourner des procédures d’analyse de données, comme une ACP

library("FactoMineR")
res.pca = PCA(COMPTE, scale.unit=TRUE, ncp=5, graph=FALSE)
plot.PCA(res.pca, axes=c(1, 2), choix="ind")

Les projections des individus (les discours) sont les suivantes

alors que celles pour les variables (les mots) sont, toujours sur les deux premiers axes factoriels,

On peut jouer des heures à se demander qui dit quoi, mais ce qui m’intéressait était de voir si les présidents étaient proches, en terme de discours. On peut alors faire des classifications hiérarchiques,

DISTANCE = dist(COMPTE)
h = hclust(DISTANCE) 
plot(as.dendrogram(h), horiz = TRUE)

ou ici avec un autre algorithme de classification

On notera les regroupements dépendent peu des distances et des méthodes de constitution de classes… et que les regroupements se font par président: tous les discours de François Mitterrand semblent proches, et tous ceux de Jacques Chirac aussi (en tous les cas ceux que j’ai téléchargé, mais l’analyse n’est pas exhaustive). On notera aussi la proximité entre Valéry Giscard d’Estaing l’année de son élection, et Nicolas Sarkozy l’année de son élection….

C’est finalement un peu rassurant de voir que les Présidents ne sont pas tous les mêmes, et qu’on peut les reconnaitre en fonction de leur discours… c’est tout du moins la prochaine étape, ou on va voir si on peut affecter des nouveaux discours (que je n’ai pas utilisés pour l’analyse) dans des classes, et repérer qui l’a écrit…

Multivariate probit regression using (direct) maximum likelihood estimators

Consider a random pair http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-01.gif of binary responses, i.e. http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-02.gif with http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-03.gif taking values 1 or 2. Assume that probability http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-04.gif can be function of some covariates.

  • The Gaussian vector latent structure

A standard model is based a latent Gaussian structure, i.e. there exists some random vector http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-06.gif such that http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-07.gif if http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-08.gif is lower than a given threshold, and 1 otherwise.
As in standard probit models, assume that

http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-09.gif

where we can assume that http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-10.gif is a Gaussian random vector. This assumption can be used to derive the likelihood of a sample http://freakonometrics.hypotheses.org/files/2015/12/biv-prob-11.gif.

> logV=function(parameter){
+ CORRELATION=parameter[1]
+ BETA=matrix(parameter[2:length(parameter)],ncol(Y),ncol(X))
+ z=cbind(X%*%(BETA[1,]),X%*%(BETA[2,]))
+ sigma=matrix(c(1,CORRELATION,CORRELATION,1),2,2)
+     a11=pmnorm(z[1,],rep(0,ncol(Y)),varcov=sigma)
+ for(i in 2:nrow(z)){a11=c(a11,pmnorm(z[i,],rep(0,ncol(Y)),varcov=sigma))}
+     a10=pnorm(z[1,1],sd=sqrt(sigma[1,1]))-pmnorm(z[1,],varcov=sigma)
+ for(i in
+ 2:nrow(z)){a10=c(a10,pnorm(z[i,1],sd=sqrt(sigma[1,1]))-pmnorm(z[i,],varcov=sigma))}
+     a01=pnorm(z[1,2],sd=sqrt(sigma[2,2]))-pmnorm(z[1,],varcov=sigma)
+ for(i in
+ 2:nrow(z)){a01=c(a01,pnorm(z[i,2],sd=sqrt(sigma[2,2]))-pmnorm(z[i,],varcov=sigma))}
+     a00=1-a10-a01-a11
+ -sum(((Y[,1]==1)&(Y[,2]==1))*log(a11) +
+     1*log(a01) +
+     2*log(a10) +
+     3*log(a00) )
+ }
> OPT=optim(fn=logV,par=c(0,1,1,1,1,1,1),method="BFGS")$par

(the code is a bit long since I had trouble working properly with matrices – or more precisely to vectorize my functions – so I used loops… I am sure it is possible to write a better code).
It is possible to generate samples (based on that specific model) to check that we can actually derive proper maximum likelihood estimators,

> library(mnormt)
> set.seed(1)
> n=1000
> r=0.5
> X1=runif(n)
> X2=rnorm(n)
> Y1S=1+5*X1
> Y2S=8-5*X1
> RES=rmnorm(n,mean=c(0,0),varcov=matrix(c(1,r,r,1),2,2))
> YS=cbind(Y1S,Y2S)+RES
> Y1=(YS[,1]>quantile(YS[,1],.5))*1
> Y2=(YS[,2]>quantile(YS[,2],.5))*1
> base=data.frame(i,Y1,Y2,X1,X2,YS)
> head(base)
  i Y1 Y2        X1          X2      Y1S      Y2S
1 1  0  0 0.2655087  0.07730312 3.177587 5.533884
2 2  0  0 0.3721239 -0.29686864 1.935307 5.089524
3 3  1  0 0.5728534 -1.18324224 4.757848 5.172584
4 4  1  0 0.9082078  0.01129269 4.600029 3.878225
5 5  0  1 0.2016819  0.99160104 2.547362 6.743714
6 6  1  0 0.8983897  1.59396745 5.309974 4.421523

(the two columns on the right are latent observations, that cannot be used since theoretically they are unobservable). Note that it is a simple regression, one of the component is here only to bring some noise. First of all, let us look at marginal probit regression

>  reg1=glm(Y1~X1+X2,data=base,family=binomial)
>  reg2=glm(Y2~X1+X2,data=base,family=binomial)
> summary(reg1)
 
Call:
glm(formula = Y1 ~ X1 + X2, family = binomial, data = base)
 
Deviance Residuals:
Min        1Q    Median        3Q       Max
-2.90570  -0.50126  -0.00266   0.49162   2.78256
 
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.291725   0.267149 -16.065   <2e-16 
X1           8.656836   0.510153  16.969   <2e-16 ***
X2           0.007375   0.090530   0.081    0.935
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 1386.29  on 999  degrees of freedom
Residual deviance:  726.48  on 997  degrees of freedom
AIC: 732.48

Number of Fisher Scoring iterations: 5
> summary(reg2)
Call:
glm(formula = Y2 ~ X1 + X2, family = binomial, data = base)
Deviance Residuals:
Min        1Q    Median        3Q       Max
-2.74682  -0.51814  -0.00001   0.57969   2.58565
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept)  3.91709    0.24399  16.054   <2e-16 ***
X1          -7.89703    0.46277 -17.065   <2e-16 ***
X2           0.18360    0.08758   2.096    0.036 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)

Null deviance: 1386.29  on 999  degrees of freedom
Residual deviance:  777.61  on 997  degrees of freedom
AIC: 783.61
Number of Fisher Scoring iterations: 5

Here, the optimization yields,

> OPT=optim(fn=logV,par=c(0,1,1,1,1,1,1),method="BFGS")$par
> OPT[1]
[1] 0.5261382
> matrix(OPT[2:7],2,3)
          [,1]      [,2]       [,3]
[1,] -2.451721  4.908633 0.01600769
[2,]  2.241962 -4.539946 0.10614807

Note that the coefficients we have obtained are almost identical to the ones obtained with R standard procedure,

>  library(Zelig)
>  REG= zelig(list(mu1=Y1~X1+X2,
+             mu2=Y2~X1+X2,
+     rho=~1),
+     model="bprobit",data=base)
>  summary(REG)
 
Call:
zelig(formula = list(mu1 = Y1 ~ X1 + X2, mu2 = Y2 ~ X1 + X2,
    rho = ~1), model = "bprobit", data = base)
 
Pearson Residuals:
                 Min        1Q     Median      3Q     Max
probit(mu1) -10.5442 -0.377243  0.0041803 0.36709 8.60398
probit(mu2)  -7.8547 -0.376888  0.0083715 0.42923 5.88264
rhobit(rho) -13.8322 -0.091502 -0.0080544 0.37218 0.85101
 
Coefficients:
                  Value Std. Error   t value
(Intercept):1 -2.451699   0.135369 -18.11116
(Intercept):2  2.241964   0.125072  17.92536
(Intercept):3  1.169461   0.189771   6.16249
X1:1           4.908617   0.252683  19.42602
X1:2          -4.539951   0.233632 -19.43203
X2:1           0.015992   0.050443   0.31703
X2:2           0.106154   0.049092   2.16235
 
Number of linear predictors:  3
 
Names of linear predictors: probit(mu1), probit(mu2), rhobit(rho)
&n
bsp;
Dispersion Parameter for binom2.rho family:   1
 
Residual Deviance: 1460.355 on 2993 degrees of freedom
 
Log-likelihood: -730.1774 on 2993 degrees of freedom
 
Number of Iterations: 3

> matrix(coefficients(REG)[c(1:2,4:7)],2,3)
          [,1]      [,2]       [,3]
[1,] -2.451699  4.908617 0.01599183
[2,]  2.241964 -4.539951 0.10615443

The correlation here is also the same

> (exp(summary(REG)@coef3[3])-1)/(exp(summary(REG)@coef3[3])+1)
[1] 0.5260951

That procedure works well an can be extended to ordinal responses (not only binary ones, or to three dimensional problems,

logV=function(beta){
BETA=matrix(beta[4:(3+ncol(Y)*ncol(X))],ncol(Y),ncol(X))
z=cbind(X%*%(BETA[1,]),X%*%(BETA[2,]),X%*%(BETA[3,]))
r12=beta[1]
r23=beta[2]
r31=beta[3]
s1=s2=s3=1
sigma=matrix(c(s1^2,r12*s1*s2,r31*s1*s3,
               r12*s1*s2,s2^2,r23*s2*s3,
               r31*s1*s3,r23*s2*s3,s3^2),3,3)
sigma1=matrix(c(s2^2,r23*s2*s3,
                r23*s2*s3,s3^2),2,2)
sigma2=matrix(c(s1^2,r31*s1*s3,
                r31*s1*s3,s3^2),2,2)
sigma3=matrix(c(s1^2,r12*s1*s2,
                r12*s1*s2,s2^2),2,2)
    a111=pmnorm(z[1,],rep(0,ncol(Y)),varcov=sigma)
for(i in 2:nrow(z)){a111=c(a111,pmnorm(z[i,],rep(0,ncol(Y)),varcov=sigma))}
    a011=pmnorm(z[1,2:3],varcov=sigma1)-pmnorm(z[1,],varcov=sigma)
for(i in 2:nrow(z)){a011=c(a011,pmnorm(z[i,2:3],varcov=sigma1)-pmnorm(z[i,],varcov=sigma))}
    a101=pmnorm(z[1,c(1,3)],varcov=sigma2)-pmnorm(z[1,],varcov=sigma)
for(i in 2:nrow(z)){a101=c(a101,pmnorm(z[i,c(1,3)],varcov=sigma2)-pmnorm(z[i,],varcov=sigma))}
    a110=pmnorm(z[1,1:2],varcov=sigma3)-pmnorm(z[1,],varcov=sigma)
for(i in 2:nrow(z)){a110=c(a110,pmnorm(z[i,1:2],varcov=sigma3)-pmnorm(z[i,],varcov=sigma))}
    a100=pnorm(z[1,1],sd=s1)-pmnorm(z[1,c(1,2)],varcov=sigma3)-pmnorm(z[1,c(1,3)],varcov=sigma2)+pmnorm(z[1,],rep(0,ncol(Y)),varcov=sigma)
for(i in 2:nrow(z)){a100=c(a100,pnorm(z[i,1],sd=s1)-pmnorm(z[i,c(1,2)],varcov=sigma3)-pmnorm(z[i,c(1,3)],varcov=sigma2)+pmnorm(z[i,],rep(0,ncol(Y)),varcov=sigma))}
    a010=pnorm(z[1,2],sd=s2)-pmnorm(z[1,c(1,2)],varcov=sigma3)-pmnorm(z[1,c(2,3)],varcov=sigma1)+pmnorm(z[1,],rep(0,ncol(Y)),varcov=sigma)
for(i in 2:nrow(z)){a010=c(a010,pnorm(z[i,2],sd=s2)-pmnorm(z[i,c(1,2)],varcov=sigma3)-pmnorm(z[i,c(2,3)],varcov=sigma1)+pmnorm(z[i,],rep(0,ncol(Y)),varcov=sigma))}
    a001=pnorm(z[1,3],sd=s3)-pmnorm(z[1,c(2,3)],varcov=sigma1)-pmnorm(z[1,c(1,3)],varcov=sigma2)+pmnorm(z[1,],rep(0,ncol(Y)),varcov=sigma)
for(i in 2:nrow(z)){a001=c(a001,pnorm(z[i,3],sd=s3)-pmnorm(z[i,c(2,3)],varcov=sigma1)-pmnorm(z[i,c(1,3)],varcov=sigma2)+pmnorm(z[i,],rep(0,ncol(Y)),varcov=sigma))}
    a000=1-a111-a011-a101-a110-a001-a010-a100
 
a111[a111<=0]=1e-50
a110[a110<=0]=1e-50
a101[a101<=0]=1e-50
a011[a011<=0]=1e-50
a100[a100<=0]=1e-50
a010[a010<=0]=1e-50
a001[a001<=0]=1e-50
a000[a000<=0]=1e-50
 
-sum(((Y[,1]==0)&(Y[,2]==0)&(Y[,3]==0))*log(a111) +
    4*log(a011) +
    5*log(a101) +
    6*log(a110) +
    7*log(a001) +
    8*log(a010) +
    9*log(a100) +
    10*log(a000) )
}

A strong assumption in that bivariate model is that residuals have a Gaussian structure. It is possible to change that assumption

  • marginally: for instance if we use a logistic cumulative distribution function, then we will have a bivariate logit regression
  • in terms of dependence structure: it is possible to consider another copula than the gaussian one, e.g. Gumbel’s copula (also called the bivariate logistic copula), or Clayton’s

Here, the following code can be used to extend the model to non Gaussian structures,

> F=function(x,r){pmnorm(x,rep(0,length(x)),
+                 varcov=matrix(c(1,r,r,1),2,2))}
> Fx=function(x1){F(c(x1,1e40),0)}
> Fy=function(x2){Fx(x2)}
> 
> logVgen=function(parameter){
+ CORRELATION=parameter[1]
+ BETA=matrix(parameter[2:length(parameter)],ncol(Y),ncol(X))
+ z=cbind(X%*%(BETA[1,]),X%*%(BETA[2,]))
+     a11=F(z[1,],r=CORRELATION)
+ for(i in 2:nrow(z)){a11=c(a11,F(z[i,],r=CORRELATION))}
+     a10=Fx(z[1,1])-F(z[1,],r=CORRELATION)
+ for(i in 2:nrow(z)){a10=c(a10,Fx(z[i,1])-F(z[i,],r=CORRELATION))}
+     a01=Fy(z[1,2])-F(z[1,],r=CORRELATION)
+ for(i in 2:nrow(z)){a01=c(a01,Fy(z[i,2])-F(z[i,],r=CORRELATION))}
+     a00=1-a10-a01-a11
+ -sum(((Y[,1]==1)&(Y[,2]==1))*log(a11) +
+     11*log(a01) +
+     12*log(a10) +
+     13*log(a00) )
+ }
>
> beta0=c(0,1,1,1,1,1,1)
> (OPT=optim(fn=logVgen,par=beta0,method="BFGS")$par)
[1]  0.52613820 -2.45172059  2.24196154  4.90863292 -4.53994592  0.01600769
[7]  0.10614807
There were 23 warnings (use warnings() to see them)

E.g.

> library(copula)
> F=function(x,r){pcopula(pnorm(x),
               claytonCopula(2, r))}
> Fx=function(x1){F(c(x1,1e40),0)
}
> Fy=function(x2){Fx(x2)}
  • An application to school tests

Consider the following dataset,

hsb2=read.table("http://freakonometrics.free.fr/hsb2.csv",
        header=TRUE, sep=",")
math_male=hsb2$math[female==0]
write_male=hsb2$write[female==0]
math_female=hsb2$math[female==1]
write_female=hsb2$write[female==1]
plot(math_female, write_female, type="p",
     pch=19,col="red",xlab="maths",ylab="writing",cex=.8)
points(math_male, write_male, cex=1.2, col="blue")

with here maths versus writing, with girls in red and boys in blue, where variables here are

  female :
    0: male
    1: female
  race :
    1: hispanic
    2: asian
    3: african-amer
    4: white
  ses :
    1: low
    2: middle
    3: high
  schtyp : type of school
    1: public
    2: private
  prog : type of program
    1: general
    2: academic
    3: vocation
  read : reading score
  write : writing score
  math : math score
  science : science score
  socst : social studies score

We can try to understand correlation between math and writing skills. Covariates can be the sex of the child, and his reading skills. The question will then be: are good students in maths and writing simply students that can read well ?

Here the code is simply

> W=hsb2$write>=50
> M=hsb2$math>=50
> base=data.frame(Y1=W,Y2=M,
+             X1=hsb2$female,X2=hsb2$read)
>
> library(Zelig)
> REG= zelig(list(mu1=Y1~X1+X2,
+             mu2=Y2~X1+X2,
+     rho=~1),
+     model="bprobit",data=base)
> summary(REG)
 
Call:
zelig(formula = list(mu1 = Y1 ~ X1 + X2, mu2 = Y2 ~ X1 + X2,
    rho = ~1), model = "bprobit", data = base)
 
Pearson Residuals:
                Min        1Q  Median      3Q    Max
probit(mu1) -4.7518 -0.502594 0.15038 0.53038 1.8592
probit(mu2) -3.4243 -0.653537 0.23673 0.67011 2.6072
rhobit(rho) -4.9821  0.010481 0.13500 0.40776 2.9171
 
Coefficients:
                  Value Std. Error  t value
(Intercept):1 -5.484711   0.787101 -6.96825
(Intercept):2 -4.061384   0.633781 -6.40818
(Intercept):3  1.332187   0.322175  4.13497
X1:1           1.125924   0.233550  4.82092
X1:2           0.167258   0.202498  0.82598
X2:1           0.103997   0.014662  7.09286
X2:2           0.082739   0.012026  6.88017
 
Number of linear predictors:  3
 
Names of linear predictors: probit(mu1), probit(mu2), rhobit(rho)
 
Dispersion Parameter for binom2.rho family:   1
 
Residual Deviance: 364.51 on 593 degrees of freedom
 
Log-likelihood: -182.255 on 593 degrees of freedom
 
Number of Iterations: 3
> (exp(summary(REG)@coef3[3])-1)/(exp(
summary(REG)@coef3[3])+1)
[1] 0.5824045

with a remaining correlation among residuals of 0.58. So with only the sex of the student, and his or her reading skill, we cannot explain the correlation between maths and writing skills. With our previous code, we have here

> beta0=c((exp(summary(REG)@coef3[3])-1)/(exp(summary(REG)@coef3[3])+1),
+      summary(REG)@coef3[c(1:2,4:7),1])
> beta0
              (Intercept):1 (Intercept):2          X1:1          X1:2
0.58240446   -5.48471133   -4.06138412    1.12592427    0.16725842
X2:1          X2:2
0.10399668    0.08273879
> (OPT=optim(fn=logV,par=beta0,method="BFGS")$par)
(Intercept):1 (Intercept):2          X1:1          X1:2
0.5824045    -5.4847113    -4.0613841     1.1259243     0.1672584
X2:1          X2:2
0.1039967     0.0827388

i.e. we obtain (almost) exactly the same estimators. But here I have used as starting values for the optimization procedure the estimators given by R. If we change them, hopefully we have a robust maximum likelihood estimator,

> (OPT=optim(fn=logV,par=beta0/2,method="BFGS")$par)
              (Intercept):1 (Intercept):2          X1:1          X1:2
   0.58233360   -5.49428984   -4.06839571    1.12696594    0.16760347
         X2:1          X2:2
   0.10417767    0.08287409
There were 12 warnings (use warnings() to see them)

So once again, it is possible to optimize numerically a likelihood function, and it works.

  1. Y[,1]==0)&(Y[,2]==1 []
  2. Y[,1]==1)&(Y[,2]==0 []
  3. Y[,1]==0)&(Y[,2]==0 []
  4. Y[,1]==1)&(Y[,2]==0)&(Y[,3]==0 []
  5. Y[,1]==0)&(Y[,2]==1)&(Y[,3]==0 []
  6. Y[,1]==0)&(Y[,2]==0)&(Y[,3]==1 []
  7. Y[,1]==1)&(Y[,2]==1)&(Y[,3]==0 []
  8. Y[,1]==1)&(Y[,2]==0)&(Y[,3]==1 []
  9. Y[,1]==0)&(Y[,2]==1)&(Y[,3]==1 []
  10. Y[,1]==1)&(Y[,2]==1)&(Y[,3]==1 []
  11. Y[,1]==0)&(Y[,2]==1 []
  12. Y[,1]==1)&(Y[,2]==0 []
  13. Y[,1]==0)&(Y[,2]==0 []

Maudits français

Tous les malouins le savent, Jacques Cartier est parti de Saint Malo pour découvrir le Canada en 1536 (si l’on considère son second voyage, c’est à dire celui où il a vraiment pénétré le royaume de Kanata en voguant sur le Saint Laurent). Il y a d’ailleurs un musée du Québec dans les remparts. Et comme s’en vente le musée, les québécois viennent de Saint-Malo.

Or, pour ceux qui ne connaissent pas Saint-Malo, c’est à deux pas du Mont Saint Michel, et du Couesnon qui sépare la Bretagne et la Normandie. Étant né en Normandie, avant de venir vivre à Rennes,  j’étais convaincu que j’avais des racines communes avec les Québécois*. Mais j’ai été surpris en voyant les noms de famille des copines de classe de ma fille: les noms ne m’étaient pas du tout familiers… Pourtant, si nous avons des racines communes, il ne serait pas surprenant que les noms de familles se retrouvent (c’est le principe de base de la généalogie, si j’ai bien tout suivi). Aussi j’ai voulu creuser davantage….

  • Que disent les experts en généalogie ?
http://freakonometrics.blog.free.fr/public/perso3/aunis.gifhttp://freakonometrics.blog.free.fr/public/perso3/bretagne.gifhttp://freakonometrics.blog.free.fr/public/perso3/Saintonge.gifhttp://freakonometrics.blog.free.fr/public/perso3/Normandie.gifhttp://freakonometrics.blog.free.fr/public/perso3/anjou.gif

On peut trouver des éléments de réponse ici ou là. Parmi les 3800 Français qui ont immigré (ou émigrer, ça dépend du point de vue) entre 1608 et 1700 :

  • La Normandie a fourni 1 pionnier sur 5.
  • Le Poitou, l’Aunis et la Saintonge ont, ensemble, donné 1 pionnier sur 4.
  • Paris et l’Ile-de-France, 1 pionnier sur 7.
  • La Bretagne, un peu plus de 3 pionniers sur 100.
  • L’Anjou, 3 pionniers sur 100.
  • La Champagne, presque 3 pionniers sur 100.
  • La Picardie, un peu plus de 2 pionniers sur 100.

 

Entre 1700 et 1765, près de 5000 autres hommes, femmes et enfants originaires de France viennent s’établir au Canada, mais “très peu proviennent de la Bretagne et des régions baignées par la mer“. Ce sont d’ailleurs les ordres de grandeur que j’ai pu avoir dans l’ouvrage de Michel Lambert (qui n’est pas un livre de généalogie à proprement parler mais qui est incroyablement intéressant, même s’il ne donne pas de source – ou de détails sur le sens – pour ces chiffres),

  • Normandie, 22.6%
  • Aunis, 16.4%
  • Perche, 11.4%
  • Ile de France (région parisienne) 10.5%
  • Poitou, 7.5%
  • Maine, 5.2%
  • Saintonge 5.2%
  • Bretagne 3.5%

Moralité, même si Jacques Cartier est parti de Bretagne, rares semblent être les bretons qui ont émigrés au Québec.

  • Calculs de probabilités conditionnelles à partir des noms de famille

Il existe des sites qui donnent les “classements” des noms de familles, au Québec par exemple (ici, avec les 1000 noms les plus portés, avec les proportions respectives), ou dans les régions françaises (, où j’ai pris à chaque fois les 2000 noms les plus portés avec les proportions respectives, en changeant de région). Les données peuvent être récupérées avec le code suivant

quebec=read.table("http://freakonometrics.free.fr/nom-quebec2.txt",   
                   header=TRUE,dec=",")
bretagne=read.table("http://freakonometrics.free.fr/nom-bretagne.txt",
                    header=TRUE,dec=",",sep="\t")
poitou=read.table("http://freakonometrics.free.fr/nom-poitou.txt",
                  header=TRUE,dec=",",sep="\t")
normandie=read.table("http://freakonometrics.free.fr/nom-basse-normandie.txt",
                     header=TRUE,dec=",",sep="\t")
aquitaine=read.table("http://freakonometrics.free.fr/nom-aquitaine.txt",
                     header=TRUE,dec=",",sep="\t")
alsace=read.table("http://freakonometrics.free.fr/nom-alsace.txt",  
                  header=TRUE,dec=",",sep="\t")
loire=read.table("http://freakonometrics.free.fr/nom-loire.txt",
                 header=TRUE,dec=",",sep="\t")

J’ai retenu 6 régions françaises, et j’ai calculé la proportions de québécois dont le nom de famille était dans le top 2000 d’une région donnée, i.e.

> head(quebec)
  Rang Nomdefamille Pourcentage
1    1     Tremblay       1.076
2    2       Gagnon       0.790
3    3          Roy       0.753
4    4         Cote       0.692
5    5     Bouchard       0.530
6    6     Gauthier       0.522

> minquebec=tolower(quebec$Nomdefamille)
> rangquebec=quebec$Rang
> pctquebec=quebec$Pourcentage/sum(quebec$Pourcentage)
> head(bretagne)
  Rang Patronyme Naissances
1    1   LE GALL      18126
2    2   LE GOFF      16093
3    3   LE ROUX      15905
4    4    THOMAS      15705
5    5    MARTIN      12094
6    6    TANGUY      12045

> minbretagne=tolower(bretagne$Patronyme)
> rangbretagne=bretagne$Rang
> pctbretagne=bretagne$Naissances/sum(bretagne$Naissances)
> I=minquebec%in%minbretagne
> sum(pctquebec[I])/sum(pctquebec)
[1] 0.2579641
Région Proportion
Bretagne 23,39%
Normandie 31,07%
Loire 32,83%
Aquitaine 27,65%
Poitou 32,50%
Alsace 9,71%

Si on retrouve peu de noms alsacien au Québec, on peut être un peu “surpris” que les régions qui ressortent le plus sont la Loire et le Poitou et pas la Bretagne et la Normandie…. Bon, j’en conviens, je travaille sur les noms de familles bruts, c’est à dire que je ne tiens pas compte du fait que certains noms se sont déformés. Il s’agit de la version simple… on peut bien entendu aller plus loin, par exemple en utilisant des modèles de mélange par exemple… à suivre donc…

*en fait, mes origines sont davantage bourguignonnes, de part mes quatre grands parents, comme le savent tous ceux qui m’ont déjà payé un verre de vin… mais ayant passé toute mon enfance en Normandie, je peux me considérer un peu comme normand. Et adorant la galette saucisse, je suis définitivement breton….

Playing with robots

My son would be extremely proud if I tell him I can spend hours building robots. Well, my robots are not as fancy as Dr Tenma’s, but they usually do what I ask them to do. For instance, it is extremely simple to build a robot with R, to extract data from websites. I have mentioned it here (one tennis matches), but it failed there (on NY Marathon). To illustrate the use of robots, assume that one wants to build his own dataset to study prices of airline tickets. First, we have to choose a departure city (e.g. Paris) and an arrival city (e.g. Montreal). Then, one wants to look at all possible dates from April first (I ran it last month) till the end of December (so we create a vector with all leaving dates, namely a vector for the day, one for the month, and one for the year). Then, we choose a return date (say 3 days after).

DEP="Paris"
ARR="Montreal"
DATE1D=rep(c(1:30,1:31,1:30,1:31,1:31,1:30,1:31,1:30,
1:31,1:31,1:29),3)
DATE1M=rep(c(rep(4,30),rep(5,31),rep(6,30),rep(7,31),
rep(8,31),rep(9,30),rep(10,31),rep(11,30),rep(12,31),
rep(1,31),rep(2,29)),3)
DATE1Y=rep(c(rep(2011,30+31+30+31+31+30+31+
30+31+31+28),rep(2012,31+29)),3)
k=3
DATE3D=c((1+k):30,1:31,1:30,1:31,1:31,1:30,1:31,
1:30,1:31,1:31,1:29,1:k)
DATE3M=c(rep(4,30-k),rep(5,31),rep(6,30),rep(7,31),rep(8,31),
rep(9,30),rep(10,31),rep(11,30),rep(12,31),rep(1,31),rep(2,29),
rep(3,k))
DATE3Y=c(rep(2011,30+31+30+31+31+30+31+30+31+
31+28-k),re
p(2012,31+29+k))

It is also possible (for a nice robot), to skip all prior dates

skip=max(as.numeric(Sys.Date()-as.Date("2011-04-01")),1)

Then, we need a website where requests can be written nicely (with cities and dates appearing explicitly). Here, I cannot not mention the website that I used since it is stated on the website that it is strictly forbidden to run automatic requests… Anyway, consider a loop create a url address (actually I chose the value of the date randomly, since I had been told that those websites had memory: if you ask too many times for the same thing during a short period of time, prices would go up),

URL=paste("http://www.♦♦♦♦/dest.dll?qscr=fx&flag=q&city1=",
DEP,"&citd1=",ARR,"&",
"date1=",DATE1D[s],"/",DATE1M[s],"/",DATE1Y[s],
"&date2=",DATE3D[s],"/",DATE3M[s],"/",DATE3Y[s],
"&cADULT=1",sep="")

then, we just have to scan the webpage, looking for ticket prices (just looking for some specific names)

page=as.character(scan(URL,what="character"))
I=which(page%in%c("Price0","Price1","Price2"))
if(length(I)>0){
PRIX=substr(page[I+1],2,nchar(page[I+1]))
if(PRIX[1]=="1"){PRIX=paste(PRIX,page[I+2],sep="")}
if(PRIX[1]=="2"){PRIX=paste(PRIX,page[I+2],sep="")}

Here, we have to be a bit cautious, if prices exceed 1000. Then, it is possible to start a statistical study. For instance, if we compare to destination (from Paris), e.g. Montréal and New York, we obtain the following patterns (with high prices during holidays),

It is also possible to run the code twice (here it was run last month, and a couple of days ago), for the same destination (from Paris to Montréal),

Of course, it would be great if I could run that code say every week, to build up a nice dataset, and to study the dynamic of prices…

The problem is that it is forbidden to do this. In fact, on the website, it is mentioned that if we want to extract data (for an academic purpose), it is possible to ask for an extraction. But if we do tell that we study specific prices, data might be biased. So the good idea would be to use several servers, to make several requests, randomly, and to collect them (changing dates and destination). But here, my computing skills – unfortunately – reach a limit….

Oscar awards: good actor versus good actress

I am not a big fan of those ceremonies, where some actors pretend that they are extremely happy to be there, and then some win a trophy, some don’t, and those who win start to cry, and those who did not get a trophy try to pretend that they are not affected, etc. The other reason is that, since I have several kids, I do not go to see the movies that often (I mean apart from Shrek, Toy Story… Harry Potter is probably the only movie I’ve seen with real actors – or at least human actors).

But I remember being surprised when I looked at the nominees in newspapers,

Actresses are beautiful and look young, while actors are more experienced. So I have try to see how old were those who win an Oscar, as best actor (here) or best supporting actor (there), and best actress (here) and best supporting actress (there).

OSCAR=read.table("http://freakonometrics.blog.free.fr/public/data/OSCAR.csv",
sep=",",header=TRUE,dec=".")
actor=OSCAR[,1]
suppactor=OSCAR[,2]
actress=OSCAR[,3]
suppactress=OSCAR[,4]
actor=actor[is.na(actor)==FALSE]
actor=actor[actor>0]
actress=actress[is.na(actress)==FALSE]
actress=actress[actress>0]
suppactor=suppactor[is.na(suppactor)==FALSE]
suppactor=suppactor[suppactor>0]
suppactress=suppactress[is.na(suppactress)==FALSE]
suppactress=suppactress[suppactress>0]
 
boxplot(actor,suppactor,actress,suppactress,col=c("blue","blue","red","red"),
names=c("actor","supp. actor","actress","supp. actress"))

On average, a best actress is 36 years old, while a best actor is 44 years old.  Which is quite a difference… Perhaps because it takes more time to an actor to be a good one ? Assuming that they start acting at 18, it takes 18 more years for an actress to be recognized as a good one (here the best one), and 26 for an actor. Or perhaps it is simply because leading actresses have to look young…
The oldest actor who won an Oscar was Henry Fonda (at the age of 76) and the oldest actress was Jessica Tendy (nearing 81). Tatum O’Neal became the youngest person to win the best suppo
rting actress award
at the age of 10 (she was 8 when she was acting). The youngest best actress was Marlee Matlin, 21. The distribution was be seen below, with actors in blue, and actresses in red, best supporting actors in dotted lines, and best actors in plain lines,

plot(density(actor),xlim=c(10,80),axes=FALSE,
col="blue",names="",ylab="",xlab="",ylim=c(0,.051))
lines(density(suppactor),col="blue",lty=2)
lines(density(actress),col="red")
lines(density(suppactress),col="red",lty=2)
axis(1)

Note that the age of supporting actors is older that leading ones. E.g. the average age for supporting actors winning an Oscar is 50, while it is  44 for actors. Similarly, it is 40 for supporting actresses, and 36 for actresses.

> mean(suppactor)
[1] 50.23762
 
> mean(actor)
[1] 44.29982
 
> mean(suppactress)
[1] 40.55766
 
> mean(actress)
[1] 36.39733

Here, I have to admit that I was surprised. I always thought that being a supporting actor was a first step before being a leading one. So winners of supporting awards should have been younger that winners of leading ones. But this is not the case.

And the dynamic here is rather stable, with actors,

and actresses,

except that the age difference between supporting roles and leading roles have increased in the 80’s for actors, while it decreased in the 80’s for actresses.

Beta kernel and transformed kernel

This Thursday I will give a talk at Laval University, on “Beta kernel and transformed kernel : applications to copula density estimation and quantile estimation“. This time, I will talk at the department of Mathematics and Statistics (13:30 at the pavillon Adrien-Pouliot). “Because copulas have bounded support (the unit square in dimension 2), standard kernel based estimators of densities are (multiplicatively) biased on borders and in corners of the support. Two techniques can be used to avoid that underestimation: Beta kernels and Transformed kernel. We will describe and discuss those two techniques in the first part of the talk. Then, we will see that it is possible to combine those two techniques to get nice estimator of several quantities (e.g. quantiles): transform the data to get on the unit interval – using a transformed kernel – then estimate the (transformed) quantile on [0,1] using a beta kernel, then get back on the initial support. As we will see on simulations, that technique can be better than standard quantile estimators, especially when data are heavy tailed.” Slides can be downloaded here.

  • kernel based density estimation

Kernel based estimation are a popular (and natural) technique to estimate densities.  It is simply and extension of the moving histogram:

so we count how many observations are a the neighborhood of the point where we want to estimate the density of the distribution. Then it is natural so consider a smoothing function, i.e. instead of a step function (either observations are close enough, or not), it is possible to give weights to observations, which will be a decreasing function of the distance,

With a smooth kernel, we have a smooth estimation of the density

http://freakonometrics.blog.free.fr/public/perso3/kernel-f-01.gif

Then it is possible to play on the bandwidth, either to get a more accurate estimation of the density, but not that smooth (small bias but large variance),

or a smoother one (large bias, but small variance),

In R, it is simply

> X=rnorm(100)
> (D=density(X))
 
Call:
	density.default(x = X)
 
Data: X (100 obs.);	Bandwidth 'bw' = 0.3548
 
       x                   y            
 Min.   :-3.910799   Min.   :0.0001265  
 1st Qu.:-1.959098   1st Qu.:0.0108900  
 Median :-0.007397   Median :0.0513358  
 Mean   :-0.007397   Mean   :0.1279645  
 3rd Qu.: 1.944303   3rd Qu.:0.2641952  
 Max.   : 3.896004   Max.   :0.3828215  
 
> plot(D$x,D$y)
  • Beta kernel

The idea of Beta kernel is to consider kernels having support [0,1]. In the univariate case,

http://freakonometrics.blog.free.fr/public/perso3/kernel-f-06.gif

where http://freakonometrics.blog.free.fr/public/perso3/kernel-f-07.gif is the density of a Beta distribution, i.e.

http://freakonometrics.blog.free.fr<br />
/public/perso3/beta-distribution.gif

For additional material, I have uploaded some R code to fit copula densities using beta kernels,

library(copula)
beta.kernel.copula.surface = function (u,v,bx,by,p) {
s = seq(1/p, len=(p-1), by=1/p)
mat = matrix(0,nrow = p-1, ncol = p-1)
for (i in 1:(p-1)) {
a = s[i]
for (j in 1:(p-1)) {
b = s[j]
mat[i,j] = sum(dbeta(a,u/bx,(1-u)/bx) *
dbeta(b,v/by,(1-v)/by)) / length(u)
} }
return(data.matrix(mat)) }

Then we can used it to see what we get on a simulated sample

library(copula)
COPULA = frankCopula(param=5, dim = 2)
X = rcopula(n=1000,COPULA)
p0 = 26
Z= beta.kernel.copula.surface(X[,1],X[,2],bx=.01,by=.01,p=p0)
u = seq(1/p0, len=(p0-1), by=1/p0)
persp(u,u,Z,theta=30,col="green",shade=TRUE,
box=FALSE,zlim=c(0,6))

http://freakonometrics.free.fr/copula-kernel-beta.gif
(yes, the surface is changing… to illustrate the impact of the bandwidth on the estimation).

  • transformed kernel estimation

I the talk, I will also mention the transformed Kernel estimate, as introduced in the book on L1 density estimation by Luc Devroye and Laszlo Györfi (the book can be downloaded here). I probably spend a few minutes on the original chapter, in order to provide another application of that techniques (not only to estimate copula densities, but here to estimate quantiles of heavy tailed distribution). In the univariate case, the R code is the following (here I consider two transformation, the quantile function of the Gaussian distribution, and the quantile function of the Student distribution with 3 degrees of freedom),

set.seed(1)
sample=rbeta(100,4,3)
 
transfN = function(x){
Y=qnorm(sample)
f=density(Y,from=-4,to=4,n=2001)
ny=sum(f$x<=qnorm(x)); 
  g=f$y[ny]/dnorm(qnorm(x))
return(g)
}
 
df0=3
 
transfT = function(x){
Y=qt(sample,df=df0)
f=density(Y,from=-4,to=4,n=2001)
ny=sum(f$x<=qt(x,3)); 
  g=f$y[ny]/dt(qt(x,df=df0),df=df0)
return(g)
}
 
tN=Vectorize(transfN)
tT=Vectorize(transfT)
 
u=seq(.01,.99,by=.01)
vN=tN(u)
vT=tT(u)
plot(u,vN,type="l",lwd=3,col="blue")
lines(u,vT,lwd=3,col="green")
lines(u,dbeta(u,4,3),col="red",lty=2)

The density estimation is the following,

(the red dotted line is the true density, since we work on a simulated sample). Now, let us get back on the initial chapter,

In the book, this is introduced as follows,

The original idea we add it to use this kernel based estimator for copulas, i.e. since we can estimate densities in high dimension with unbounded support, using

http://freakonometrics.blog.free.fr/public/perso3/kernel-f-02.gif

the idea is to transform marginal observations,

http://freakonometrics.blog.free.fr/public/perso3/kernel-f-10.gif

and to use the fact that the associated copula density can be written

http://freakonometrics.blog.free.fr/public/perso3/kernel-f-12.gif

to derive an intuitive estimator for the copula density

http://freakonometrics.blog.free.fr/public/perso3/kernel-f-13.gif

An important issue is how do we choose the transformation

And Luc Devroye and Laszlo Györfi mention that this can be used to deal with extremes.

well, extremes are introduced through bumps (which is not the way I would have been dealing with extremes)

and note that several results can be derived on those bumps,

e.g.

Then, there is an interesting discussion about estimating the optimal transformation

and I will prove that this can be an extremely interesting idea, for instance to estimate quantiles of heavy tailed distribution, if we use also the beta kernel estimator on the unit interval. This idea was developed in a paper with Abder Oulidi, online here.

Remark: actually, in the book, an additional reference is mentioned,

but I have never been able to find a copy… if anyone has one, I’d be glad to read it…

Some stylized facts about large risk covers

A couple of weeks ago, David Cummins (here) was giving a talk in Laval University. And we’ve seen a series of extremely interesting graphs and figures about catastrophe reinsurance market, as well as Cat Bonds prices. The first one was the rate one line index for catastrophe reinsurance (the rate on line is the excess of loss premium expressed as a percentage of the reinsurance cover), from Guy Carpenter (2010, page 10 here).

Following hurricane Andrew in 1992, prices went up quite high. But following hurricane Katrina (which is, so far, the most costly insured disaster following the second World War, with a cost exceeding 70 billions US$ – 2008 $ – while Andrew was only 24 billions – again 2008 $), the bump is much smaller. I though cycles where much larger in the reinsurance industry.

Then there was a discussion about cat bond pricing, with a graph from Lane Financial (2010, page 13, here) with the ratio premium over expected loss

This is extremely interesting, even if it is only about cat bond, and not about reinsurance covers. Usually, when we introduce premium principles in actuarial courses, we start with the pure premium, i.e.

http://freakonometrics.blog.free.fr/public/perso2/chargement-PP-02.gifThen we explain that with such a price, ruin probability is certain (with an infinite time horizon), so we need to add a safety margin, and a standard idea (but that can be criticized since the expected value has – usually – nothing to do with the variability) is to add a loading proportional to the pure premium. Then the premium is

http://freakonometrics.blog.free.fr/public/perso2/chargement-PP-01.gifFor small risks, like motor insurance, the loading is not huge. Actually, if risks have finite variance, it can be obtained simply using the central limit theorem (but I’ll get back on that point in a couple of weeks). Here, we see that loading http://freakonometrics.blog.free.fr/public/perso2/thetaloading.gif can be large (up to 400% in 2009).

An finally an updated graph with a comparison between BB corporate bondscoupon, and BB catastrophe bonds coupon,

(I guess the source is again Morton Lane). I found surprising the recent gap (following Katrina) between the two spreads. I guess financial market started to be scared and understood that catastrophes are not that rare…. I wonder what 2008 and 2009 prices looked like.

Comparer des taux sur deux populations

Lors du dernier cours, nous avions évoqué les tests de comparaison des moyennes et des proportions sur deux échantillons. Pour cela, nous avions vu qu’il était possible d’utiliser la statistique

http://freakonometrics.hypotheses.org/files/2015/12/comp-sample.gif

http://freakonometrics.hypotheses.org/files/2015/12/compar-sample2.gif

La statistique doit alors suivre, sous l’hypothèse où les proportions sont égales une loi normale centrée réduite. Sous R, c’est assez facile à implémenter. Afin d’illustrer, utiliser l’information suivante

Bon, en l’état on n’a pas vraiment un taux, mais un nombre de tués sur les routes. On peut introduire la probabilité d’avoir un tué sur les routes par minute. Le code sous R serait alors

> prop.test(x=c(308,308/1.027), n=c(31*24*60,31*24*60), alt="two.sided")
 
        2-sample test for equality of proportions with continuity correction
 
data:  c(308, 308/1.027) out of c(31 * 24 * 60, 31 * 24 * 60)
X-squared = 0.0834, df = 1, p-value = 0.7727
alternative hypothesis: two.sided
95 percent confidence interval:
 -0.0009198487  0.0012826342
sample estimates:
     prop 1      prop 2
0.006899642 0.006718249

Autrement dit, la probabilité d’avoir un accident, à la minute, est sensiblement le même, avec une p-value de 77%. On notera sur le graphique suivant que l’impact du pas de temps a globalement peu d’importance….)

L’idéal serait d’avoir des données détaillées, mais il faudra attendre un peu pour ça…

Time horizon in forecasting, and rules of thumb

I recently received an email about forecasting and rules of thumb. “Dans la profession […] se transmet une règle empirique qui voudrait que l’on prenne un historique du double de l’horizon de prévision : 20 ans de données pour une prévision à 10 ans, etc… Je souhaite savoir si cette règle n’aurait pas, par hasard, un fondement théorique quitte à ce que le rapport ne soit pas de 2 pour 1, mais de 3 pour 1 ou de 1 pour 1 par exemple.” To summarize briefly, the rule is to consider a 2-1 ratio for the period of observation vs. forecast horizon. And the interesting question is if there are justifications for such a rule…

At first, I remembered a rules of thumb, from the book by Box and Jenkins, which states that it is meaningless to look at autocorrelations when lags exceed the sample size over 6. So with 12 years of data, autocorrelations with a lag higher than two years are useless. But it is not what is mentioned here. So I looked at some dataset, and some standard time series models.

  • It depends on the series

It might obvious… but if it is the case, it means that it will be difficult to have a general rule of thumb. Consider e.g. the number of airline passengers,

library(forecast)
X = AirPassengers
ETS = ets(X)
plot(forecast(ETS,h=length(X)/2))

or some sales in a big store,

or car casualties in France, or the temperature in Nottingham Castle,

or the water level at Lack Hurron, or the flow of the Nile river,

or see also here for forecasting techniques in demography. Actually, in the case of life insurance, actuaries have to forecast future demography, i.e. try to assess death rates of those who currently purchase retirement contracts, who might be 20 years old. So they have to forecast death rate until 2100, say. One the one hand, it sounds difficult to make forecast over a century (it is already difficult for climate, I guess it is even more complex for human life). On the other hand, a 2-1 ratio means that we have to use data from 1800… Here again, it is difficult to justify that mortality in the 1850 could be interesting to say anything about mortality in 2050. So I guess it will be difficult to justify the use of general rules of thumb….

  • It depends on the model

Consider the following (simulated) series. Several models can be fitted. And the shape on the forecast (and the forecast error) will depend on the model considered. The benchmark can be the model without any dynamics, i.e. we assume that observations are i.i.d. Or more classically, assume that it is simple a white noise, i.e. an i.i.d centered process. Then the forecast is the following,

With that kind of assumption, we see that the 2-1 ratio is useless since we can get forecasts up to any horizon…. But that does not seem very robust. For instance, if we consider exponential smoothing techniques, we can obtain

Which is rather different. And with the 2-1 ratio, obviously, there is a lot of uncertainty at the end ! It would be even worst if we assume that we look at a random walk. Because actually a dozen models – at least – can be considered, from ARIMA, seasonal ARIMA, Holt Winters, Exponential Smoothing, etc…

http://freakonometrics.blog.free.fr/public/perso2/animationforecast.gif

So I do not see any theoretical justification of that rule of thumb. Obviously, the maximum horizon can not be extremely far away if the series is non-stationary, with a very irregular pattern, and with a lot of noise… So we’re back at the beginning. If anyone is willing to share his or her experience, comments are open.

Talk at Laval University at the Actuarial Seminar

I was last Friday at Laval University for a conference by David Cummins and Mary Weiss (here). I will be back tomorrow, this time to give a talk, on “distorting probabilities in actuarial science” (the talk will be extremely close to the one I gave at McGill in November). “In this talk, we will first get back on properties of distortion operators for pricing financial and insurance risks. Based on the dual version of the expected utility framework, we will see how distorted risk measures have been introduced, from VaR and TVaR, to Esscher premium and Wang’s measures. Then we will discuss extensions in higher dimension. We will discuss tail properties of distorted copulas (in the particular case of Archimedean copulas). A natural application will be aging problems (in survival analysis or in credit risk).” Slides can be downloaded from here.

 

This talk can be seen as a first part, the second one behing the talk I will give in 15 days, again at Laval University, but this time for the Seminar of Statistics. The talk will be on “Beta kernel and transformed kernel : applications to quantile estimation, and copula density estimation“.

Variable annuities is not a systemic risk ?

The Geneva Association just published on its website an interesting report on variable annuities and systemic risk (online here). Based on a definition of potentially systemically risky activities, on interconnectedness or substitutability, the report claims that since “none of the criteria is triggered”, variables annuities is “not a potentially systemically risk activity”. Even if “short-term effects are conceivable”. I guess it is a diplomatic way to say it…

Note that a series of slides can also be downloaded (there) on insurance and systemic risk. But that deserves a more detailed post.

 

STT2700, estimation, tests et coupes du monde

Mercredi, pour le dernier cours, nous allons revenir sur l’estimation, les tests, et plus généralement sur la modélisation statistique. Pour cela, j’avais pensé travailler sur les nombres de buts marqués, par match, lors de différentes coupes du monde de soccer (1982, 1998 et 2010). Je ne mets pas l’intégralité du code aujourd’hui, l’idée est pour l’instant de mettre en ligne des données qui serviront à répondre aux questions qui seront posées mercredi. Le code (accompagné – éventuellement – d’explications théoriques) sera posté par la suite.

soccer1982=read.table("http://freakonometrics.free.fr/soccer1982")
S82=(soccer1982$V1+soccer1982$V2)
soccer1998=read.table("http://freakonometrics.free.fr/soccer1998")
S98=(soccer1998$V1+soccer1998$V2)
soccer2010=read.table("http://freakonometrics.free.fr/soccer2010")
S10=(soccer2010$V1+soccer2010$V3)

Les boxplot associés à ces trois échantillons sont les suivants,

On va se poser des questions autour de ces données, par exemple voir s’il est vraisemblance (ou pas) que le nombre moyen de but dans un match (avant prolongation, s’il y en a eu). On peut commencé par essayer de se demander quel modèle utiliser. Classiquement, la loi de Poisson est la plus utilisée (en plus, c’est la seule loi qui est autorisée lorsqu’on publie un billet le 1er avril). Les histogrammes sont les suivants

boxplot(S82,S98,S10,col=c("red","yellow","blue"),
label=("1982","1998","2010"))
hist(S82,breaks=0:11,col="red")
hist(S98,breaks=0:11,col="yellow")
hist(S10,breaks=0:11,col="blue")

Si on compare les fonctions de répartition empiriques à celles de lois de Poisson ajustées par maximum de vraisemblance, on obtient, pour la coupe du monde de 1982

et pour celle de 2010,

Visuellement, l’ajustement semble relativement bon, surtout en 2010. On peut aussi faire un test du chi-deux,

> library(vcd)
> (GF=goodfit(S10,type="poisson"))

Observed and fitted values for poisson distribution
with parameters estimated by ML

 count observed     fitted
     0        7  6.6409703
     1       17 15.0459484
     2       13 17.0442384
     3       14 12.8719508
     4        7  7.2907534
     5        5  3.3036226
     6        0  1.2474617
     7        1  0.4037543

> summary(GF)

	 Goodness-of-fit test for poisson distribution

                      X^2 df  P(> X^2)
Likelihood Ratio 5.586765  5 0.3485255

On voit que l’on accepte l’ajustement par une loi de Poisson. Pour ceux qui veulent une visualisation, sur la figure ci-dessous, on a la densité d’une loi du chi-deux. Le premier trait vertical est la valeur observée, et l’aire jaune est alors la p-value (qui excède largement 5%). En rouge on a 5%, donc le second trait vertical est la borne de la région critique associé au test pour une erreur de première espèce valant 5%,

On peut ensuite faire plein de tests.  On suppose que . On va pouvoir tester

http://freakonometrics.free.fr/test-soccer-04.gif

contre une hypothèse alternative

http://freakonometrics.free.fr/test-<br /><br /> soccer-06.gif

Comme on a une hypothèse sur la loi des observations qui semble robuste, on peut utiliser un test de type rapport de vraisemblance.
On peut aussi faire un test de la forme

http://freakonometrics.free.fr/test-soccer-09.gif

contre

http://freakonometrics.free.fr/test-soccer-10.gif

(histoire de tester des hypothèses simples – qui ont une interprétation). Sinon, comme ce qui nous intéresse, c’est de savoir si on a plus de trois buts par matchs, on peut définir la variable binomiale http://freakonometrics.free.fr/test-soccer-03.gif, en notant que

http://freakonometrics.free.fr/test-soccer-02.gif

est une proportion – donc facile à tester – qui nous intéresse ici compte tenu du problème que l’on cherchera à résoudre. On pourra alors tester, par exemple

http://freakonometrics.free.fr/test-soccer-08.gif

contre

http://freakonometrics.free.fr/test-soccer-07.gif

Ces derniers tests sont alors facile à mettre en œuvre,

> Z=(S10>=3)*1
> prop.test(sum(Z),length(Z),p=1/2,alternative="less")

	1-sample proportions test with continuity correction

data:  sum(Z) out of length(Z), null probability 1/2 
X-squared = 1.2656, df = 1, p-value = 0.1303
alternative hypothesis: true p is less than 0.5 
95 percent confidence interval:
 0.0000000 0.5322764 
sample estimates:
       p 
0.421875

On peut aussi faire des tests de moyenne sur

http://freakonometrics.free.fr/test-soccer-11.gif

Un test de l’hypothèse

http://freakonometrics.free.fr/test-soccer-04.gif

contre une hypothèse alternative

http://freakonometrics.free.fr/test-soccer-06.gif

s’écrit alors
> t.test(S10,mu=3,alternative ="less")

	One Sample t-test

data:  S10 
t = -3.7763, df = 63, p-value = 0.0001775
alternative hypothesis: true mean is less than 3 
95 percent confidence interval:
     -Inf 2.590273 
sample estimates:
mean of x 
 2.265625
Mais on l’aura l’occasion de revoir tous les points du cours, y compris aller peut être un peu plus loin, par exemple sur la comparaison de moyenne entre échantillons,
> t.test(S82,S98,var.equal=FALSE)

	Welch Two Sample t-test

data:  S82 and S98 
t = 0.427, df = 85.266, p-value = 0.6704
alternative hypothesis: true difference in means is not equal to 0 
95 percent confidence interval:
 -0.5503669  0.8514658 
sample estimates:
mean of x mean of y 
 2.807692  2.657143

"sendo l'intento mio scrivere cosa utile a chi la intende…"