“Facebook manipule vos émotions” : Milgram 2.0

Les médias n’ont eu aucune difficulté à médiatiser ad nauseam la dernière actualité du réseau social Facebook : en manipulant les informations que lisent plusieurs centaines de millions d’utilisateurs, on peut créer une variation de sentiment de quelques points de pourcentages — et qui correspond, en pratique, à trois fois rien.

Faire varier l’opinion d’un ou plusieurs iotas est inscrit dans l’ADN des médias, et si le verbe “manipuler” est remplacé par le verbe “personnaliser”, on retombe sur la définition de la page d’accueil de Google ou du Monde : de l’information, et beaucoup de publicité, taillée sur mesure pour l’utilisateur, en partie grâce aux données des autres utilisateurs.

Or, les utilisateurs Facebook ne se sont pas tous fait une raison sur le fait que “quand on ne paie pas, on est le produit”. Cette expérience n’est pas unique et ses résultats ne sont pas si encourageants que ça, mais sa grande échelle fournit un bon motif à chacun pour s’indigner de cet état de fait.

Du coup, bien que tout soit écrit noir sur blanc dans les conditions d’utilisation (que personne ne lit) et que n’importe quel essai clinique contrôlé pose exactement les mêmes questions (élevées au risque de vie ou de mort dans certains cas), c’est le cocktail, très efficacement servi par Facebook aux médias, qui fait le plus de bulles, à partir de :

  • 90% d’eau claire (les effets sont de très faible magnitude)
  • 9% de big data (sans guillemets : n > 500 000, bitches)
  • 1% de Milgram 2.0

Le dernier ingrédient concerne les normes éthiques qui s’appliquent aux expériences contrôlées : Facebook semble avoir suivi les normes états-uniennes en la matière, en validant son étude auprès de l’IRB, mais ces normes sont récentes et jamais complètement consensuelles.

Et surtout, on ne sait pas ce que Facebook va faire de ces résultats : si la finalité d’une expérience contrôlée est claire dans le cas d’un essai clinique, elle l’est moins dans le cas d’un réseau social, d’autant plus que les publicitaires n’avaient pas besoin de cette étude pour acheter ses services.

En définitive, c’est ce dernier travestissement qui peut poser problème : sous couvert de mener une recherche inductive de sociologie appliquée à l’insu de votre plein gré, Facebook vend sa force de frappe publicitaire, et votre réaction indignée fait partie intégrante de la stratégie de diffusion auprès des futurs investisseurs.

Milgram, peut-être, mais “2.0”.

Extraire un corpus médiatique sans (trop) saigner des yeux

Vous vous êtes déjà demandé quelle avait la couverture médiatique d’un projet de loi comme le projet de loi DADVSI ? ou, plus connu, le projet de loi HADOPI, qui donna lieu à un feuilleton législatif de plusieurs années ?

J’avais très rapidement mentionné le sujet en évoquant un papier co-écrit avec Pierre Gueydier, présenté à l’AFSP en 2013 et que nous avons commencé à remettre à jour. Comme d’habitude, tout est en ligne.

Le papier portant sur la politisation, une étude préliminaire de la médiatisation des projets de loi peut être un bon moyen de jeter un premier coup d’oeil aux individus, aux institutions et aux organisations mobilisées autour de leur examen.

Quelques essais et 300 lignes de code plus loin, on dispose donc d’un corpus de 6350 articles issus de sept médias français différents1, qui ressemble à ça au fil du temps :

counts

Comment faire

  • Pour chaque média, il y a un moteur de recherche utilisant une pagination des résultats. La première étape consiste donc à parcourir chaque page de résultats, en récupérant les adresses des articles.
  • Ensuite, pour chaque article, on a accès soit à une page donnant accès au texte intégral, soit aux premières lignes du texte dans le cas des articles payants du Figaro et du Monde.
  • Enfin, il faut se donner une syntaxe permettant de sauvegarder le contenu d’un lien HTTP vers un fichier texte, ce qui demande quelques essais-erreurs avec les expressions régulières.

Les techniques servant à récupérer et à nettoyer les données ayant déjà été traitées dans plein d’autres billets (exemple), je ne développe pas sur ce point, mais suis intéressé par tout scraper équivalent pour d’autres sites de médias.

Qu’en tirer

Le raisonnement du texte étant qualitatif, l’exploration du corpus est avant tout une manière de trianguler des décisions de terrain, comme le choix de se focaliser sur certains acteurs plutôt que d’autres.

Histoire de repérer les acteurs, on extrait tous les termes contenant une majuscule initiale, que l’on nettoie ensuite des termes courants. Restent les termes comme “Vivendi Universal” ou “Frédéric Mitterrand”.

On parcourt ensuite les mille termes les plus fréquents, dont on tire une liste de presque 350 entités, allant de la classe politique à Twitter en passant par les DRM et la jurisprudence SABAM.

Voici à quoi ressemble la co-occurrence de ces entités dans les articles publiés entre 2012 et aujourd’hui, représentées sous la forme d’un réseau de termes fréquemment associés à la “mission Lescure-préparant-l’acte-II-de-l’exception culturelle” :

seq3

Le réseau est naturellement très dense (il y a énormément de co-occurrences), mais les liens sont plus ou moins ténus, grâce à une technique de pondération qui tient compte du nombre d’entités identifiées dans chaque article2.

En additionnant ces liens, on obtient un indice plus synthétique, le degré pondéré de centralité. Dans le graphique ci-dessus, la taille des entités est proportionnel à cet indice, qui n’est qu’une mesure possible parmi d’autres.

Voici donc, pour terminer, les quinze premiers scores de centralité sur la totalité des neuf années couvertes. D’autres tableaux et graphiques explorant des segments temporels spécifiques de la période couverte sont disponibles dans l’annexe du papier.

Screen Shot 2014-06-26 at 3.39.09 PM

Je n’ai pas le temps de m’acharner sur les données, mais cette preuve du concept montre qu’il n’est pas difficile de récolter un corpus médiatique, hélas moins riche qu’une base de données comme Factiva ou LexisNexis, mais d’ampleur raisonnable.

Si vous avez des suggestions sur comment modéliser tout ça proprement, à coups de topic models ou autre chose, laissez un commentaire, mais c’est en général à ce stade-là que l’on commence à saigner un peu des yeux.

  1. Libération apparaît dans le corpus Écrans.fr, et les articles des Échos ne sont pas disponibles avant décembre 2011. []
  2. Cette technique permet de mettre sur un même plan les articles en texte intégral et ceux pour lesquels on ne dispose que des deux premiers paragraphes. []

Big Data Fail ?

La base de données GDELT (Global Database of Events, Language, and Tone), déjà mentionnée ici, donne enfin lieu à quelques analyses précises. Les résultats sont sans équivoque : la base, qui contient plusieurs millions d’articles sur toutes sortes d’événements à travers toute la planète, ne sert pas à grand chose pour le moment.

Les problèmes semblent moins venir des données elles-mêmes que de leur classification a posteriori. L’exemple du kidnapping géant par Boko Haram au Nigeria en mai dernier l’illustre très bien : l’événement a été géocodé à une quarantaine d’endroits différents, avec pour conséquence… le comptage d’autant d’événements différents.

Pas étonnant, du coup, que personne ne s’y retrouve, en particulier lorsque l’architecte de la base affirme que les caricatures danoises de Mahomet sont l’événement mondial le plus saillant sur les trente-cinq dernières années. La personnalité de l’architecte en question, qui a fait toutes sortes de déclarations grandiloquentes, y est peut-être aussi pour quelque chose, mais ce n’est qu’une supposition de ma part.

Cela ne condamne pas définitivement les données, mais jette un sérieux doute sur leur exploitation en l’état actuel de la base. On peut imaginer toutes sortes de rectifications (après tout, c’est l’intérêt d’avoir placé la base en accès ouvert), ou imaginer des réformes plus radicales, comme limiter la base à quelques sources bien choisies à l’entrée et espérer en tirer quelque chose de mieux structuré à la sortie—c’est la stratégie suivie par l’outil équivalent que possède le Department of Defense américain.

Un bref aperçu filigrané des propositions du rapport Hautcoeur

Le rapport Hautcoeur sur l’enseignement des sciences économiques dans le supérieur a l’air intéressant, surtout si l’on s’amuse à lire le filigrane des recommandations. En partant du principe qu’on ne recommande que ce qui n’existe pas encore de manière univoque et généralisée, voici par exemple la recommandation #2, qui suit l’obligatoire recommandation #1 sur la pluridisciplinarité et la spécialisation progressive :

2. Favoriser la construction et la critique des données et des faits stylisés par les étudiants dès le premier cycle, au sein des cours d’une part, et en les associant, en tant qu’assistants, à des projets de recherche d’autre part.

L’auteur du rapport a le mérite de tenter un exercice périlleux : émettre des recommandations à destination des étudiants, sans trop directement émettre de critiques à destination… des enseignants. Mais concrètement, lorsqu’il écrit dans son résumé que “[l]es étudiants doivent apprendre à maîtriser la construction et l’analyse critique des bases de données et indicateurs statistiques”, il s’adresse aussi aux chercheurs qui font l’économie (hum) de cette critique dans leurs propres travaux—les économistes n’étant bien sûr pas les seuls concernés, seulement les plus exposés.

Il me semble en effet difficile de ne pas faire de lien entre cette recommandation et les récentes “controverses” autour des données de Reinhart et Rogoff ou, plus récemment, de Piketty ; je place “controverse” entre guillemets car, dans le premier cas, les erreurs sont grossières et avérées, alors que dans le second, la charge de l’accusation est au mieux, mince, au pire, pas complètement honnête.

On trouve aussi, dans le rapport, une proposition portée de longue date par la CJC sur l’intégration des docteurs dans la haute fonction publique, ainsi qu’une demande de contournement de l’agrégation comme instrument principal de promotion intra-disciplinaire. Dans le texte :

supprimer l’agrégation du supérieur comme mode prioritaire de recrutement

Les termes “suppression” et “agrégation” reviennent de plus en souvent côte-à-côte. L’enjeu est légèrement différent en science politique, mais la position de l’ANCMSP, votée dès 2007, mérite d’être mentionnée ici. Ayant longtemps milité dans les deux associations, je m’en tiendrai à ces simples mentions, tout en remarquant que d’autres éléments centraux du système d’enseignement et de recherche français ont survécu à des tentatives de suppression dans la période récente.

Toujours dans les recommandations, et toujours en lecture filigrane :

7. Imposer aux organisations publiques de publier les évaluations des politiques publiques effectuées sur appel d’offre et de favoriser la réplication de ces évaluations.

On aura donc lu : à l’heure actuelle, les organisations publiques ne sont pas tenues de publier les évaluations des politiques publiques effectuées sur appel d’offre (et financées par la collectivité)1. Je ne sais pas si c’est vrai, ni si ça se fait de poser une QPC sur un article (le quinzième) de la Déclaration des Droits de l’Homme et du Citoyen2.

La recommandation suivante se passe de commentaire :

8. Préciser les potentiels conflits d’intérêt des enseignants-chercheurs dans les publications, enseignements et rapports d’évaluation.

“Préciser” doit être l’antonyme d’“occulter” : filigrane, toujours.

