web-dev-qa-db-fra.com

Comment visualiser un grand réseau en R?

Les visualisations de réseau deviennent courantes dans la science en pratique. Mais à mesure que les réseaux augmentent en taille, les visualisations communes deviennent moins utiles. Il y a tout simplement trop de nœuds/sommets et de liens/arêtes. Souvent, les efforts de visualisation finissent par produire des "boules de poils".

Certaines nouvelles approches ont été proposées pour surmonter ce problème, par exemple:

Je suis sûr qu'il existe de nombreuses autres approches. Ainsi, ma question est: Comment surmonter le problème des boules de poils, c'est-à-dire comment visualiser les grands réseaux en utilisant R?

Voici du code qui simule un réseau exemplaire:

# Load packages
lapply(c("devtools", "sna", "intergraph", "igraph", "network"), install.packages)
library(devtools)
devtools::install_github(repo="ggally", username="ggobi")
lapply(c("sna", "intergraph", "GGally", "igraph", "network"), 
       require, character.only=T)

# Set up data
set.seed(123)
g <- barabasi.game(1000)

# Plot data
g.plot <- ggnet(g, mode = "fruchtermanreingold")
g.plot

enter image description here

Cette question est liée à Visualisation d'un graphique non orienté trop grand pour GraphViz? . Cependant, je ne cherche pas ici des recommandations générales de logiciel mais des exemples concrets (en utilisant les données fournies ci-dessus) quelles techniques aident à faire une bonne visualisation d'un grand réseau en utilisant R (comparable aux exemples de ce fil: R: Scatterplot avec trop de points ).

54
majom

Une autre façon de visualiser de très grands réseaux est avec BioFabric (www.BioFabric.org), qui utilise des lignes horizontales au lieu de points pour représenter les nœuds. Les arêtes sont ensuite affichées à l'aide de segments de ligne verticaux. Une démonstration D3 rapide de cette technique est présentée à: http://www.biofabric.org/gallery/pages/SuperQuickBioFabric.html .

BioFabric est une application Java, mais une version R simple est disponible sur: https://github.com/wjrl/RBioFabric .

Voici un extrait du code R:

 # You need 'devtools':
 install.packages("devtools")
 library(devtools)

 # you need igraph:
 install.packages("igraph")
 library(igraph)

 # install and load 'RBioFabric' from GitHub
 install_github('RBioFabric',  username='wjrl')
 library(RBioFabric)

 #
 # This is the example provided in the question:
 #

 set.seed(123)
 bfGraph = barabasi.game(1000)

 # This example has 1000 nodes, just like the provided example, but it 
 # adds 6 edges in each step, making for an interesting shape; play
 # around with different values.

 # bfGraph = barabasi.game(1000, m=6, directed=FALSE)

 # Plot it up! For best results, make the PDF in the same
 # aspect ratio as the network, though a little extra height
 # covers the top labels. Given the size of the network,
 # a PDF width of 100 gives us good resolution.

 height <- vcount(bfGraph)
 width <- ecount(bfGraph)
 aspect <- height / width;
 plotWidth <- 100.0
 plotHeight <- plotWidth * (aspect * 1.2)
 pdf("myBioFabricOutput.pdf", width=plotWidth, height=plotHeight)
 bioFabric(bfGraph)
 dev.off()

Voici un aperçu de la version BioFabric des données fournies par le questionneur, bien que les réseaux créés avec des valeurs de m> 1 soient plus intéressants. Le détail de l'encart montre un gros plan du coin supérieur gauche du réseau; Le nœud BF4 est le nœud de degré le plus élevé du réseau, et la configuration par défaut est une recherche en largeur du réseau (en ignorant les directions Edge) à partir de ce nœud, avec les nœuds voisins traversés par ordre décroissant de degré de nœud. Notez que nous pouvons immédiatement voir que, par exemple, environ 60% des voisins du nœud BF4 sont de degré 1. Nous pouvons également voir à partir du bord inférieur strict de 45 degrés que ce réseau à 1000 nœuds a 999 bords, et est donc un arbre.

BioFabric presentation of example data

Divulgation complète: BioFabric est un outil que j'ai écrit.

16
wjrl

C'est une question intéressante, je ne connaissais pas la plupart des outils que vous avez énumérés, alors merci. Vous pouvez ajouter HivePlot à la liste. C'est une méthode déterministe consistant à projeter des nœuds sur un nombre fixe d'axes (généralement 2 ou 3). Regardez la page liée, il existe de nombreux exemples visuels.

enter image description here

