Notes sur R et l’analyse de réseaux

Comme promis la semaine dernière, nouvelle annonce qui consacre mes deux obsessions pour la programmation statistique avec R et l’analyse de réseaux, toujours avec R :

r-notes

Le blog est syndiqué sur R-Bloggers, qui agrège plein de blogs sur R. Vous pouvez aussi vous y abonner par son flux Atom ou par son flux RSS.

Le moteur du blog est une version bidouillée de Dropplets.

Quelques notes déjà rédigées

J’ai commencé ce nouveau blog pour stocker des notes dont je suis le premier utilisateur, notamment sur les sujets suivants :

Je me suis aussi servi du blog pour documenter des résultats bizarres, faire des suggestions sur l’enseignement avec RStudio, et tenter des petites expériences avec jQuery, telles que celle-ci avec l’API Pinboard.

Il s’agit vraiment de notes plus que d’un blog : tout est rédigé dans un jargon pas très amusant, et il n’y a pas de commentaires, ni même de lien évident pour me contacter — d’où cette nouvelle publication en dehors du ‘bistro.

Dernière petite chose, vous pouvez désormais apercevoir les derniers billets du Polit’bistro et de R / Notes sur ma homepage universitaire, encore une fois grâce à jQuery, et plus précisément grâce au plugin FeedEk, qui permet de récupérer des contenus de fils RSS :

blogs-rss-feedek

Pour les fans, il y a aussi un peu de jQuery (avec beaucoup de JavaScript et un peu d’animations CSS3) sur la page où j’héberge ma frimousse.

Bonne(s) lecture(s) !

Une liste de ressources sur l’analyse de réseaux

Mon obsession pour les structures relationnelles a difficilement pu échapper aux lecteurs de ce blog. Bonne nouvelle : cette obsession est désormais sous la forme d’une liste de plus de 200 300 ressources en ligne.

awesome-network-analysis

La liste recense les ouvrages, conférences, cours, jeux de données, revues scientifiques, collectifs de recherche, articles de synthèse, logiciels et tutoriels qui me paraissent, ainsi qu’à quelques autres, très recommandables sur le sujet.

La liste étant collaborative, vous êtes bien sûr invités à y contribuer, en y rajoutant vos ressources recommandées, ou même en proposant d’en retrancher certaines, afin de s’en tenir à une liste de ressources strictly awesome.

La liste fait pleinement usage des fonctionnalités de GitHub : sa feuille de route (des idées sur sa future diffusion) se trouve sur son wiki, et les améliorations déjà prévues sont listées à cette adresse. Voici les améliorations déjà prévues :

awesome-network-analysis-issues

Cette liste est donc aussi peut-être aussi l’occasion de vous mettre à Git, un logiciel de gestion de versions concurrentes, et surtout, à GitHub, qui simplifie énormément son apprentissage.

Annonce préliminaire en supplément : une description un peu plus technique de la liste présentée ci-dessus se trouve à cette adresse, sur un blog (en anglais) dont je reviendrai faire la publicité ici dans une semaine.

Mise à jour : la liste mentionnée ci-dessus a rejoint la liste des Awesome Lists, ainsi que la liste Awesome R et son très joli site Internet, qui contient plein de ressources utiles sur R. À explorer sans modération :

awesome-R-website

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 “unes” de Charlie Hebdo : quelques réseaux de plus

Le 6e Congrès de l’Association Française de Sociologie commence après-demain. Le Réseau Thématique 37 « Sociologie des médias » y organise une réunion autour des événements “Charlie Hebdo”, à laquelle Gaël devait participer, sans finalement pouvoir s’y rendre. Sur son invitation, je le remplacerai pour évoquer cette petite note, qui reprend une partie de ce que vous avez pu lire sur ce blog au sujet des « unes » de Charlie Hebdo et de l’analyse des associations thématiques qu’elles contiennent.

charlie-afs2015

La note ne procède pas tout à fait de la même manière que les billets du blog. J’ai retiré tout ce qui avait trait aux ERGM pour utiliser quelque chose d’un peu moins sophistiqué mais de tout aussi parlant. Dans un premier temps, j’ai affiné les catégories thématiques dans lesquelles j’ai regroupé les mots-clés utilisés par le blog Strips Journal pour coder les “unes” de Charlie Hebdo. L’échantillon reste très réduit : le blog ne couvre que les années 2009 à 2015, soit un peu plus de 300 “unes”.

J’ai ensuite fait figurer ces “unes” dans des réseaux bipartites où apparaissent à la fois les “unes” et leurs catégories thématiques. Voici par exemple le réseau des “unes” et de leurs thèmes pour l’année 2011 (cliquer sur le réseau pour le voir en plus grand) :

themes_network_2011

La topologie du réseau renvoie aux deux grands pôles thématiques traités par Charlie Hebdo dans ses “unes”, avec l’actualité politique nationale d’un côté (catégories en bleu), et tous les autres thèmes de l’autre, dont l’actualité internationale et la religion. Cette représentation permet d’effectuer des calculs de distance pondérée, à partir il est facile de repérer les catégories thématiques “proches” ou “éloignées” dans le réseau tissé par les “unes”. Voici les distances entre les catégories thématiques de l’année 2011 (cliquer…) :

distance_matrix_2011

La matrice de distance traduit la même information que le réseau : les catégories les plus “proches” de la catégorie “Religion” sont les catégories “Violence” et “International”, dans cet ordre. La note systématise cette grille de lecture à toutes les catégories sur toutes les années de 2009 à 2015, où il apparaît clairement que la catégorie “Religion” est régulièrement associée à la catégorie “Violence”, sans entretenir toutefois de lien privilégié avec cette catégorie, qui est également associée à d’autres thématiques que la religion.

Bref, je ne sais toujours pas si Charlie Hebdo est “obsédé” par l’islam, si tant est que cela veuille dire quelque chose1. En revanche, je pense qu’on peut établir, au moyen de ses “unes”, que Charlie Hebdo ne réserve pas ses critiques qu’à la seule institution religieuse—sur la période étudiée, le personnel politique en prend au moins autant, sinon plus, pour son grade—,et qu’en plus, sa critique de la religion en “une” survient au sein d’une “triade thématique”, où elle se retrouve liée, sans grande surprise, à l’actualité internationale.

Si vous êtes à l’UVSQ après-demain, j’aurai quelques minutes pour expliquer tout ça. Et comme je n’ai jamais mis les pieds dans un Congrès AFS, ce sera l’occasion de voir à quoi ça ressemble.

Dernière petite chose. Dans le billet précédent, je terminais en mentionnant le blog elementR, pour apprendre à utiliser R dans un contexte de recherche en sciences sociales. En ce qui concerne les réseaux, il faut cette fois-ci mentionner l’excellent blog du groupe fmr (“flux, matrices, réseaux”), qui publie depuis longtemps de très bonnes ressources pour apprendre l’analyse de réseaux, avec R ou d’autres logiciels (voir, par exemple, ce texte sur les ERGM, que j’aurais dû citer dans plusieurs billets précédents sur les “unes” de Charlie Hebdo).

  1. Comme Gaël, et comme les auteurs de cette tribune, j’aurais plutôt tendance à penser que non, même si la “une” me semble être un bon dispositif de mesure des orientations stratégiques que peut prendre la direction d’un hebdomadaire. Il faudrait néanmoins avoir accès à d’autres données (qualitatives), ainsi qu’à un échantillon de “unes” s’étalant sur une période plus longue, pour pouvoir étudier cette question, un peu sur le modèle de ce qu’a fait Nicolas Hubé sur la presse allemande et française. []

Un modèle spatial de l’espace partisan sur Twitter

Note : ce billet est une version modifiée du billet publié le 17 avril. Les résultats sont à jour de la présentation que nous en avons fait, avec Ewen, à la journée d’étude « Science Po Quanti » qui s’est tenue hier. Si le fond du truc vous intéresse et/ou que vous avez un accès à l’API REST de Twitter dont vous ne vous servez pas, faîtes signe dans les commentaires, ou envoyez un tweet à @phnk ou @3wen (ou les deux).

Rappel des faits

Fin mars, j’ai rapidement expliqué comment utiliser les “followers” des comptes Twitter de la classe politique pour en positionner les différentes personnalités les unes par rapport aux autres. En partant du principe que Marine Le Pen va avoir plusieurs “followers” en commun avec Éric Ciotti, quelques-uns avec Valérie Pécresse, mais beaucoup moins avec François Hollande et encore moins avec Pierre Larrouturou, on peut reconstituer l’équivalent d’un spectre gauche-droite où la seule information de départ est la liste des “followers” de chaque personnalité, et où le résultat final est un positionnement sur une échelle unidimensionnelle allant de gauche à droite1.

Cette méthodologie, dite d’estimation de positions idéales, est bien connue en science politique : il s’agit, fondamentalement, d’identifier la dimension principale d’un espace latent, à partir d’une variable binaire comme un vote positif ou négatif. Cette méthode est généralement appliquée aux parlementaires à partir de leurs votes sur les scrutins publics, mais il y a plusieurs autres applications connues : à partir du moment où l’on dispose de votes publics, on peut par exemple s’en servir sur les décisions des juges de la Cour Suprême, ou sur les votes des pays membres des Nations Unies.

L’originalité de l’approche de Barberá (version gratuite), que j’ai déjà cité abondamment dans le billet précédent, est d’avoir transposé cette méthodologie à Twitter2, et de l’avoir appliquée avec succès aux États-Unis et à cinq pays européens. En regardant son fil Twitter récent, j’ai pu constater que sa méthodologie fonctionne également assez bien sur des personnalités politiques brésiliennes, et plusieurs papiers publiés (version gratuite) ou en cours de publication s’apprêtent à montrer que cela marche bien aussi dans d’autres contextes, y compris au-delà des frontières nationales (à suivre…).

Qu’en est-il des personnalités politiques françaises ?

Bon, notez bien que tout ce qui suit est un résultat préliminaire, car le modèle n’a pas fini de converger, malgré la très bonne machine sur laquelle Ewen est en train de le faire tourner. Vous avez bien noté la nature préliminaire des résultats ? Go :

ideal_points_parties

Le graphique ci-dessus correspond au modèle #1 de Barberá, appliqué à 418 personnalités politiques françaises, qui correspondent aux “n” en bas du graphique. Les barres verticales indiquent les positions minimales et maximales pour chaque parti, et le cercle indique la moyenne. Pour le moment, l’échantillon de “followers informatifs” est légèrement inférieur à 18 000. Pour revoir le tout premier résultat obtenu sur un échantillon encore plus petit, cliquer ici, et pour les résultats finaux sur 721 personnalités politiques, attendez encore quelques semaines. Le code de réplication (en cours d’amélioration) et la liste complète des personnalités politiques sont déjà en ligne3.

Sur le graphique, les petites croix correspondent aux scores gauche-droite des partis selon la moyenne établie par ParlGov, ce qui permet de comparer nos résultats aux mesures conventionnelles du positionnement de ces partis. Comme on peut déjà le voir, ça commence bien : “l’ordre” des partis politiques est presque celui attendu. En d’autres termes, les individus qui suivent les personnalités politiques françaises sur Twitter permettent de reconstituer l’espace partisan gauche-droite de ces personnalités de manière quasi-identique à ce que produisent des enquêtes d’experts comme la Chapel Hill Expert Survey, qui va néanmoins plus loin que cette seule dimension.

Vers quoi se dirige-t-on ?

Ce billet ne fait que résumer à très grands traits la méthode que nous sommes en train d’appliquer avec Ewen pour obtenir des estimations de points idéaux à partir de données issues de Twitter. Le point de départ de cette entreprise était un défi d’ordre strictement méthodologique : peut-on faire pareil, avec nos propres données, sur une matrice (d’adjacence) plus large, et en comprenant, à peu près, ce que l’on fait subir à cette pauvre matrice, par l’intermédiaire d’une modélisation assez compliquée ?

Les résultats finaux sont en cours de calcul, mais les résultats intermédiaires ont encourageants, et le code nous a d’ores et déjà permis de produire toutes sortes de résultats supplémentaires assez originaux. Le graphique présenté ci-dessus n’est que le point de départ de ces résultats : toute une batterie de tests montre des corrélations intéressantes au niveau géographique, par exemple. Voici un exemple de ces corrélations, qui se situent toutes entre 0.4 et 0.5 :

map_vote

Le panel de gauche montre le point idéal moyen des départements, calculé à partir des “followers informatifs” que l’on a réussi à localiser au niveau départemental ou municipal. Le panel de droite donne la carte du vote Sarkozy au second tour de la présidentielle de 2012. La corrélation est à 0.5, ce qui permet simplement de constater que les positions idéales générées par le modèle ne sont pas complètement décorrélées des comportement électoraux au niveau géographique.

Vous l’avez compris en lisant le paragraphe précédent : le modèle que l’on utilise n’estime pas des points idéaux que pour les seules personnalités politiques, mais aussi pour les “followers informatifs” que l’on y inclut (ce que ne produit pas vraiment une estimation “classique” de points idéaux à partir de données comme les votes parlementaires). Je n’ai pas évoqué cette spécificité du modèle jusqu’à présent, mais cela vous donne une petite idée de ce vers quoi se dirige l’analyse.

  1. Concrètement, la seule hypothèse nécessaire est celle d’une homophilie entre les personnalités politiques et leurs “followers”, ce qui s’établit sans difficulté quand on parle de plusieurs milliers de “followers” par personnalité. La raison pour laquelle on tombe sur un axe gauche/droite est qu’il s’agit de la dimension principale la plus forte (le clivage le plus fort). []
  2. Je comprends cette transposition comme un renversement de la proposition habituelle des modèles existants : en termes strictement utilitaristes, au lieu de considérer les votes comme “l’offre” et les personnalités politiques comme “la demande”, on considère les comptes Twitter de personnalités politiques comme constituant “l’offre”, et la liste des “followers” comme “la demande”. []
  3. Comme l’indiquent les différents totaux cités, le modèle repose sur une stratégie de sous-échantillonnage assez difficile à résumer en quelques mots. Pour indication, le nombre de “followers informatifs” sur lequel tourne actuellement le modèle final est légèrement supérieur à 44 000, après application de tous les critères cités dans le papier de Barberá. []

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

Notice technique, illustrée par la communication officielle du Front national

Suite aux séries de billets sur les “unes” de Charlie Hebdo, les revues de la sociologie française et les réseaux législatifs, j’ai reçu quelques emails – merci ! – me demandant de réexpliquer “la base” du truc :

  • comment est-ce que l’on fait pour récupérer les données ?
  • comment est-ce que l’on fait pour en sortir un réseau ?

Je vais prendre un petit exemple facile pour illustrer le principe : comment récupérer la communication officielle du Front national à partir de son site Internet, et comment en extraire un réseau de co-occurrences.

Pour cet exemple, je suppose que vous connaissez un minimum de langage HTML. Si ce n’est pas le cas, vous aurez besoin d’une semaine au maximum pour apprendre tout ce qu’il faut savoir. Le langage HTML servant à “écrire Internet”, c’est aussi le langage le mieux documenté sur Internet : commencez ici, par exemple.

Les outils

Commençons par la base.

Il vous faudra une bonne connexion Internet : idéalement de la fibre optique, mais plus généralement, une connexion qui ne va pas tomber en rade et rajouter des erreurs de téléchargement dans une procédure qui risque déjà d’en générer par elle-même. Votre connexion Ethernet universitaire, qui est probablement filtrée d’une manière ou d’une autre, n’est peut-être pas la candidate idéale ; le wifi de votre université, encore moins.

Ensuite, il vous faut un peu d’espace disque. Utiliser un disque externe pour télécharger des centaines de fichiers est une très mauvaise idée : la moindre erreur d’écriture peut envoyer l’intégralité du disque dans les Limbes. L’idéal est d’utiliser une clé USB pas chère mais de bonne qualité, histoire que le disque dur ne soit jamais menacé. Si votre disque dur est un SSD, le risque de le foutre en l’air est toutefois minime.

Enfin, il vous faut un langage de programmation, et si possible, un langage qui va vous permettre d’enchaîner les opérations (téléchargement, visualisation, modélisation) de manière fluide. J’utilise R, mais Python est un autre bon candidat. R est bien documenté, bien illustré, la communauté répond vite et bien aux questions, et les toutes dernières techniques de modélisation y sont très bien représentées.

Il est vivement conseillé d’utiliser RStudio pour coder en R. Il vous faudra aussi un navigateur Internet avec une interface de développement intégrée, pour visualiser le code source des pages HTML que vous voulez récupérer : Chrome, Firefox, Opera ou Safari feront l’affaire.

Les packages

Quel que soit votre choix de langage, vous allez devoir vous servir d’extensions pour accomplir les différentes opérations dont vous avez besoin. Pour ce petit exemple, on va utiliser les cinq packages R suivants :

  • rvest, pour récupérer les données
  • lubridate, pour en convertir les dates
  • stringr, pour manipuler les données textuelles
  • dplyr, pour manipuler les données
  • ggplot2, pour visualiser les données

Incidemment, tous ces packages ont été développés par la même personne, avec l’aide de plusieurs autres.

On rajoutera quelques packages quand on en arrivera à l’étape “réseaux”.

La source

Toutes les donnés que l’on va récupérer proviennent de la section “Actualités” du site Internet frontnational.com. La structure de l’information qui s’y trouve est régulière : la section contient une suite d’articles qui appartiennent à une ou plusieurs catégories, avec parfois un ou plusieurs mots-clés supplémentaires. Chaque article possède un titre, qui renvoie à une page individuelle, et une date, exprimée en français :

Screen Shot 2015-03-15 at 12.58.52

Jetez à présent un coup d’oeil à la source HTML de la page “Actualités” avec les Developer Tools de votre navigateur (j’utilise ceux de Chrome) : en quelques clics et recherches par mots-clés, vous allez y trouver le code HTML qui structure l’information. Ici, les articles de la page se trouvent dans le diviseur #pk_content, les titres des articles sont codés comme des titres de niveau 3 de classe .pk_entry_title, et chaque titre fait l’objet d’un lien a :

Screen Shot 2015-03-15 at 13.06.58

Vous savez à présent ce que vous allez chercher dans chaque page. Dernière étape : combien de pages va-t-on récupérer ? Le système de pagination du site est ultra-simple à identifier :

Screen Shot 2015-03-15 at 13.19.13

Chaque page est numérotée de 2 à X, l’adresse étant de type /actualites/page/4, par exemple. La page finale est identifiable par essai-erreur : si vous essayez d’accéder à la page /actualites/page/200, vous obtenez une erreur. Cherchez un peu, et vous allez trouver qu’à l’heure actuelle, il y a 179 pages qui vous ramènent jusqu’à l’actualité du Front national en avril 2013—soit presque deux ans de données.

Le code

Pour récupérer les titres, liens, dates, catégories et mots-clés de tous les articles de la section “Actualités” du site Internet du Front national :

  1. On crée une boucle qui va de 179 à 1 ;
  2. On télécharge la page correspondant à cette valeur ; et
  3. On extrait ces informations de la page.

La base du truc ressemble à ça :

for(i in 179:1) {

  # l'adresse de la page sur le site Internet
  p = paste0("http://www.frontnational.com/actualites/page/", i)

  # le nom de fichier de la page téléchargée
  f = paste0("page", i, ".html")

  # télécharger la page si le fichier est absent
  if(!file.exists(f))
    download.file(p, f, mode = "wb", quiet = TRUE)

}

La condition if(!file.exists(f)) permet de relancer le code en cas d’erreur—mais il n’y en aura pas dans cet exemple : le site ne pose pas de souci, et ma connexion Internet n’en a pas posé non plus.

On dispose à présent de toutes les pages HTML de la section “Actualités”, et à chaque itération, l’adresse du fichier de la page est stocké dans la variable f. Pour extraire les informations de cette page :

# lire la page
h = html(f)

# extraire le lien de chaque article
url = html_nodes(h, "#pk_content h3.pk_entry_title a") %>% 
  html_attr("href")

# extraire le titre de chaque article
title = html_nodes(h, "#pk_content h3.pk_entry_title a") %>% 
  html_text()

# extraire les dates, catégories et mots-clés
meta = html_nodes(h, ".pk_entry_meta p") %>% 
  html_text()

On utilise ici les fonctions du package rvest. Rapide explication de texte :

  • Les deux premiers appels de la fonction html_nodes extraient les titres ;
  • html_attr("href") en extrait le lien individuel, html_text() en extrait le titre; et
  • l’opérateur %>% permet d’enchaîner les opérations de manière lisible

Cette syntaxe est une simplification de la syntaxe XPath, qui sert à parcourir les documents XML, dont font partie les documents HTML. Le package XML permet de faire la même chose, mais de manière moins lisible.

On obtient trois différentes variables textuelles à partir de ces opérations :

  • La variable url va contenir des liens de ce type :
    [1] "http://www.frontnational.com/2015/03/lettre-ouverte-de-marine-le-pen-aux-acteurs-des-politiques-du-handicap/"                              
    [2] "http://www.frontnational.com/2015/03/document-de-campagne-departementales-22-et-29-mars-2015/"                                             
    [3] "http://www.frontnational.com/2015/03/lettre-de-marine-le-pen-a-lattention-de-monsieur-olivier-schrameck-president-du-csa/"
  • La variable title va contenir des titres :
    [1] "Lettre ouverte de Marine Le Pen aux acteurs des politiques du handicap"                                
    [2] "Document de campagne départementales 22 et 29 mars 2015"                                               
    [3] "Lettre de Marine Le Pen à l’attention de Monsieur Olivier Schrameck, Président du CSA"
  • La variable meta va contenir le reste :
    [1] "13 mars 2015/Tribunes libres/Mots-clefs: Handicap"                          
    [2] "12 mars 2015/Annonces/Mots-clefs: Départementales 2015"                     
    [3] "12 mars 2015/Tribunes libres/Mots-clefs: CSA, Injures"

La dernière variable contient plusieurs informations, il va donc falloir un peu plus de code pour la séparer dans ses différents éléments :

  • On commence par extraire le texte de la date à partir d’une expression régulière qui en repère l’année (élément \\d{4}, qui cherche quatre chiffres consécutifs), puis on la convertit du format français “jour mois année” vers un format générique :
    date = str_extract(meta, "(.*)\\d{4}/")
    date = parse_date_time(str_sub(date, end = -2), 
                           "%d %B %Y", locale = "FR_fr")
    date = as.Date(date)
  • On extrait ensuite la ou les catégorie(s), qui se situent toujours après le premier caractère / de la variable meta (c’est-à-dire après la date). Pour ce faire, on utilise le caractère / pour diviser la variable en plusieurs petits bouts de texte, et l’on sélectionne le second :
    category = sapply(str_split(meta, "/"), function(x) x[2])
  • Enfin, on répète l’opération pour le bloc de texte correspondant aux mots-clés, en prenant soin de virer le texte dont on n’a pas besoin au passage. Il n’y pas toujours de mots-clés : on se prémunit donc contre cette possibilité en prévoyant la possibilité d’une variable manquante NA.
    tags = sapply(str_split(meta, "/"), function(x) {
      x = x[ grepl("Mots-clefs", x) ]
      x = gsub("Mots-clefs: ", "", x)
      ifelse(length(x), x, NA)
    })

En mettant toutes ces opérations à la chaîne, et en stockant les informations que l’on extrait dans un jeu de données, on arrive à 42 lignes de code qui collectent 3 581 liens et titres d’articles de la source. Tous les articles sont catégorisés, mais 728 d’entre eux n’ont pas de mots-clés.

Visualisation hyper-basique

Cherchons à visualiser un aspect très simple du corpus : qui parle au nom du Front national auprès des médias, et dans quelles proportions ?

Pour cela, on retient les 977 articles qui appartiennent à la catégorie “Médias”, et l’on extrait les noms des intervenants, encore une fois à l’aide d’une expression régulière1. L’expression en question est élaborée en jetant un rapide coup d’oeil aux titres des articles, et en rassemblant leurs intervenants dans une même expression un peu longue :

"Marine (L|l)e Pen|Marion( |-)Maréchal|Nicolas Bay|Gollnisch|F(l)?(orian|\\.) (P|p)hilippot|Louis Aliot|Steeve Briois|Sébastien Chenu|Stéphane Ravier|Thibault de la Tocnaye|Wallerand de Saint( |-)Just|Marie-Christine Arnautu|Bousquet-Cassagne|Gilbert Collard|Julien Sanchez|Julien Rochedy|Jean-Marie Le Pen|Lacoste-Lareymondie|Philippe Murer|Sophie Montel|Laurent Lopez|Gaëtan Dussausaye|David Rachline|Bernard Monot|Aymeric Chauprade|Michel Guiniot|Edouard Cavin|Jean-Claude Otto-Bruc|Dominique Martin"

Cette expression repère tous les intervenants, et ne laisse que 16 articles sans intervenants de côté.

Il ne reste plus qu’à visualiser la quantité d’articles produites par le Front national pour sa catégorie “Médias” entre avril 2013 et aujourd’hui, en coloriant les articles par les noms des intervenants, et après avoir regroupé les intervenants avec moins de 10 articles (seuil arbitraire) dans une catégorie résiduelle. Ce qui nous donne :

fn_medias_bars

Florian Philippot est en brun, et Marine Le Pen est en bleu (clair). Je vous promets que je n’ai pas choisi les couleurs : il s’agit des couleurs par défaut de l’excellent ggplot2.

Un dernier petit coup d’oeil, pour terminer, aux mois qui ont donné le plus d’articles, et aux intervenants de ces articles. Cette fois-ci, on utilise les fonctions du package dplyr pour agréger le corpus (objet m) par mois (variable ym) et par intervenant (variable who2), puis pour compter “leurs” articles, puis pour voir les dix premiers mois classés par nombre d’articles :

filter(m, who2 != "(autres)") %>% 
  group_by(who2, ym) %>% 
  summarise(n = n()) %>% 
  group_by() %>% 
  arrange(-n)

Ce qui nous donne Florian Philippot et Marine Le Pen en tête, et très loin devant le reste du peloton. Leurs mois d’activité médiatique les plus intenses correspondent aux élections municipales de mars 2014 et à la formation du premier gouvernement Valls :

1  florian philippot  2014-5 27
2      marine le pen  2014-3 23
3  florian philippot 2013-10 21
4  florian philippot  2015-2 20
5  florian philippot 2014-11 19
6  florian philippot  2013-6 18
7  florian philippot  2015-1 18
8  florian philippot 2014-12 17
9      marine le pen  2013-9 17
10 florian philippot 2013-12 16

Enfin, si l’on répète l’opération avec la catégorie “Interventions”, on trouve les députés Gilbert Collard et Marion Maréchal-Le Pen en tête de cortège, suivis des eurodéputés frontistes, mais sur des quantités moindres (il n’y a que 336 articles, soit trois fois moins de données) et plus irrégulières :

fn_interventions_bars

Pour reproduire ces résultats, allez voir le code, il y en a pour même pas 100 lignes.

Visualisation en réseau

Revenons sur la totalité du corpus. Ce corpus contient 3 581 articles constituant les “actualités” du Front national, et 80% des articles possèdent des mots-clés. Il y a 699 mots-clés différents dans le corpus. Voici les premiers d’entre eux, qui apparaissent plus de 100 fois dans le corpus, c’est-à-dire dans plus de 3% des articles possédant des mots-clés :

Européennes 2014 118
Immigration      133
Insécurité       102
Islam radical    111
Municipales 2014 261
Paris            150
Valls            122

Aucune surprise. Voyons à présent quelles associations de mots-clés reviennent fréquemment dans ce corpus.

Première étape : créer un jeu de données à deux colonnes, où chaque ligne contient une association de deux mots-clés conjointement présents sur un même article. En langage réseau, ça s’appelle une edge list non dirigée, et en langage R, ça peut se construire comme ça, à partir de la variable b$tags contenant les mots-clés de chaque article :

# associations de mots-clés dans chaque article
e = lapply(b$tags, function(x) {
  
  y = unique(unlist(strsplit(x, ",\\s?")))
  y = expand.grid(i = y, j = y, stringsAsFactors = FALSE)
  y = filter(y, i != j)
  y = apply(y, 1, function(x) paste0(sort(x), collapse = "///"))
  y = unique(y)
  data.frame(i = gsub("(.*)///(.*)", "\\1", y),
             j = gsub("(.*)///(.*)", "\\2", y),
             stringsAsFactors = FALSE)
  
})

# assemblage des associations en une seule liste
e = bind_rows(e)

# pondération de chaque association par sa fréquence
e = group_by(e, i, j) %>% summarise(n = n())

Pour la suite, il va nous falloir utiliser le package network pour convertir cette liste en objet “réseau”, auquel on va rajouter la pondération de chaque association de mots-clés, c’est-à-dire la fréquence de chacune de ces associations dans le corpus, que l’on a calculée à la toute fin du bloc de code précédent :

n = network(e[, 1:2 ], directed = FALSE)
set.edge.attribute(n, "weight", e[, 3])

Bon, à ce stade, on a le réseau complet des co-occurrences de mots-clés dans les articles “Actualités” du site du Front national, d’avril 2013 à aujourd’hui. Ça fait beaucoup, ce dont on peut se rendre compte en visualisant le réseau à l’état brut. On produit cette visualisation avec la fonction ggnet, dont on a déjà parlé :

fn_network_0

L’épaisseur des liens entre deux mots-clés est ici proportionnelle à leur fréquence d’apparition dans le corpus, simplifiée en cinq catégories correspondant à des fréquences d’associations de 1 (co-occurrence unique), 2, 3, 4 et 5 ou plus. Le code de visualisation ressemble à ça :

# diviser les co-occurrences en 5 catégories : 1, 2, 3, 4 et 5+
w = as.numeric(cut(e[, 3], c(0, 1, 2, 3, 4, Inf)))
w = w / max(w)
# visualiser le réseau complet en faisant varier l'épaisseur des liens
ggnet(n, size = 1,
  segment.color = "black",
  segment.alpha = .5,
  segment.size = w)

Ce que l’on voit au centre, ce sont les associations de mots-clés qui reviennent fréquemment ; ce que l’on voit en périphérie, ce sont les associations de mots-clés beaucoup moins fréquentes. Concentrons-nous sur le centre en ne retenant que les associations de mots-clés apparaissant au moins cinq fois dans le corpus :

# sous-réseau des co-occurrences de fréquence 5+
nn = n
delete.edges(nn, which(w < 1))
delete.vertices(nn, isolates(nn))

ggnet(nn, size = 1,
      segment.alpha = .5, segment.color = "black",
      label.nodes = TRUE,
      label.size = 3 * as.numeric(cut(degree(nn), unique(quantile(degree(n))), 
                                      include.lowest = TRUE)))

On a ici rajouté le nécessaire pour faire apparaître les mots-clés en question, et pour leur donner une taille proportionnelle au nombre d’associations dans lesquelles ils apparaissent. Le résultat ne va pas non plus vous étonner :

fn_network_5

Visualisation animée

On introduit à présent un dernier package, animation, qui va nous permettre de montrer le réseau de co-occurrences de mots-clés à chaque étape de l’affinage entre le réseau complet, qui montre toutes les co-occurrences, jusqu’à la dernière, c’est-à-dire la co-occurrence de mots-clés la plus fréquente du corpus.

Le code ressemble à ce que l’on a déjà vu, mais dans une boucle qui élimine progressivement les associations de mots-clés les moins fréquentes :

# animation
saveGIF({
  
  w = sort(unique(e[, 3]))
  for(i in w[ -length(w) ]) {
    
    nn = n
    delete.edges(nn, which(e[, 3] <= i))
    delete.vertices(nn, isolates(nn))
    
    g = ggnet(nn, size = 0,
              segment.alpha = .5, segment.color = "black",
              label.nodes = TRUE,
              label.size = 3 * as.numeric(cut(degree(nn), 
                                              unique(quantile(degree(n))),
                                              include.lowest = TRUE))) +
      ggtitle(paste("Associations apparaissant au moins", i, "fois"))
    
    print(g)
    
  }
}, movie.name = "fn_network.gif", interval = 1)

Ce qui nous donne une suite de réseaux de plus en plus “vides”, où les mots-clés “Taubira” et “Paris” ont une assez longue durée de vie, et où les mots-clés “Paris” et “insécurité” survivent jusqu’en fin de chaîne :

fn_network

Voici le code complet de la partie “réseaux”.

Bilan technique

Dans ce billet, on a utilisé :

  • R et tout plein de packages R
  • Un navigateur Internet
  • De la syntaxe HTML et XPath
  • Des expressions régulières2
  • Un tout petit peu d’analyse de réseaux

Toutes ces technologies sont gratuites et bien documentées.

Le corpus “Actualités du Front national” a servi d’exemple parce qu’il ne présentait que des difficultés minimales, qu’il ne m’a fallu que quatre minutes pour le télécharger, et que je ne comptais en présenter que des aspects très simples. Je n’ai même pas téléchargé les articles complets, par exemple, ni envisagé leur analyse textuelle.

Les exemples que je montre sur ce blog sont souvent plus larges : le corpus des revues et articles de la plateforme Cairn.info, par exemple, que j’ai utilisé pour parler des revues de sociologie, contient plus de 400 revues et à peu près 20 000 articles. Mais la logique de base reste proche de celle détaillée ci-dessus.

Mise à jour, 18 décembre 2015 : le Front national ayant légèrement modifié les réglages de son serveur, il faut désormais faire semblant d’utiliser un navigateur pour accéder à son site Internet de manière programmatique. Le code de ce billet a été mis à jour pour ce faire, ce qui permet au passage d’étendre les données jusqu’à décembre 2015, soit 228 pages d’actualités contenant 1 329 interventions de représentants du Front national dans les médias.

Le Canard enchaîné de cette semaine s’est par ailleurs fait le relais des conflits internes au Front national qui opposent Florian Philippot aux soutiens de Marion Maréchal-Le Pen, une source indiquant à cette occasion que Nicolas Bay était de plus en plus envoyé dans les médias par le parti pour infléchir la représentation de ce dernier par Florian Philippot.

On peut vérifier cette affirmation de plein de manières, mais l’on se contentera ici de la plus simple, qui consiste à calculer, à partir de notre source (le seul site Internet du Front national), le pourcentage d’interventions médias du Front national représenté par Florian Philippot. Les barres en rouge indiquent les mois d’élection (municipales, européennes, départementales et régionales), et l’on a retiré les mois de juillet/août pour ne pas inclure de ratios calculés sur des petits dénominateurs :

fn_medias_philippot_bars_updated

Ce graphique permet de constater qu’avec moins d’une invention média sur cinq, Florian Philippot est effectivement à son plus bas taux de représentation médiatique du Front national en décembre 2015. Une diminution similaire était observable au moment des élections municipales. Jugé sur le même critère, Nicolas Bay reste une figure moins médiatique du parti sur la période observée, sauf justement à quelques occasions, dont le mois de décembre 2015 :

fn_medias_bay_bars

Je profite de cette mise à jour pour signaler que Joël est apparu dans l’émission Envoyé spécial du 17 décembre 2015, pour parler justement de Marion Maréchal-Le Pen.

  1. Attention, celle-ci n’extrait que le premier intervenant : s’il y en a plusieurs, le deuxième passe à la trappe. Il n’y a que cinq articles où le problème se pose. []
  2. Alexandre fait remarquer qu’on devrait les appeler “expressions rationnelles”. S’il vous faut d’autres exemples, en voici quelques-uns. []

Twitter permet-il de reconstituer l’espace partisan français ?

Note #1 : ce billet a été mis à jour pour refléter les données que nous avons produites avec Ewen. Voir cet autre billet pour les premiers résultats du modèle cité en fin de texte (les résultats finaux ne seront pas disponibles avant plusieurs mois, vu la lenteur de l’estimation ; je n’ai réactualisé ces deux billets qu’avec des résultats intermédiaires).

Note #2 : et pour augmenter ce réseau d’une centaine de points supplémentaires, il suffit de rajouter les données de Regards Citoyens, basées sur les listes de comptes Twitter publiées par les deux chambres parlementaires. Le réseau qui en ressort est très, très similaire à celui présenté ci-dessous.

Tout comme le dernier billet en date, une bonne partie des billets de ce blog porte sur les réseaux législatifs, où j’utilise les cosignatures de propositions de loi pour faire émerger un espace politique à deux dimensions. Dans cet espace, les parlementaires s’agrègent (se rapprochent ou s’éloignent) en fonction de différentes affinités, au premier rang desquelles l’affiliation partisane.

Peut-on retrouver cet espace partisan à partir de données complètement différentes ? Pablo Barberá s’est posé la question en partant de Twitter : si l’on regarde qui suit qui sur Twitter, est-ce que les connexions créées par les “followers” permettent de reconstituer l’espace partisan de la même manière que, par exemple, les votes ou les cosignatures ?

De quoi parle-t-on au juste ?

Quand on dispose des votes des parlementaires, on peut établir le degré de similarité de ces votes d’un parlementaire à l’autre. Quand il y a deux partis en compétition, comme aux États-Unis, les parlementaires qui votent le plus souvent avec leur parti se retrouvent à chaque extrémité du spectre (que l’on va qualifier de spectre “idéologique”), et ceux qui votent parfois avec le parti adverse se retrouvent au centre.

Toujours aux États-Unis, ce genre d’analyse peut donner un truc comme ça (via), quand on se donne deux dimensions principales pour représenter l’espace partisan à partir des votes des parlementaires :

On appelle ça des “estimations de positions idéales” (estimated ideal points). Faîtes un tour sur quelques blogs américains, et vous allez trouver plein d’exemples de ces calculs. Si vous avez le temps de lire quelques articles, cherchez les articles les plus cités de Simon Jackman. Et si tout cela vous rappelle vos cours de Master sur Anthony Downs, ça tombe bien, parce que c’est à peu près ça.

… Et le rapport avec Twitter ?

Une bonne partie de la classe politique (aux États-Unis, en France, ailleurs) est sur Twitter. Un compte Twitter peut avoir des “amis”, sélectionnés par le titulaire du compte, mais aussi des “followers”, sur lesquels le titulaire du compte n’a pas de contrôle. L’hypothèse de base : les “followers” sont plus enclins à suivre les comptes Twitter des hommes politiques qu’ils apprécient que l’inverse1.

Prenons désormais tous les “followers” de toute la classe politique française. Certains d’entre eux vont suivre un ou plusieurs comptes Twitter d’hommes politiques de gauche : Hollande, Valls, quelques députés PS, etc. D’autres vont suivre les députés UDI / MODEM, et/ou Nicolas Sarkozy. D’autres, Marine Le Pen et les eurodéputés FN. Et ainsi de suite. Et d’autres vont faire des mélanges.

Vous avez compris le principe : les “followers” peuvent être compris comme une forme de signal politique. Les “followers” de Dominique Voynet, par exemple, sont plutôt susceptibles d’être aussi les “followers” d’autres personnalités politiques EELV, ou de la “gauche plurielle” (PS, PRG, PCF) ; en revanche, ils sont peu susceptibles de faire partie des “followers” de Jean-Marie Le Pen ou d’Éric Ciotti.

Est-ce que ce qu’on peut tirer des positions idéales de ces similarités et contrastes entre “followers” sur Twitter ? Pablo Barberá montre que, pour les États-Unis et pour plusieurs pays européens, la réponse est oui. Voici par exemple, pour les États-Unis, la corrélation entre les positions idéales estimées à partir des votes (scores DW-NOMINATE, axe vertical) et celles estimées à partir des “followers” sur Twitter :

barbera

Plutôt encourageant, non ? Allez lire le reste du papier, c’est vraiment très bien fichu, et même si les résultats pour les pays européens sont un peu plus bordéliques, contexte multi-partisan oblige, ils sont quand même très pertinents.

… Et ça marche pour la France ?

Pablo Barberá n’a pas traité la France, mais on peut supposer que cela va marcher au moins aussi bien que pour les pays européens. C’est une hypothèse que l’on peut facilement mettre à l’épreuve des faits. Pour ça, il nous faut :

  • une liste des comptes Twitter de plein de personnalités politiques françaises (députés, maires, conseillers locaux…) : ça tombe bien, le site Élus 2.0 de la société Idéose en liste 800 ;
  • une manière de récupérer leurs “followers” : ça tombe bien, Pablo Barberá a publié le code pour aller taper dans l’API REST de Twitter via R ;
  • et enfin, un ou plusieurs comptes Twitter personnels, pour pouvoir récupérer toutes les données en quelques jours : et ça tombe bien, j’ai les droits nécessaires sur deux comptes, @phnk et @politbistro.

Bilan : après quelques adaptations du code de Barberá et trois jours de requêtes dans l’API, on obtient la liste des “followers” de 795 1 008 comptes Twitter d’élus, dont “l’audience Twitter” est de 3 115 538 3.16 million de “followers” différents2.

Quels sont les élus dont les comptes Twitter sont les plus suivis ? La tête du peloton n’est pas très surprenante :

> select(d, twitter, followers)
Source: local data frame [1,008 x 2]

          twitter followers
