Réseaux en Méta-analyse
en langage R
L'essentiel de cette page
Cette page explique comment analyser automatiquement des notions pour les racorder sous la forme d'un réseau de relations.
1- Charger (et installer si nécessaire) toutes les librairies nécessaires
install.packages("readtext")
install.packages("quanteda")
install.packages("quanteda.textmodels")
install.packages("quanteda.textstats")
install.packages("quanteda.textplots")
library("readtext") # Ouverture de plusieurs documents de tous les types
library(quanteda) # textmining
quanteda_options(language_stemmer = "french")
library(quanteda.textmodels) # A installer si nécessaire.
library("quanteda.textstats")
library("quanteda.textplots")
library(igraph)
2- Ouvrir toutes les publications collectées dans un dossier
On peut télécharger un grand nombre de publications scientifiques au format pdf à partir de google scholar ou de pubmed. Le mieux est d'avoir un abonnement, plutôt que d'utiliser des cites légaux comme Scihub en s'y connectant avec VPN !
# A remplacer par l'adresse deson dossier
setwd("G:/statistiques/Textuel/Platanus/publi")
P <- readtext("*",encoding ="UTF-8")
P$text
mon_corpus <- corpus(P$text)
3- Transformer l'ensemble en corpus
Chaque publication doit être coupée phrase par phrase afin qu'on analyse les mots qui se retrouvent dans la même phrase :
mon_corpus <- corpus_segment(mon_corpus, "\\.\\s[A-Z]", extract_pattern = FALSE)
4- Nettoyer le corpus
library(textclean)
corpus<- replace_symbol(mon_corpus)
corpus<- replace_non_ascii(corpus,replacement="")
corpus<- strip(corpus, char.keep = "~~", digit.remove = TRUE, apostrophe.remove = F)
mes_caracteres <- table(unlist(strsplit (corpus,"")))
print(mes_caracteres)
uniq_car <- names(mes_caracteres) # pour afficher tous les types de caracteres
print(uniq_car)
library("stringr")
corpus <- str_replace_all(corpus,uniq_car[1], " ")
5- Tokeniser (découper les phrases mots par mots)
toks_news <- tokens(corpus,remove_punct=T,remove_numbers=F) %>%
tokens_remove(., pattern = stopwords('fr'), valuetype = 'fixed') %>% tokens_tolower(., keep_acronyms = FALSE)
6- Ouvrir un dictionnaire de correspondance pour lister les synonymes d'un termes
library("openxlsx")
dico_perso <- read.xlsx(file.choose())
#dico_perso<- data.frame(lapply(dico_perso, function(x) {gsub(" ", "", x)}))
# Initialisation d'une liste vide
liste <- list()
# Construction de la liste avec les termes du
for(i in 1:nrow(dico_perso)){
# data.fr[i,1] = item; #str_split decompose la seconde col.
#model <- str_replace_all(dico_perso[i,2]," ","")
model <- dico_perso[i,2]
liste[dico_perso[i,1]] <- str_split(model, pattern=',')
}
liste
dic <- dictionary(liste)
Ce dictionnaire collecte tous les gènes, protéines et termes en lien avec le sujet du chancre coloré qui extermine le platane oriental (et occidental).
Une colonne pour le nom principal et une colonne Synonyme.
En bonus, on peut demander à chatgpt implémanté dans R de scanner l'ensemble des publications pour enrichir lui-même le dictionnaire (à sauvegarder à la fin avec write.xlsx() de {openxlsx}.
commande_de_base <- "J'ai un dictionnaire R (object dic) dont voici le contenu. Il contient des noms et d'éventuels synonymes (tenant compte aussi des variants liés aux pluriels ou accents). Lis le texte qui suit et produit un code R qui permettrait de mettre à jour mon dictionnaire dic en y ajoutant le vocabulaire qui te semble représentatif de ce sujet scientifique (ou en mettant éventuellement à jour les synonymes de l'ensemble des mots de dic). Attention, donne une réponse la plus simple possible, uniquement un seul bloc de code R entre des bornes ```"
library(chatgpt) # Attention, il faut aller chercher la commande exec_chatgpt_code et charger son API
tokens <- 5000
for (i in 1:length(corpus)) {
print(i)
taille <- nchar(corpus[i])
# Si mon corpus est trop grand, il va falloir le traiter par paquets
if (taille>tokens ) {
print("Traitement par paquets, trop de tokens")
diviseur <- nchar(corpus[i])%/%5000+1
for (j in 1:diviseur) {
#consigne <- paste(commande_de_base,paste(capture.output(print(dic)),collapse=" "))
consigne <-paste(commande_de_base,paste(capture.output(print(data.frame(t(unlist(dic))))),collapse=" "))
consigne <- paste(consigne," et un morceau de la publication à traiter :")
consigne <- paste(consigne, substr(corpus[i], j*tokens -(tokens -1), j*tokens ))
generated_text <- ask_chatgpt(consigne)
exec_chatgpt_code(generated_text) # Mise à jour du dictionnaire - commande à télécharger
reset_chat_session(system_role = "You are a R coder.")
}
} else {
consigne <-paste(commande_de_base,paste(capture.output(print(data.frame(t(unlist(dic))))),collapse=" "))
consigne <- paste(consigne," et un morceau de la publication à traiter :")
consigne <- paste(consigne, corpus[i])
generated_text <- ask_chatgpt(consigne)
exec_chatgpt_code(generated_text)
reset_chat_session(system_role = "You are a R coder.")
}
}
dic <- dictionary(dic)
7- Nettoyer le token pour remplacer les synonymes par le terme de base
toks_news <- tokens_lookup(toks_news, dic, exclusive=T, levels=1:2, nomatch = "_UNMATCHED")
8- Mise du token en DFM (Matrice d'occurences)
my_dfm<- dfm(toks_news)
9- Générer une matrice de cooccurrences
mywd <- dico_perso[,1] ; nperso <- length(mywd)
mymat <- fcm(toks_news, context = "window", count = "weighted", window = 12,
, ordered = TRUE, tri = FALSE)
positionr <- na.omit(match(mywd,rownames(mymat)))
positionc <- na.omit(match(mywd,colnames(mymat)))
matx <- mymat[positionr, positionc]
nrow(matx) ; matx
10- Afficher le réseau correspondant au sujet
Le code ci-dessous permet de construire le réseau suivant et de comprendre quels groupes de gènes sont liés dans la mise en place de la maladie du chancre colorée par Ceratocystis platani chez le platane.
net <- graph_from_adjacency_matrix(matx, weighted=T)
net <- simplify(net, remove.multiple = T, remove.loops = TRUE) # élaguer les liens redondants
E(net)$arrow.size <- 0 # Exemple de sauvegarde d'un paramètre qu'on aurait plus ainsi à mettre dans comme paramètre de plot comme c'est le cas ci-dessous...
E(net)$edge.color <- "black"
# Afficher le tout en tenant compte avec betweenness du poids relatifs d'un mot pour lui donner une taille
plot(net ,vertex.size=sqrt(betweenness(net))+10,vertex.color="green",
edge.arrow.size =0,arrow.mode=0,edge.color="black")
#
clp <- cluster_optimal(net)
class(clp)
#
l <- layout_with_fr(net)
plot(clp, net, layout = l, vertex.size=sqrt(betweenness(net))+15)