Supprimer des données ?

Il y a une dizaine de jours, je participais à la conférence Sciences XXL, à l’INED, où nous parlions des utilisations des données massives en Sciences Sociales, et au même moment, j’ai découvert – en discutant avec plusieurs assureurs – qu’ils envisageaient de supprimer des données, de manière également massive. Quand on veut faire de l’économétrie de la finance, on peut utiliser des données de cours boursiers, qu’on peut trouver en ligne, ou – pour une granularité plus faible – acheter à des fournisseurs de données. Mais quand on fait de l’économétrie de l’assurance, avoir des données est plus compliqué. Dans mon tout premier cours d’assurance dommage, j’enseignais la théorie, faute de données. Depuis, j’ai réussi à récupérer des données. On a mis ces données dans un package R (casdatasets), et mieux: avec des jeux de données (prêtées par des assureurs) on a pu lancer notre troisième pricing game, qui devrait nous permettre de mieux comprendre la dynamique des marchés d’assurance.

Bref, j’ai été particulièrement surpris d’apprendre que des assureurs envisageaient de détruire des données (individuelles). J’avais entendu de tels propos lors qu’avec Arnaud on commencé à travaillé sur le risque de catastrophes naturelles, et qu’on essayait de mieux comprendre l’impact des tempêtes Lothar et Martin, en décembre 2009. En particulier, au commencement de nos recherches, nous voulions avoir un ordre de grandeur du nombre de polices d’assurance (multirisques habitation) dans un portefeuille, ou plutôt le taux de polices touchées, si possible avec une granularité spatiale assez faible. Des assureurs ont pu nous aider à avoir des ordres de grandeur, par département

mais d’autres nous ont dit qu’il serait difficile de retrouver les données, qui remontent à près de 20 ans. Voire impossible. Et c’est là qu’on a commencé à entendre parler de suppression de données personnelles. Et si les données n’ont pas été agrégées au niveau que l’on souhaite, c’est impossible de faire la requête, 20 ans après.

Continue reading Supprimer des données ?

Toi aussi, raconte ce que tu veux avec des graphiques

L’autre jour, les décodeurs publiaient sur le site du Monde un article sur l’utilisation des graphiques en base 100,

Je reprends le commentaire

Celui-ci indique, sans appel selon Mme Le Pen, le déclin des économies françaises, italiennes et espagnoles face à l’industrie allemande. Marine Le Pen n’hésite ainsi pas à affirmer que le déclin de la production française est lié à l’introduction de la monnaie unique en 2001.

On peut reconstruire le graphique assez facilement, les données étant en ligne sur https://data.oecd.org/

base=read.table(loc,sep=",",header=TRUE)
extract=function(nom="FRA"){
b=base[base[,1]==nom,c("TIME","Value")]
names(b)=c("TIME",nom)
return(b)
}
B=extract("FRA")
B=merge(B,extract("DEU"),all.x=TRUE,all.y=TRUE)
B=merge(B,extract("ESP"),all.x=TRUE,all.y=TRUE)
B=merge(B,extract("ITA"),all.x=TRUE,all.y=TRUE)
dim(B)
B$TIME
B$t=seq(1950+1/8,2016+7/8,by=1/4)
plot(B$t,B$FRA,type="l",col="blue",lwd=2)
i=which(B$T=="2001-Q1")
Bi=B
for(j in 2:5) Bi[,j]=Bi[,j]*100/Bi[i,j]
plot(B$t,Bi$FRA,type="l",col="blue",lwd=2,ylim=range(Bi[which(B$T=="1990-Q1"):which(B$T=="2016-Q4"),2:5],na.rm=TRUE),xlim=c(1990,2020))
text(2019,Bi$FRA[max(which(is.na(Bi$FRA)==FALSE))],"FRA",col="blue")
lines(B$t,Bi$DEU,lwd=2)
text(2019,Bi$DEU[max(which(is.na(Bi$DEU)==FALSE))],"DEU")
lines(B$t,Bi$ESP,lwd=2,col="red")
text(2019,Bi$ESP[max(which(is.na(Bi$ESP)==FALSE))],"ESP",col="red")
lines(B$t,Bi$ITA,lwd=2,col="green")
text(2019,Bi$ITA[max(which(is.na(Bi$ITA)==FALSE))],"ITA",col="green")

Maintenant, on peut aussi changer la référence de la base 100. Par exemple, la victoire de la France à la Coupe du Monde Foot

i=which(B$T=="1998-Q2")

Damned,