1       fhollande    949862
2  nicolassarkozy    719424
3    mlp_officiel    554177
4     jlmelenchon    424239
5            nk_m    389409
6    anne_hidalgo    338536
7         najatvb    332141
8          bayrou    279149
9      montebourg    275652
10   cecileduflot    274962
..            ...       ...

Il va désormais falloir nettoyer un peu ces listes, pour ne retenir que les “followers” les plus informatifs, au sens bayésien du terme : ceux qui produisent l’information de meilleure qualité sur l’espace latent que l’on cherche à identifie. Dans son papier, Barberá utilise plusieurs critères à cet effet :

barbera-subset1

barbera-subset2

Au stade purement exploratoire, on ne va appliquer que le critère n°5, en ne retenant pour la suite que les “followers” qui suivent au moins quatre comptes Twitter d’élus. Ce seuil légèrement plus élevé que celui de Barberá correspond au nombre moyen de comptes Twitter d’élus suivis par l’ensemble des “followers”. Ce critère nous donne 694 846 environ 725 000 “followers informatifs”3.

… Et en images, ça donne quoi ?

Voyons désormais ce que les données produisent comme espace partisan, en exploitant leur nature relationnelle. Construisons une énorme matrice d’adjacence, de dimension 795 x 694 846 1 008 x 725 390, avec les élus en lignes et leurs “followers informatifs” en colonne, puis convertissons cette matrice en une edge list de cette forme :

> head(e)
              i            j  n
1 _davidlefevre    a_leboeuf  7
2 _davidlefevre   a_suguenot 10
3 _davidlefevre    abachelay 57
4 _davidlefevre adefressenel 55
5 _davidlefevre    adegermay 17
6 _davidlefevre adelinehazan  8

Indication de lecture : 7 des “followers informatifs” du compte Twitter @_davidlefevre (élu local MODEM) suivent également le compte Twitter @a_leboeuf (député UMP). La matrice d’adjacence est asymmétrique, et la liste est donc dirigée : le nombre de “followers informatifs” du compte Twitter @a_leboeuf qui suivent aussi le compte Twitter @_davidlefevre est potentiellement différent.

Normalisons, pour terminer, le nombre de “followers informatifs” partagés par deux comptes Twitter d’élus. Il se trouve que le compte Twitter @_davidlefevre est suivi par 476 “followers informatifs” : or, seulement 7 d’entre eux suivent aussi le compte Twitter @a_leboeuf. Cette fraction nous donne, pour chaque paire (dyade) dirigée de comptes Twitter d’élus, la propensité à partager des “followers informatifs”, qui sera nécessairement comprise entre 0 et 14 :

> head(e)
              i            j  n          w
1 _davidlefevre    a_leboeuf  7 0.01470588
2 _davidlefevre   a_suguenot 10 0.02100840
3 _davidlefevre    abachelay 57 0.11974790
4 _davidlefevre adefressenel 55 0.11554622
5 _davidlefevre    adegermay 17 0.03571429
6 _davidlefevre adelinehazan  8 0.01680672

Indication de lecture : environ 1.4% des “followers informatifs” du compte Twitter @_davidlefevre suivent également le compte Twitter @a_leboeuf. Cette propensité permet de repérer des affinités très fortes : par exemple, parmi les comptes Twitter d’élus du Front National, plus de 90% des “followers informatifs” des comptes Twitter @mcaucouturier, @mireilledornano et @steevebriois suivent aussi @mlp_officiel.

Cette liste peut être représentée sous forme de réseau, en filtrant la liste des liens d’intensité située au-delà d’un seuil arbitraire. Lorsque l’on visualise le réseau des liens d’intensité 0.5, par exemple, il suffit que deux élus partagent plus de 50% de “followers informatifs” pour être connectés, ce qui crée un réseau assez dense où plusieurs formations partisanes sont proches les unes des autres :

network_0.5_paper

La méthode de pondération donne parfois une position centrale à des acteurs politiques périphériques, mais ce n’est pas la préoccupation ici : on cherchait juste à vérifier, en première approche, que les liens formés entre les comptes Twitter par leurs “followers informatifs” renvoient bien à un espace partisan latent qui ressemble à l’espace partisan réel — ce qui a l’air d’être le cas.

Le réseau permet notamment de repérer la position structurellement remarquable du Front National, qui fait figure d’outsider, et celle de Marine Le Pen, qui est presque la seule au FN à partager plus de 50% de ses “followers informatifs” (qui sont un peu plus de 200 000) avec d’autres élus que les élus FN :

> filter(e, w > .5, i == "mlp_officiel")
             i              j      n         w
1 mlp_officiel         bayrou 113166 0.5100187
2 mlp_officiel      fhollande 115244 0.5193838
3 mlp_officiel    jlmelenchon 124640 0.5617299
4 mlp_officiel nicolassarkozy 112203 0.5056786

… Et la suite ?

La suite implique de faire tourner un modèle spatial hyper-lourd qui met des plombes à converger. Comme je n’ai pas encore réussi à faire tourner le truc sur ma machine de bureau, je vais m’en tenir à l’approche exploratoire. Mais si vous avez un processeur hyper-puissant sous la main et quelques connaissances en R, laissez un commentaire, je suis très preneur ! C’est en cours : voir ce billet.

  1. L’homophilie conduisant à l’exposition sélective, vous pouvez rédiger cette hypothèse de plusieurs manières pour finir au même endroit. []
  2. Quelques comptes sont inaccessibles parce que la liste des comptes n’est pas parfaitement à jour. En creusant plus loin avec Ewen, nous avons mis la liste à jour et rajouté environ 200 comptes. []
  3. Ici aussi, le chiffre est à jour de la collecte des données effectuée avec Ewen un peu après des élections départementales de 2015 []
  4. Ce schéma de pondération pénalise les comptes Twitter les plus suivis et, à l’inverse, avantage les comptes avec peu de “followers”, mais il suffit à des fins exploratoires []

Un “stress test” des revues de sociologie connectées par leurs auteurs

Dans le billet précédent et dans celui d’avant, on a mesuré l’entre-soi éditorial de la sociologie, c’est-à-dire la tendance des revues à “capturer” leurs auteurs.

À partir de l’échantillon des revues “Sociologie et société” de la plateforme Cairn, on peut en effet montrer que beaucoup des auteurs de ces revues ne publient que dans un nombre très limité de revues, ce qui est particulièrement vrai de certaines revues très spécialisées, rédigées par des auteurs se comportant comme des “cliques” peu connectées au reste des revues de la discipline.

Mesurons à présent la même chose, mais de toute autre manière : quelles sont les revues les plus connectées aux autres revues de l’espace éditorial de la sociologie ?

La méthode générale

On change ici une partie essentielle du raisonnement : l’objectif devient de recréer le réseau sous-jacent à cet espace éditorial, et d’y connecter les revues entre elles en fonction de la propension de leurs auteurs à publier dans d’autres revues. Au niveau technique, cette opération requiert d’établir un protocole de construction du réseau éditorial, qu’on résumera de la manière suivante :

  1. On commence par extraire tous les auteurs ayant publié dans une revue initiale X donnée. Cela nous donne une liste plus ou moins longue d’auteurs.
  2. On identifie ensuite tous les articles de ces auteurs, qu’ils aient été publiés dans la revue en question ou pas. Cela nous donne une liste d’articles.
  3. On regroupe ces articles par leur revue de publication : cela nous donne un nombre total d’articles par revue, qui est très élevé pour la revue initiale X, et plus faible pour les autres.
  4. On normalise le nombre d’articles par revue en le divisant par le nombre d’articles dans la revue initiale X : cela nous donne une fraction théoriquement bornée entre (0, 1], du moment où la revue initiale est celle qui concentre le plus de publications.
  5. Enfin, on se sert de cette fraction pour établir un lien pondéré entre la revue initiale X et chacune des autres revues identifiées par les étapes précédentes.

Illustration de la méthode :

  1. On extrait tous les auteurs ayant publié (dans les limites de l’échantillon) dans la Revue française de sociologie : il y en a 348.
  2. On identifie les articles de ces auteurs : il y en a 1 651, répartis dans 84 revues, ce qui est beaucoup, et qui va nous donner 84 liens différents au final.
  3. On regroupe ces articles par revue de publication, et l’on observe que ces 348 auteurs ont publié 352 articles dans la Revue française de sociologie, mais aussi 83 articles dans la Revue européenne des sciences sociales, par exemple :
    1                      francaise-de-sociologie  352
    2             europeenne-des-sciences-sociales   83
    3                      societes-contemporaines   68
    4                                   mouvements   67
    5                         l-annee-sociologique   63
  4. On divise ces totaux par 352, puis l’on retire la Revue française de sociologie pour ne pas créer de lien entre la revue et elle-même, ce qui n’aurait pas de sens. On obtient des coefficients de pondération entre 0 et 1 :
    1 europeenne-des-sciences-sociales 0.2357955
    2          societes-contemporaines 0.1931818
    3                       mouvements 0.1903409
    4             l-annee-sociologique 0.1789773
    5            informations-sociales 0.1562500
  5. Enfin, on crée un lien d’intensité 0.23 entre la Revue française de sociologie et la Revue européenne des sciences sociales, et de même pour les 83 autres revues suivantes.

Laissez reposer la pâte quelques heures, et c’est prêt.

Le schéma de pondération

Cette méthode produit un réseau très dense, qui connecte 96 revues entre elles par des liens d’intensité très variable. D’ailleurs, dans quelques rares cas, ces liens sont d’intensité supérieure à 1, lorsque le pool d’auteurs d’une revue a moins publié dans cette revue que dans une autre. C’est ce que l’on peut voir en dessinant la fonction de répartition empirique de ces liens, en les classant par leur intensité :

weights_ecdf

Quels sont ces cas particuliers ? Ils sont peu nombreux et explicables : par exemple, les auteurs de la revue Clio ont plus publié dans la revue Clio. Femmes, genre et société que dans la revue Clio. Ce n’est pas surprenant : il s’agit d’une seule et même revue, qui a juste changé d’identifiant sur Cairn… Quant aux autres cas particuliers, il s’agit de revues publiées par le Ministère de la Culture, ne contenant qu’un seul article par numéro.

> filter(e, w >= 1)
                    i                          j        w      ecdf
