Travailler avec des textes:

Partie 4: Visualisation


L. Vaudor, ISIG, UMR 5600-EVS

Rencontres R 2018

Tables lexicales, occurrences, co-occurrences

Avant de réaliser quelques graphiques pour montrer le contenu lexical de nos textes il faudra la plupart du temps quelques calculs basiques sur nos données (par exemple agréger les données pour obtenir les fréquences d’occurrence des termes).

Pour réaliser ces quelques transformations on peut généralement utiliser les fonctions de dplyr

Ici, on repart du tableau suivant

tib_mots_nonvides <- read_csv("data/tib_mots_nonvides.csv") %>% 
  na.omit()
head(tib_mots_nonvides)
## # A tibble: 6 x 4
##   doc                      auteur                mot     lemme  
##   <chr>                    <chr>                 <chr>   <chr>  
## 1 data/blog_de_ginette.htm Emma, 22 ans, Limoges poule   poule  
## 2 data/blog_de_ginette.htm Emma, 22 ans, Limoges mur     mur    
## 3 data/blog_de_ginette.htm Emma, 22 ans, Limoges pain    pain   
## 4 data/blog_de_ginette.htm Emma, 22 ans, Limoges dur     dur    
## 5 data/blog_de_ginette.htm Emma, 22 ans, Limoges nourrir nourrir
## 6 data/blog_de_ginette.htm Emma, 22 ans, Limoges petits  petit

On pourrait être amené à

Fréquences d’occurrence

freq_mots <- tib_mots_nonvides %>%
  group_by(lemme) %>% 
  summarise(freq=n()) %>% 
  arrange(desc(freq)) %>% 
  na.omit()
head(freq_mots)
## # A tibble: 6 x 2
##   lemme   freq
##   <chr>  <int>
## 1 canard     5
## 2 thon       5
## 3 cochon     4
## 4 danser     4
## 5 petit      4
## 6 chat       3

Ici, je n’en ai pas besoin (mon jeu de données est tout petit) mais je pourrais également filtrer les données pour ne garder qu’une fréquence minimale, ou ne garder que les \(n\) mots les plus fréquents…

freq_mots %>%
  filter(freq>=5)
## # A tibble: 2 x 2
##   lemme   freq
##   <chr>  <int>
## 1 canard     5
## 2 thon       5
freq_mots %>% top_n(3,freq)
## # A tibble: 5 x 2
##   lemme   freq
##   <chr>  <int>
## 1 canard     5
## 2 thon       5
## 3 cochon     4
## 4 danser     4
## 5 petit      4

Nuage de mots

Le nuage de mots constitue sans doute l’une des représentations les plus classiques pour ce genre de table lexicale…

On le réalise ici avec le package wordcloud (et sa fonction wordcloud())

library(wordcloud)
wordcloud(freq_mots$lemme,
          freq_mots$freq,
          min.freq=1)

Diagramme en bâtons

ggplot(filter(freq_mots,freq>1), 
       aes(x=lemme, y=freq)) +
  geom_bar(stat="identity", fill="skyblue")+
  coord_flip()

ggplot(filter(freq_mots,freq>1),
       aes(x=forcats::fct_reorder(lemme,freq), y=freq)) +
  geom_bar(stat="identity", fill="skyblue")+
  coord_flip()

Diagramme en bâtons

freq_mots <- tib_mots_nonvides %>%
  group_by(doc,lemme) %>% 
  summarise(freq=n()) %>% 
  arrange(desc(freq)) %>% 
  na.omit()
head(freq_mots)
## # A tibble: 6 x 3
## # Groups:   doc [3]
##   doc                        lemme   freq
##   <chr>                      <chr>  <int>
## 1 data/blog_de_jean-marc.htm thon       5
## 2 data/blog_de_ginette.htm   cochon     3
## 3 data/blog_de_norbert.htm   danser     3
## 4 data/blog_de_ginette.htm   petit      2
## 5 data/blog_de_ginette.htm   poule      2
## 6 data/blog_de_jean-marc.htm canard     2
ggplot(freq_mots,
       aes(x=forcats::fct_reorder2(lemme,doc,freq), y=freq)) +
  geom_bar(stat="identity", aes(fill=doc))+
  facet_grid(.~doc)+
  coord_flip()

Co-occurrences

Si l’on s’intéresse non plus seulement à la fréquence individuelle des termes mais qu’on cherche à caractériser les termes qui sont souvent employés ensemble (au sein d’un même commentaire par exemple) on peut utiliser les fonctions du package widyr.

library(widyr)
mots_cooc <- tib_mots_nonvides %>%
  pairwise_count(lemme,feature=auteur,sort=TRUE) 

head(mots_cooc)
## # A tibble: 6 x 3
##   item1  item2      n
##   <chr>  <chr>  <dbl>
## 1 cochon petit   3.00
## 2 petit  cochon  3.00
## 3 petit  poule   2.00
## 4 cochon poule   2.00
## 5 canard poule   2.00
## 6 poule  petit   2.00

Corrélations

motA:T motA:F Total
motB:T \(N_{TT}\) \(N_{TF}\) \(N_{T.}\)
motB:F \(N_{FT}\) \(N_{FF}\) \(N_{F.}\)
Total \(N_{.T}\) \(N_{.F}\) N

\[Cor=\frac{N_{TT}N_{FF}-N_{TF}N_{FT}}{\sqrt{N_{T.}N_{F.}N_{.F}N_{.T}}}\]

mots_cors <- tib_mots_nonvides %>% 
  pairwise_cor(lemme,auteur,sort=TRUE)
head(mots_cors)
## # A tibble: 6 x 3
##   item1   item2 correlation
##   <chr>   <chr>       <dbl>
## 1 pain    mur          1.00
## 2 dur     mur          1.00
## 3 nourrir mur          1.00
## 4 mur     pain         1.00
## 5 dur     pain         1.00
## 6 nourrir pain         1.00

Pour la suite on va joindre les tableaux mots_cooc et mot_cors

mots_cooc <- left_join(mots_cooc,
                       mots_cors,
                       by=c("item1","item2"))

Graphes

On souhaite maintenant représenter les relations entre les mots par un graphe (le lien est défini par la co-occurrence des mots dans un même commentaire). On va pour ce faire créer un graphe à partir du tableau mots_cooc.

library(igraph)
mots_graph <- graph_from_data_frame(mots_cooc)
class(mots_graph)
## [1] "igraph"

Un graphe se caractérise par

Représentation du graphe

Maintenant que l’objet de classe “graph” est créé, on va le représenter. Il faut pour cela calculer un “layout” des différents noeuds du graphe puis spécifier ce qu’on veut faire apparaître graphiquement à travers les commandes du package ggraph dont la logique est proche de celle de ggplot2.

library(ggraph)
my_graph <- mots_graph %>%
   ggraph(layout = "fr") +
   geom_edge_link(edge_colour="steelblue") +
   geom_node_point(color = "khaki1", size = 5) +
   geom_node_text(aes(label = name), repel = TRUE) +
   theme_void()
plot(my_graph)