Celui-ci indique, le déclin des économies françaises, italiennes et espagnoles face à l’industrie allemande. Ce déclin de la production française est lié à la victoire de la France à la Coupe du Monde de Football.

ou la dernière victoire de la France à l’Eurovision

i=which(B$T=="1977-Q3")

Damned,

Celui-ci indique, le déclin des économies françaises et espagnoles face à l’industrie allemande. Ce déclin de la production française est lié à la victoire de la France à l’Eurovision.

ou encore, la naissance de Mme Le Pen

i=which(B$T=="1968-Q3")

Damned,

Celui-ci indique, le déclin de l’économie française face aux industries allemande et espagnole. Ce déclin de la production française est lié à la naissance de Mme Le Pen.

Le Master Statistique & Econométrie est mort

Après 10 ans, le master Statistique & Econométrie de l’Université de Rennes 1 va disparaître…. pour renaître de ses cendres sous le nom Mathématiques Appliquées, Statistique, cohabilité par l’Université de Rennes 1, Rennes 2, Agrocampus Ouest, l’ENSAI et l’INSA Rennes, à la rentrée. En particulier, il y aura un parcours “Prévision et Prédiction Economiques“. Il y aura beaucoup de nouveaux cours, mais j’aurais l’occasion d’en reparler…

The U.S. Has Been At War 222 Out of 239 Years

This morning, I discovered an interesting statistic, “America Has Been At War 93% of the Time – 222 Out of 239 Years – Since 1776“,  i.e. the U.S. has only been at peace for less than 20 years total since its birth. I wanted to check, get a better understanding and look at other countries in the world.

As always, we can try to extract information from wikipedia, since there are pages dedicated to that information

url="https://en.wikipedia.org/wiki/List_of_wars_involving_the_United_States"
download.file(url,destfile = "warUS.html")
url="https://en.wikipedia.org/wiki/List_of_wars_involving_France"
download.file(url,destfile = "warFR.html")
url="https://fr.wikipedia.org/wiki/Liste_des_guerres_de_la_France#Premi.C3.A8re_R.C3.A9publique"
download.file(url,destfile = "guerre.html")
url="https://en.wikipedia.org/wiki/List_of_wars_involving_Canada"
download.file(url,destfile = "warCAN.html")

If we look at the US page, there are tables, so it should be easy to extract it. For instance,

Even if the war did last 1 day, we will say that the US were at war in 1811. The information we want to confirm can be “there were 21 full years – from Jan 1st till Dec 31st – where the US were not at war, once, during those years“. From the row above, we can claim that the US were at war in 1811. Most of the time, we have

I.e. there is a beginning (here 1775) and an end (1783). So here, the US are said to be at war in 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783. To extract the information, we look for regular expressions in the first column, with number, on 4 digits.

https://freakonometrics.hypotheses.org/files/2017/03/guerre-us1.png

Well, sometimes it can be a bit tricky, since we have 3 dates, 1941, 1945 and (in the legend) 1944. But if we consider the minimal and the maximal dates, we have our range of dates.

Now that we we how to extract information, let’s do it. The code will be

library(stringr)
ext_date=function(x){
dates12="[0-9]{4}"
#grep(pattern = dates2, x = col1[1])
L=str_extract_all(as.character(x),dates12)
return_L=list()
if(length(L)>0){
for(j in 1:length(L))
if(length(L[[j]])==1) return_L[[j]]=as.numeric(L[[j]])
if(length(L[[j]])>=2) return_L[[j]]=seq(min(as.numeric(L[[j]])),max((as.numeric(L[[j]]))))
}
return(return_L)}

For the US, we get the following years

library(XML)
tables=readHTMLTable("warUS.html")
list_dates=list()
for(i in 1:length(tables)){
if(!is.null(dim(tables[[i]]))){
if(ncol(tables[[i]])>1){
col1=tables[[i]][,1]
list_dates[[i]]=lapply(col1,ext_date)
}
}}
d=unique(unlist(list_dates))

(red means at war, while green means no-war) and indeed,

> length(d)
[1] 222

there were 222 years with war.  Now, what about another country. Like France. Here I use the French wiki page, since information is not in tables in the English one.

tables=readHTMLTable("guerre.html")
list_dates=list()
for(i in 1:length(tables)){
if(!is.null(dim(tables[[i]]))){
if(ncol(tables[[i]])>1){
col1=tables[[i]][,1]
col2=tables[[i]][,2]
col12=paste(col1,col2)
list_dates[[i]]=lapply(col12,ext_date)
}
}}
d=unique(unlist(list_dates))

On the same period of time (starting in 1775), France was also on war most of the time.