1                clio clio-femmes-genre-histoire 1.032182 0.9981329
2    culture-chiffres           culture-methodes 1.225000 0.9988798
3      culture-etudes           culture-methodes 1.258824 0.9992532
4      culture-etudes        culture-prospective 1.035948 0.9985063
5      culture-etudes                    reseaux 1.332244 0.9996266
6    culture-methodes                    reseaux 1.000545 0.9977595
7 culture-prospective                    reseaux 2.669935 1.0000000

On va laisser de côté ces cas particuliers, et se concentrer sur le reste des liens, d’intensité variant entre 0 et 1. Commençons par un exemple : où se trouvent, parmi tous ces liens, ceux qui relient la revue Genèses à d’autres autre revues ? La réponse est que ces liens se trouvent un peu partout dans la distribution : les auteurs de cette revue ont publié dans plusieurs autres revues, parfois peu, parfois beaucoup :

ecdf_geneses

Les liens les plus forts de la revue Genèses la relie aux revues Politix, Sociétés contemporaines et Actes de la recherche en sciences sociales – ce qui ne surprendra pas les politistes (ou “sociologues du politique”), qui publient fréquemment dans ces trois revues et contribuent ainsi à les rapprocher dans le réseau que l’on a construit :

                                           i                       j         w      ecdf
1                                    geneses                 politix 0.4652329 0.9973793
2                                    geneses societes-contemporaines 0.3591092 0.9910146
3 actes-de-la-recherche-en-sciences-sociales                 geneses 0.3445658 0.9887683
4                                    geneses             savoir-agir 0.3008793 0.9839012
5                                    geneses              sociologie 0.2491052 0.9734182
6                                    geneses     le-mouvement-social 0.2359327 0.9689255

Quid de la revue Sociétés, qui a servi de point de départ à ces billets ? Cette revue est également connectée à d’autres, mais par des liens beaucoup plus ténus, soit parce que ses auteurs ont beaucoup publié dans Sociétés, soit parce qu’ils ont peu publié ailleurs, ce qui revient au même dans notre schéma de pondération :

                     i        j          w      ecdf
1       communications societes 0.16422287 0.9359790
2             societes   volume 0.07563025 0.8169225
3 l-annee-sociologique societes 0.06060606 0.7663796
4              diogene societes 0.05665375 0.7472857
5              reseaux societes 0.05206477 0.7263197
6 ethnologie-francaise societes 0.05197472 0.7255709

Lorsque l’on va chercher à visualiser ces liens, on va tenir compte de leur intensité pour ne faire apparaître que les liens les plus forts : pour cela, on se servira de leur distribution cumulée pour créer un “effet de seuil”, qui nous permettra de ne visualiser, par exemple, que les 20% des liens les plus forts. Cela permettra de visualiser un réseau moins dense, plus lisible, et surtout plus significatif.

Les réseaux

Voici le réseau constitué à partir de l’échantillon de revues dont on dispose, à des valeurs différentes du seuil évoqué ci-dessus. On commence à un seuil de 0 (réseau complet), que l’on augmente ensuite par incréments de 0.1 pour retirer les liens les plus faibles, puis par incréments de 0.01 lorsque l’on atteint 0.9, de manière à ne garder que les liens les plus forts entre les revues les plus intensément connectées à d’autres :

full

Au fur et à mesure que le seuil augmente, on ne garde que les liens les plus significatifs entre les revues. L’animation permet de percevoir cet effet de composition, mais ne permet pas de scruter le réseau de manière précise. Du coup, voici une version statique du réseau, où l’on n’a retenu que les 2.5% des liens les plus forts entre les revues (cliquer pour la version PDF) :

example_975

Que trouve-t-on parmi les liens les plus forts entre les revues de sociologie ? Beaucoup de relations qui font sens si l’on connaît un peu cette littérature, comme par exemple :

  • des liens forts entre les revues Clio, Nouvelles questions féministes et Travail, genre et société (tout en haut du graphe ; vous aurez deviné le thème) ;
  • des liens forts entre Genèses, Politix, Actes de la recherche en sciences sociales et Savoir/agir (au centre ; pas de surprise non plus) ; et
  • des liens forts entre des revues généralistes : L’Année sociologique, la Revue française de sociologie, Sociologie et la Revue européenne des sciences sociales.

Jusque-là, tout va bien. Regardons à présent les différentes positions prises par la même revue au fil des graphes. On commence avec la revue Sociologie, que vous voyez ci-dessous sous la forme d’un point rouge. Au fur et à mesure que l’on éclaircit le réseau en n’en retenant que les liens les plus forts, la revue devient de plus en plus centrale, jusqu’à l’avant-dernière étape, où elle disparaît (effet de seuil à 0.99) :

sociologie

Voyons à présent la revue Sociétés. Dès le départ, la revue occupe une position plus périphérique, étant moins connectée aux autres revues que ne l’était la revue Sociologie. Sa relégation à la périphérie de l’espace éditorial devient de plus en plus claire au fur et à mesure qu’on augmente le seuil en-dessous du lequel on ignore les liens entre revues. Sociétés disparaît du réseau lorsque le seuil d’intensité atteint 0.93 :

societes

La méthode de mesure

Bien. Faisons le bilan.

Pour chaque revue, on dispose de réseaux pondérés qui exprime la propension de la revue à être connectée aux autres revues de l’espace éditorial sociologique, mesuré sous une forme limitée à l’échantillon des revues Cairn. Les différents réseaux pondérés de chaque revue sont obtenus en augmentant graduellement le seuil d’intensité des liens qui y figurent.

Ce schéma d’observation permet de mesurer, pour chaque revue, son degré de centralité dans l’espace éditorial sociologique, qui peut être très élevé, auquel cas la revue est “centrale” dans cet espace éditorial, ou très faible, auquel cas cette revue est périphérique dans ce même espace. Ce degré de centralité est mesurable à différents seuils contenus entre 0 et 11.

Du coup, voilà ce qu’on va faire :

  1. On construit les relations de chaque revue à tous les seuils compris entre 0 et 0.99, par incrément de 0.01 (soit 100 réseaux par revue) ;
  2. Dans chaque réseau, on mesure le degré de centralité pondéré de la revue2, que l’on divise par le degré de centralité maximal observé dans le réseau ;
  3. Puis l’on met toutes ces données sur un même graphique, pour comparer les revues entre elles à partir de leur degré de centralité relatif.

Que va-t-il se passer lorsque l’on va appliquer cette méthodologie ?

  • Les revues centrales de l’espace éditorial vont se distinguer par un degré de centralité élevé, qui va rester élevé jusqu’à des niveaux de seuil eux-mêmes élevés, lorsque l’on en considère plus qu’une fraction des liens les plus forts entre les revues.
  • Les revues périphériques de l’espace éditorial vont se distinguer par un degré de centralité plus faible, qui va s’effondrer au fur et à mesure que l’on limite le réseau à ses liens les plus intenses, jusqu’à disparaître à des niveaux de seuil élevés.

C’est donc une forme de “stress test” que l’on va faire subir aux revues de la sociologie : à partir de 100 valeurs différentes, on va tester leur centralité dans l’espace éditorial disciplinaire constitué par les revues de la plateforme Cairn, et voir lesquelles se maintiennent à des niveaux élevés dans cet espace, même lorsque l’on “épure” le réseau pour n’en retenir que les liens les plus forts, c’est-à-dire ceux qui représentent plusieurs articles, rédigés par plusieurs auteurs navigant d’une revue à l’autre.

Ce “stress test” va identifier certaines revues “centrales”, qui publient plusieurs auteurs actifs dans d’autres revues. À l’inverse, il va aussi identifier les revues dont les auteurs se comportent comme des “cliques” : ces revues vont en effet assez rapidement disparaître du réseau connectant les revues entre elles, de par l’absence d’activité éditoriale soutenue de leurs auteurs dans d’autres revues.

Les résultats

Voici les résultats de la méthode de calcul décrite plus haut appliquée aux 96 revues de l’échantillon. Chaque ligne représente le degré de centralité relatif d’une revue, et l’on a fait ressortir quelques revues par des couleurs distinctes :

degree_all

Dans ce graphique, on observe le degré de centralité relatif de deux revues centrales de la sociologie : Actes de la recherche en sciences sociales et la Revue française de sociologie. Ces revues correspondent à des écoles : la première est d’influence bourdieusienne, la deuxième d’influence durkheimienne3. Mais cette filiation n’empêche pas leurs auteurs d’être acceptés pour publication dans d’autres revues, d’où leur fort degré de centralité dans l’espace éditorial.

Il en va de même pour Genèses, Réseaux et Sociologie : ces revues sont également connectées à de nombreuses autres par l’intermédiaire de leurs auteurs. Pourquoi ? Il y a plusieurs explications possibles : Réseaux, par exemple, est une revue centrale pour les études communication, qui est connectée à plusieurs revues moins centrales dans ce sous-domaine des recherches sociologiques, comme la revue Télévision, ce qui lui procure une position avantageuse dans l’espace éditorial4.

De la même manière que ces résultats permettent de repérer les revues dont les auteurs cherchent à se positionner au centre de l’espace éditorial sociologique, ils permettent aussi d’identifier les revues dont les auteurs sont beaucoup plus isolés dans cet espace. Nota bene : dans une structure en réseau, l’isolement se traduit par un positionnement en périphérie ; l’isolement et la marginalité y sont donc structurellement équivalentes. Je vous laisse appliquer cinquante nuances de subtilité à ce glissement conceptuel.

J’ai ainsi fait exprès de faire figurer la revue Recherches en soins infirmiers, qui est très illustrative de cette position structurale : de par sa nature hyper-spécialisée, cette revue attire des auteurs extérieurs au champ universitaire, qui ne cherchent pas à s’imposer dans l’espace éditorial sociologique, et qui publient par conséquent peu dans le reste des revues de la discipline. La position marginale de la revue s’explique donc très bien.

Il nous reste, enfin, la revue Sociétés, dont le sous-titre est : “Revue des sciences humaines et sociales”. Dans le billet précédent et dans celui d’avant, cette revue apparaissait déjà parmi les revues les plus caractéristiques d’un entre-soi éditorial ; l’analyse par réseaux permet de compléter cette observation en renforçant le constat de marginalité de ses auteurs dans l’espace éditorial sociologique.

Conclusion

À partir des résultats accumulés au cours des trois derniers billets, on peut désormais affirmer que l’on a établi la nature marginale de la revue Sociétés dans l’espace éditorial sociologique, entendu encore au fois au sens limité de l’échantillon des revues hébergées sur la plateforme Cairn. Cet échantillon est par définition incomplet, mais il est tout de même suffisamment large pour que l’on ait confiance dans ce résultat.

Quand les auteurs du canular publié par la revue Sociétés affirment que cette revue publie des auteurs qui “restent entre eux” au lieu d’aller confronter la validité de leur démarche scientifique au reste de la profession, on ne peut que leur donner raison, et constater avec eux que la revue Sociétés publie un groupe d’individus qui ne bénéficie que de connexions très faibles au reste de l’espace éditorial sociologique.

Qu’est-ce que cela signifie ? Ce n’est pas un jugement de fond : ni le contenu des articles, ni leurs citations, n’ont été mobilisés dans l’analyse. Toutefois, les liens que tissent les sociologues en publiant dans plusieurs revues renvoient aux alliances, aux coopérations et aux soutiens qui s’expriment entre différents segments de la discipline universitaire : c’est cette caractéristique du travail éditorial qui sous-tend les réseaux que l’on a fait apparaître, et qui permet de discriminer les revues centrales des revues périphériques.

De ce point de vue, et dans la limite de démonstration imposée par l’échantillon, la revue Sociétés est une revue structurellement marginale dans la discipline sociologique, ce qui n’est pas le cas, loin s’en faut, de toutes les revues représentant un courant d’analyse spécifique—à condition de considérer, bien sûr, que les publications de cette revue méritent le titre de courant d’analyse, ce que Manuel Quinon et Arnaud Saint-Martin remettent très justement en cause (et ils ne sont pas les seuls).

Pour aller plus loin

Voici le code complet de l’analyse. Le code permet très facilement d’inclure d’autres espaces disciplinaires représentés sur la plateforme Cairn.info ; en revanche, inclure les revues des plateformes Persée.fr, Érudit.org ou Revues.org demanderait beaucoup, beaucoup plus de travail.

Cette analyse pourrait être développée pour faire un petit article à destination d’une revue comme le Bulletin de méthodologie sociologique ; merci de laisser un commentaire si vous êtes intéressé.

  1. Au seuil 0, on considère tous les liens qui peuvent exister entre les revues par l’intermédiaire des auteurs qui publient dans plusieurs d’entre elles ; au seuil 0.99 approchant 1, on ne considère que les liens les plus forts. []
  2. Suivez ce lien pour comprendre la méthode de calcul. J’ai utilisé un paramètre de pondértion alpha de 1, ce qui signifie que j’ai utilisé la généralisation de Barrat pour pondérer le degré de chaque revue. []
  3. Si vous êtes spécialiste du sujet (je ne le suis pas), donnez-moi de meilleurs qualificatifs dans les commentaires. []
  4. On observera avec amusement que la revue la plus centrale au seuil le plus élevé est justement la revue… Réseaux. Autrement dit, cette revue est la mieux connectée aux autres par le biais des publications de ses auteurs : pas surprenant pour une revue trans-disciplinaire qui se situe à la frontière entre sociologie et “sciences de l’info.-comm.”. []

Religion et violence dans les “unes” de Charlie Hebdo

Mise à jour du lendemain : voir aussi ce texte, tout juste publié dans Le Monde.

Suite et fin (définitive, cette fois-ci) d’une suite de billets publiée en quatre épisodes : mercredi, vendredi et dimanche de la semaine dernière, et mardi de cette semaine :

  1. Les données (le billet introductif, le plus accessible)
  2. Leur exploration (quelques visualisations en plus)
  3. Les premiers modèles (ou “les ERGM en trois mots”)
  4. Le modèle définitif (les finitions pour la route)

Il s’agit d’une synthèse : pas grand chose de nouveau, juste des précisions et une reformulation de l’argument général. Je n’ai pas modifié le code source de l’analyse, qui reste disponible et améliorable, comme je vais le rappeler un peu plus bas.

Désolé d’avoir accidentellement publié un brouillon de ce billet tôt ce matin.

Et oui, je veux bien la médaille en chocolat du titre racoleur. Ooh yeah.

La question initiale

À la suite de l’attentat du 7 janvier, le travail de la rédaction de Charlie Hebdo a fait l’objet de toutes sortes d’accusations, allant du blasphème à l’islamophobie en passant par le mauvais goût. Mais comme l’ont fait remarquer deux sociologues dans les colonnes du Monde, le tirage assez confidentiel du magazine permet d’écarter l’idée que ces accusations soient fondées sur une lecture attentive de Charlie Hebdo : ce sont plutôt ses illustrations de “une”, beaucoup plus accessibles que le magazine lui-même, qui ont généré ces critiques.

Les mêmes sociologues se servent des “unes” de Charlie Hebdo pour se demander si l’hebdomadaire est vraiment si “obsédé” – c’est leur terme – par l’islam que le suggèrent certaines critiques. Sans surprise, ils découvrent que ce n’est pas vraiment le cas, dans la mesure où Charlie Hebdo fait beaucoup plus souvent sa “une” sur l’actualité politique (ou économique, ou sociale) française que sur la religion, et qu’en matière de religion, le catholicisme (via l’institution papale) en prend beaucoup plus pour son grade que les autres religions monothéistes.

La méthode de cette étude est assez simple : on catégorise le contenu des “unes”, puis on fait un tri à plat, puis on en tire des observations sur la fréquence de tel ou tel personnage, thème ou événement. L’analyse des “unes” d’un support de presse n’est d’ailleurs pas une nouveauté en soi : allez voir chez Baptiste Coulmont (qui parle d’une étude des “unes” de Paris Match par Alain Chenu), ou bien lisez le bouquin que Nicolas Hubé a tiré de sa thèse sur les “unes” des journaux allemands et français, ou bien lisez cet article sur la représentation des femmes en “une” d’un magazine sportif.

Cette technique d’analyse “fréquentiste” a toutefois de sérieuses limites, car il y a aussi une dimension relationnelle à exploiter dans ce type de données : dans l’illustration de “une”, qui est connecté à qui, et à quoi ? On peut en effet suggérer que la “une” d’un hebdomadaire satirique est un travail de mise en relation : tel thème, personnage ou événement s’y trouve mis en relation avec au moins un autre, de manière à créer une association mentale qui, renforcée par le titrage de la “une”, suggère une interprétation (plus ou moins) comique, cynique ou ironique1.

La question du traitement de tel ou tel thème par Charlie Hebdo dépasse donc la simple fréquence de ce thème dans ses “unes”, et devient : à travers ce dispostif symboliqe qu’est la “une”, à qui et à quoi tel thème se retrouve-t-il associé ? Si le quotidien La Croix, par exemple, associe fréquemment le catholicisme et l’action humanitaire dans ses “unes”2, qu’en est-il des “unes” de Charlie Hebdo sur la religion ? C’est cette question que l’on va traiter, à partir d’une catégorisation des “unes” qui permet de repérer les thèmes de la religion et de la violence.

Pourquoi cette question de la relation entre religion et violence dans les “unes” de Charlie Hebdo ? Parce que, comme l’a écrit Gaël Villeneuve dans sa réaction à l’étude publiée par Le Monde, mesurer “l’islamophobie” est conceptuellement hors de portée, le terme prêtant à toutes les confusions possibles. En revanche, établir que Charlie Hebdo associe, au sens objectif du terme (c’est-à-dire : met en relation ; pas “amalgame” ou “assimile”), la religion à un thème comme la violence, tient du domaine du possible.

Les données de Strips Journal

Comme je l’ai expliqué dans le tout premier billet de cette série, c’est le blog Strips Journal qui a rendu possible cette exploration des associations thématiques dans les “unes” de Charlie Hebdo, grâce à son codage de 338 “unes” de Charlie Hebdo publiées entre 2006 et 2015. Ce codage inclut la quasi-intégralité des années 2009-2014 et assigne en moyenne 4 mots-clés par “une”, noms propres et événements inclus. C’est à partir de ces mots-clés que l’on peut constituer des réseaux de co-occurrence comme celui-ci, qui représente toutes les 338 “unes” du corpus :

full_network

Le réseau contient des mots-clés recatégorisés en six grands thèmes à partir d’un codage supplémentaire qui peut certainement être amélioré. Si vous souhaitiez vous y coller, il suffit d’améliorer ce script, ou pour celles et ceux qui sont allergiques au code, cette feuille CSV, qui contient les mots-clés des “unes” (colonne tag), leur catégorie thématique (colonne theme), et les numéros de Charlie Hebdo dans lesquels ils apparaissent (colonne nums). Une catégorisation de meilleure qualité3 permettrait d’affiner tous les résultats présentés dans cette série.

Comme le réseau de toutes les “unes” du corpus n’est pas très lisible, il peut être utile, à des fins exploratoires, de le scinder en plusieurs sous-réseaux temporels : c’est ce que j’ai proposé dans un deuxième billet, en découpant le corpus en périodes de trois mois et en mesurant la présence de chaque thème au cours de chaque période. À cette échelle, il devient plus facile d’observer certaines co-occurrences de mots-clés, et notamment celles qui concernent la religion (en vert), le terrorisme (en rouge) et la violence (en rouge) :

network_quarters

 

Pour compléter ces représentations graphiques, et afin de faire la jonction avec l’étude résumée dans Le Monde, on peut souhaiter les accompagner de quelques statistiques sur les mots-clés qu’ils contiennent. Prenons, par exemple, les 10 mots-clés les plus fréquemment utilisés pour catégoriser le contenu des “unes” de Charlie Hebdo incluses dans le corpus. Ces mots-clés ne surprendront certainement pas les lecteurs de Charlie Hebdo, et contiennent au moins deux termes (“religion” et “intégrisme”) qui retiendront notre attention plus tard :

1              sarkozy   80
2            élections   42
3    françois hollande   40
4             religion   35
5        marine le pen   25
6                   fn   23
7       présidentielle   23
8           intégrisme   22
9  présidentielle 2012   22
10      extrême droite   21

Voyons, à présent, les dix associations de mots-clés les plus fréquentes. Cette liste révèle que les mots-clés sont partiellement redondants entre eux : les mots-clés concernant les élections, par exemple, reviennent très souvent ensemble pour catégoriser les mêmes “unes”. En conséquence, le réseau des co-occurrences des mots-clés contient certaines associations très fortes entre des thèmes et des sous-thèmes, entre des institutions et leurs représentants, bref, entre des “classes” et des “sous-classes” de phénomènes :

1            élections      présidentielle 23
2            élections présidentielle 2012 22
3       présidentielle présidentielle 2012 22
4            élections             sarkozy 17
5       extrême droite                  fn 17
6           intégrisme            religion 17
7                   fn       marine le pen 15
8  présidentielle 2012             sarkozy 15
9       présidentielle             sarkozy 15
10      extrême droite       marine le pen 14

Simplifions, enfin, ces associations, en remplaçant les mots-clés par l’une des sept catégories générales évoquées ci-dessus. Cette simplification permet de catégoriser les “unes” à partir d’un ou plusieurs thèmes (entre 1 et 5, et 2 en moyenne). En regardant les fréquences brutes et relatives de ces thèmes, on observe ainsi le poids relatif de chaque thème dans le corpus. Attention, les années 2006, 2007 et 2015 ne contiennent que quelques “unes” chacune et ne sont incluses ci-dessous que pour référence.

charlie_themes_freq

charlie_themes_prop

Cette simplification produit 15 associations thématiques possibles, dont la fréquence varie en fonction de différents facteurs, comme le nombre de mots-clés de chaque catégorie, mais aussi la pertinence de chaque association dans le corpus. Sans surprise, les associations les plus fréquentes sont ainsi des associations monothématiques, correspondant à la situation où la même “une” a reçu deux mots-clés de la même catégorie ; mais on trouve aussi souvent des associations entre des thèmes différents :

1              Politique-Varia  578
2                  Varia-Varia  544
3          Politique-Politique  465
4            Religion-Religion  131
5          International-Varia  122
6               Religion-Varia  103
7               Varia-Violence   85
8      International-Politique   69
9           Politique-Violence   51
10 International-International   47
11           Religion-Violence   42
12          Politique-Religion   40
13      International-Religion   32
14      International-Violence   23
15           Violence-Violence   13

Quoi et pourquoi modéliser ?

À ce stade, on va souhaiter modéliser les associations thématiques formées par les mots-clés des “unes” de Charlie Hebdo. Ce que l’on va pouvoir modéliser, comme expliqué dans un billet plus détaillé, c’est la probabilité conditionnelle de chaque association, en fonction de plusieurs facteurs comme le nombre de mots-clés par catégorie. Cette modélisation va nous servir à estimer aussi précisément que possible la probabilité d’une association, dans les “unes” de Charlie Hebdo, entre les thèmes “Religion” et “Violence”, qui contiennent les mots-clés suivants :

Religion (23 mots-clés) :
antisémitisme, athées, benoit xvi, bible, burka, charia, coran, dieu, évêque, françois 1er, intégrisme, jesus, laïcité, lourdes, mahomet, opus dei, pape, prophète, ramadan, religion, torah, vatican, voile
Violence (21 mots-clés) :
11 septembre, al-qaida, assassinat, attentats, ben laden, discrimination, guerre, homophobie, incendie criminel, jihad, massacre, mohamed merah, otage, parricide, pédophilie, sexisme, terrorisme, torture, tueur de masse, violence, xénophobie

Afin d’être aussi clair que possible sur la méthode, rappelons qu’elle permet de mesurer une probabilité conditionnelle, c’est-à-dire “nette”, ou “indépendante” de plusieurs autres probabilités. On vient de le dire, les catégories thématiques ne contiennent pas le même nombre de mots-clés, et les associations les plus fréquentes sont monothématiques. Ce qu’apporte un modèle, et que ne permet pas un simple tri à plat, c’est de “contrôler” ces facteurs, c’est-à-dire de les prendre en compte afin de mesurer isolément la probabilité d’association entre deux thèmes différents.

Dans le modèle qu’on met en place, sous la forme d’une équation log-linéaire et additive qui va ensuite être estimée à partir de plusieurs milliers de simulation de graphes aléatoires, on va donc utiliser différents termes correspondant à chacune de ces probabilités. Dans un dernier billet, j’ai présenté la forme définitive prise par cette équation, après en être passé par quelques modélisations exploratoires, et après avoir introduit un terme servant à mesurer une propriété endogène du réseau (spécifiquement, sa tendance à la transitivité entre certains mots-clés).

Pour rappel, les termes du modèle définitif sont les suivants :

  • probabilité globale d’une co-occurrence entre deux mots-clés
  • probabilité d’occurrence des mots-clés de chaque thème
  • probabilité d’une association entre deux mots-clés d’un même thème
  • probabilité d’une association entre deux mots-clés de thèmes différents
  • probabilité de trouver une relation transitive entre trois mots-clés

En aparté — je profite de ce billet pour signaler que, dans la spécification exacte du modèle ci-dessus, j’ai utilisé trois paramètres expérimentaux qui ne figurent pas encore dans la documentation technique du code associé à la technique de modélisation que j’utilise. Je dois l’utilisation de ces paramètres à un email de Pavel Krivitsky, qui m’a aussi aidé à comprendre comment paramétrer les mêmes modèles en tenant compte de la pondération des co-occurrences. Pour celles et ceux que ça intéresse, allez lire les emails de Pavel sur la liste de diffusion du projet statnet.

Qu’a-t-on trouvé ?

Pour rappel encore, on a obtenu les résultats suivants :

edges                           -5.23 (0.08)

nodefactor.International        -0.31 (0.21)
nodefactor.Politique            -0.04 (0.15)
nodefactor.Religion             -0.52 (0.29)
nodefactor.Violence             -0.22 (0.29)

nodematch.International          1.26 (0.49)
nodematch.Politique              0.98 (0.35)
nodematch.Religion               3.28 (0.67)
nodematch.Violence               0.29 (1.30)

mix.International.Politique      0.30 (0.36)
mix.International.Religion       0.85 (0.63)
mix.Politique.Religion           0.32 (0.52)
mix.International.Violence       0.42 (0.70)
mix.Politique.Violence           0.29 (0.43)
mix.Religion.Violence            2.16 (0.50)

gwdsp.fixed.1                    0.05 (0.00)

BIC                                16095.79

Ces résultats se comprennent de la manière suivante :

  • Les mots-clés de chaque thème n’ont pas la même propension à former des liens, c’est-à-dire qu’ils n’ont pas la même tendance à être utilisés en co-occurrence avec d’autres mots-clés. Les mots-clés les plus susceptibles d’être liés à d’autres sont ceux du thème “Politique”. Les mots-clés les plus susceptibles d’être liés à d’autres sont ceux du thème “Religion”.
  • Les associations monothématiques (entre deux mots-clés d’un même thème) sont très fréquentes, en particulier pour les catégories “International” et “Religion”, qui sont donc, d’une certaine manière, les thèmes les plus homogènes (c’est-à-dire les thèmes dont les mots-clés sont les plus à même de ne pas être “mélangés” avec ceux d’un autre thème).
  • Une fois que l’on a pris en compte ces deux premières formes d’effets, les associations entre mots-clés de thèmes différents restent encore fréquentes, voire très fréquentes pour l’association entre les mots-clés du thème “Religion” et ceux du thème “Violence”, comme dans les associations “Benoît XVI” et “pédophilie” ou bien “ben Laden” et “intégrisme”.
  • Enfin, le réseau exprime une très légère tendance aux relations transitives, ce qui signifie que certains chaînes de trois mots-clés, comme “Sarkozy → élections → présidentielle 2012”, se retrouvent fréquemment dans les co-occurrences. Aussi léger soit-il, il est très important de mesurer cet effet isolément, pour ne pas fausser les autres effets que l’on mesure.

Résumons.

Dans les 338 “unes” étudiées, la religion et les actes violents sont loin d’être les thèmes les plus traités : si l’on omet la catégorie résiduelle “Varia”, le thème le plus fréquemment associé à ces “unes” est le thème “Politique”, qui revient dans un tiers d’entre elles, alors que les thèmes “Religion” et “Violence” apparaissent chacun dans un peu moins de 9% des “unes”, sans être systématiquement associés l’un à l’autre. Une “une” sur dix pour un hebdomadaire, ça fait une “une” tous les deux mois et demi, ou cinq par an.

Mais que nous apprend cette fréquence ? Pas grand chose : elle ne dit rien de la probabilité d’association entre le thème “Religion” et un autre. Quelle est ainsi la probabilité d’association de ce thème au thème “Violence”, qui contient des mots-clés associés au terrorisme et à d’autres actes violents ? Les modèles que l’on a présentés indiquent que, toutes choses égales par ailleurs, la probabilité d’association entre les deux thèmes est très forte : sans être dominants dans le corpus des “unes”, elles sont très fortement liées entre elles.

Pour aller plus loin

Pour aller plus loin dans cette modélisation des “unes” de Charlie Hebdo, il faudrait à présent voir les autrès thèmes associés à la religion dans ce corpus : trouvera-t-on, par exemple, que la religion est aussi fortement associée au thème “Capitalisme”, également bien représenté dans les “unes” du magazine ? Il faudrait pour cela identifier précisément ce thème, ce que l’on n’a pas pris le temps de faire ici, mais cela vaudrait la peine de le vérifier à partir d’un codage thématique plus détaillé, comme suggéré plus haut.

Alors, islamophobe, Charlie Hebdo ? Je n’en sais toujours rien, et je m’en balance : le terme est suffisament plastique pour accommoder les biais de confirmation des uns et des autres, et ces biais ne m’intéressent pas. En revanche, je reconnais le peu que je connais de cet hebdomadaire dans l’association entre religion et violence. Est-ce normal ? À mon sens, oui : le clergé catholique est lié à des scandales de pédophilie et à la stigmatisation de l’homosexualité, et l’islamisme est lié au terrorisme international.

Voilà, c’est terminé. Bonne journée, et n’oubliez pas de vous aimer les uns les autres, bordel de merde.

  1. La thèse de Nicolas Hubé traite rapidement de cette dimension au passage consacré à l’ironie et aux jeux de mots dans la titraille journalistique (p. 182). []
  2. Cet exemple est fictif : je ne l’ai pas mesuré, et je ne lis pas assez La Croix pour avoir la moindre idée de quoi parle ce journal, mais je suppose qu’il est “obsédé”, au sens fréquentiste de la métaphore, par le catholicisme, ce qui illustre bien l’importance des associations – positives ou négatives – que produisent les “unes”. De plus, je n’ai pas pris l’association entre catholicisme et action humanitaire complètement au hasard. []
  3. Par meilleure qualité, j’entends : chaque mot-clé doit appartenir à un seul thème, et idéalement, les thèmes doivent contenir à peu près le même nombre de mots-clés (mettons, entre 20 et 30), dont l’occurrence dans le corpus ne varie pas trop (mettons, entre 50 et 150). []