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

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

Récupérer les tweets des élections départementales

Au cas où un lecteur ait à disposition une machine qui puisse tourner sans s’arrêter sur les quinze prochains jours, histoire d’avoir une bonne fenêtre de tir…

1. Il vous faut un compte Twitter

À partir de votre compte Twitter, créez une application en vous rendant à cette adresse. Le compte en question doit être lié à un numéro de téléphone. Les autres informations à fournir ne sont pas importantes : donnez n’importe quel nom et description à l’application, cochez la case en dessous des conditions d’utilisation, et vous allez vous retrouver sur une page qui permet de récupérer ces deux informations :

Screen Shot 2015-03-21 at 18.13.58

Il vous faut l’information apparaissant sous les deux barres rouges.

2. Il vous faut le package R ROAuth

Dans R, installez le package ROAuth, puis insérez vos deux codes dans les commandes suivantes :

# install.packages("ROAuth")
library(ROAuth)

requestURL = "https://api.twitter.com/oauth/request_token"
accessURL = "https://api.twitter.com/oauth/access_token"
authURL = "https://api.twitter.com/oauth/authorize"
consumerKey = ""
consumerSecret = ""
my_oauth = OAuthFactory$new(consumerKey = consumerKey,
                            consumerSecret = consumerSecret,
                            requestURL = requestURL,
                            accessURL = accessURL,
                            authURL = authURL)

Une fois ces commandes exécutées, exécutez celle-ci :

