« Analyse de réseaux avec R » : différence entre les versions
(first!) |
(grands points finis) |
||
Ligne 1 : | Ligne 1 : | ||
==Introduction== | ==Introduction== | ||
L'analyse de réseaux (en anglais, 'network analysis' ou 'NA') est une des approches méthodologiques les plus populaires utilisée en [https://edutechwiki.unige.ch/en/Learning_analytics analytique de l'apprentissage] (Romero & Ventura, 2020). [http://ceur-ws.org/Vol-2868/article_7.pdf Poquet et al. (2021)] indiquent que l'analyse de réseaux permet la modélisation et l'analyse de données relationnelles en éducation. | L'analyse de réseaux (en anglais, 'network analysis' ou 'NA') est une des approches méthodologiques les plus populaires utilisée en [https://edutechwiki.unige.ch/en/Learning_analytics analytique de l'apprentissage] ([https://bookdown.org/chen/la-manual/files/Romero%20and%20Ventura%20-%202020.pdf Romero & Ventura, 2020]). [http://ceur-ws.org/Vol-2868/article_7.pdf Poquet et al. (2021)] indiquent que l'analyse de réseaux permet la modélisation et l'analyse de données relationnelles en éducation. Un réseau est composé d'un groupe d'entités ou d'éléments appelés noeuds ('nodes') ou sommets ('vertices') et une relation qui les connecte que l'on appelle arêtes ('edge') ou lien ('link'). Ainsi, la visualisation créée via l'analyse de réseaux peut être utile pour cartographier les relations et les interactions, identifier des schémas/patterns d'interaction, identifier les étudiant·e·s actif·ve·s et inactif·ve·s et détecter le rôle de certain·e·s étudiant·e·s ou enseignant·e·s. | ||
Cette page vous montrera un exemple d'analyse de réseaux entre des étudiant·e·s et leur nombre de visualisation à un exercice. Nous verrons donc quels sont les exercices qui sont le plus visualisés et les liens entre les exercices les plus fréquemment visualisés. De plus, nous aurons aussi une cartographie des étudiant·e·s qui ont besoin de visualiser certains exercices plus que d'autres. | Cette page vous montrera un exemple d'analyse de réseaux entre des étudiant·e·s et leur nombre de visualisation à un exercice. Nous verrons donc quels sont les exercices qui sont le plus visualisés et les liens entre les exercices les plus fréquemment visualisés. De plus, nous aurons aussi une cartographie des étudiant·e·s qui ont besoin de visualiser certains exercices plus que d'autres. | ||
Ligne 18 : | Ligne 18 : | ||
<source> | <source> | ||
rm(list=ls()) # effacer l'environnement | |||
rm(list=ls()) | |||
# install.packages("pacman") # à exécuter si pas déjà installé | # install.packages("pacman") # à exécuter si pas déjà installé | ||
library(pacman) | library(pacman) | ||
pacman::p_load(igraph, | pacman::p_load(igraph, # bibliothèques utilisées | ||
dplyr | dplyr | ||
) | ) | ||
setwd(dirname(rstudioapi::getSourceEditorContext()$path)) # définir le répertoire de travail au répertoire actuel (./algebra_2005_2006/) | |||
data <- read.table("algebra_2005_2006_master.txt", sep="\t", header = T) # importer les données | |||
data <- read.table("algebra_2005_2006_master.txt", sep="\t", header = T) | |||
</source> | </source> | ||
Vous devez maintenant avoir dans votre environnement le data frame 'data' avec 3967 obs. de 19 variables | Vous devez maintenant avoir dans votre environnement le data frame 'data' avec 3967 obs. de 19 variables | ||
<source> | |||
'data.frame': 3967 obs. of 19 variables: | str(data) | ||
</source> | |||
## 'data.frame': 3967 obs. of 19 variables: | |||
===Préparation des 'egdes' et 'nodes'=== | ===Préparation des 'egdes' et 'nodes'=== | ||
La première étape afin de créer le réseau est de déterminer la liste des arêtes ('edges') et des noeuds ('nodes'). De ce fait, les colonnes/variables qui vont nous intéresser sont : | |||
* <code>Anon.Student.Id</code> : Identifiant (id) de l'étudiant·e, qui servira de noeud (node) = la ''source'' | * <code>Anon.Student.Id</code> : Identifiant (id) de l'étudiant·e, qui servira de noeud (node) = la ''source'' | ||
Ligne 48 : | Ligne 47 : | ||
* <code>Problem.View</code> : Nombre de fois où l'exercice a été visualisé, qui servira de ''poids'' (weight) dans les liens entre les différents noeuds (étudiant·e - exercice). | * <code>Problem.View</code> : Nombre de fois où l'exercice a été visualisé, qui servira de ''poids'' (weight) dans les liens entre les différents noeuds (étudiant·e - exercice). | ||
Afin de limiter notre visualisation à un nombre restreint de noeuds et ne pas voir | Afin de limiter notre visualisation à un nombre restreint de noeuds et ne pas voir l'intégralité des exercices visualisés par les 575 étudiant·e·s de notre jeu de données, nous allons nous intéresser seulement aux exercices qui ont été visualisés plus de 5 fois. | ||
<source> | |||
table(data$Problem.View) | |||
2930 582 165 103 61 41 19 14 8 12 14 5 2 3 2 1 1 1 1 1 1 (occurence) | </source> | ||
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 28 (nombre de visualisation d'un exercice) | |||
## 2930 582 165 103 61 41 19 14 8 12 14 5 2 3 2 1 1 1 1 1 1 (occurence) | |||
Nous allons maintenant créer les data frames <code>edges</code> et <code>nodes</code> qui contiendront les données nécessaires à la création du réseau. | Nous allons maintenant créer les data frames <code>edges</code> et <code>nodes</code> qui contiendront les données nécessaires à la création du réseau. | ||
Le data frame <code>edges</code> contiendra obligatoirement en première colonne les noeuds 'sources' en deuxième colonne les noeuds 'cibles' (ce qui formera les arêtes/liens). '''Toutes les colonnes supplémentaires seront considérées comme des attributs | Le data frame <code>edges</code> contiendra obligatoirement en première colonne les noeuds 'sources' en deuxième colonne les noeuds 'cibles' (ce qui formera les arêtes/liens). '''Toutes les colonnes supplémentaires (à partir de la troisième colonne) seront considérées comme des attributs, voir plus bas'''. Ici, on extraira de nos données l'attribut de 'poids' qui est le nombre de fois où l'étudiant·e a visualisé l'exercice. | ||
<source> | <source> | ||
Ligne 64 : | Ligne 66 : | ||
weight = data.Problem.View) %>% | weight = data.Problem.View) %>% | ||
filter(weight > 5) | filter(weight > 5) | ||
head(edges) | |||
</source> | </source> | ||
Le data frame <code>nodes_s</code> contiendra la liste de tous les étudiant·e·s. De même, le data frame <code>nodes_p</code> contiendra la liste de tous les exercices. La première colonne contiendra | ## source target weight | ||
## 1 2oNLCndtam EG61 10 | |||
## 2 46z59pQP58 LIT78A 6 | |||
## 3 52vEY7f17k EG58 7 | |||
## 4 8rsfNQdio8 EG63A 6 | |||
## 5 668lBbaKFE EG22 6 | |||
## 6 668lBbaKFE EG44 9 | |||
On voit donc que l'étudiant·e "2oNLCndtam" a regardé l'exercice "EG61" 10 fois. | |||
Le data frame <code>nodes_s</code> contiendra la liste de tous les étudiant·e·s. De même, le data frame <code>nodes_p</code> contiendra la liste de tous les exercices. La première colonne contiendra obligatoirement tous les noeuds. ''Toute colonne supplémentaire (à partir de la deuxième colonne) sera considérée comme un attribut.'' Ici, on y ajoutera en deuxième colonne le 'nom court' des noeuds qui sera montré dans le réseau. | |||
<source> | <source> | ||
Ligne 83 : | Ligne 96 : | ||
nodes <- rbind(nodes_s, nodes_p) %>% | nodes <- rbind(nodes_s, nodes_p) %>% | ||
filter(id %in% edges$source | id %in% edges$target) | filter(id %in% edges$source | id %in% edges$target) | ||
head(nodes) | |||
</source> | </source> | ||
## id name | |||
## 1 2oNLCndtam s3 | |||
## 2 46z59pQP58 s4 | |||
## 3 52vEY7f17k s5 | |||
## 4 8rsfNQdio8 s9 | |||
## 5 668lBbaKFE s23 | |||
## 6 PpTLi2Qz8E s33 | |||
Nous voyons ici le 'nom court' attribué à chaque étudiant·e. | |||
===Création du graphique=== | ===Création du graphique=== | ||
Maintenant que les data frames des noeuds et des arêtes ont été créés, nous allons dresser le graphique correspondant grace à la fonction <code>graph_from_data_frame(d =..., vertices = ..., directed = FALSE</code> qui prend en arguments <code>d = ...</code> le data frame des noeuds (''nodes''), <code>vertices = ...</code> le data frame des arêtes (''edges'') et <code>directed = FALSE</code> pour signifier qu'il n'y a pas de direction entre les noeuds. L'exécution | Maintenant que les data frames des noeuds et des arêtes ont été créés, nous allons dresser le graphique correspondant grace à la fonction <code>graph_from_data_frame(d =..., vertices = ..., directed = FALSE</code> qui prend en arguments <code>d = ...</code> le data frame des noeuds (''nodes''), <code>vertices = ...</code> le data frame des arêtes (''edges'') et <code>directed = FALSE</code> pour signifier qu'il n'y a pas de direction entre les noeuds. L'exécution de la fonction <code>plot()</code> suivant donnera le graphique ci-après : | ||
g <- graph_from_data_frame(d = edges, vertices = nodes, directed = FALSE) | g <- graph_from_data_frame(d = edges, vertices = nodes, directed = FALSE) | ||
Ligne 101 : | Ligne 125 : | ||
Les attributs seront tous les paramètres des noeuds et arêtes qui peuvent être modifiés afin de rendre le réseau plus lisible. Quasiment tout peut être modifié : la taille, la couleur, les labels, etc. On peut aussi les changer selon une condition (par exemple montrer les noms des noeuds seulement lorsqu'ils sont reliés à d'autres noeuds de façon forte). Avant de modifier, voyons quels attributs sont déjà présents dans notre graphique <code>g</code>. | Les attributs seront tous les paramètres des noeuds et arêtes qui peuvent être modifiés afin de rendre le réseau plus lisible. Quasiment tout peut être modifié : la taille, la couleur, les labels, etc. On peut aussi les changer selon une condition (par exemple montrer les noms des noeuds seulement lorsqu'ils sont reliés à d'autres noeuds de façon forte). Avant de modifier, voyons quels attributs sont déjà présents dans notre graphique <code>g</code>. | ||
* <code>E( | * La fonction <code>E()</code> : permet de voir les arêtes/liens (''''E'''dges') du graphique créé <code>g</code>. On peut lui assigner des attributs directement avec <code>$</code> (voir plus bas). | ||
* <code>edges_attr( | * La fonction <code>edges_attr()</code> : permet de voir les ''attributs'' des arêtes (''''E'''dges) du graphique créé <code>g</code>. Si vous exécutez cette commande et avez suivi le tutoriel, vous verrez que <code>$weight</code> est montré : | ||
<source> | |||
$weight | edge_attr(g) | ||
</source> | |||
## $weight | |||
## [1] 10 6 7 6 6 9 (...) | |||
:> il s'agit du nom de la troisième colonne de notre data frame <code>edges</code> ! Voyez-vous le lien ? Je vous explique : la fonction <code>graph_from_data_frame()</code> a traduit la troisième colonne de le data frame <code>edges</code> comme étant un attribut ''weight''. | :> il s'agit du nom de la troisième colonne de notre data frame <code>edges</code> ! Voyez-vous le lien ? Je vous explique : la fonction <code>graph_from_data_frame()</code> a traduit la troisième colonne de le data frame <code>edges</code> comme étant un attribut ''weight''. | ||
* <code>V( | * La fonction <code>V()</code> : permet de voir les noeuds (''''V'''ertices') du graphique créé <code>g</code>. On peut lui assigner des attributs directement avec <code>$</code> (voir plus bas). | ||
* <code>vertex_attr( | * La fonction <code>vertex_attr()</code> : permet de voir les ''attributs'' des noeuds (''''V'''ertices) du graphique créé <code>g</code>. Si vous exécutez cette commande et avez suivi le tutoriel, vous verrez que <code>$name</code> est montré : | ||
<source> | |||
$name | vertex_attr(g) | ||
</source> | |||
## $name | |||
## [1] "s3" "s4" "s5" "s9" "s23" (...) | |||
:> il s'agit du nom de la deuxième colonne de notre data frame <code>nodes</code> ! Voyez-vous le lien (bis) ? La fonction <code>graph_from_data_frame()</code> a traduit la deuxième colonne de le data frame <code>nodes</code> comme étant un attribut ''name''. | :> il s'agit du nom de la deuxième colonne de notre data frame <code>nodes</code> ! Voyez-vous le lien (bis) ? La fonction <code>graph_from_data_frame()</code> a traduit la deuxième colonne de le data frame <code>nodes</code> comme étant un attribut ''name''. | ||
Ligne 170 : | Ligne 200 : | ||
[[Image:networkana_graph5.jpeg]] | [[Image:networkana_graph5.jpeg]] | ||
Nous pouvons maintenant voir les interactions entre étudiant·e·s et exercices assez clairement. | |||
==Types de graphiques== | ==Types de graphiques== | ||
D'autres types de graphiques peuvent être créés, voici une petite liste de ce qui peut se faire : | |||
par(mfrow=c(2, 3), mar=c(0,0,1,0)) | |||
set.seed(42) | |||
plot(g, layout=layout_randomly, main="Aléatoire") | |||
set.seed(42) | |||
plot(g, layout=layout_in_circle, main="Cercle") | |||
set.seed(42) | |||
plot(g, layout=layout_as_star, main="Etoile") | |||
set.seed(42) | |||
plot(g, layout=layout_as_tree, main="Arbre") | |||
set.seed(42) | |||
plot(g, layout=layout_on_grid, main="Grille") | |||
set.seed(42) | |||
plot(g, layout=layout_with_fr, main="Force-directed") # fruchterman-reingold | |||
par(mfrow=c(1,1), mar=c(0,0,0,0)) | |||
La fonction <code>plot()</code> utilise donc par défaut l'algorithme de Fruchterman-Reingold, ce dernier étant le plus communément utilisé, il permet de créer des arêtes de même longueur et se croisent le moins possible. Ainsi, les noeuds sont dispersés de manière uniforme et on peut aussi voir que les noeuds qui partagent les mêmes connexions sont plus proches entre elles (voir https://yunranchen.github.io/intro-net-r/igraph.html#layouts pour d'autres dispositions 'force-directed'). | |||
Un dernier type de graphique qui va être montré ici sera le type 'détection de communauté' (en anglais, ''community detection''). Grace à ce type de graphique, on pourra voir plus précisément les noeuds qui sont densément connectés entre eux (formant des groupes/'communautés'). La fonction <code>cluster_edge_betweenness()</code> va permettre cela : | |||
<source> | |||
cnet <- cluster_edge_betweenness(g) | |||
set.seed(42) | |||
plot(cnet, | |||
g) | |||
</source> | |||
[[Image:networkana_graph6.jpeg]] | |||
Pour d'autres graphiques de ce type, voir https://yunranchen.github.io/intro-net-r/igraph.html#community-detection | |||
==Analyse critique de l'outil== | ==Analyse critique de l'outil== | ||
Ligne 197 : | Ligne 261 : | ||
==Liens== | ==Liens== | ||
* https:// | * '''Base de données''' | ||
::https://pslcdatashop.web.cmu.edu/Files?datasetId=4524 (Base de donnée 'Data Files for KDD Cup 2010' via DataShop) | |||
* '''Tutoriels''' | |||
::http://pablobarbera.com/big-data-upf/html/02a-networks-intro-visualization.html | |||
::https://kateto.net/networks-r-igraph | |||
::https://robwiederstein.github.io/network_analysis/intro.html | |||
::https://www.jessesadler.com/post/network-analysis-with-r/ | |||
::https://www.r-bloggers.com/2021/04/social-network-analysis-in-r/ | |||
::https://yunranchen.github.io/intro-net-r/igraph.html (le plus complet) | |||
----- | ----- | ||
[[Utilisateur:Kenneth Rioja|Kenneth Rioja]] ([[Discussion utilisateur:Kenneth Rioja|discussion]]) | [[Utilisateur:Kenneth Rioja|Kenneth Rioja]] ([[Discussion utilisateur:Kenneth Rioja|discussion]]) 27 mars 2022 à 10:34 (CEST) | ||
[[Catégorie:Analytique et exploration de données]] | [[Catégorie:Analytique et exploration de données]] | ||
[[Catégorie:R]] | [[Catégorie:R]] |
Version du 27 mars 2022 à 09:34
Introduction
L'analyse de réseaux (en anglais, 'network analysis' ou 'NA') est une des approches méthodologiques les plus populaires utilisée en analytique de l'apprentissage (Romero & Ventura, 2020). Poquet et al. (2021) indiquent que l'analyse de réseaux permet la modélisation et l'analyse de données relationnelles en éducation. Un réseau est composé d'un groupe d'entités ou d'éléments appelés noeuds ('nodes') ou sommets ('vertices') et une relation qui les connecte que l'on appelle arêtes ('edge') ou lien ('link'). Ainsi, la visualisation créée via l'analyse de réseaux peut être utile pour cartographier les relations et les interactions, identifier des schémas/patterns d'interaction, identifier les étudiant·e·s actif·ve·s et inactif·ve·s et détecter le rôle de certain·e·s étudiant·e·s ou enseignant·e·s.
Cette page vous montrera un exemple d'analyse de réseaux entre des étudiant·e·s et leur nombre de visualisation à un exercice. Nous verrons donc quels sont les exercices qui sont le plus visualisés et les liens entre les exercices les plus fréquemment visualisés. De plus, nous aurons aussi une cartographie des étudiant·e·s qui ont besoin de visualiser certains exercices plus que d'autres.
Nous allons utiliser la librairie igraph
, librairie la plus accessible pour certain·e·s et la plus téléchargée (voir Figure 1.2 dans https://robwiederstein.github.io/network_analysis/intro.html).
Préparation des données
Téléchargement des données sur votre ordinateur
Les données utilisées proviennent du set 'Data Files for KDD Cup 2010' en accès libre sur DataShop (https://pslcdatashop.web.cmu.edu/Files?datasetId=4524)). Une fois connecté·e à DataShop, téléchargez les données "Algebra I 2005-2006, A development data set; 575 students, 813,661 steps". Décompressez le zip et créez un fichier .R dans le dossier fraichement décompressé 'algebra_2005_2006'.
Importer les données dans RStudio
Ouvrez RStudio et exécutez le code ci-dessous :
rm(list=ls()) # effacer l'environnement
# install.packages("pacman") # à exécuter si pas déjà installé
library(pacman)
pacman::p_load(igraph, # bibliothèques utilisées
dplyr
)
setwd(dirname(rstudioapi::getSourceEditorContext()$path)) # définir le répertoire de travail au répertoire actuel (./algebra_2005_2006/)
data <- read.table("algebra_2005_2006_master.txt", sep="\t", header = T) # importer les données
Vous devez maintenant avoir dans votre environnement le data frame 'data' avec 3967 obs. de 19 variables
str(data)
## 'data.frame': 3967 obs. of 19 variables:
Préparation des 'egdes' et 'nodes'
La première étape afin de créer le réseau est de déterminer la liste des arêtes ('edges') et des noeuds ('nodes'). De ce fait, les colonnes/variables qui vont nous intéresser sont :
Anon.Student.Id
: Identifiant (id) de l'étudiant·e, qui servira de noeud (node) = la sourceProblem.Name
: Nom de l'exercice, qui servira de noeud (node) = la cibleProblem.View
: Nombre de fois où l'exercice a été visualisé, qui servira de poids (weight) dans les liens entre les différents noeuds (étudiant·e - exercice).
Afin de limiter notre visualisation à un nombre restreint de noeuds et ne pas voir l'intégralité des exercices visualisés par les 575 étudiant·e·s de notre jeu de données, nous allons nous intéresser seulement aux exercices qui ont été visualisés plus de 5 fois.
table(data$Problem.View)
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 28 (nombre de visualisation d'un exercice) ## 2930 582 165 103 61 41 19 14 8 12 14 5 2 3 2 1 1 1 1 1 1 (occurence)
Nous allons maintenant créer les data frames edges
et nodes
qui contiendront les données nécessaires à la création du réseau.
Le data frame edges
contiendra obligatoirement en première colonne les noeuds 'sources' en deuxième colonne les noeuds 'cibles' (ce qui formera les arêtes/liens). Toutes les colonnes supplémentaires (à partir de la troisième colonne) seront considérées comme des attributs, voir plus bas. Ici, on extraira de nos données l'attribut de 'poids' qui est le nombre de fois où l'étudiant·e a visualisé l'exercice.
edges <- data.frame(data$Anon.Student.Id, data$Problem.Name, data$Problem.View) %>%
rename(source = data.Anon.Student.Id,
target = data.Problem.Name,
weight = data.Problem.View) %>%
filter(weight > 5)
head(edges)
## source target weight ## 1 2oNLCndtam EG61 10 ## 2 46z59pQP58 LIT78A 6 ## 3 52vEY7f17k EG58 7 ## 4 8rsfNQdio8 EG63A 6 ## 5 668lBbaKFE EG22 6 ## 6 668lBbaKFE EG44 9
On voit donc que l'étudiant·e "2oNLCndtam" a regardé l'exercice "EG61" 10 fois.
Le data frame nodes_s
contiendra la liste de tous les étudiant·e·s. De même, le data frame nodes_p
contiendra la liste de tous les exercices. La première colonne contiendra obligatoirement tous les noeuds. Toute colonne supplémentaire (à partir de la deuxième colonne) sera considérée comme un attribut. Ici, on y ajoutera en deuxième colonne le 'nom court' des noeuds qui sera montré dans le réseau.
nodes_s <- data.frame(unique(data$Anon.Student.Id)) %>%
mutate("name" = paste0("s", row.names(.))) %>%
rename(id = unique.data.Anon.Student.Id.)
nodes_p <- data.frame(unique(data$Problem.Name)) %>%
mutate("name" = paste0("p", row.names(.))) %>%
rename(id = unique.data.Problem.Name.)
Le data frame nodes
réunit les deux data frames créés précédemment tout en gardant les noeuds filtrés dans le data frame edges
.
nodes <- rbind(nodes_s, nodes_p) %>%
filter(id %in% edges$source | id %in% edges$target)
head(nodes)
## id name ## 1 2oNLCndtam s3 ## 2 46z59pQP58 s4 ## 3 52vEY7f17k s5 ## 4 8rsfNQdio8 s9 ## 5 668lBbaKFE s23 ## 6 PpTLi2Qz8E s33
Nous voyons ici le 'nom court' attribué à chaque étudiant·e.
Création du graphique
Maintenant que les data frames des noeuds et des arêtes ont été créés, nous allons dresser le graphique correspondant grace à la fonction graph_from_data_frame(d =..., vertices = ..., directed = FALSE
qui prend en arguments d = ...
le data frame des noeuds (nodes), vertices = ...
le data frame des arêtes (edges) et directed = FALSE
pour signifier qu'il n'y a pas de direction entre les noeuds. L'exécution de la fonction plot()
suivant donnera le graphique ci-après :
g <- graph_from_data_frame(d = edges, vertices = nodes, directed = FALSE) set.seed(42) plot(g)
"Pas très joli", vous allez me dire. En effet, faisons en sorte de le rendre plus lisible grace aux fameux attributs.
Visualisation des attributs
Les attributs seront tous les paramètres des noeuds et arêtes qui peuvent être modifiés afin de rendre le réseau plus lisible. Quasiment tout peut être modifié : la taille, la couleur, les labels, etc. On peut aussi les changer selon une condition (par exemple montrer les noms des noeuds seulement lorsqu'ils sont reliés à d'autres noeuds de façon forte). Avant de modifier, voyons quels attributs sont déjà présents dans notre graphique g
.
- La fonction
E()
: permet de voir les arêtes/liens ('Edges') du graphique créég
. On peut lui assigner des attributs directement avec$
(voir plus bas).
- La fonction
edges_attr()
: permet de voir les attributs des arêtes ('Edges) du graphique créég
. Si vous exécutez cette commande et avez suivi le tutoriel, vous verrez que$weight
est montré :
edge_attr(g)
## $weight ## [1] 10 6 7 6 6 9 (...)
- > il s'agit du nom de la troisième colonne de notre data frame
edges
! Voyez-vous le lien ? Je vous explique : la fonctiongraph_from_data_frame()
a traduit la troisième colonne de le data frameedges
comme étant un attribut weight.
- La fonction
V()
: permet de voir les noeuds ('Vertices') du graphique créég
. On peut lui assigner des attributs directement avec$
(voir plus bas).
- La fonction
vertex_attr()
: permet de voir les attributs des noeuds ('Vertices) du graphique créég
. Si vous exécutez cette commande et avez suivi le tutoriel, vous verrez que$name
est montré :
vertex_attr(g)
## $name ## [1] "s3" "s4" "s5" "s9" "s23" (...)
- > il s'agit du nom de la deuxième colonne de notre data frame
nodes
! Voyez-vous le lien (bis) ? La fonctiongraph_from_data_frame()
a traduit la deuxième colonne de le data framenodes
comme étant un attribut name.
Modification des attributs
Je ne présente ici que quelques exemples de modifications d'attributs, il bien d'autres façons de modifier son graphique et là est la force de R !
$width
Vous pouvez ajouter un attribut à E(g)
comme si c'était un data frame. Ici, $weight
est un attribut que l'on avait déjà avant et on crée à présent width
comme étant le log()+1 de la weight (rappel : nombre de visualisation d'un exercice pour chaque étudiant·e - exercice)
E(g)$width <- log(E(g)$weight) + 1 set.seed(42) plot(g)
$size
Pour les noeuds, pensez bien à la commande V(g)
. strength(g)
est la somme des visualisations (weight) par node.
V(g)$size <- log(strength(g)) * 4 set.seed(42) plot(g)
$label + ifelse
Nous allons émettre une condition ifelse
et l'attribuer au $label
des noeuds. Si la somme des visualisations par noeud est supérieure à 25 alors on garde le nom du noeud, sinon on ne l'affiche pas.
V(g)$label <- ifelse(strength(g) >= 25, V(g)$name, NA) # show name only when strength >= 75 set.seed(42) plot(g)
Ça commence a être mieux, voyez l'utilité d'assigner un nom court aux noeuds.
$color + %in%
Nous allons attribuer la couleur rouge aux noeuds montrant les étudiant·e·s et la couleur dorée aux noeuds des exercices. En créant la liste des étudiant·e·s et la liste des exercices, il suffit d'assigner à V(g)$color
la couleur correspondante, suivant si le nom se trouve dans la liste etudiant ou exercice.
etudiant <- nodes_s$name exercice <- nodes_p$name V(g)$color <- NA V(g)$color[V(g)$name %in% etudiant] <- "red" V(g)$color[V(g)$name %in% exercice] <- "gold" set.seed(42) plot(g)
Nous pouvons maintenant voir les interactions entre étudiant·e·s et exercices assez clairement.
Types de graphiques
D'autres types de graphiques peuvent être créés, voici une petite liste de ce qui peut se faire :
par(mfrow=c(2, 3), mar=c(0,0,1,0)) set.seed(42) plot(g, layout=layout_randomly, main="Aléatoire") set.seed(42) plot(g, layout=layout_in_circle, main="Cercle") set.seed(42) plot(g, layout=layout_as_star, main="Etoile") set.seed(42) plot(g, layout=layout_as_tree, main="Arbre") set.seed(42) plot(g, layout=layout_on_grid, main="Grille") set.seed(42) plot(g, layout=layout_with_fr, main="Force-directed") # fruchterman-reingold par(mfrow=c(1,1), mar=c(0,0,0,0))
La fonction plot()
utilise donc par défaut l'algorithme de Fruchterman-Reingold, ce dernier étant le plus communément utilisé, il permet de créer des arêtes de même longueur et se croisent le moins possible. Ainsi, les noeuds sont dispersés de manière uniforme et on peut aussi voir que les noeuds qui partagent les mêmes connexions sont plus proches entre elles (voir https://yunranchen.github.io/intro-net-r/igraph.html#layouts pour d'autres dispositions 'force-directed').
Un dernier type de graphique qui va être montré ici sera le type 'détection de communauté' (en anglais, community detection). Grace à ce type de graphique, on pourra voir plus précisément les noeuds qui sont densément connectés entre eux (formant des groupes/'communautés'). La fonction cluster_edge_betweenness()
va permettre cela :
cnet <- cluster_edge_betweenness(g)
set.seed(42)
plot(cnet,
g)
Pour d'autres graphiques de ce type, voir https://yunranchen.github.io/intro-net-r/igraph.html#community-detection
Analyse critique de l'outil
Comme le disent Poquet et al. (2021), la construction d'un réseau dépend des choix faits par les chercheur·euse·s, en outre les choix de ce qui est étudié (noeuds), quelles interactions vont être choisies (liens) et la façon dont laquelle la force entre les liens doit être considérée (poids). Ces choix influencent la façon dont le réseau est construit et impactent indirectement l'interprétation du/de la chercheur·euse.
Recommandations pour les études utilisant cet outil
Voir Poquet et al. (2021) :
- Quels sont les noeuds (nodes) et leur pertinence face au contexte, à la théorie, ou la question de recherche?
- Quels sont les liens (edges), et que représentent-ils?
Références
Koedinger, K.R., Baker, R.S.J.d., Cunningham, K., Skogsholm, A., Leber, B., Stamper, J. (2010) A Data Repository for the EDM community: The PSLC DataShop. In Romero, C., Ventura, S., Pechenizkiy, M., Baker, R.S.J.d. (Eds.) Handbook of Educational Data Mining. Boca Raton, FL: CRC Press.
Poquet, O., Saqr, M., & Chen, B. (2021). Recommendations for network research in learning analytics: 2021 NetSciLA Workshop “Using Network Science in Learning Analytics: Building Bridges towards a Common Agenda”, NetSciLA 2021. CEUR Workshop Proceedings, 2868, 34–41.
Romero, C., & Ventura, S. (2020). Educational data mining and learning analytics: An updated survey. Wiley Interdisciplinary Reviews-Data Mining and Knowledge Discovery, 10(3). https://doi.org/10.1002/widm.1355
Saqr, M., & Alamro, A. (2019). The role of social network analysis as a learning analytics tool in online problem based learning. BMC medical education, 19(1), 160. https://doi.org/10.1186/s12909-019-1599-6
Liens
- Base de données
- https://pslcdatashop.web.cmu.edu/Files?datasetId=4524 (Base de donnée 'Data Files for KDD Cup 2010' via DataShop)
- Tutoriels
- https://yunranchen.github.io/intro-net-r/igraph.html (le plus complet)
Kenneth Rioja (discussion) 27 mars 2022 à 10:34 (CEST)