Suivent, un peu plus loin, deux recommandations bizarroïdes : celle qui demande au CNRS de recréer les contrats post-doctoraux qu’il a supprimés par centaines quand ses crédits sont partis à l’ANR (recommandation #16), et celle qui demande à ce que cette même ANR se coordonne avec la Commission européenne pour financer des CDI (recommandation #17), ce qui semble complètement contre-nature : aucune de ces institutions ne me semble vouloir s’engager dans cette voie.

La ministre/secrétaire d’État trouvera tout cela certainement très intéressant, et y trouvera même certainement des ressemblances avec les discussions sur ces mêmes points lors des Assises qu’elle avait elle-même organisé. Idem pour une bonne partie des annexes reprenant les enquêtes CEREQ, que l’on retrouve dans un rapport sur deux.

Pour terminer, big up à Baptiste Coulmont, grâce à qui on trouve désormais des graphiques réalisés avec R dans un rapport public ! Voir page 123, reproduite ci-dessous. En revanche, les “nuages de mots” des autres pages ne me semblent pas servir à grand chose, même si c’est joli.

Screen Shot 2014-06-09 at 1.32.13 PM

Voilà pour l’aperçu des premières pages — sachant que la lecture des premières pages est exactement ce qu’il restera, à terme, du rapport. Allez jeter un coup d’oeil par vous-même, et dîtes-moi si vous y avez lu autre chose : pour ma part, j’y ai trouvé d’excellentes propositions, en lien avec d’autres propositions actuelles, et sans révolution copernicienne du statu quo : un rapport public comme on les connaît dans le secteur.

  1. L’État n’ayant pas besoin de passer des marchés publics avec ses propres corps d’inspection, peut-être est-il moins concerné que les collectivités locales, qui dépensent des sommes parfois faramineuses en rapports d’audit. []
  2. En revanche, pour avoir déjà consulté des rapports rendus par des micro-entreprises de consultants jugés scientifiques grâce à des diplômes gracieusement obtenus dans les années soixante (de l’aveu même de leurs détenteurs), je pense qu’il y aurait de quoi s’amuser un peu si les logiques de l’open access et de la réplication venaient à s’y appliquer. []

Qui arrivera à décoder la bombe à retardement symbolique du patrimoine des élus ?

Les décodeurs du Monde constataient récemment que les déclarations de patrimoine des élus, issues du “scandale Cahuzac”, font l’objet d’un dispositif hyper-restrictif, empêchant notamment toute prise de note lors de leur consultation en présence d’un agent préfectoral (voir les articles 1 et 3 de l’arrêté fraîchement publié).

Screen Shot 2014-06-10 at 7.37.23 PM

Aux Pays-Bas, des petits malins ont utilisé une faille juridique pour collecter en temps réel les résultats des dernières élections européennes. Rien ne semblant interdire la lecture des déclarations à haute voix, j’imagine que le dispositif français doit aussi avoir une faille—il y en a toujours au moins une, comme en matière de sécurité informatique1.

Plus sérieusement, le Parlement français a donc décidé de s’en tenir aux effets d’annonce, ce qui fait que pour un citoyen français, il reste plus difficile de s’informer sur les ressources des élus de son propre parlement que d’obtenir la même information pour la Roumanie, qui diffuse les déclarations d’intérêts et de patrimoine de ses élus, des candidats aux élections, et plus généralement de tous les agents financés par de l’argent public, qu’ils soient fonctionnaires ou pas2 :

Screen Shot 2014-06-10 at 7.46.26 PM

La comparaison avec la Roumanie est bien évidemment faussée par la corruption endémique de son appareil d’État, qu’on se doit d’espérer moindre chez les parlementaires français. Mais dans une démocratie comparable, la Grande-Bretagne, le scandale des dépenses parlementaires de 2009 me semble avoir débouché sur quelque chose de légèrement plus pertinent : les parlementaires y bénéficient désormais d’une assistance administrative les aidant à remplir leurs déclarations de revenus et à ne pas s’acheter de nains de jardin avec leur carte bancaire de représentant du peuple3.

Bref, plutôt qu’un risque de hack généralisé du dispositif grâce à une opération massive de désobéissance civile et de crowdsourcing des données, le Parlement français me semble avoir surtout pris le risque d’affronter, un de ces quatre, le même scandale que la Grande-Bretagne—c’est-à-dire un mélange d’antiparlementarisme assez rarement étayé et de dépenses injustifiées mais souvent accidentelles et futiles.

Et dans cette dernière hypothèse, les conséquences électorales seront, à coup sûr, beaucoup plus sévères que celles occasionnées par le scandale Cahuzac, sans même parler des dégâts collatéraux que de tels scandales peuvent engendrer. C’est cette perspective, inquiétante mais à mon sens tout à fait réelle, qui me fait penser que cet arrêté est une petite bombe à retardement symbolique, placée à mi-distance des deux chambres parlementaires4.

Encore un point commun avec la Grande-Bretagne, en quelque sorte.

  1. Histoire d’être bien clair, je n’encourage personne à aller vérifier cette hypothèse. Les sans-papiers savent qu’un agent préfectoral peut obtenir l’intervention des forces de police sur place. []
  2. Le dispositif roumain est né d’une condition posée lors de l’entrée du pays dans l’Union européenne. Apparemment, “deux poids, deux mesures” s’écrit “două greutăți, două măsuri” en roumain. []
  3. Je plaisante à peine : certains députés britanniques se sont fait mettre au pilori par la presse pour avoir acheté des cabanons de jardin ou des canards en plastique pour leur baignoire. []
  4. Ce raisonnement devrait inciter les parlementaires à considérer les associations comme Regards Citoyens de manière moins négative, mais je suis biaisé par mes propres amitiés sur cet exemple. []

Utiliser les résultats électoraux du ministère de l’intérieur

Toux ceux qui ont eu à utiliser un jour ou l’autre les fichiers de résultats électoraux diffusés par le ministère de l’Intérieur français savent que ceux-ci nécessitent un assez lourd travail de mise en forme afin d’être exploitables, en tout cas pour les élections pour lesquelles l’offre électorale n’est pas homogène sur le territoire (c’est-à-dire toutes sauf les présidentielles). En effet, les fichiers Excel diffusés par le ministère comprennent une ligne par territoire (commune, par exemple), et autant de colonnes que nécessaires pour mettre les résultats de tous les candidats. Il serait pourtant tellement simple de mettre le fichier en format “long”, c’est-à-dire une ligne par combinaison territoire/candidat… Mais il faut croire que personne au ministère n’a jamais eu à lire un de leur fichier dans R ou un autre logiciel de statistiques (ou de cartographie). Au passage, on peut regretter que le site data.gouv ne demande ni même ne suggère à ses contributeurs de fournir les données en format tabulaire…

Quoi qu’il en soit, ceux qui ont à utiliser ces données ont généralement créé leurs petites routines pour traiter ces données. Sous Excel, le processus est particulièrement douloureux. Je me rappelle avoir fait planté des ordinateurs en faisant tourner des macros VBA…

Ayant eu à bricoler un script sous R pour importer ce genre de fichiers, j’ai décidé de le diffuser – ce qui a le mérite de m’obliger à le nettoyer un peu, et ce qui permettra, je l’espère, que d’autres l’améliorent. J’ai donc créé un tout petit package (il n’a qu’une fonction !) que j’ai mis sur mon compte Github.

Précision importante : le script, à l’heure actuelle, agrège les résultats en fonction des étiquettes attribuées par le ministère de l’Intérieur. C’est une limite importante, mais qui suffit à la plupart des utilisations courantes.

C’est une version 0.1 mais qui est fonctionnelle. À l’heure actuelle, traiter le fichier de résultat des européennes par communes (36762+ lignes, 227 colonnes) prend de l’ordre de cinq minutes sur un ordinateur de bureau classique. Ce n’est pas dramatique mais c’est un peu long. À l’avenir, je vais essayer d’accélérer cela – a priori en codant le cœur du script en C++, ce qui me forcera à m’y mettre. Mais peut-être d’autres auront-ils d’autres pistes – je ne suis pas sûr que mon algorithme soit optimal.

Sur ma todolist également : construire une application Shiny autour du package, pour que ceux qui n’utilisent pas R puissent quand même l’utiliser pour transformer leurs données.
Autre idée : permettre d’agréger les résultats autrement que par étiquette. C’est techniquement assez trivial, mais ça pose des problèmes de fond, du fait de l’hétérogénéité territoriale de l’offre électorale. Mais on pourrait imaginer la possibilité, par exemple, que l’utilisateur fournisse au script une sorte de “dictionnaire” associant les listes ou candidats à une nomenclature spécifique.

Je suis preneur en tout cas de tous les retours et suggestions des utilisateurs ! Et j’espère que ce sera utile à quelques uns !

Law Factory = Law Factory++

Le projet final du projet de recherche “La fabrique de la loi” a été présenté à la conférence “Law Factory II“. C’est en ligne depuis jeudi dernier, allez jeter un coup d’oeil :

Screen Shot 2014-06-02 at 3.22.22 PM

La conférence m’a permis de présenter mes résultats définitifs et de revoir oplein de gens chouettes, dont l’un des auteurs de Parltrack, qui m’avait appris XPath (avec Bram) il y a quelques années.

Comme j’aime beaucoup Parltrack, j’ai voulu jouer un peu avec les données. voici une visualisation interactive des amendements déposés dans les commissions du Parlement européen lors de la législature 2009-2014 (à jour du 26 mai 2014) :

Screen Shot 2014-06-02 at 3.03.09 PM

Screen Shot 2014-06-02 at 3.09.00 PM

Comme pour le Parlement français, tout est codé en une page PHP + HTML/CSS + Javascript qui utilise Sigma.js et des données exportées depuis R ; le code donne tout ce qu’il faut pour reproduire les graphiques ou la visualisation, en utilisant ggnet et rgexf.

Une page séparée montre les réseaux sous-jacents, qui sont très peu denses lorsque les commissions comptent peu de membres : la commission “Crises”, par exemple, n’a pas l’air de passionner les foules de législateurs en délire. Les dimensions des réseaux résument ces différences :

density

Note de lecture : les abréviations des commissions sont positionnées selon le nombre d’eurodéputés présents dans le réseaux (y), et le nombre total de cosignatures dans la commission (x). La taille des libellés est proportionnelle à la synthèse des deux informations, la densité du réseau.

La modularité change du tout au tout selon la commission. La pêche et les pétitions sont des commissions peu polarisées, de même que celles sur les transports, le budget ou les droits des femmes. Cette représentation change dans les commissions “Culture” ou “Agriculture”, où la modularité est deux fois plus importante. Les commissions les plus polarisées (CRIS et SURE) ont trop peu de noeuds pour que la mesure soit pertinente.

modularity

Note de lecture : les abréviations des commissions sont positionnées selon la modularité de leur réseau. Les points gris donnent la modularité maximale mesurable (algorithmes Louvain et Walktrap). La couleur donne le ratio entre modularité empirique et modularité maximisée. Toutes les mesures sont comprises dans l’intervalle [0,1].

Toutes les interventions plénières des eurodéputés, en 100 lignes (de code)

Quelques notes tirées de trois conversations sur les sept derniers jours. C’était plus long à décrire qu’à coder.

Commençons par récupérer la liste des eurodéputés, en trois étapes :

  1. La source : l’index complet est disponible en une seule page, ce qui rend les choses faciles. Le zéro final de l’adresse est le numéro de législature ; il y en a 7 au total, et la dernière possède un index des députés un peu plus détaillé, que l’on utilisera peut-être un autre jour.
  2. La méthode : il y a quatre ans, on m’a fait découvrir XPath, qui est une syntaxe servant à sélectionner des éléments dans un document structuré. XPath, c’est un peu comme les expressions régulières, ou découvrir comment trafiquer un PDF sans laisser de traces dans les métadonnées : ça change la vie1.
  3. La syntaxe : le site Internet du Parlement européen est rédigé en HTML propre (car généré automatiquement), avec des éléments bien imbriqués les uns dans les autres : c’est le cas idéal. La source de l’index, consultable dans tout navigateur, donne la syntaxe exacte des éléments utilisés ci-dessous.

Illustration de l’explication ci-dessus :

Screen Shot 2014-05-19 at 9.26.24 PM

À présent, dans R :

  1. On souhaite juste sauvegarder un “annuaire” minimal des 3 000 et quelques eurodéputés, et le sauvegarder dans un fichier qui servira d’index général où chaque eurodéputé est identifiable par trois éléments : le nom complet, inutilisable car plein d’accents et non unique2, l’URL (l’adresse de sa page personnelle), et dans cette URL, un numéro, 4484 par exemple, qui servira d’identifiant unique plus tard.
  2. La fonction de téléchargement va lire la page HTML, en extraire les éléments pertinents à partir de sa structure, et renvoyer tout ça dans un jeu de données. On sauvegardera les données au format CSV, un format en texte simple qui sauvegardera correctement les accents dans les noms si l’on s’assure que le parser les lit en encodage UTF-8.
  3. Petite nuance : quand vous voulez extraire un lien, la syntaxe XPath vous le permet directement ; mais pour extraire le texte d’un lien, le truc sur lequel on clique pour aller au lien en question, il vous faut la “valeur XML”, d’où la fonction xmlValue ci-dessous. Le reste du code demande surtout de se renseigner sur XPath, et ce n’est pas compliqué du tout, surtout si l’on apprend par essai-erreur.

Il va donc vous falloir installer puis charger les librairies (a.k.a packages, extensions, plugins, comme vous voulez) jsonlite, plyr et XML, et 20 lignes plus tard, vous avez tous les eurodéputés dans un fichier CSV.

Plus compliqué, obtenir toutes leurs interventions parlementaires :

  1. Sur la page de chaque eurodéputé (exemple), un lien fournit toutes les interventions en séance plénière (exemple). En lisant encore une fois la source de la page, on trouve le petit bout de Javascript qui génère cette information, et surtout l’URL qui renvoie cette information depuis la base de données utilisée en coulisses du site.
  2. L’information est au format JSON, pour lequel il y a non pas un, ni deux, mais trois packages R qui peuvent assurer la conversion vers le format classique des jeux de données R, data.frame. Jeroen Ooms m’a prouvé en cinq lignes que son package était le meilleur, et j’ai pu vérifier depuis qu’il a entièrement raison3.
  3. Les fonctions conditionnelles de type if else, qui permettent par exemple de ne rien faire si aucune donnée n’a été trouvée, servent à contrôler l’exécution du script. Le code ci-dessous contient deux autres structures apparentées, while et try. Quelques détails chiants si vous ne les utilisez pas fréquemment :
    • while est un itérateur habituellement moins préférable que for (ou, dans R, qu’une vectorisation de type *apply), mais qui marche très bien ici pour lister les interventions de chaque eurodéputé(e)4.
    • try permet de continuer l’exécution même si un problème de connexion Internet empêche ponctuellement de lire une page (erreurs 404, 502, 503… amusez-vous bien)5.

Voilà pour le détail, et 30 lignes plus tard, vous pouvez récupérer les interventions de n’importe quel eurodéputé dans n’importe quelle législature (1 à 7), en utilisant son numéro d’identifiant unique (id)6.

Ça se complique encore un peu mais on y est presque. Le workflow final est le suivant :

  1. Pour chaque eurodéputé dans l’index général, extraire le numéro d’identifiant unique de l’adresse de sa page Internet, puis aller chercher ses interventions publiques dans chacune des 7 législatures parlementaires. La partie “pour chaque député” est purement itérative (for), mais la partie “chacune des législatures” est vectorisée : on va de 1 à 7, et on applique à chaque fois la fonction get_cre de 20 lignes décrite plus haut. Le seul bénéfice avéré de la vectorisation dans ce cas réside dans l’économie d’accolades et de lignes de code à gérer.
  2. Il ne reste que les soucis de format. Le premier est très simple : la partie vectorisée du code renvoie une liste, que l’on va aplatir au format data.frame avec rbind.fill, la fonction la plus utile du monde après paste (si si). Enfin, dernier problème : les fichiers JSON utilisent des listes, mais vos jeux de données sont des tableaux (i.e. des matrices avec des attributs) qui utilisent des cellules. Une liste vide est NULL, alors qu’une cellule vide est NA : welcome to the R Inferno ! Heureusement, une fois le problème détecté, il se règle en une ligne, à appliquer à chaque colonne susceptible de contenir des listes/cellules nulles/vides afin de les “purger” — sinon, pas d’écriture possible au format CSV.
  3. Prévoir, dans quelques heures, environ 1700 fichiers de résultats (car tous les eurodéputés n’interviennent pas, loin de là), pour environ 90 MB d’espace disque. Cet exemple est très “léger” et relativement rapide, mais d’expérience, vous avez vraiment intérêt à toujours penser à la taille des résultats sur disque avant de faire quoi que ce soit — à moins d’avoir la trésorerie pour détruire un disque dur de temps à autre7.

Illustration de l’avertissement ci-dessus, tiré d’un autre projet dont les résultats des modélisations font plusieurs gigaoctets de plus que les données brutes, ce qui est logique quand on utilise des simulations ou, comme ici, un bootstrap :

Screen Shot 2014-05-16 at 1.39.12 PM

On termine en écrivant poliment le nombre d’eurodéputés restants à l’écran, et avec 20 lignes de plus, l’index général est mis à profit pour télécharger, dans un dossier records à créer préalablement, les métadonnées de tout ce que les eurodéputés ont raconté en séance plénière depuis qu’il y a des données disponibles, dans des fichiers nommés UID_cre.csvUID est l’identifiant unique de chaque eurodéputé.

Ça fait 100 lignes en tout, avec quelques trucs en plus.

Le résultat à l’écran ressemble à l’illustration ci-dessous, avec des pseudo-barres de progression quand il y a des fichiers en téléchargement (je montre une exécution avec les résultats déjà présents sur le disque, d’où les “0″ jamais suivis des “100, 200, 300…” correspondant au téléchargement de chaque page d’interventions). Le code est exécuté dans TextMate via son plugin R, (qui doit exister pour d’autres éditeurs comme SublimeText).

Screen Shot 2014-05-19 at 9.32.46 PM

Sans avoir regardé en détail, les données intégrales ne semblent concerner que les trois dernières législatures. Le même code peut aussi collecter les opinions prononcées en tant que rapporteur, les motions, les questions écrites etc. avec à peu près autant de facilité, et pour rajouter des variables aux eurodéputés eux-mêmes, il suffit d’extraire plus d’informations de leurs pages personnelles—mais cela dépasserait le temps que je voulais passer sur cet exercice.

Je termine en pensant aux vraies feignasses dans mon genre : le code et les données en une seule archive. Add. : et si ça vous intéresse, j’ai aussi un fichier CSV de 400 MB contenant toutes les interventions orales des eurodéputés au cours des législatures 5–7 (1999–2004, 2004–2009 et 2009-2014).

  1. Les métadonnées, c’est ce que la NSA sait sur vous et sur votre grand-mère. Ça sert aussi à détecter des trucs bizarres dans les copies d’étudiants, ou à savoir qui rédige vraiment les rapports publics que vous trouvez parfois dans la presse en ligne. []
  2. Ce menu détail rend les dernières données de VoteWatch inutiles pour cet exercice, mais voici quand même un guide à leur réutilisation avec R, en trois parties : un, deux, trois. []
  3. La vignette du package explique très bien pourquoi, et en pratique, c’est l’argument flatten = TRUE qui fait la moitié du boulot de virer les listes pour mettre des colonnes, histoire que le résultat ressemble moins à un flux qu’à un tableau de données. L’autre moitié du boulot prend une ligne, lire plus haut. []
  4. La variable idx est lue dans le fichier JSON et correspond à la pagination des interventions publiques, qui sont fournies par tranche de 100 interventions en partant de zéro, parce que Javascript compte à partir de zéro. Elle est égale à 100, 200, 300 ... tant qu’il reste des pages d’interventions publiques dans la pagination du site Internet, -1 quand on se trouve sur la dernière page d’interventions. La variable est directement égale à 0 quand il n’y a aucune intervention publique. []
  5. Vu le grand nombre de pages à couvrir, N eurodéputés * P pages d’environ 100 interventions, le script va nécessairement avoir quelques soucis : il faut le réexécuter quelques fois pour arriver à télécharger tout ce qui est possiblement téléchargeable. Je laisse de côté les fonctions de mise à jour, (il suffit d’effacer les fichiers-cibles en amont). []
  6. Par exemple, le président actuel du Parlement est codé 1911, donc la fonction get_cre(1911, 7) renvoie les interventions (nombreuses, car majoritairement procédurales) de son mandat en cours. []
  7. N’imaginez même pas essayer d’écrire les résultats sur une clé USB : ce n’est pas vraiment un support froid, et je garantis à 200% que tout essai sur une clé USB de plus de 8 GB aura pour seul effet de la rendre complètement et définitivement inutilisable. []

Visualisation interactive des cosignatures à l’Assemblée nationale

Suite et fin d’un feuilleton sur les données parlementaires et la visualisation des réseaux de cosignatures, sous-titré : “Tant qu’il y aura des données.” Le code et les données sont accessibles dans ce répertoire,, et j’espère bientôt présenter ces slides.

L’an dernier, je suspectais l’arrivée d’un nouveau moteur de recherche pour les amendements de l’Assemblée nationale. Ça y est, il est en ligne, et la mauvaise nouvelle est que la nouvelle interface ne se laisse pas faire et demanderait une réécriture complète de mon code d’extraction des cosignatures.

Ce premier échantillon m’a incité à coder l’extraction des cosignatures sous la forme de fonctions génériques, auxquelles j’ai ensuite passé les mêmes listes de cosignatures issues des amendements (depuis 2002) et des propositions de loi (depuis 1986) de l’Assemblée nationale et du Sénat.

Baptiste Coulmont avait défriché le terrain il y a déjà plusieurs années, et la structure de ces données constituait un bon terrain d’entraînement pour apprendre à manipuler des réseaux pondérés et bipartites, de même que le format des données fut un bon terrain d’entraînement pour coder des fonctions d’extraction un peu complexes, utilisant des données collectées en ligne ou sorties de bases SQL.

Voici quelques résultats sous la forme d’une visualisation interactive qui passe des données et des paramètres produits avec R à la librairie de visualisation Javascript produite par deux membres du Médialab de Sciences Po, sigma.js (cliquez sur les images pour la version complète) :

fig_sigma

La visualisation se limite aux propositions de loi de l’Assemblée nationale, qui sont disponibles sur la période la plus longue, couvrant toutes les périodes de cohabitation de la Cinquième République. Elles donnent à voir les cosignatures d’environ 2 000 députés travaillant à ces cosignatures de manière très différenciée selon qu’ils appartiennent à un groupe parlementaire ou à un autre, à droite ou à gauche, dans l’opposition ou dans la majorité1. Les voici géocodés :

sponsor_maps

L’interface de la visualisation permet de mettre l’accent sur les réseaux égocentrés des députés, ce qui ne sert pas à grand chose d’un point de vue analytique2, mais qui permet de mieux identifier les membres des bureaux chargés de centraliser les cosignatures:

Screen Shot 2014-02-20 at 4.04.34 PM

L’interface affiche quelques informations sur les députés tirées de leurs fiches dans la base Sycomore, ainsi que leurs distances moyennes, soit la “rapidité” avec laquelle on peut relier un député à tous les autres en suivant leurs co-signatures :

fig_sigma_detail

En ce qui concerne la construction des graphes, quelques copains assistants parlementaires (merci !) m’ont incité à structurer tous les réseaux collectés de la même manière que James Fowler, en ne retenant que les liens entre les premiers auteurs et leurs cosignataires3. J’ai découpé les données du Sénat sur les mêmes périodes temporelles que l’Assemblée nationale, par législature.

J’ai aussi calculé toute une série de mesures similaires (centralité, modularité, etc.) en tenant compte de la nature pondérée des liens entre co-signataires. Ces mesures sont expliquées en détail dans le papier qui accompagne le code du projet, et qui devrait finir par contenir des modélisations plus avancées des données4.

Avant d’effectuer les mesures, j’ai standardisé les groupes parlementaires en grandes familles sur la période observée pour pouvoir comparer d’une législature à l’autre. Voici par exemple une mesure de centralité sur la législature en cours, qui met en valeur les quelques députés intermédiaires entre les groupes minoritaires et majoritaires, à la fois dans la majorité et dans l’opposition.

fig-weighted14

Enfin, voici la contribution du groupe parlementaire à la polarisation maximale du réseau, qui mesure l’intensité du travail parlementaire intra-groupe par rapport à l’activité inter-groupe — une manière de mesurer l’importance de la segmentation partisane, déjà visuellement remarquable. Suivant cette mesure, le Parlement français est beaucoup plus discipliné que le Congrès américain, même si le Sénat apparaît systématiquement moins contraint par la discipline de parti et semble même l’être de moins en moins.

fig-max_m

Pour produire le même style de visualisation sans trop mettre les mains dans le cambouis Javascript, voici une autre visualisation qui utilise une interface clés-en-main, tous les deux écrits par une équipe de l’Oxford Internet Institute, pour un résultat approchant de mon propre bricolage5 :

fig_oii

  1. Ces variables explicatives apparaissent régulièrement dans les études législatives, notamment celles utilisant les scrutins publics (roll calls). []
  2. Le récent “Que sais-je ?” d’Emmanuel Lazega sur les structures relationnelles l’explique à plusieurs reprises dans les deux premiers chapitres. []
  3. Les bureaux des groupes opèrent fréquemment par cosignature collective sous principe d’opt-in par défaut, ce qui a pour conséquence d’inclure les groupes parlementaires complets ou quasi-complets dans sur les cosignataires. Les biais induits par cette pratique sont minimisés si l’on ne retient que les liens asymmétriques et que l’on pondère les liens par le nombre de cosignataires, ce qui est la stratégie suivie par Fowler, qui peut aussi être normalisée. []
  4. Appel aux dons : si vous avez une heure à perdre au café et que vous savez lire les diagnostics d’un ERGM estimé à partir d’une distribution de Poisson, écrivez-moi maintenant, tout de suite. []
  5. Et pour cause, c’est toujours Sigma.js qui est utilisée en arrière-plan pour dessiner le réseau, avec quelques différences avantageuses comme l’emploi d’un moteur de rendu graphique compatible avec une gamme de navigateurs légèrement plus large. []