Tous les articles par mathieu rajerison

Législatives 2012: Activité Professionnelle et Appartenance Politique

Ici, nulle géographie, nous allons exploiter les données du fichier des élections législatives. Il est téléchargeable à cette adresse:
http://www.data-publica.com/data/13587–liste-des-6603-candidats-aux-elections-legislatives-des-10-et-17-juin-2012

Ce fichier a déjà fait l’objet d’analyses sur des blogs:

Le fichier des élections législatives possède deux informations que nous allons utiliser spécifiquement ici: la profession du candidat et son affiliation à un parti, ceci afin de voir s’il existe un lien entre les deux.

Plan:
  • Tableau de contingence et visualisation
  • Classification hiérarchique
  • Analyse Factorielle des Correspondances

Tableau de contingence et visualisation

Ces informations apparaissent toutes deux en lignes: il existe une colonne pour identifier la profession, une autre pour le parti. Nous allons transformer le fichier un petit peu afin de procéder à notre analyse, en ayant en lignes les métiers, en colonnes les différents partis et au sein du tableau, les valeurs d’effectifs. Nous allons aboutir à ce que l’on appelle un tableau de contingence.

En proportions, cela donne:

Classification hiérarchique

On peut essayer de dégager une hiérarchie, une classification des différentes activités professionnelles en prenant en compte les effectifs des activités pros au sein de chaque parti.

Certains regroupements sont peu surprenants:

  • Les cadres semblent afficher le même bord politique: cadre supérieur, ingénieur, chef d’entreprise
  • De même que ceux qui le porte-feuille de clients (assez surprenant!): expert comptable, agent d’assurances, notaire, …
  • Aussi, des candidats qui travaillent dans le domaine du bâtiment: entrepreneur en bâtiments, contremaitre, architecte.
  • Des professions médicales: dentiste, chirurgien, vétérinaire
  • Des activités liées à la créativité: homme de lettres et artiste, artisan, journaliste et autre média.
  • Des commerçants aussi sont regroupés

Par contre, on ne sait toujours pas quelle relation lie chacune des activités professionnelles aux partis. Si le candidat est ouvrier, chef d’entreprise ou enseignant, vers quel parti tendra-t-il à se rapprocher et ce lien est-t-il fort?

Analyse factorielle des correspondances

On peut aller plus loin en effectuant une analyse factorielle de correspondances.
Sur le blog de François Guillem ainsi que sur le blog de Jean-Baptiste Coulmont, on trouve des applications très sympathiques de l’ACP.

Dans notre cas, on effectuerait une ACP si l’on avait une liste d’individus et un score d’appartenance aux idées de chaque parti pour chacun d’eux, sans que l’on ne connaisse rien d’eux. Cette analyse aboutirait à l’analyse de relations entre partis, voire entre des individus et des partis.

Une AFC est comparable à une ACP, à ceci près qu’elle prend en entrée deux variables qualitatives au lieu d’une. Il s’agit d’une ACP particulière qui, en superposant une ACP sur le profil-lignes (ici, les activités professionnelles) et une autre sur le profil-colonnes (nature du parti), permet de dégager des proximités entre les différentes modalités inhérentes aux deux variables.

La prudence est de mise dans une AFC lorsque les effectifs sont faibles. Voici un classement dans l’ordre croissant des effectifs marginaux des activités professionnelles (somme de tous les effectifs par parti pour chaque métier).

Un résumé rapide d’une AFC sur notre pool de données législatives donne ceci:

      eigenvalue percentage of variance cumulative percentage of variance
dim 1 0.24250254              38.284494                          38.28449
dim 2 0.13548582              21.389491                          59.67398
dim 3 0.05178132               8.174848                          67.84883
dim 4 0.04483564               7.078317                          74.92715
dim 5 0.03231638               5.101869                          80.02902
dim 6 0.02886831               4.557514                          84.58653

Dans le meilleur des cas, les deux premières dimensions suffisent à expliquer en grande partie l’inertie totale/la variance de notre nuage de points mais ici, à elles deux, elles n’en restituent que 59.7 %, soit un peu plus de la moitié et moins des 2/3.  A partir de la troisième dimension, les inerties partielles attribuées aux axes sont assez faibles et égales. On s’arrêtera à deux axes quand même en ayant intégré cette lacune.