Cela fonctionne mieux si vous avez un attribut nodal catégorique dans votre jeu de données, de sorte que vous pouvez l'utiliser pour sélectionner l'axe vers lequel un nœud va. Par exemple, lorsque vous étudiez le réseau social d'une université: les étudiants sur un axe, les enseignants sur un autre et le personnel administratif sur le troisième. Mais bien sûr, il peut également fonctionner avec un attribut numérique discrétisé (par exemple, les jeunes, les personnes d'âge moyen et les personnes âgées sur leurs axes respectifs).

Ensuite, vous avez besoin d'un autre attribut, et il doit être numérique (ou au moins ordinal) cette fois. Il est utilisé pour déterminer la position d'un nœud sur son axe. Vous pouvez également utiliser certaines mesures topologiques, telles que le degré ou la transitivité (coefficient de regroupement).

Comment construire un hiveplot http://www.hiveplot.net/img/hiveplot-undirected-01.png

Le fait que la méthode soit déterministe est intéressant, car il permet de comparer différents réseaux représentant des systèmes distincts (mais comparables). Par exemple, vous pouvez comparer deux universités (à condition d'utiliser les mêmes attributs/mesures pour déterminer les axes et la position). Il permet également de décrire le même réseau de différentes manières, en choisissant différentes combinaisons d'attributs/mesures pour générer la visualisation. C'est la manière recommandée de visualiser un réseau, en fait, grâce à ce qu'on appelle un panneau Hive.

Plusieurs logiciels capables de générer ces tracés Hive sont répertoriés dans la page que j'ai mentionnée au début de cet article, y compris les implémentations dans Java et R.

10
Vincent Labatut

J'ai eu affaire à ce problème récemment. En conséquence, j'ai trouvé une autre solution. Réduisez le graphique par communautés/grappes. Cette approche est similaire à la troisième option décrite par le PO ci-dessus. En guise d'avertissement, cette approche fonctionnera mieux avec des graphiques non orientés. Par exemple:

library(igraph)

set.seed(123)
g <- barabasi.game(1000) %>%
  as.undirected()

#Choose your favorite algorithm to find communities.  The algorithm below is great for large networks but only works with undirected graphs
c_g <- fastgreedy.community(g)

#Collapse the graph by communities.  This insight is due to this post http://stackoverflow.com/questions/35000554/collapsing-graph-by-clusters-in-igraph/35000823#35000823

res_g <- simplify(contract(g, membership(c_g))) 

Le résultat de ce processus est la figure ci-dessous, où les noms des sommets représentent l'appartenance à la communauté.

plot(g, margin = -.5)

enter image description here

Ce qui précède est clairement plus agréable que ce désordre hideux

plot(r_g, margin = -.5)

enter image description here

Pour relier les communautés aux sommets originaux, vous aurez besoin de quelque chose qui ressemble à ce qui suit

mem <- data.frame(vertices = 1:vcount(g), memeber = as.numeric(membership(c_g)))

OMI, c'est une bonne approche pour deux raisons. Premièrement, il peut en théorie traiter n'importe quel graphe de taille. Le processus de recherche de communautés peut être répété en continu sur des graphiques réduits. Deuxièmement, l'adoption d'une approche interactive donnerait des résultats très lisibles. Par exemple, on peut imaginer que l'utilisateur puisse cliquer sur un sommet dans le graphique réduit pour développer cette communauté en révélant tous ses sommets d'origine.

7
Jacob H

Un autre paquet intéressant est networkD . Il existe une myriade de moyens de représenter les graphiques dans cette bibliothèque. En particulier, je trouve le forceNetwork une option intéressante. Il est interactif et vous permet donc d'explorer réellement votre réseau. C'est génial pour EDA, mais c'est peut-être trop "tortueux" pour le travail final.

3
Jacob H

J'ai regardé autour de moi et n'ai trouvé aucune bonne solution. Mon approche a été de supprimer les nœuds et de jouer avec la transparence Edge. Il s'agit plus d'une solution de conception que d'une solution technique, mais j'ai pu tracer des réseaux de type géphi jusqu'à 50 000 bords sans trop de complications sur mon ordinateur portable.

avec votre exemple:

plot(simplify(g), vertex.size= 0.01,Edge.arrow.size=0.001,vertex.label.cex = 0.75,vertex.label.color = "black"  ,vertex.frame.color = adjustcolor("white", alpha.f = 0),vertex.color = adjustcolor("white", alpha.f = 0),Edge.color=adjustcolor(1, alpha.f = 0.15),display.isolates=FALSE,vertex.label=ifelse(page_rank(g)$vector > 0.1 , "important nodes", NA))

enter image description here

Exemple de Twitter mentionne un réseau avec 30 000 arêtes:

enter image description here

0
supercontra