Chapitre 2 : Préparer le corpus

93821899_5446eed3ef_b

 

Dans ce premier chapitre, nous nous intéressons uniquement aux mots, et non aux phrases ou aux n-grams. On peut utiliser les mêmes outils dans ces cas de figure.

1 la construction d’un corpus avec tm

Un corpus pour tm est un format de fichier particuliers. La première étape consiste à le créer à partir du vecteur de texte ( pratiquement un fichier à une colonne et autant de lignes que d’unités de textes.

tweets_corpus <- Corpus(VectorSource(tweets_text))

Les fonctions de  tm vont nous permettre de nettoyer le texte, c’est à dire  :

  • Suppression des nombres qui n’apportent pas d’information
  • Suppression de la ponctuation
  • Mise en minuscule de tous les mots pour homogénéiser la morphologie.
  • Suppression des stop words ( articles, pronoms, conjonctions…)
  • Élimination des espaces excédentaire ( un espace marque deux mots distincts)
  • Suppression de mots particuliers ( ici ceux qui ont serti à la sélection du corpus)
  • Lemmatisation pour réduire à une racine unique l’ensemble des termes.
tweets_corpus <- tm_map(tweets_corpus, removeNumbers) #enlever les nombre
tweets_corpus <- tm_map(tweets_corpus, removePunctuation) # ici cela va supprimer automatiquement tous les caractères de ponctuation
tweets_corpus <- tm_map(tweets_corpus, content_transformer(tolower)) #mettre en minuscule
tweets_corpus <- tm_map(tweets_corpus, removeWords, stopwords("french")) # ici cela va supprimer automatiquement une bonne partie des mots français "basiques", tels que "le", "la", etc. mais il en manque ! Il manque par exemple "les"...
tweets_corpus <- tm_map(tweets_corpus, stripWhitespace) # ici cela va supprimer automatiquement tous les espaces vides
tweets_corpus <- tm_map(tweets_corpus, removeWords,c("IA","AI", "artificiel","intelligence","artificalintelligent","artificiel","artificial","ml", "deeplearning")) #enelver le terme commun
tweets_corpus <- tm_map(tweets_corpus, stemDocument, language = "french") #on cherche les radicaux des termes

Une spécificité des tweet est de contenir souvent des mentions caractérisé par le préfixe @ et des liens par http, l’utilisation de fonctions permet de résoudre ce problème. En voici un exemple pour chacun des cas :

removeURL <- function(x) gsub("http[[:alnum:][:punct:]]*", "", x) #enlever les liens
tweets_corpus <- tm_map(tweets_corpus, content_transformer(removeURL)) #enlever les liens

removeACC <- function(x) gsub("@\\w+", "", tweets_corpus) #enlever les comptes
tweets_corpus <- tm_map(tweets_corpus, content_transformer(removeACC)) #enlever les comptes

Le nettoyage étant fait ne reste plus qu’à créer le tableau que nous allons analyser où les lignes sont les termes et les colonnes les documents ( unités de texte) avec la fonction TermDocumentMatrix. Dans l’exemple un controle est appliqué : ne sont retenu que les mots de 2 à 30 caractères.

tdm <- TermDocumentMatrix(tweets_corpus, control=list(wordLengths=c(2, 30)))

si besoin on peut créer le symétrique : un DocumentTermMatrix (dtm)

 

2 La même chose avec Tidyverse

Tidyverse est une alternative plus moderne qui permet de mettre en place des pipes efficaces avec l’opérateur %>% et les verbes de dplyr .

La première étape est d’importer le corpus dans R. Dans notre cas, notre corpus est composé de 102 articles au format .txt se trouvant dans un même fichier. Le nom des documents est leur date de publication. Nous allons récupérer ces textes dans un tableau et y accoler leurs noms ainsi que l’année de publication (qui correspondent aux 4 premiers caractères du nom de l’article) :

setwd("~/Thèse/Airbnb/airbnb/airbnbcitizen")
tbl % 
  map_chr(~ read_file(.)) %>% 
  data_frame(text = .)%>%
 mutate(year=substr(list.files(pattern = "*.txt"), start=1, stop=4))%>%
  mutate(doc=(list.files(pattern = "*.txt")))%>%
 group_by(doc,year) %>%
  ungroup()
tbl
## # A tibble: 102 x 3
##    text                                                        year  doc  
##                                                            
##  1 "\r\nAirbnb Citizen\r\nSeptember 9th, 2013\r\nBerlin and t~ 2013  2013~
##  2 "\r\nAirbnb Citizen\r\nJune 12th, 2013\r\nContributing to ~ 2013  2013~
##  3 "\r\nAirbnb Citizen\r\nOctober 21st, 2013\r\nNews from the~ 2013  2013~
##  4 "\r\nAirbnb Citizen\r\nFebruary 13th, 2014\r\nAirbnb and h~ 2014  2014~
##  5 "\r\nAirbnb Citizen\r\nApril 21st, 2014\r\nNew York and th~ 2014  2014~
##  6 "\r\nAirbnb Citizen\r\nApril 22nd, 2014\r\nStatement on He~ 2014  2014~
##  7 "\r\nAirbnb Citizen\r\nMarch 25th, 2014\r\nAirbnb economic~ 2014  2014~
##  8 "\r\nAirbnb Citizen\r\nMarch 25th, 2014\r\nAirbnb economic~ 2014  2014~
##  9 "\r\nAirbnb Citizen\r\nMarch 26th, 2014\r\nA major step fo~ 2014  2014~
## 10 "\r\nAirbnb Citizen\r\nSeptember 1st, 2015\r\nOscar\x92s N~ 2015  2015~
## # ... with 92 more rows

Nous allons maintenant découper les textes selon les mots employés :

tbl%
  unnest_tokens(word, text)
tbl
## # A tibble: 54,600 x 3
##    year  doc          word     
##                 
##  1 2013  20130909.txt airbnb   
##  2 2013  20130909.txt citizen  
##  3 2013  20130909.txt september
##  4 2013  20130909.txt 9th      
##  5 2013  20130909.txt 2013     
##  6 2013  20130909.txt berlin   
##  7 2013  20130909.txt and      
##  8 2013  20130909.txt the      
##  9 2013  20130909.txt airbnb   
## 10 2013  20130909.txt community
## # ... with 54,590 more rows

Nous pouvons tout de suite regarder quels sont les mots les plus fréquents :

tbl %>%
  count(word, sort = TRUE)
## # A tibble: 5,267 x 2
##    word       n
##      
##  1 the     2514
##  2 to      1863
##  3 and     1754
##  4 in      1537
##  5 of      1306
##  6 airbnb  1115
##  7 a        846
##  8 for      652
##  9 we       643
## 10 that     485
## # ... with 5,257 more rows

Nous constatons que les mots les plus fréquents dans les différents articles correspondent à des mots vides, qui n’apportent pas de sens particulier mais qui servent à structurer le texte. Nous pouvons supprimer ces mots vides ( appelé aussi stopwords).

De plus, nous observons que Airbnb est très présent, ce qui est normal vu qu’il s’agit d’un corpus de textes issus d’Airbnb. Nous pouvons également supprimer ce mot du corpus sans perdre de sens. Nous allons faire de même avec le terme citizen, puisque ce mot est associé à Airbnb pour désigner le site duquel sont extraits les textes. Pour cela, nous allons ajouter ces deux termes à la liste des mots vides à supprimer, puis nous allons nettoyer le corpus :

custom_stop_words <- bind_rows(data_frame(word = c("airbnb","citizen"), 
                                          lexicon = c("custom")), 
                               stop_words)
tbl%
  anti_join(custom_stop_words)
## Joining, by = "word"
tbl %>%
  count(word, sort = TRUE)
## # A tibble: 4,767 x 2
##    word          n
##         
##  1 home        470
##  2 hosts       434
##  3 sharing     400
##  4 community   292
##  5 city        265
##  6 paris       263
##  7 guests      259
##  8 cities      251
##  9 people      210
## 10 local       207
## # ... with 4,757 more row

3 Méthodes plus élaborées

Les textes sont de nature bien différentes : un corpus de lettres manuscrites, des abstracts d’une revue scientifique, de la littérature éditées, des pages webs corporate. Chaque situation présente des spécificité importante. Quand il n’y a pas eu de travail d’édition, coquille et fautes d’orthographe ajoutent du bruit, quand le texte est élaboré il peut être intéressant de se concentrer sur certains aspects de la langue (quels objets, quels qualificatifs, quels verbes). L’écriture numérique utilisent largement d’autres marqueurs : emoji notamment.

3.1 la correction d’orthographe

Dans le cas où le texte est tapuscrit (par exemple une question ouvertes dans un questionnaire web), une correction d’orthographe pour homogénéiser la morphologie du lexique est nécessaire.

3.1 traitement des émoticon

Les emoticon fréquent dans les réseaux sociaux, peuvent être naturellement être traité comme des chaines de caractères à part entière. On en trouvera un exemple ici : http://opiateforthemass.es/articles/emoticons-in-R/

( au juste pour les enlever avec tm :

gsub("[^\x01-\x7F]", "", Texts)

3.2 POS tagging

Le traitement lexical esquissé au dessus se limite à filtrer parmi les mots ceux qui contribuent à la production de sens, et se réduit à l’analyse lexicale. Il peut être intéressant de les coder en fonction de leur nature afin de distinguer au moins les verbes, les substantifs  ou les qualificatifs.

Ce type de méthodes est appelée Part Of Speech Tagging.  Un certain nombre de ressources disponibles sur r pour cette tâche sont disponibles ici.

Publicités