Voici le graphique de notre AFC:

Pour pouvoir définir nos axes, on utilise deux notions: la première est la contribution à l’inertie principale selon un axe, la deuxième, le  cosinus carré.

  1. La première se calcule en utilisant les coordonnées de la modalité considérée, son effectif  marginal, l’effectif total des candidats ainsi que l’interie principale de l’axe. Elle ne favorise pas  les métiers où il existe peu de candidats. 
  2. Le cosinus carré permet, par une simple formule trigonométrique autour des coordonnées d’une modalité, de déterminer la qualité de la représentation d’une modalité selon l’axe considéré.

Les modalités les plus contributives serviront de fil directeur afin de définir nos axes.

Axe 1

Pour les lignes

                                        Dim 1       Dim 2        Dim 3
Ouvrier (secteur privé)             13.826404 0.006545828 1.028070e-02
Professeur du secondaire et techn.  11.146823 3.325899414 3.222432e+00
Enseignant 1er deg.-directeur école  8.169252 1.617955387 9.755707e-01
Industriel-Chef entreprise           6.909406 1.452912388 8.674976e+00
Cadre supérieur (secteur privé)      6.033875 2.415535798 3.407859e+00
Fonctionnaire de catégorie B         5.705795 0.205800913 1.476177e-02
Avocat                               4.859643 1.857456635 2.092405e-01
Employé (autres entrep. publiques)   4.588501 0.062211865 3.014305e-05
Agent technique et technicien        3.611098 0.503568174 8.181242e-01
Grands corps de l’état               3.332086 7.191733408 1.909935e+00

On observe que des catégories socio-professionnelles sont très bien représentées selon cet axe, en particulier si l’on considère la profession d’ouvrier et de cadre supérieur, chef d’entreprise. Ces deux catégories s’opposent nettement selon l’axe1. Pour des valeurs de très bonne contribution, on retrouve d’ailleurs de très bonnes qualités de représentation (cosinus carrés): Fonctionnaire de catégorie B, ouvrier..
L’axe 1 semble également afficher un gradient dans les revenus, de l’ouvrier, du salarié agricole au chirurgien, au cadre supérieur.

                                        Dim 1       Dim 2        Dim 3
Fonctionnaire de catégorie B        0.8445433 0.017018866 4.665529e-04
Employé (autres entrep. publiques)  0.8352921 0.006327298 1.171687e-06
Enseignant 1er deg.-directeur école 0.8210169 0.090847686 2.093560e-02
Ouvrier (secteur privé)             0.7928073 0.000209701 1.258745e-04

Pour les colonnes

                                         Dim 1        Dim 2     Dim 3
 Extrême gauche                     53.6458070 3.685077e-01  0.586280
 Union pour un Mouvement Populaire  20.5045345 9.552070e+00  6.440497
 Front de gauche                     8.7616438 6.926126e+00  2.052448
 Divers droite                       6.3457991 5.398400e+00  4.939185
 Socialiste                          2.2204804 2.743800e+01  1.195895
 Parti radical                       2.1260108 3.077681e-01  3.394504
 Le Centre pour la France            2.0347689 4.064435e-01 10.014818
 Autres                              1.2411170 1.353765e+01 16.187905
 Nouveau Centre                      1.1801562 4.032157e-04  2.733341
 Alliance centriste                  0.4726506 9.336666e-02  1.076020

Il n’y a que pour l’extrême gauche et l’UMP que l’on observe de fortes contributions. Ces deux partis s’opposent d’ailleurs très nettement selon l’axe 2. Les partis “minoritaires” sont assez mal représentés selon cette dimension. On ne peut dire cependant dire que l’axe 1 représente des extrêmes dans les idées car la contribution de l’extrême droite est peu élevée. L’axe 1 semble opposer les conservateurs et les autres.

Axe 2

Pour les lignes et colonnes selon l’axe 2

                                          Dim 1     Dim 2       Dim 3