my_oauth$handshake(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl"))

Votre navigateur va s’ouvrir et vous offrir un code PIN à rentrer dans R :

Screen Shot 2015-03-21 at 18.19.02

Une fois que c’est fait, sauvegardez le résultat :

save(my_oauth, file = "oauth.rda")

Et vous y êtes presque.

3. Il vous faut le package R streamR

Le petit bout de code expliqué ci-dessus traînait sur mon disque dur. Je ne me souviens pas de la source exacte, mais c’était sans doute un tutoriel de Pablo Barbera. Le même a écrit le package streamR, qui va vous permettre de récupérer une sélection de tweets identifiés par les mots-clés et hashtags des élections départementales. Installez le package, puis lancez cette boucle :

# install.packages("streamR")
library(streamR)

# load credentials
load("my_oauth.Rdata")

# scrape for 15 days
for(i in (15 * 24 * 2):1) {

  n = sprintf("%03.0f", i)
  f = paste0("tweets", n, ".json")

  cat(n, "scraping to", f, "...\n")
  filterStream(f, track = c("départementales", "departementales",
                            "#departementales2015", "#departementales",
                            "#départementales2015", "#départementales",
                            "#dep2015"),
               timeout = 60 * 25, oauth = my_oauth)

  # leave five minutes out
  Sys.sleep(60 * 5)

}

La boucle produit un fichier toutes les 25 minutes et ignore dix minutes d’information par heure, histoire de laisser l’API de Twitter souffler un peu. Les résultats ne sont pas limités aux tweets en français, mais vous aurez tout le loisir de faire le tri plus tard.

Un petit test effectué ce samedi m’a renvoyé un peu plus de 4 600 résultats de bonne qualité (dont 4 100 en français) en moins de six heures. Il est très facile d’explorer ce genre de données en utilisant, par exemple, environ 700 comptes Twitter d’élus et de partis politiques français, afin de voir s’ils sont souvent retweetés :

Rplot

Le codage ci-dessus est très incomplet : je n’ai codé que les comptes Twitter des médias les plus évidents (presse quotidienne, chaînes de télévision et quelques médias en ligne), et n’ai inclus dans la catégorie “Officiels” que le seul compte Twitter du Ministère de l’Intérieur. Récoltez les données demain et les jours suivants, et vous aurez un bon matériau pour faire beaucoup mieux.

Une fonction pour passer des réseaux à ggplot2

Mise à jour : la fonction ggnet a été publiée dans le package GGally (merci à Barret, qui se charge de tenir le package à jour et qui a fourni une excellente relecture du code).

J’ai terminé de travailler sur la fonction ggnet évoquée dans un récent billet. Ça donne des graphiques comme ça :

example3

La fonction est à présent robuste à chacune de ses options : vous pouvez omettre n’importe quel argument (sauf le premier !) et toujours obtenir quelque chose de graphiquement potable. Il reste juste une petite faiblesse sur l’option quantize.weights, qui doit probablement planter si une classification par quartiles ne parvient pas à identifier les noeuds (les points) de manière unique.

Les exemples de la fonction couvrent les cas les plus simples avec des données simulées et montrent bien la filiation avec le code original de Moritz Marbach :

rnd = network::network.initialize(10)
cat = LETTERS[rbinom(10, 4, .5)]
ggnet(rnd, 
      label = TRUE,
      color = "white",
      segment.color = "grey10",
      node.group = cat)

rnd

L’option label.nodes est particulièrement flexible grâce à l’aide de Joël sur un bout du code. Un point du graphique, ou n’importe quelle série de points identifiés par l’attribut vertex.names, peuvent être légendés, ce qui donne des combinaisons faciles avec l’argument node.group, comme dans ce graphique qui distingue les “followers” de NKM de tous les autres :

example4

Pour des calculs plus avancés, jetez un coup d’oeil aux fonctions du fichier functions.R, qui simplifient un peu le boulot en calculant les “followers/followings” ou en calculant des mesures de centralité pour chaque groupe parlementaire. Les packages à consulter pour l’analyse de réseau sont les packages igraph, network et sna (ou alors un logiciel comme Pajek, mais l’analyse ne sera pas réplicable comme elle peut l’être avec R).

Rajout #1 : nouvel exemple avec des données sur la répartition des sièges de grands groupes industriels et de cabinets d’avocats dans 55 villes mondiales.

cities

En six lignes de code, dont trois pour récupérer les données :

url = url("http://networkdata.ics.uci.edu/netdata/data/cities.RData")
print(load(url))
close(url)
type = network::get.vertex.attribute(cities, "type")
type = ifelse(grepl("City|Law", type), gsub("I+", "", type), "Firm")
ggnet(cities,
      mode = "kamadakawai",
      alpha = .2,
      node.group = type,
      label = c("Paris", "Beijing", "Chicago"),
      color = "darkred")

Plus de données pour tester la fonction ici et .

Rajout #2 : spécial dédicace aux carnetiers d’Hypothèses ! On reprend les données de Josquin Debaz et on représente le réseau des bloggers en décembre 2010, en pondérant les noeuds par le nombre de liens sortants :

hypo.net

En cinq trois lignes de code, dont quatre pour convertir le réseau au bon format :

url = "http://gspr.ehess.free.fr/media/hypothesosphere10C07.net"
hyp = network::read.paj(url)
ggnet(hyp, 
      label = TRUE, 
      size = 12, 
      vjust = -1.5, 
      weight = "outdegree")

Rajout #3 : le même réseau en d3 grâce au package en cours de développement d3Network, de Christopher Gangrud (cliquer sur l’aperçu pour la version interactive, hébergée ailleurs) :

d3Network screenshot

Le code est encore une fois assez court, puisqu’il ne faut qu’une dizaine de lignes pour convertir de Pajek (.net) à igraph à d3 :

# data
require(igraph)
url = "http://gspr.ehess.free.fr/media/hypothesosphere10C07.net"
hyp = read.graph(url, format = "pajek")
df = asDF(hyp)
Source = df$vertexes[df$edges$V1, 2]
Target = df$vertexes[df$edges$V2, 2]
df = data.frame(Source, Target)
# d3Network
devtools::install_github("d3Network", "christophergandrud")
require(d3Network)
d3Network(df,
          file = "hypothesosphere.html",
          width = 900,
          height = 750,
          fontsize = 12)

S’il vous venait l’idée de vouloir représenter le réseau des députés sur Twitter en d3, essayez ceci, mais attendez-vous à un gros amas de points qui mettra longtemps à se stabiliser :

file = "network.txt"
link = "https://raw.github.com/briatte/ggnet/master/network.txt"
## downloader::download(link, file)
df = read.csv(file, sep = "\t")
names(df)
## devtools::install_github("d3Network", "christophergandrud")
require(d3Network)
d3Network(df, "network.html")

339 députés sur Twitter

Les données sur la classe politique semblant toujours trouver preneur, voici un encart publicitaire pour un jeu de données contenant les comptes Twitter de 339 députés de la législature en cours :

example1

J’ai récolté les données pour illustrer une fonction qui sert à visualiser des données de type « réseau » avec ggplot2 (note : plus de détails sur le code ici). Voici quelques compléments sur les données :

  • Le « gris central » est Jacques Bompard, mais il est central au réseau malgré lui : il est là à cause des députés qu’il suit ou qui le suivent, et qui l’attirent au centre. Voir ci-dessous pour les détails.
  • L’anomalie « rose chez les bleus » est Kheira Bouziane, dont le compte Twitter est à présent fermé et le site Internet en reconstruction. Je n’ai aucune explication. Il ne faut pas surlire les données.
  • La « rose très excentrée » est Pascale Boistard. Il y a aussi ce député UMP qui m’a fait rigoler : plein de gens le suivent, mais lui ne suit absolument personne. Il n’apparaît pas dans le graphique.

Si vous souhaitez explorer le réseau, voici une rapide fonction « qui est suivi par qui » :

who.is.followed.by <- function(df, x) {
  f = df[which(df$Source == x), ]$Target
  print(as.character(f))
  print(table(ids$Groupe[which(ids$Twitter %in% f)]))
}

Amusez-vous bien :

who.is.followed.by(df, "JacquesBompard")
who.is.followed.by(df, "Marion_M_Le_Pen")

Exercice : rédiger la fonction inverse who.follows() (qui, comme celle ci-dessus, peut s’écrire en une ligne).

Notes de construction : les données sont un mashup entre les données du site Tweet Député (qui est bourré d’erreurs et de fautes d’orthographe), celles réunies par le Lab Europe 1 lors de la campagne électorale de juin 2012 (avec beaucoup de comptes de campagne plus ou moins temporaires et les députés devenus ministres), celles du compte Twitter de l’Assemblée nationale, et le fichier sur les députés en mandat du site Nos Députés, établi par Regards Citoyens avant les partielles de décembre 2012. Le scraping des comptes a eu lieu au cours des quatre dernières semaines.

Envoyez vos corrections, et allez voir d’autres travaux similaires chez Arthur Charpentier, qui avait relayé une visualisation des données de juin 2012 avec Gephi par Ewen Gallic, chez Jonathan Chibois, qui travaille sur ces données en conservant une perspective longitudinale, ou chez Baptiste Coulmont, qui m’a inspiré ce graphique.

Rajout #1 : j’avais oublié de citer la visualisation d’Ewen Gallic, c’est fait. Par ailleurs, j’ai tenté de rendre les données de mon graphique disponibles en deux fichiers “nodes/edges” pour Gephi : le résultat est là (pour autant de temps que possible), et inclut aussi un fichier GEXF exporté avec le package rgexf. Je n’ai pas réussi à utiliser ces fichiers correctement avec Gephi 0.82, que je connais très mal. Have fun!

Rajout #2 : si vous vous demandez comment analyser ce genre de réseau, jetez un coup d’oeil à ce qui a été fait sur les meilleurs tennismen mondiaux.

Polit’bistro sur Twitter

Les sondages et les questions pédagogiques semblent avoir ranimé Polit’bistro, au moins le temps d’un weekend. Joël et moi étant également actifs sur Twitter, voici notre tentative de micro-blogging à quatre mains :

Il nous manque la page Facebook pour pouvoir nous livrer à des décomptes un peu nerdy, mais ça devrait finir par se faire si le bistro nécessite une succursale. On en est très loin pour le moment.

À bientôt sur une plateforme ou sur une autre !

P.S. Le graphique qui nous sert de logo vient d’une note d’Andrew Gelman sur le vote aux États-Unis.