Commit b640da69 authored by Ednomesor's avatar Ednomesor

MAJ Quanti

parent 05cbb55b
#R. Letricot - Quantilille
# Initiation à l'analyse de réseau - Séance 2
# 27 juin 2017
#Je nettoie mon espace de travail
rm(list=ls())
setwd("~/Documents/framagit/cours_SNA/script_R/")
#J'active mes extensions
library(igraph)
library(colorRamps)
#####Préparation à l'exercice####
#Chargement des données
liens<-read.csv("data/stormofswords/stormofswords_liens.csv",sep=",", header=TRUE)
noeuds<-read.csv("data/stormofswords/stormofswords_noeuds.csv",sep=",", header=TRUE)
#transformation en objet igraph
net<- graph_from_data_frame(d=liens, vertices=noeuds, directed = F)
#Aïe ! Le pb est que l'id ne correspond pas au nom des listes de liens
#J'ai besoin de remodeler mes dataframes
#J'utilise la fonction subset pour n'utiliser que les colonnes utiles
liens<-subset(liens, select = c("source", "target", "weight"))
noeuds<-subset(noeuds, select = c("nom", "sexe", "maison", "maison_code"))
#normalement là tout se passera bien
net<- graph_from_data_frame(d=liens, vertices=noeuds, directed = F)
####Rappel####
class(net)
(net)
# E pour inspecter les arêtes du réseau
E(net)
# V pour inspecter les sommets du réseau
V(net)
#S'il y a des données attributaires arêtes/sommets on peut y accéder de cette façon
E(net)$weight
V(net)$sexe
V(net)$maison
####A propos des fichiers####
#Comment ce fichier a-t-il été constitué ? De quoi s'agit-il ?
#Etude du 3e livre du trône de fer
#Chaque personnage cité dans l'ouvrage est un noeud du réseau
#Un lien entre deux personnages a été créé si leur nom apparait à un distance de 15 mots dans le livre
#Les liens ne sont pas orientés mais valués selon leur récurrence entre les personnages
#Pour plus d'information sur la constitution du fichier : https://www.macalester.edu/~abeverid/thrones.html
l <- layout_with_fr(net)
l <- norm_coords(l, ymin=-1, ymax=1, xmin=-1, xmax=1)
####MESURES SUR LE GRAPHE####
#Densité du graphe
graph.density(net)
#Diamètre du graphe
diameter(net)
#Transitivité - clustering coefficient
transitivity(net, type=c("globalundirected"))
V(net)$TRANS<-transitivity(net, type=c("localundirected"))
#### MESURES SUR LES SOMMETS ####
###Centralité de degré###
#Les personnnages les + connectés - noeuds du réseau ayant un grand nombre de liens incidents
V(net)$DC<-degree(net)
#Ce qui donne les mesures suivantes
V(net)$DC
#taille du label du noeud
plot(net,
vertex.size=V(net)$DC/6,
vertex.color="purple",
vertex.label = V(net)$name,
vertex.label.cex=V(net)$DC/18,
vertex.label.color="grey10",
layout = l
)
resultats<-as_data_frame(net, what = c("vertices"))
#On peut enlever les noeuds les moins importants
net2<-delete_vertices(net, V(net)$DC<2)
plot(net2,
vertex.size=V(net2)$DC/5,
vertex.color="purple",
vertex.label = V(net2)$name,
vertex.label.cex=V(net2)$DC/20,
vertex.label.color="grey10",
layout = layout_with_fr(net2)
)
#### CENTRALITE D'INTERMEDIARITE ####
V(net)$BET<-betweenness(net)
#Visualisation des résultats
plot(net,
vertex.size=V(net)$BET/190,
vertex.color="green",
vertex.label = V(net)$name,
vertex.label.cex=V(net)$BET/550,
vertex.label.color="grey10",
layout = l
)
resultats<-as_data_frame(net, what = c("vertices"))
####CENTRALITE DE PROXIMITE####
#Closeness Centrality#
V(net)$CLO<-closeness(net)
#Visualisation des résultats (pas très lisible)
plot(net,
vertex.size=V(net)$CLO*1000,
vertex.color="green",
vertex.label = V(net)$name,
vertex.label.cex=V(net)$CLO*1000,
vertex.label.color="grey10",
layout = l
)
resultats<-as_data_frame(net, what = c("vertices"))
####CENTRALITE EN VECTEUR PROPRE
#Eigenvector Centrality#
V(net)$EIGEN<-evcent(net)$vector
plot(net,
vertex.size=V(net)$EIGEN*7,
vertex.color="pink",
vertex.label = V(net)$name,
vertex.label.cex=V(net)$EIGEN*1.5,
vertex.label.color="grey10",
layout = l
)
####POINT D'ARTICULATION DU RESEAU ####
articulation_points(net)
####MESURES LIENS####
#Edge betweenness
E(net)$EDG.BET<-edge.betweenness(net)
plot(net,
edge.width=E(net)$EDG.BET/80,
vertex.size=2,
vertex.color="yellow",
vertex.label = ifelse(degree(net)>7, V(net)$label, NA),
vertex.label.color="grey10",
layout = l
)
#Longueur du chemin moyen
average.path.length(net)
#Chemin plus court
df.shortest<-as.data.frame(shortest.paths(net))
#### CLIQUES ####
#Taille de la plus grande clique
clique_num(net)
# Noeud impliqué dans la plus grande clique
largest_cliques(net)
#k-cores
coreness(net)
####A faire ensemble - Détection communautés####
#edge.betweenness.community
com<-edge.betweenness.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="Edge Betweenness community",
layout = l
)
com<-fastgreedy.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="Fastgreedy community",
layout = l
)
com<-walktrap.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="Walktrap community",
layout = l
)
com<-spinglass.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="Spinglass community",
layout = l
)
com<-leading.eigenvector.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="leading eigenvector community",
layout = l
)
com<-label.propagation.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="Label propagation community",
layout = l
)
com<-multilevel.community(net)
V(net)$color<-com$membership+1
plot(net,
vertex.label.cex = 0.7,
vertex.size = 5,
main="Multilevel community",
layout = l
)
#Récupérer toutes les mesures du graphe dans un dataframe
#On peut vouloir ces résultats dans un dataframe
df.allmesures<-as_long_data_frame(net)
......@@ -53,123 +53,7 @@ V(net)$maison
#Les liens ne sont pas orientés mais valués selon leur récurrence entre les personnages
#Pour plus d'information sur la constitution du fichier : https://www.macalester.edu/~abeverid/thrones.html
####MESURES SUR LE GRAPHE####
#Densité du graphe
graph.density(net)
#Diamètre du graphe
diameter(net)
#Transitivité - clustering coefficient
transitivity(net, type=c("globalundirected"))
V(net)$TRANS<-transitivity(net, type=c("localundirected"))
#### MESURES SUR LES SOMMETS ####
###Centralité de degré###
#Les personnnages les + connectés - noeuds du réseau ayant un grand nombre de liens incidents
V(net)$DC<-degree(net)
#Ce qui donne les mesures suivantes
V(net)$DC
#taille du label du noeud
plot(net,
vertex.size=V(net)$DC/8,
vertex.color="purple",
vertex.label = V(net)$name,
vertex.label.cex=V(net)$DC/18,
vertex.label.color="grey10",
layout = layout.fruchterman.reingold(net)
)
resultats<-as_data_frame(net, what = c("vertices"))
plot(resultats)
#On peut récupérer ces valeurs dans un dataframe
test<- data.frame(
deg.centralite = V(net)$DC,
row.names = V(net)$name
)
#On peut enlever les noeuds les moins importants
net2<-delete_vertices(net, V(net)$DC<0.01)
plot(net2,
vertex.size=V(net2)$DC*20,
vertex.color="purple",
vertex.label = V(net2)$name,
vertex.label.cex=V(net2)$DC*5,
vertex.label.color="grey10",
layout = layout.fruchterman.reingold(net2)
)
#### CENTRALITE D'INTERMEDIARITE ####
V(net)$BET<-betweenness(net)
#On peut récupérer ces valeurs dans un dataframe
test<- data.frame(
deg.centralite = V(net)$DC,
deg.intermed = V(net)$BET,
row.names = V(net)$name
)
#Visualisation des résultats
plot(net,
vertex.size=V(net)$BET/190,
vertex.color="green",
vertex.label = V(net)$name,
vertex.label.color="grey10",
layout = layout.fruchterman.reingold(net)
)
####CENTRALITE DE PROXIMITE####
#Closeness Centrality#
V(net)$CLO<-closeness(net)
#On peut récupérer ces valeurs dans un dataframe
test<- data.frame(
deg.centralite = V(net)$DC,
deg.intermed = V(net)$BET,
deg.close = V(net)$CLO,
row.names = V(net)$name
)
####CENTRALITE EN VECTEUR PROPRE
#Eigenvector Centrality#
V(net)$EIGEN<-evcent(net)$vector
#On peut récupérer ces valeurs dans un dataframe
test<- data.frame(
deg.centralite = V(net)$DC,
deg.intermed = V(net)$BET,
deg.close = V(net)$CLO,
eigen.centralite = V(net)$EIGEN,
row.names = V(net)$name
)
####POINT D'ARTICULATION DU RESEAU ####
articulation_points(net)
####MESURES LIENS####
#Edge betweenness
E(net)$EDG.BET<-edge.betweenness(net)
#Longueur du chemin moyen
average.path.length(net)
#Chemin plus court
df.shortest<-as.data.frame(shortest.paths(net))
#### CLIQUES ####
#Taille de la plus grande clique
clique_num(net)
# Noeud impliqué dans la plus grande clique
largest_cliques(net)
coreness(net)
#Récupérer toutes les mesures du graphe dans un dataframe
#On peut vouloir ces résultats dans un dataframe
df.allmesures<-as_long_data_frame(net)
# Produire les mesures locales et globales du réseau :
# - identifier les personnages principaux du point de vue du réseau, les intermédiaires,
# les mieux connectés à l'ensemble du réseau, les noeuds voisins d'un personnage qui vous interesse,
# les cliques
......@@ -240,6 +240,8 @@ plot(net,
#Longueur du chemin moyen
mean_distance(net)
#k-cores
graph.coreness(net)
#### CLIQUES ####
####Taille de la plus grande clique####
......@@ -251,8 +253,11 @@ largest_cliques(net)
dyad_census(net2)
triad_census(net2)
####DETECTION DE COMMUNAUTES####
#Récupérer toutes les mesures du graphe dans un dataframe
#On peut vouloir ces résultats dans un dataframe
df.allmesures<-as_long_data_frame(net)
......@@ -26,10 +26,22 @@ Les données que nous allons manipuler peuvent, quant à elles, faire l'objet de
L'ensemble des données, scripts et présentations que j'ai produit pour la formation Quantilille est disponible sur le dépôt GIT :
## Ressources utiles
Laurent Beauguitte, Analyser les réseaux avec R (packages statnet, igraph et tnet). DEA. Analyser les réseaux avec R, UMR Géographie-cités, 2012, pp.17. Disponible sur HalSHS <https://cel.archives-ouvertes.fr/cel-00687871/document>
Julien Barnier, \textit{Introduction à R}, livret de formation, dernière version disponible sur : <http://alea.fr.eu.org/pages/intro-R>.
Julien Barnier, *Analyse de réseau avec R*, livret de formation, 2011 :
<https://alea.fr.eu.org/git/doc_reseaux_r.git/blob_plain/HEAD:/networks.pdf>
Tutoriel sur igraph produit par l'un de ses développeurs <http://igraph.github.io/netuser15/user-2015.html#1>
Concernant les différentes méthodes de détection de communautés avec igraph :
<https://stackoverflow.com/questions/9471906/what-are-the-differences-between-community-detection-algorithms-in-igraph>
Egalement pour une version précédente de igraph :
<https://www.r-bloggers.com/summary-of-community-detection-algorithms-in-igraph-0-6/>
## Mesures globales d'un réseau
Les mesures globales portent sur l'intégralité du réseau et vont donner une idée générale de sa structure.
......@@ -234,7 +246,7 @@ plot(net,
```
```{r}
```{r, tidy=TRUE, tidy.opts=list(width.cutoff=60), fig.align='center', fig.height=4}
plot(net2,
vertex.size=V(net2)$CLO*200,
vertex.color="purple",
......@@ -313,7 +325,7 @@ average.path.length(net)
mean_distance(net)
```
```{r}
```{r, tidy=TRUE, tidy.opts=list(width.cutoff=60), fig.align='center', fig.height=4}
shortest.paths(net, "A", "H")
all_shortest_paths(net, "A", "H")$nrgeo
path.length.hist(net)$res
......@@ -333,6 +345,70 @@ largest_cliques(net)
La définition de la clique demeure assez contraignante. Il arrive qu'un sous-graphe ne soit pas complet mais néanmoins pertinent du point de vue de la question de recherche. C'est pourquoi d'autres méthodes permettent de fixer soi-même les structures de cliques recherchées.
## Exercice solo ##
Produire les mesures locales et globales à partir du jeu de données `stormofswords` disponible dans le dossier `/data`.
Une petite préparation du fichier est nécessaire en amont.
```{r, tidy=TRUE, tidy.opts=list(width.cutoff=60), fig.align='center', fig.height=4}
#R. Letricot - Quantilille
# Initiation à l'analyse de réseau - Séance 2
# 27 juin 2017
#J'active mes extensions
library(igraph)
library(colorRamps)
#####Préparation à l'exercice####
#Chargement des données
liens<-read.csv("~/Documents/framagit/cours_SNA/script_R/data/stormofswords/stormofswords_liens.csv",sep=",", header=TRUE)
noeuds<-read.csv("~/Documents/framagit/cours_SNA/script_R/data/stormofswords/stormofswords_noeuds.csv",sep=",", header=TRUE)
#transformation en objet igraph
#net<- graph_from_data_frame(d=liens, vertices=noeuds, directed = F)
#Aïe ! Le pb est que l'id ne correspond pas au nom des listes de liens
#J'ai besoin de remodeler mes dataframes
#J'utilise la fonction subset pour n'utiliser que les colonnes utiles
liens<-subset(liens, select = c("source", "target", "weight"))
noeuds<-subset(noeuds, select = c("nom", "sexe", "maison", "maison_code"))
#normalement là tout se passera bien
net<- graph_from_data_frame(d=liens, vertices=noeuds, directed = F)
####Rappel####
class(net)
(net)
####A propos des fichiers####
#Comment ce fichier a-t-il été constitué ? De quoi s'agit-il ?
#Etude du 3e livre du trône de fer
#Chaque personnage cité dans l'ouvrage est un noeud du réseau
#Un lien entre deux personnages a été créé si leur nom apparait à un distance de 15 mots dans le livre
#Les liens ne sont pas orientés mais valués selon leur récurrence entre les personnages
#Pour plus d'information sur la constitution du fichier : https://www.macalester.edu/~abeverid/thrones.html
```
## Détection de communautés
Les communautés en analyse de réseau sont des sous-graphes dont les noeuds sont fortement connectés. On confronte souvent leur partitionnement avec ce que pourrait donner leur détection dans un graphe aléatoire.
Il existe plusieurs algorithmes de détection de communautés dans igraph :
* *edge betweenness community* : est un algorithme de décomposition hiérarchique basé sur la mesure de la centralité d'intermédiarité des liens. Le partitionnement du graphe s'effectue en enlevant un à un de manière décroissante les liens selon leur score d'intermédiarité. Il se fonde sur l'idée que quelques liens seulement seront le passage obligé entre la communauté et le reste du graphe. Cette méthode s'avère gourmande en calcul dans la mesure où le score de edge betweenness est recalculé à chaque lien enlevé.
* *fastgreedy community* : autre décomposition hiérarchique basée cette fois sur la modularité qui est la différence entre le nombre de liens présents dans la communauté et le nombre de liens attendus de façon aléatoire. Elle s'échelonne entre -1 et 1. La valeur positive (au dessus de 0.3) signifie que la structure de la communauté est significative au regard d'un graphe généré de manière aléatoire.
* *walktrap community* : algorithme qui parcourt le graphe de manière aléatoire. Le chemin est court (3 à 5 liens), partant du principe que de petits déplacements aléatoires seront à même de se trouver dans une communauté car elle contient peu de liens reliants le reste du graphe.
* *spinglass community* : issue de la physique et du modèle Potts. Chaque sommet se voit attribuer une valeur de rotation qui sera influencée selon la valeur des autres sommets auxquels il est relié.
* *leading eigenvector community* : approche hiérarchique top-down qui partitionne le réseau si cela augmente la modularité globale. Le partitionnement s'appuie sur le calcul du eigenvector.
* *label propagation community* : on assigne aléatoirement un label à chaque sommet. De manière itérative, on réassigne le label en fonction du label le plus fréquent parmi les sommets voisins. Quand le label devient le plus donné par tous les voisins, l'algorithme s'arrête.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment