Hypothesosphère : le réseau des blogs d’Hypothèses, (presque) cinq ans plus tard

Il y a quelques années (en décembre 2010, pour être précis), Josquin Debaz avait rédigé un billet sur le réseau des blogs de la plateforme Hypothèses, “Hypothesosphère”, où il reconstituait le réseau des blogs indexés par la plateforme à partir des hyperliens entre les articles de ces blogs. Je me suis demandé si ça ne valait pas le coup d’actualiser son analyse, en récoltant des données permettant d’assembler ce réseau à différents points temporels, puis d’identifier les thèmes traités par les communautés qui forment ce réseau.

Le résultat montre qu’environ un tiers des blogs de la plateforme Hypothèses a, au moins une fois, renvoyé ses lecteurs vers un autre blog de la plateforme. Au cours des années 2009 à 2015, la plateforme s’est enrichie de nombreux blogs, ce qui donne, même lorsque l’on se concentre sur un échantillon de ces blogs, comme ci-dessous, un réseau qui contient de nombreuses “sous-communautés” (linguistiques, notamment), et quelques blogs (dont Polit’bistro !) nettement plus centraux que les autres :

hyponet

Cliquer le graphe ci-dessus pour la version PDF plus lisible, où l’on aperçoit clairement le blog des concepteurs de la plateforme (en plein milieu), ainsi que la partie germanophone d’Hypothèses (au sud). Ci-dessous, une longue notice technique, avec une visualisation temporelle du réseau à chaque année d’existence de la plateforme, et une modélisation des thématiques abordées dans les billets de chacune des communautés au fil du temps.

Échantillonnage des données

Depuis le billet de Josquin Debaz, l’index d’Hypothèses s’est beaucoup enrichi, et a aussi certainement changé au niveau du code, car les “vieux” billets (ceux de la page 300, par exemple) n’y sont pas indexés comme les nouveaux. Du coup, pour actualiser l’Hypothesosphère, mieux vaut peut-être passer par le catalogue OpenEdition, qui recense actuellement 1 071 blogs dont on peut ensuite récupérer les articles :

openedition-catalogue

Pour effectuer cette dernière opération, j’ai simplement essayé de lire chaque “page” de chaque blog, de la première à la dernière. Certains blogs, comme celui-ci par exemple, n’utilisent pas de pagination (ce que l’on peut raisonnablement considérer comme un événement survenant de manière aléatoire parmi les blogs de la plateforme), et sont en conséquence exclus de l’échantillon que l’on va constituer1.

Dans un premier temps, il faut donc lister les blogs et essayer de lister tous leurs articles. En une demi-heure d’essais-erreurs avec le code HTML des blogs, qui tournent tous sur WordPress mais pas avec les mêmes gabarits et donc avec des balises HTML différentes, j’en suis arrivé à ce script, qui est certainement plus lent que celui qu’a rédigé Josquin Debaz (en Python), mais qui fonctionne suffisamment bien sur la plateforme Hypothèses actuelle.

Le résultat est un échantillon qui contient 622 blogs, soit 60 % du catalogue total d’OpenEdition, et un total de 77 608 articles, soit 124 articles par blog en moyenne2. Si l’on compare les années de création des blogs du catalogue OpenEdition à celles des blogs contenus dans l’échantillon, les différences de proportion de chaque année à l’intérieur de chaque groupe sont minimes et aléatoires, ce qui est plutôt bon signe pour la qualité de l’échantillon.

Année Catalogue % Échantillon %
2009 76 7 65 10
2010 81 8 61 10
2011 138 13 78 13
2012 282 26 149 24
2013 233 22 118 19
2014 126 12 61 10
2015 133 12 88 14

Construction des réseaux temporels

Dans un second temps, il faut ensuite scanner le contenu des articles des blogs sélectionnés, et en extraire les liens vers des adresses de blogs hébergés sur Hypothèses. Alors que l’opération précédente n’a pas demandé plus de quelques heures, celle-ci risquait de prendre beaucoup plus longtemps, étant donné la quantité de données à parcourir. Du coup, j’ai à nouveau échantillonné dans les données, en ne téléchargeant que 25% des 77 608 articles, soit 19 402 articles3.

Vu que l’on va vouloir observer la manière dont l’Hypothesesosphère a changé au cours du temps, on va ensuite scanner ces articles pour y trouver les inter-citations entre blogs, en notant également la date de parution des articles et le nombre d’inter-citations par article, qui pourra faire office de coefficient de pondération si besoin. Je ne vais pas jusqu’à sous-échantillonner pour limiter le nombre d’articles par blog, mais c’est envisageable4.

Enfin, on va écrire le code de visualisation de l’Hypothesesosphère de chaque année, en mettant des couleurs sur les huit “communautés” de blogs les plus larges, que l’on identifie grâce à un algorithme qui maximise la modularité (le degré de ségrégation) du réseau. Le code ressemble fortement à ce que j’ai déjà décrit dans plusieurs billets précédents, et notamment dans ce petit tutoriel, qui couvre aussi la récupération des données.

Ci-dessous, un exemple de visualisation produit par ce code. Je dis “exemple” car le placement des blogs est en partie aléatoire, comme l’exige n’importe quel algorithme de placement à force dirigée. À noter aussi : la visualisation ne montre pas que le réseau est dirigé, mais il suffit de faire attention à la couleur des liens pour la deviner (lorsque les liens sont plus foncés, c’est qu’ils sont réciproques : les blogs se font mutuellement référence).

hyponet

Pour obtenir un résultat plus exhaustif, il suffit d’augmenter le seuil précité de 25%, ce qui permettra de scanner un plus grand nombre d’articles, et donc potentiellement de rendre l’Hypothesesosphère de chaque année un peu plus dense. Le seuil que j’ai choisi devrait toutefois suffire pour se faire une première idée de ce à quoi ressemble le réseau complet des inter-citations entre les blogs de la plateforme.

Modélisation des communautés

Les réseaux présentés ci-dessus contiennent des blogs, liés entre eux par des articles. Chacun de ces articles contient des mots-clés, ou a minima une catégorie qui correspond, elle-même, à un mot-clé. La plupart des mots-clés sont en français, sauf dans les sous-communautés linguistiques d’Hypothèses, qui utilisent des mots-clés, en allemand, en anglais, en espagnol.

De plus, on a segmenté chaque réseau de manière algorithmique, en communautés optimales. Par conséquent, il est facile de créer des groupes de mots-clés correspondant à une communauté de blogs connectés par leurs inter-citations, ce qui est ici une manière de passer de la forme “réseau” à la forme textuelle en intégrant l’information structurelle du réseau dans la constitution du corpus textuel.

On va donc représenter les données de nos réseaux temporels sous la forme d’un corpus, où chaque document correspond aux mots-clés d’une communauté. Le corpus produit par cette opération contient autant de documents que n’apparaissent de communautés au fil des sept années d’existence de la plateforme, soit un corpus de 127 documents : 3 pour 2009, 7 pour 2010, jusqu’à 29 documents pour 2015.

On peut nettoyer des documents de manière approximative, en nettoyant les termes comme s’ils étaient tous français—ce qui n’est pas très grave : la langue va, quoique l’on fasse, fortement discriminer les communautés de blogs non francophones. Et enfin, on envoie ces documents à un topic model structurel, qui, un peu comme dans cet exemple, prend en compte l’année et la communauté de chaque document5.

Le résultat de cette opération sera un certain nombre de “thèmes” traités par les sous-communautés d’Hypothèses, identifiés à partir de quelque chose qui se rapproche d’un modèle multi-niveaux quant au type d’information qu’on fournit à l’estimateur. Le nombre de thèmes identifiés est arbitraire : j’ai choisi d’en identifier 20, un chiffre proche du nombre moyen de communautés identifiées dans chacun des réseaux (18)6.

Résultats : les thèmes de l’Hypothesesosphère

Dans les résultats ci-dessous, chaque ligne correspond à un regroupement thématique, ordonné du plus au moins fréquent dans le corpus, et représenté par ses trois premiers mots-clés (sans les suffixes, qui ont sauté au nettoyage). On aperçoit les thèmes constitués autour des billets en langue allemande, ou ceux créés autour de zones géographiques (“chin” ou “arab”) :

hypotopics

On aperçoit aussi, dans les thèmes, certains sujets bien précis : “polit” et “scienc”, par exemple, dans le thème n°2, correspond au séminaire “Politique des Sciences” de l’EHESS. Ce dernier constat est un peu embêtant : concrètement, le modèle que l’on a utilisé a “sur-identifié” certains sujets, plutôt que d’identifier des thèmes réellement transverses au corpus.

Le modèle fournit une probabilité d’occurrence de chaque thème dans chaque document, ce qui permet de connecter les thèmes entre eux en corrélant ces probabilités. On obtient ainsi, pour terminer, le réseau de thèmes suivants, où les couleurs correspondent à nouveau aux communautés optimales, et où l’on aperçoit distinctement l’espace thématique germanophone de la plateforme Hypothèses, de même que les thèmes les plus génériques (“actualités”, “lectures”, “colloques”, …) :

hyponet_topics

Pour améliorer cette visualisation, il faudrait déjà envisager d’augmenter l’échantillon des articles au-delà des 25% précités. Ensuite, il faudrait réfléchir à un découpage temporel plus intelligent que celui proposé ici. En effet, segmenter l’Hypothesesosphère par année civile n’est probablement pas très pertinent : on pourrait essayer d’utiliser plutôt les années universitaires, ou même un découpage plus fin se rapprochant des semestres.

Enfin, et surtout, une modélisation plus robuste des thèmes de l’Hypothesesosphère nécessiterait d’affiner trois des paramètres de la modélisation proposée ci-dessus : (1) le nettoyage des mots-clés en fonction de leur langue, (2) le nombre de thèmes à identifier, et (3) l’identification des thèmes, de manière à jouer à la fois sur la prévalence et le contenu des termes du corpus, comme l’explique la documentation du package stm :

stm-metadata

Ces améliorations demanderaient de passer plus de temps sur la collecte des données et sur le calibrage du modèle. Avis aux intéressé(e)s !

Pour aller plus loin

Ce billet explique comment actualiser les données initialement imaginées par Josquin Debaz, et suggère de modéliser ces données à mi-chemin entre l’analyse de réseaux et l’analyse textuelle. Ce croisement méthodologique est assez fréquent : voir, par exemple, ce papier récemment présenté au Congrès de l’AFSP, qui étudie la “web-sphère” créée autour du hashtag #CharlieHebdo sur Twitter.

Quelques liens, donc, pour terminer.

Pour reproduire l’analyse, allez voir ce dossier, qui inclut la liste des blogs à partir de laquelle on a constitué l’échantillon, et l’exemple de corpus sur lequel on a travaillé pour ce billet. Le code n’est pas particulièrement compliqué, et il est facilement amendable (on pourrait, par exemple, étudier le réseau bipartite des blogs d’Hypothèses citant des articles publiés sur revues.org).

Pour analyser du texte, la méthode que j’ai employée (et que j’avais déjà évoquée ici et , notamment) n’est pas la plus simple, ni même la plus conclusive. Pour des alternatives aux topic models, cf. notamment les méthodes de classification hiérarchiques implémentées par Iramuteq, ainsi que ce billet d’Étienne, qui explique clairement ce qu’est un topic model et qui recense d’autres autres méthodes disponibles.

Pour visualiser des réseaux, je passe systématiquement par la fonction ggnet (voir le billet de présentation et d’autres exemples), mais vous voudrez peut-être passer par igraph (qui vient de passer en version 1.0.0 ! et le bouquin a l’air génial), ou par une librairie permettant de visualiser le réseau par périodes. Dans ces deux cas, jetez un coup d’oeil à cet excellent tutoriel de visualisation réseau, par Katherine Ognyanova.

Pour illustrer ce que l’on peut apprendre en lisant le tutoriel ci-dessus, voici un dernier graphe, qui montre la croissance cumulée de l’Hypothesesosphère, de janvier 2009 à juin 2015. Si vous utilisez Google Chrome, vous pouvez également jouer avec la version interactive, réalisée avec le package (encore très expérimental) ndtv, que j’ai découvert grâce au tutoriel.

hypodyn

Contrairement aux autres graphes du billet, ces deux animations utilisent un échantillon beaucoup plus large de presque 85 000 billets publiés sur la plateforme, au fil desquels 340 blogs ont renvoyé leurs lecteurs vers 484 blogs, pour un total de 605 blogs différents actuellement présents dans l’Hypothesesosphère.

  1. Le meilleur moyen de travailler sur l’intégralité de la base serait bien sûr de l’obtenir auprès de la plateforme (à laquelle je contribue très épisodiquement), mais le texte intégral pèse certainement trop lourd pour pouvoir être facilement transféré. De plus, la base intégrale doit contenir les brouillons des articles des blogs, ou ceux publiés de manière privée. Pour ne pas rentrer dans ces problèmes, je n’ai accédé qu’aux données publiques de la plateforme. []
  2. En relançant le script plusieurs fois pour pallier aux erreurs réseau, je suis arrivé jusqu’à 885 blogs et 104 844 articles, soit 118 articles par blog en moyenne. []
  3. Il est fortement recommandé, à ce stade, de laisser une seconde entre chaque téléchargement, pour ne pas stresser la plateforme. []
  4. Cette étape serait nécessaire si l’on souhaitait contrôler (éliminer) les différences de volume de publication d’une année sur l’autre, de manière comparer des probabilités d’occurrence (ou plutôt, des écarts par rapport à une hypothèse d’équiprobabilité, qui peut s’estimer de différentes manières) dans chacun des réseaux temporels. []
  5. Très grossièrement, un topic model structurel est un topic model (soit une technique de regroupement de termes discriminants en thèmes, ou topics) qui peut prendre en compte de l’information supplémentaire sur les documents (des “méta-données”, comme ici l’année de “parution” du document formé par les mots-clés, et la communauté qui a “produit” ce document cette année-là, au fil de ses billets de blogs). Pour des exemples de topic models, cf. cette synthèse, cet article, et ce projet, sur le même thème que ce billet. []
  6. À noter : il y a de plusieurs manières d’identifier le nombre de thèmes à rechercher dans un corpus. Certaines d’entre elles sont expliquées dans les documents cités dans la note précédente. []

Les réseaux de cosignatures législatives de quinze pays européens

Mise à jour, janvier 2017 : la recherche présentée ci-dessous est désormais publiée dans un ouvrage collectif. Le manuscrit est en ligne depuis belle lurette.

Mise à jour, juin 2016 : les données présentées dans ce billet ont évolué, et vont continuer d’évoluer. Pour une présentation plus récente, voir ce billet de juin 2016.

Si la série de billets “Charlie Hebdo” vous a plu, voici quelques réseaux en plus. Add. Et si ce billet vous a plu, la base de données et les visualisations interactives comptent désormais 24 chambres parlementaires de 18 pays européens (les trois nouveaux pays sont l’Irlande, le Portugal et la Slovakie).

Vous vous souvenez peut-être de ce premier travail, dont j’avais parlé courant 2014, sur les réseaux des cosignatures de propositions de loi et d’amendements à l’Assemblée nationale. L’idée venait de Baptiste Coulmont.

La présentation de ce travail en conférence était plutôt bien passée. À cette époque, j’avais déjà rajouté les réseaux de cosignatures du Sénat, très faciles à construire grâce à son portail open data.

À l’occasion d’une summer school avec piscine et sauna (si si), j’ai ensuite élargi l’assiette empirique à six pays européens. Puis j’ai fait le tour de tous les pays membres de l’Union européenne et de l’AELE1.

Ce qui m’amène à la base de données actuelle : j’ai fini par assembler 100 réseaux de cosignatures législatives dans 19 chambres parlementaires de 15 pays européens. Voici un texte qui les présente rapidement2.

Les réseaux sont limités aux propositions de loi, mais cette limite permet de remonter plus loin dans le temps, sur une base plus comparable. Le code est aussi beaucoup moins dégueulasse que le code initial pour la France.

Voici par exemple l’exemple l’Islande actuelle :

net_is2013-2017

Ou encore l’Italie actuelle (chambre basse) :

net_it_ca17

Ou encore la République tchèque actuelle :

net_cz7

Et enfin, voici un tableau récapitulatif des pays et des chambres parlementaires couvertes. Les liens “plots” amènent aux représentations graphiques statiques, les liens “viz” aux visualisations interactives. Amusez-vous bien.

Pays / Chambre
Autriche (chambre basse) code plots viz
Belgique (deux chambres) code plots viz
Bulgarie code plots viz
République tchèque (chambre basse) code plots viz
Danemark code plots viz
Finlande code plots viz
France (deux chambres) code plots viz
Hongrie code plots viz
Islande code plots viz
Italie (deux chambres) code plots viz
Lithuanie code plots viz
Norvège code plots viz
Roumanie (deux chambres) code plots viz
Suède code plots viz
Suisse (chambre basse) code plots viz

Le code contient des fonctions facilement réutilisables pour construire d’autres réseaux, et certains pays peuvent encore être rajoutés, à condition de trouver un moyen de récupérer les données (ce qui est parfois assez compliqué).

Si vous vous demandez à quoi peuvent servir ces réseaux, jetez un coup d’oeil au texte précité, ou au papier de Justin H. Kirkland sur la structure collaborative des chambres parlementaires, ou à ce papier sur la segmentation partisane.

Si vous souhaitez participer à l’amélioration, l’élargissement ou l’analyse de la base, je suis preneur : il y a beaucoup, beaucoup de données dans ces graphes (environ 195 000 propositions de loi et 13 000 parlementaires).

Dernier truc : j’ai publié un billet similaire à celui-ci sur la plateforme OpeningParliament.org, qui rassemble des organisations mobilisées autour de la thématique de l’open data dans le domaine législatif.

  1. À l’exception des micro-États, comme Andorre. []
  2. Le texte contient aussi un modèle très simple de la segmentation partisane des réseaux. []

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].

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. []

Réseaux et hyper-réseaux

Ce joli tutoriel sur les premières étapes d’une construction de réseau bipartite avec R remarque que ce sont ces toutes premières étapes, où il faut penser en « listes » et en « matrices », qui sont les plus difficiles.

J’aimerais fournir un exemple de cette difficulté, qui me semble flagrante en sciences sociales où l’on se dispense généralement de réfléchir à la géométrie des données autrement que par la pratique1.

Hier, une étudiante me disait que l’exercice le plus compliqué du cours du semestre dernier était celui où il fallait trouver la manière la plus efficace de coder numériquement – dans une feuille de tableur, par exemple – le graphique suivant :

Heer et al.

Le graphique est un tableau qui représente les rencontres entre les personnages des Misérables : chaque fois qu’un personnage en a rencontré un autre, la case du graphique est colorée. L’auteur des données (qui fait par ailleurs partie du Panthéon de la science informatique pour ses recherches en algorithmique) n’a oublié que quelques relations.

Oubliez les couleurs différentes, car ce qui compte, comme l’indique Étienne dans son tutoriel, se trouve sur les bords du tableau. La caractéristique essentielle ici est que les colonnes et les lignes contiennent les mêmes noms : le réseau que contient ce tableau, qui va de personnage à personnage, est dit “unipartite” car il contient un seul type d’entité2.

Une fois converti en réseau, ce graphique donne l’équivalent de ce que vous pouvez obtenir en dessinant la “rosace” de vos amis Facebook, en les pointant sur un cercle et en les reliant par un arc à chaque fois qu’ils se connaissent aussi entre eux : un réseau d’interconnaissance où un seul type d’acteur apparaît. En voici un autre exemple :

Via The Monkey Cage.

Dans ce réseau unipartite, les liens vont de banque à banque, et dans les précédents, les liens allaient d’individu à individu. Mais ces représentations gomment les intermédiaires de ces relations : par quels ressources financières les banques établissent-elles ces liens ? dans quels bâtiments les individus se rencontrent-ils ?

Ces intermédiaires sont parfois pertinents pour l’analyse, et presque toujours pertinents pour l’exploration, ce qui demande d’introduire une entité supplémentaire dans les données. Dans un réseau bipartite ou “à deux modes”, les relations vont ainsi d’un type d’entité à un autre, établissant la jonction entre deux surfaces réticulaires.

Comme le signale Étienne, l’exemple classique de ce type de réseau est celui des réseaux d’affiliation entre des individus et des groupes, qui contiennent par exemple des artistes de hard rock et les groupes auxquels ils ont participé. Les couleurs distinguent les deux modes du réseau artiste-groupe :

Testament.BlackSabbath.small_

Le mode primaire d’un réseau social à deux modes est généralement un agent et le mode secondaire une structure, qui peut être de n’importe quelle nature : par exemple, en ce qui concerne les featurings dans le rap français, les artistes peuvent être liés par des albums solo, des compilations ou des groupes. L’application aux communautés en ligne est également aisée, comme dans l’exemple ci-dessous :

bipartite

On peut aller plus loin et introduire n types d’entités dans ce qu’on appellera alors un réseau k-partite, ou “hyper-réseau”, avec un mode primaire et tout plein de modes secondaires imbriqués les uns dans les autres. Pour illustrer cette catégorie, les réseaux sociaux qui utilisent des “tags” pour désigner leurs “ressources” (vidéos, liens, billets…) fournissent un bon exemple de réseau tripartite, représenté ici tout à droite :

Screen Shot 2014-03-21 at 11.22.10 AM

Les questions qui se posent dans cette configuration des données évoquent celle des structures multi-niveaux, où chaque niveau va obéir à ses propres règles de variabilité, croisée avec celles des réseaux, où chaque observation est structurellement dépendante d’une partie des autres, ce qui a pour effet de rendre inopérants les modèles homoscédastiques auxquels on est généralement habitué en sciences sociales3.

Ce croisement se modélise assez bien, même si les temps de calcul sont plutôt longs, car les matrices étudiées sont larges et que la simulation de données aléatoires dans des dimensions identiques aux données réelles y intervient à plusieurs reprises, généralement à plusieurs milliers d’occurrences. Ces problèmes se posent et se résolvent dans des termes analogues en dehors des sciences sociales proprement dites.

La manipulation de réseaux requiert ces différentes représentations spatiales, qui se traduisent fondamentalement par des listes et des matrices, et qui se prolongent ensuite dans des objets de type “réseau” : objets de classe igraph ou network dans R, fichiers GEXF manipulables avec Gephi, données aux format Pajek ou UCINET…

D’où l’utilité de ce qu’indique Étienne, et aussi de tout ce que Baptiste a pu raconter au fil de ses billets, sur les toutes premières étapes de construction de ces réseaux, car la chaîne des opérations qui suit est plus longue et plus complexe que pour l’analyse de données “plates”, comme les tableaux croisés, plus familières en sciences sociales, mais parfois moins efficaces pour se représenter une réalité intrinsèquement relationnelle à un degré élevé de granularité empirique4.

Il n’y a pas de révolution méthodologique associée à ces techniques de mesure et de visualisation, notamment parce que le reste des méthodes fonctionne plutôt bien au regard des objectifs interprétatifs que l’on se donne, mais les réseaux permettent d’alimenter les modèles avec des données plus proches de certaines représentations relationnelles de la réalité, ce dont on a assez régulièrement besoin en sociologie.

  1. La difficulté sous-jacente résidant dans la manipulation des arrays, celle-ci concerne aussi tout langage informatique qui peut manipuler des objets de taille supérieure à 1, donc pas de souci à se faire, on est bien sur un problème répandu et partagé. []
  2. Ce réseau est aussi très faiblement dense : il contient peu de relations par rapport à l’ensemble des relations possibles, représenté par l’intégralité des cases du tableau. Le codage le plus efficace pour ce graphique est une matrice creuse. Quelques étudiants sont intuitivement arrivés à ce résultat lorsque j’ai corrigé l’exercice en classe, mais la vaste majorité se demandait ce qu’on avait fumé. []
  3. Le format des enseignements de statistiques introductives encourage clairement à privilégier ces approches, probablement avec raison dans la mesure où tous les enseignements sur l’inférence linéaire sont utiles pour analyser des réseaux. []
  4. Merci également à Pedro Jordano, qui m’a initié à ces notions lorsque j’ai commencé à étudier la visualisation de réseaux, à la fois pour apprendre un peu de programmation fonctionnelle et pour enfin comprendre un manuel que j’avais photocopié en intégralité il y a presque dix ans, sans jamais le lire ensuite. []

Activisme en ligne et structures relationnelles

Quelques images qui illustraient un très bref passage en revue du thème indiqué en titre, pour la journée d’étude du Master GIDE à Lille :

Les trois premières slides sont tirées de recherches antérieures sur les réseaux d’activistes anti-DADVSI et anti-HADOPI (voir ce papier récent), et les deux qui suivent sont des exemples d’utilisation méthodique de données Twitter. Les sources sont reprises dans les commentaires des slides.

La deuxième partie de l’exposé portait sur les réseaux pondérés, unimodaux et bimodaux, sur la simulation de liens aléatoires dans des réseaux sociaux, et sur les réseaux dynamiques, qui évoluent au fil du temps, et qui se modélisent de manière encore plus avancée. La dernière slide n’avait presque rien à voir.

L’idée de la présentation était de dire :

  1. Quand on étudie des réseaux d’activistes, on peut avoir les mêmes préoccupations que dans l’étude d’un réseau social : classer les éléments influents (par degré de centralité ou par distances minimales), ou dessiner des réseaux égocentrés. Néanmoins, quand les réseaux se multiplient, la topologie de chaque réseau devient essentielle pour comprendre quel type d’influence s’exerce dans quel environnement : étudier des réseaux égocentrés, comme ci-dessous, ne suffit plus.

    Screen Shot 2014-03-13 at 5.10.05 PM

  2. De plus, lorsque l’on étudie une structure très dense (ou l’inverse), la structure des liens change, et il faut pouvoir prendre en compte le nombre d’échanges entre les noeuds du réseau, voire les supports intermédiaires, comme d’un cas des réseaux bimodaux de type « user-hashtag », pour pouvoir modéliser la structure du réseau et l’importance de certaines caractéristiques comme les effets d’interconnaissance :

    Screen Shot 2014-03-13 at 5.10.31 PM

  3. Enfin, il faut se donner les moyens de se demander si le réseau observé aurait pu exister par accident, en simulant quelques-uns de ses paramètres et en découpant ce travail dans le temps pour saisir les évolutions temporelles de la structure. Je n’ai pas développé ce point parce c’était hors-sujet et que je n’ai pas eu le temps de l’apprendre au cours des dernières vacances (de Noël…), mais j’y reviendrai ici quand j’aurai des données et des modèles finalisés à présenter.

Il y a eu une question dans la salle sur le cas d’un “buzz” qui est apparemment passé de Twitter aux rédactions nationales en un weekend, mais je crois avoir répondu que la structure du réseau (médiatique) était moins importante pour expliquer le phénomène que le mécanisme d’imitation rationnelle qui contraint les journalistes quotidiens à créer des “buzz” de toutes pièces, pour le meilleur comme pour le pire.

Derniers graphiques avant 2014

En faisant tourner à nouveau les scripts de réseaux législatifs dont j’ai déjà parlé plusieurs fois ici, j’ai pu vérifier les résultats précédents sur des données un peu plus propres (merci Regards Citoyens) et étendues à tous les amendements de l’année qui se termine :

Screen Shot 2013-12-30 at 7.55.26 AM

Mais j’ai aussi pu vérifier (cf. la fin de cette note) que l’Assemblée nationale doit s’apprêter à réorganiser son site Internet : entre juillet et décembre 2013, l’index des amendements déposés sous la 13e législature a diminué de 450 à 250 dossiers, et j’ai vérifié, plusieurs d’entre eux sont tout à fait valides (ce n’est pas une correction attribuable à des problèmes de datation, par exemple).

En attendant que ce mystère s’éclaircisse, voici la tête des données actualisées. Les barres grises comptent les amendements individuels, les barres rouges les amendements co-signés à moins de dix, et les barres bleues les amendements co-signés par plus de dix députés, avec des pics de co-signatures vers 200 sur les lois de finance et autres joyeusetés. Le pic gris monstrueux correspond au mariage pour tous.

amendments_sponsors

Je vous épargne un graphique de réseau en plus. Non, je déconne, voici un dernier réseau législatif de l’année, basé sur presque 40 000 amendements déjà co-signés sur la législature en cours. Il me reste à calculer les mesures de centralité et de modularité en tenant compte de la pondération du réseau — c’est en cours.

network.example

Meilleurs voeux !

Des réseaux et des mots

Histoire d’en terminer avec les réseaux de députés, voici quelques slides publicitaires pour la fonction ggnet du package GGally, qui rassemble plusieurs fonctions graphiques exploitant la syntaxe de ggplot2 :

Côté analyse, le réseau « Twitter » des députés est moins parlant que celui de leur travail législatif, même s’il lui ressemble structurellement, mais je ne reviens pas là-dessus, n’ayant pas beaucoup plus de données qu’il y a quelques mois.

Je présenterai les slides sur ggnet mercredi à R Addicts Paris, aux côtés d’autres présentations beaucoup plus avancées dans la manipulation de graphiques. Côté réseaux, il y a plein de pistes pour produire des réseaux manipulables, comme sigma.js ou d3Network. Voici un exemple de réseau textuel visualisé avec cette dernière fonction, qui utilise d3.js :

d3Network

Cliquez sur l’image pour la version dynamique. Les données sont tirées d’un petit exemple de modélisation textuelle dans un corpus faiblement structuré, conçu pour Baptiste Coulmont.

Dans cet exemple, les liens entre les termes correspondent à leur probabilité d’association dans un ensemble de termes lemmatisés, où les termes sont groupés par « thèmes possibles« . La modélisation utilise des distributions de Dirichlet et s’estime, grosso modo, de manière “fixe”, “aléatoire” ou “bayésienne” — ce qui prend des plombes dès que le corpus contient plus de quelques centaines de documents…

Dernier truc en cours, un autre exemple de temps de calcul très lent, et qui demande en plus un très long processus préalable de récupération des données. Le graphique suivant contient un peu plus d’un million d’observations, agrégées par semaine de publication et séparées visuellement par institution d’origine :

fig4_week

Le projet auquel se rattache les données est trop peu construit pour en dire vraiment plus, sinon que R et RStudio gèrent très bien les manipulations graphiques sur un million de points, à condition d’être disposé à aller se faire un café (ou même en racheter à côté) pendant que les objets ggplot2 (environ 250 MB par objet) percolent. Peut-être bigvis peut-il encore réduire ce temps de calcul, mais dans tous les cas, R fonctionne à un million de points : testé, approuvé.

Bonnes fêtes :)

Un réseau de 68 203 co-signatures sur 11 569 amendements

J’ai récemment évoqué les co-signatures d’amendements, en me demandant tout du long si le réseau des co-signataires reflétait la même structuration partisane que le réseau des députés sur Twitter. Voici le résultat final sur les 11 500 amendements co-signés depuis le début de la 14e législature en cours :

network.fruchtermanreingold

J’ai rapidement annoté le graphique que m’a sorti ggnet après un calcul de douze minutes pour constituer le réseau1. Pour générer ou actualiser les données, il suffit de récupérer les dossiers parlementaires puis d’en extraire les co-signataires. Le résultat est une gigantesque liste de listes à décomposer en 68 203 paires uniques de co-signataires :

neta.prep

Pour tester mes versions intermédiaires, j’ai utilisé des échantillons réduits. Sur ces échantillons, le groupe GDR est complètement isolé, car il rédige moins d’amendements en valeur absolue et n’en co-signe pas souvent avec des membres d’autres groupes parlementaires. Voici le réseau avec 500 co-signatures sélectionnées au hasard :

neta.500

Puis, lorsque l’on augmente la “résolution” en prenant un échantillon dix fois plus large de 5 000 amendements, les connexions commencent à apparaître, plaçant le groupe GDR dans l’opposition, en dehors du groupe de “soutien” radical-écologiste placé à côté de la majorité socialiste :

neta.5000

Le réseau place également les élus frontistes dans cette opposition, mais comme il manque quelques données, les points gris ne sont pas tous des élus NI. Tout est perfectible, mais je n’ai pas le temps de corriger ce problème, créé par la présence d’homonymes. J’ai rédigé cette version dans le train et vais m’en tenir à ça.

La force du marqueur partisan est aussi évident que dans le cas des députés sur Twitter : l’immense majorité des liens se tisse à l’intérieur des groupes parlementaires. Cet effet ne révèle toutefois rien d’inconnu, et surtout rien de complet : le travail parlementaire trans-groupe, déjà identifiable dans ces visualisations, est simplement plus discret que ces signaux publics que sont les liens par Twitter ou par co-signature d’amendements2.

Pour terminer, une visualisation de la centralité des points montre les inégalités d’investissement dans le travail de co-signature d’amendements (tout en sachant que ce travail exclut de facto celui, non négligeable en quantité et certainement en temps, sur les amendements déposés au nom d’un seul député) :

network.centrality

Le code et les données sont en ligne, avec les notes de construction et les instructions pour actualiser les données. Il doit être possible, moyennant des retouches mineures au code du scraper, de récupérer les mêmes données pour les législatures précédentes.

Mise à jour : le code permet désormais de travailler sur les deux législatures précédentes et de visualiser les données sous forme de réseaux bipartites, un type de réseau à “deux modes” où l’on représente les acteurs et les événements (ici, les co-signatures d’amendements) sur le même graphe. Ces réseaux sont à l’honneur dans le dernier numéro de Social Networks.

Voici à quoi ressemble un réseau bipartite de la législature en cours, à partir d’un échantillon aléatoire de 5 500 amendements. La stratégie d’obstruction législative dans l’opposition est parfaitement lisible, de même que la division du travail entre les groupes et leurs positions respectives vis-à-vis du nexus majorité/opposition :

network.bipartite.14

Je n’avais pas prévu d’aller vers ce type de visualisation, mais Pedro Jordano m’a convaincu et a fourni le code qui sert à convertir les données entre single-mode et two-mode. En raison de la taille et de la nature du réseau, il faut également penser à le stocker dans une matrice “économe” qui compresse l’espace pris par les tonnes de “zéros” qu’on trouve dans les réseaux bipartites : le code pour cette sparse matrix est venu d’un billet de Solomon Messing sur le sujet.

  1. Ce n’est pas du “big data”, mais il faut quand même aplanir une matrice de plusieurs millions de lignes pour créer le réseau. []
  2. Il suffit de penser, par exemple, aux amendements déposés en commission, exclus des données uniquement nominatives montrées ici. []

Députés stratèges : un travail en cours sur des co-signatures d’amendements

Quand un député choisit de co-signer un amendement, avec combien d’autres députés co-signe-t-il ? On peut supposer que cela dépend avant tout de son groupe parlementaire, avec une stratégie « de masse » dans les groupes de la majorité (SRC) et de l’opposition (UMP), et une stratégie « isolationniste » dans les autres groupes.

C’est plus ou moins ce que l’on peut voir sur les 11,568 co-signatures d’amendements de la législature en cours. Le graphique suivant montre le nombre moyen et l’écart-type de ces co-signatures pour cent députés pris au hasard dans la masse des données, et où l’on voit bien la stratégie des députés écologistes ou frontistes :

demo_mu
(Cliquer sur le graphique pour une version PDF un peu plus lisible.)

Add. Voici la version complète, qui fait 171 cm de long et qui a mis vingt minutes à sortir sur un processeur 1.8GHz/8GB, même en vectorisant l’intégralité du calcul.

Les données proviennent d’un petit exercice de scraping qui permet aussi de dessiner le réseau des co-signatures. Le graphique suivant montre ce réseau sur les 10 000 derniers amendements déposés, et l’on y voit clairement la position centrale, isolée ou carrément décentrée de chaque groupe parlementaire :

demo
(Cliquer sur le graphique pour une version PDF avec quelques explications.)

Le matériau de réplication pour ces graphiques est en cours de constitution, sur une idée de Baptiste Coulmont qui avait produit un travail similaire. Mon obsession pour les réseaux de députés a enfin trouvé un nouveau support empirique ! Plus de nouvelles quand j’arriverai à finaliser les (très, très longues) routines d’extraction des données.