Fonctionnaire de catégorie A       5.844613e-03 14.782627  0.04618557
Employé (secteur privé)            1.302235e+00 11.858040  4.46289301
Retraité de l’enseignement         1.212100e+00  7.494665  0.83004297
Grands corps de l’état             3.332086e+00  7.191733  1.90993498
Etudiant                           7.154676e-04  5.870858  7.52139123
Autre retraité                     1.260179e-01  4.951988  4.13172449
Permanent politique                2.506618e+00  4.307984  7.17496219
Professeur du secondaire et techn. 1.114682e+01  3.325899  3.22243177
Retr.artis.commerc.chef d entrep.  6.103767e-01  3.053174 10.53309174
Commercant                         3.706510e-01  2.908927  0.50359611
                                           Dim 1     Dim 2        Dim 3
 Socialiste                          2.220480421 27.438003  1.195895249
 Ecologiste                          0.005144083 15.292174  2.809477381
 Autres                              1.241116999 13.537654 16.187904983
 Front National                      0.191649846 11.166394 31.816832284
 Union pour un Mouvement Populaire  20.504534463  9.552070  6.440496989
 Front de gauche                     8.761643759  6.926126  2.052447511
 Divers droite                       6.345799136  5.398400  4.939184582
 Extrême droite                      0.247869905  3.610187 12.713174193
 Radical de Gauche                   0.362048589  2.962734  0.052368789
 Divers gauche                       0.339019594  1.675900  0.006959395

L’analyse selon la dimension 2 est plus délicate. Nous nous contenterons de l’analyse selon la première dimension..

En considérant le nuage de points, de manière globale, il apparaît que les professions exercées par les candidats correspondent aux franges de population qu’ils sont censés défendre. Il n’y a pas vraiment d’antagonisme entre le métier exercé et le parti de ralliement. Peu de professions d’encadrement du côté de l’extrême gauche et inversement du côté de celui de l’UMP.

Il faut bien se remémorer que la somme des inerties principales des 2 axes n’est est que légèrement supérieure à la moitié, ce qui rend l’analyse moins fiable que dans ces cas on l’on retrouve une très forte contribution des 2 axes (supérieure à 80%). De plus, il y a peu de candidats exerçant certains métiers (salarié agricole, notaire, agent d’affaires…), ce qui rend l’analyse d’autant plus délicate pour ces éléments-là.

Si l’on avait préalablement réduit les classes pour les activités professionnelles: métiers manuels, relationnels, médicaux, libéraux ainsi que les partis en classes de partis: modéré, extrême, marginal, gauche ou droite, nous aurions sans doute eu une AFC de meilleure qualité.

Résultats du second tour: Nature du vote et Distance au littoral

Article en français

French elections: nature of votes versus distance to the coast : In the previous post, we saw how to make a simple choropleth of votes. Here, I detail how to create a dataviz combining a map and a standard xy plot to visualize the relation that exists between the nature of votes and the distance to the coast. A good opportunity to use a very interesting R library: spatstat.

 Dans le précédent post, nous avons vu comment ajouter les résultats du vote à de la donnée spatialisée afin d’aboutir à une petite choroplèthe des résultats:

Avant de réaliser l’article sur la réalisation d’une carte isarithmique et de partir en week-end prolongé :), je vous propose ici un petit article sur une méthode de représentation graphique de la relation existant entre la nature des votes et la distance séparant chaque commune au littoral.

Pour cela, dans un premier temps, il faut télécharger le trait de côte disponible sur le site du Service Hydrographique et Océanique de la Marine:

La représentation que nous allons voir se prête assez peu, en soi, à l’analyse mais elle nous permettra de voir comment utiliser la librairie spatiale R spatstat à travers le calcul de distance au plus proche voisin, et de voir l’affichage de graphiques.

Voici le code en entier. Les explications suivent par la suite:
 

Voici le résultat:

Nature du vote et distance au littoral

Le code expliqué:

Afin de déterminer la distance séparant chaque commune au trait de côte, on va utiliser la librairie spatstat. Celle-ci n’utilise pas les mêmes types d’objets que les librairies spatiales standardes, à savoir SpatialPoints/Lines/Polygones. Pour les points, elle définit la classe ppp et pour les lignes, la classe psp. On effectue en préalable une coercion des classes SpatialPoints/Lines vers ppp et psp afin de pouvoir utiliser les données spatiales dans spatstat.