Less than the US, but still: 185 years with war,

> length(d[d>=1775])
[1] 185

And on a longer period of time? Why not start, say, around the Hundred Years’s War,

meaning that since 1337, there were (only) 174 years without a single war where France was involved.

Let’s try another one. Like Canada,

tables=readHTMLTable("warCAN.html")
list_dates=list()
for(i in 1:length(tables)){
if(!is.null(dim(tables[[i]]))){
if(ncol(tables[[i]])>1){
col1=tables[[i]][,1]
list_dates[[i]]=lapply(col1,ext_date)
}
}}
d=unique(unlist(list_dates))

Guess what… there’s a lot of green on that graph. Surprised?

Data XXL et Démographie Participative

Petite virée parisienne pour trois jours. Je serais à Science Po mercredi pour travailler un peu, et à l’INED jeudi et vendredi pour la conférence Sciences XXL – Ce que l’abondance et la diversité des données numériques font aux sciences sociales. Jeudi, je serais discutant pour la session “outils”, et vendredi après-midi, nous allons clôture la conférence avec un rapide retour sur un travail joint avec Olivier et Ewen, sur ‘Les données collaboratives généalogiques au service de la démographie historique’. Le travail est très vaste, et nous présenterons quelques résultats de réconciliation entre les tables de mortalité historique de l’INED, et celle que nous avons reconstituées sur des données démographiques…. Par exemple avec les naissances de 1850

et celles de 1899

La suite…. vendredi (ou plus tard, on n’a pas fini de jouer avec ces données).

 

Reading text automatically

It is now very easy to read (automatically) some text that can be found in a pdf file. For instance, consider the program of the conference we had yesterday – and today – in Rennes

> library(pdftools)
> scan_pdf <- pdf_text("http://crem.univ-rennes1.fr/Documents/Docs_sem_divers/2017_03_10-11_JJD/JDD_prog.pdf")
> cat(scan_pdf)
Journées Jeunes Docteurs
Programme du jeudi 9 mars 2017
Faculty of Economics - Rennes - Amphi Henri Krier
9h- 9h30 - Accueil
9h30-10h15 :      Présentation du CREM, de la faculté et des activités de recherche liées du ou laboratoire
10h15-10h50 :     Emmanuel LORENZON (Université de Bordeaux, GREThA)
Collusion with a rent seeking agency in sponsored search auctions
10h50-11h25 :     Julien BERTHOUMIEU (Université de Bordeaux, GREThA)
The Impact of “At-the-Border” and “Behind-the-Border” Policies on Cost-Reducing Research
and Development
Co-écrit avec Antoine Bouët

(etc). As you can see, it is working well, even in French, where we have those weird letters (with accents). Here, it is working well because the pdf is vectorized, i.e. it was generated properly, by open office.

But sometimes, we can have only a scanned version of a letter

or just a picture with some typed text. I will not mention hand-writing because it is much more complex.

The other day, my friend Fleur did show me a picture, and some very simple lines of code,

> library('tesseract')
> pic1="http://freakonometrics.hypotheses.org/files/2017/03/pic1.png"
> text_fr <- ocr(pic1, engine = tesseract("fra"))
> cat(text_fr)
Près de 14.400 décès