tc <- readOGR("F:/DATAS/TRAIT_COTE/TCH.shp", "TCH")
tc.psp <- as(tc, "psp")
 
comm.pp <- SpatialPointsDataFrame(coordinates(comm2), data=comm2@data)
comm.pp <- as(comm.pp, "ppp")

Une fois cela fait, on peut alors utiliser la fonction nncross. Celle-ci permet de déterminer le voisin le plus proche (segment ou point) ainsi que la distance qui le sépare de ce dernier.

nn <- spatstat::nncross(comm.pp, tc.psp)

On peut regarder ce que cela donne au niveau des distances commune – littoral. Pour cela, on utilise la fonction spplot qui adapte les fonctions d’affichage graphique de la librairie lattice aux objets géographiques. C’est une autre possibilité d’affichage, en plus de la fonction de base plot vue dans le post précédent.

comm2$dist <- nn$dist
spplot(comm2, "dist", col=NA)
Distances entre chaque commune et le littoral
PS: on dirait du raster mais ça n’en est pas 🙂

Les données que l’on va utiliser pour les représentations suivantes sont:
– Les coordonnées xy des centroïdes de communes
– Le pourcentage de vote pour l’un et l’autre des candidats
– La distance de séparation commune – trait de côte

Nous allons créer un data.frame exprès pour cela, concentrant toutes ces informations:

df <- data.frame(pcsar=comm2$pc.sar, x=comm.pp$x, y=comm.pp$y, dist=nn$dist)

Attaquons-nous aux graphiques.

On va utiliser une couleur rouge pour les votes dominants de gauche et bleue pour ceux de droite (logique). Contrairement à avant, on n’utilisera pas de nuance liée au pourcentage. On intègre également une valeur de transparence de 10%.

alpha <- .1
cols <- rgb(ifelse(pcsar > .5, 0, 1), 0, ifelse(pcsar > .5, 1, 0), alpha)

Il n’y aura rien de nouveau au niveau du graphique géographique par rapport au post précédent, à part que l’on affiche des points et non des polygones. On superposera aussi le trait de côte.

plot(comm2.ctrd, col=cols, pch=16, cex=2, xlim=bb[1,], ylim=bb[2,])
plot(tc, col="white", lwd=4, add=TRUE)

C’est là, la partie nouvelle: à partir du data.frame appelé sobrement df, nous allons réaliser un plot x versus y assez standard. En x, nous aurons la distance séparant chaque commune de la côte, en y, la latitude et en couleur de point la nature du vote. Cette dernière sera donc la troisième dimension de ce graphique.

plot(dist, df$y, pch=16, cex=2, col=cols, xlab=NA, ylab=NA, axes=FALSE)

Le paramètre graphique par(mfrow=c(1,2)) a permis de mettre côte à côte le graphique géographique et le graphique xy. 

par(mfrow=c(1,2), bg="black")

 J’ai choisi de représenter les traits de la même couleur afin de pouvoir faire la relation entre les deux. En quelque sorte, pour aboutir au second graphique. C’est comme si on prenait la France et qu’on la dépliait, l’étendait selon son littoral.

abline(v=0, col="white", lwd=4)

Nature du vote et distance au littoral

Intéressant ou pas, à vous de voir! En tout cas, nous avons pu voir quelques fonctions bien sympathiques!

 
 

Résultats du second tour: ma première choroplèthe avec R


 article en français

French elections – my first choropleth with R : Many journalists say that the electoral campaigns are becoming “data campaigns”. The candidates are fighting, making massive use of numbers. They’re looking for the number that will make the other one wrong. They’re speaking numbers, displaying plots, graphics – interactive or not – about what the actual state of the country is, and how they intend to change it. Why not taking the most of the elections data to learn how to make a simple choropleth with R?

The entire code is available for download at the end of the article

Dans cet article, nous allons créer une petite choroplèthe des résultats du second tour des élections présidentielles.

Voici les adresses de téléchargement des fichiers source:
– Contours des communes : http://professionnels.ign.fr/ficheProduitCMS.do?idDoc=6185461
– Résultats des élections : http://www.data-publica.com/opendata/13495–resultats-du-deuxieme-tour-de-l-election-presidentielle-2012

Dans un premier temps, nous avons besoin d’installer les paquets appropriés: rgdal pour lire les données au format ESRI et maptools pour certains traitements associés aux données géographiques.

install.packages(c("rgdal", "maptools"))

Puis, nous importons, d’un côté les contours des communes de GEOFLA:

comm <- readOGR("F:/DATAS/GEOFLA/COMMUNES/COMMUNE.SHP", "COMMUNE")

et le fichier du résultat du second tour des élections présidentielles.

votes <- read.csv2("IN/resultats2012.csv", sep=",", quote=""")

Le fichier des votes contient plusieurs colonnes. Pour les afficher:

names(votes)

Calculons le pourcentage de votants par parti:

votes$pc.sar <- votes$results.sarkozy /  votes$results.exprimes
votes$pc.hol <- votes$results.hollande / votes$results.exprimes
On peut d’ores et déjà afficher quelques statistiques:
summary(votes$pc.sar)
summary(votes$pc.hol)
 

Retenons uniquement les communes pour lesquelles des résultats électoraux sont renseignés dans le fichier.

nmatch <- which(is.na(match(comm@data$INSEE_COM, votes$commune.code)))
print(comm@data[nmatch, c("INSEE_COM", "NOM_COMM")])
comm <- comm[-nmatch, ]

Et hop, la jointure:

m <- merge(comm@data, votes, by.x="INSEE_COM", by.y="commune.code", all.x=TRUE)

Il faut aussi affecter un nom unique à chaque ligne. Pour les objets géographiques, on utilise la fonction spChFIDs et pour les data frames, row.names. Affectons le numéro INSEE de la commune:

comm <- spChFIDs(comm, as.character(comm$INSEE_COM))
rownames(m) <- as.character(m$INSEE_COM)

Maintenant, on peut aboutir à un nouvel objet géographique muni des résultats des élections.

comm2 <- SpatialPolygonsDataFrame(as(comm, "SpatialPolygons"), data=m)

Voici un petit diagramme qui schématise toutes les étapes:

Effectuer une jointure avec R

Nous allons, dans la carte, créer 20 classes de valeurs à partir des pourcentages avec la fonction classIntervals

cls <- classIntervals(comm2$pc.sar, n=20, style="equal")

Notre palette de couleurs ira du rouge pour Mr Hollande au bleu, pour Mr Sarkozy, mais en passant par un point d’arrêt: le blanc là où il n’y a pas d’affection particulière pour l’un ou l’autre des candidats (votes proches de 50%). Considérant cette palette à trois couleurs, nous retrouvons les couleurs de chaque valeur et classe de cette façon:

colcode <- findColours(cls, c("red", "white", "blue"))

Affichons le résultat:

plot(comm2, col=colcode, border=NA)
title(main="résultats des élections présidentielles - second tour") 

Cela pourrait être sympa de mettre les contours des régions en plus. Cela nous permettra de voir en même temps comment dissoudre des polygones en fonction d’une valeur. Les contours des régions n’existent pas dans GEOFLA mais on peut les créer à partir du fichier des départements. On le fait comme ceci:

dep <- readOGR("F:/DATAS/GEOFLA/DEPARTEMENTS/DEPARTEMENT.SHP", "DEPARTEMENT")
reg <- maptools::unionSpatialPolygons(dep, dep$NOM_REGION)
 

On ajoute les contours de régions en les convertissant vers des objets lignes. Dans le jargon spatial R, on parle de coercion et cela se fait avec la librairie maptools. On ajoute aussi les libellés des régions. Pour la transparence des contours et des libellés, on utilise le 4e argument de la fonction rgb.

plot(as(reg, "SpatialLines"), col=rgb(0,0,0,.2), lwd=2, add=T)
text(coordinates(reg), labels=row.names(reg), cex=.5, col=rgb(0,0,0,.5))
title(main="résultats des élections présidentielles - second tour")

Dans le prochain post, nous verrons comment aboutir à une représentation de ce type, toujours pour les élections présidentielles

Carte isarithmique des élections selon David B. Sparks

N’hésitez pas à poser vos questions dans l’espace des commentaires si vous rencontrez des difficultés!

Le code entier https://gist.github.com/2857180