Si [épidémie de grippe est un phénomène récurrent. celle de
2016—2017 présente plusieurs spécificités. outre sa virulence :
une survenue plus précoce que d‘habitude. une activité
modérée en médecine ambulatoire. mais un impact fort en
milieu hospitalier.

It looks like we’ve be able to extract typed text from a picture ! I want to check. I have to admit, first of all that installation on a linux machine is tricky: one has to install first leptonica, and then follow some guidelines to install tesseract (see also Artem‘s advices). It took me some time, but I’ve been able to install the package.

The first important step, it to train the algorithm with some texts in French (because it is in French in my picture)

> library('tesseract')
> tesseract_download("fra")

Then, I did try with the picture that Fleur did send me (the picture was inserted in the core of the message)

> pic2="http://freakonometrics.hypotheses.org/files/2017/03/pic2.png"
> text_fr <- ocr(pic2, engine = tesseract("fra"))
> cat(text_fr)
Près de 14400 decès

s. mm….agw«… ………«…m ……
a……u…u Dhs—ur; ;pmum…. ;: u……
… W»: »… w…q…na… … ……
…… ………u…_ …… mm……
…… nwm/u

… … mm…—mg…»— sa…… su a.…….…
: :mmræwesdæ ; ; m…decnflwtülflws WWW…
un»… M on m…… . … … .. m...… wma:
.,… … V, …… … …;………yg…gn…
…… pe- le…samemeuuœwpwv m…
mum

Clearly, something went wrong here. When I got that output, I thought that I did not train properly the function. But it was not the answer. As described in that post (in French) it is necessary to have a clean picture, to read it properly

And actually, if we zoom in our picture – the first one, used by Fleur, to show me that package – we have

while for the second one – with a lower resolution – we have

It is necessary to have a scan of a typed text with high resolution… And you have to admit that it is awesome….

The good thing is that I have to work with a judge, in France, to assess quality of experts. And since most of the reports are typed, and then scanned, I am glad to have such a function. I just have to make sure that the resolution is high enough…

Juxtaposer des cartes et ‘confounding’

Pour aller un peu plus loin que mon précédant billet, élections, pièges à com(mentaires à la con) je voulais juste montrer quelques cartes, obtenues par simulations. Mais avant, revenons deux minutes sur la notion de ‘confounding‘. Pour reprendre le dessin de wikipedia, l’idée est que, conditionnellement à Z (notre ‘confounding factor’), les variables X et Y sont indépendantes. Mais cette indépendance conditionnelle peut (comme bien souvent) impliquer une forte corrélation entre X et Y. On peut ainsi imaginer un modèle de la forme X=Z+\varepsilon \varepsilon désigne une composante idiosyncratique, et Y=Z+\eta (où là aussi \eta est une composante idiosyncratique).

Par exemple, on peut supposer que Z est une variable liés à la lattitude du département, par exemple la température moyenne (histoire d’avoir une vague histoire à raconter, et d’être moins rébarbatif)

> n=115
> X=matrix(rnorm(3*n),n,3)
> X[,1]=sort(X[,1])
> library(maps)
> map("france",fill =TRUE,
col= rgb(1,0,0,pnorm(X[,1])))

Maintenant, supposons qu’on ait une variable X très corrélée à Z, par exemple la vente de crème solaire (en volume, toujours pour raconter une histoire qui illustrerait un peu mon propos)

> r=.8
> X[,2]=r*X[,1]+sqrt(1-r^2)*X[,2]
> map("france",fill =TRUE,
col= rgb(0,1,0,pnorm(X[,1])))

ce qui donne le nuage de points suivant (avec une forte corrélation avec le ‘confounding factor’)

On suppose maintenant qu’on a une autre variable Y , elle aussi très corrélée à Z, par exemple le prix d’une plaquette de beurre (qui pourrait être très cher dans le sud, où l’on cuisine plutôt à l’huile)

> r=.8
> X[,3]=r*X[,1]+sqrt(1-r^2)*X[,3]
> map("france",fill =TRUE,
col= rgb(0,1,0,pnorm(X[,1])))

avec une corrélation du même ordre, avec le ‘confounding factor’

Si on juxtapose les deux cartes, on a des variables corrélées,

mais on ne peut pas en conclure, juste en regardant ces cartes, que les ventes de crème solaire influencent le prix d’une plaquette de beurre ! Et on peut même accentuer encore l’effet, en jouant un peu sur les couleurs. Par exemple, avec

> map("france",fill =TRUE,col = rgb(1,0,0,qbeta(pnorm(X[,1]),.2,.5)))

on accentue un peu l’écart entre le nord et le sud (je joue ici sur l’échelle des couleurs, pas sur les valeurs !)

et sur nos deux variables, on a encore une juxtaposition qui donne envie de raconter un jolie histoire, non ?

Ah oui, ma corrélation entre les variables X et Y est relativement forte, de l’ordre de 0.6 (qui est supérieure à ce qu’on avait observé hier sur le taux de chômage et le taux du FN aux élections régionales)

> cor(X)
[,1]      [,2]      [,3]
[1,] 1.0000000 0.7863838 0.7727523
[2,] 0.7863838 1.0000000 0.6312878
[3,] 0.7727523 0.6312878 1.0000000

mais la corrélation est très sensible aux lois marginales, ça ne veut pas dire grand chose. Même si, visuellement, le nuage de points peut faire penser à celui qu’on avait hier

Bref, juxtaposer des cartes, c’est joli. De là à en déduire quoi que ce soit….

Élections, pièges à com (mentaires à la con)

Je suis tombé hier, sur le site de The Economist sur deux cartes, juxtaposées, une présentant le taux de chômage (en rouge, à gauche) et l’autre le vote FN (en bleu, à droite),

L’idée serait ici de comparer les cartes, et de se dire que les deux variables “taux de chômage” (produit par l’insee) et “vote FN” (aux élections régionales de 2015) seraient corrélées, et que l’une expliquerait peut être l’autre… Comme il est difficile (?) d’affirmer que le vote FN pourrait induire du chômage, on serait tenté de dire que les chômeurs votent FN, un raccourci de ce genre. Je ne dis pas que c’est faux, je dis juste que c’est s’aventurer sur un terrain dangereux, quand on commence à comparer des cartes, rapidement (et donner lieu à toutes sortes de commentaires à la con, pour expliquer le titre du billet). Sur ces deux variables, on peut d’ailleurs regarder les données brutes,

Oui, les variables semble très corrélées, par département. Après, si on calcule la corrélation, on “seulement” 0.516. Soit dit en passant, la corrélation ne dépend pas de l’orientation du graphique, j’aurais parfaitement pu mettre le taux de chômage en ordonnées. Mais classiquement, l’ordonnée est la variable que l’on souhaite expliquer, et l’abscisse est la variable (dite) explicative. Même si, comme toujours en régression, on n’établit aucun lien causal.

Bien sûr, il y a des départements pour lesquels il y a un écart, avec un chômage fort, et qui pourtant ne semblent voter massivement pour le FN (aux élections régionales).

En fait, on peut trouver des dizaines de cartes, qui présente des répartitions relativement proches, comme le rapport inter-décile des niveaux de vie par département

le taux de pauvreté par département

(on pouvait retrouver cette carte en ligne)

ou encore la part des minima sociaux dans le revenu disponible des ménages par département

Bref, on aurait très envie de dire que le vote FN s’explique par le chômage, la pauvreté, etc. Mais on ne peut pas…. C’est une faute de raisonnement, connu sous le nom d’ecological fallacy. En effet, le vote est un comportement individuel, par sa nature même (on va, individuellement, mettre un bulletin dans l’urne). Et on n’a pas le droit d’induire des comportements individuels d’observations agrégées… Ca ne veut pas dire que la relation causale n’est pas présente, ou le contraire… ça veut juste dire qu’on ne peut rien affirmer, juste en juxtaposant des cartes, on n’a aucunement une preuve (tout juste une vague corrélation au niveau agrégé). Aussi tentant que ça puisse être.

Pour dire quelque chose de censé sur les choix de vote, il est nécessaire d’avoir des enquêtes (ou peut être avoir accès à des votes électroniques, comme le vote des français de l’étranger aux législatives, par exemple, mais ça n’est pas vraiment possible, donc on va se limiter aux études, aux sondages). Par exemple le graphique dans Les Echos, à l’époque des régionales, justement,

Le chômage et le niveau de diplôme étant des variables très corrélées, on pourrait avoir l’impression d’avoir une piste.

Un problème important dans les cartes, c’est leur granularité : quand on regarde les départements, on est sur des espaces géographiques beaucoup trop grands ! un département, c’est très hétérogène. En particulier, il peut y avoir, ou pas, de grosse métropole. Certains chercheurs ont souligné que le vote FN est important dans la grande périphérie des métropoles, estimant qu’il augmente avec la distance du centre-ville. On le voit assez nettement sur la carte suivante

Le soucis, quand on utilise une granularité plus fine, c’est qu’on ne voit plus grand chose, comme sur les cartes ci-dessous, qui reprennent le résultat du FN aux élections régionales

et le taux de chômage (des 25-55 ans)

Bref, faire une étude montrant une relation causale, c’est pas simple… mais promis, si je trouve des données, je veux bien me lancer !

Exposé à Caen

Je serais en début de semaine à Caen pour un exposé sur “Understanding the Choice Negociated vs. Court Settlements in Bodily Injury Claim Compensations“, à partir de travaux en cours avec Enora Belz, Pierre-Yves Geoffard et Julien Tomas.

In car accidents, involving bodily injuries, a no-fault system has been instated in 1985, the so-called ‘loi Badinter‘. Following the accident (and after consolidation of victims injuries), the insurer of the driver of the car should offer a compensation to all victmims, that should cover health expenditures up to healing or recovery, as well as additional compensation for temporary incapacity, loss of professional earnings, temporary functional deficit, etc. The victim can either accept that compensation, or choose to go to court. Then a judge settles the claim, and the insurer has to pay for this compensation. Using the official data of AGIRA (association pour la gestion des informations sur le risque automobile), with more than 111,000 victims, injured between 1999 and 2014, we try to explain amounts obtained. The challenge here is that we only have to final settlement, and if the victim goes to court, the amount offered by the insurance company. Using Maddala (1983)’s limited dependent model, we model those two amounts, and then investigate the choice to go to court for a victim.