Skip to content

Commit 164fa68

Browse files
linogalianaantukigithub-actions[bot]root
authored
Travail partie NLP (#328)
* Relec ka 2711 (début NLP) (#327) * descriptif NLP * 01_intro * 02_exoclean * dev * Automated changes * Automated changes * uo * wordcloud * Automated changes * Automated changes * ddd * Automated changes * Automated changes * spacyu * fini chap 1 * relevanc * reoordonne * Automated changes * Automated changes * Automated changes * Automated changes * exo 2 start * Add files via upload * word * spooky * Automated changes * Automated changes * Automated changes * Automated changes * horror * Automated changes * Automated changes * update * Automated changes * Automated changes * box * evol * index * fear * refs * Automated changes * Automated changes * corrige erreur * Automated changes * Automated changes * petit mot * Automated changes * Automated changes * dd * Automated changes * Automated changes * dd * Automated changes * Automated changes Co-authored-by: Kim A <kim.antunez@ensae.fr> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: root <root@vscode-python-717802-0.vscode-python-717802.projet-cartiflette.svc.cluster.local>
1 parent f479f12 commit 164fa68

File tree

4 files changed

+490
-202
lines changed

4 files changed

+490
-202
lines changed

content/course/NLP/01_intro/index.qmd

Lines changed: 161 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Quelques éléments pour comprendre les enjeux"
2+
title: "Quelques éléments pour comprendre les enjeux du NLP"
33
date: 2020-10-15T13:00:00Z
44
draft: false
55
weight: 10
@@ -20,6 +20,7 @@ summary: |
2020
en oeuvre une série d'étapes de nettoyage de texte. Ce chapitre va
2121
explorer quelques méthodes classiques de nettoyage en s'appuyant
2222
sur le _Comte de Monte Cristo_ d'Alexandre Dumas.
23+
bibliography: ../../../../reference.bib
2324
---
2425

2526
::: {.cell .markdown}
@@ -39,23 +40,36 @@ print_badges("content/course/NLP/01_intro.qmd")
3940
:::
4041

4142

42-
43-
{{% box status="warning" title="Warning" icon="fa fa-exclamation-triangle" %}}
44-
Le NLP est un domaine immense de recherche. Cette page est une introduction
43+
Le _NLP_ est un domaine immense de recherche. Cette page est une introduction
4544
fort incomplète à la question. Il s'agit de montrer la logique, quelques exemples
4645
avec `Python` <i class="fab fa-python"></i>
4746
et s'amuser avec comme base d'exemple un livre formidable :books: :
48-
*Le Comte de Monte Cristo*
49-
{{% /box %}}
47+
*Le Comte de Monte Cristo*.
48+
49+
Dans le cadre de l'introduction au NLP que vous pouvez retrouver dans
50+
les différents chapitres, nous évoquons principalement les champs suivants du NLP:
51+
52+
- _Preprocessing_
53+
- Approches _bag of words_ et contextuelles (n-grams, etc.)
54+
- _Topics modelling_
55+
- _Word embedding_
56+
57+
Cela laisse de côté des champs très actifs de recherche
58+
du NLP, notamment l'analyse de sentiment ou les modèles de
59+
langage (modèles GPT par exemple). Les outils découverts
60+
dans cette partie du cours permettront, si vous le désirez,
61+
de bénéficier d'une base solide pour approfondir tel ou tel
62+
sujet.
63+
5064

51-
## Base d'exemple
65+
# Base d'exemple
5266

5367
La base d'exemple est le *Comte de Monte Cristo* d'Alexandre Dumas.
5468
Il est disponible
5569
gratuitement sur le site
5670
[Project Gutemberg](http://www.gutenberg.org/ebooks/author/492) comme des milliers
5771
d'autres livres du domaine public. La manière la plus simple de le récupérer
58-
est de télécharger avec le module `urllib` le fichier texte et le retravailler
72+
est de télécharger avec le _package_ `request` le fichier texte et le retravailler
5973
légèrement pour ne conserver que le corpus du livre :
6074

6175
```{python}
@@ -80,12 +94,13 @@ dumas[10000:10500]
8094
```
8195

8296

83-
## La particularité des données textuelles
97+
# La particularité des données textuelles
8498

85-
### Objectif
99+
## Objectif
86100

87101
Le *natural language processing* (NLP) ou
88-
*traitement automatisé de la langue* (TAL) en Français, vise à extraire de l'information de textes à partir d'une analyse statistique du contenu.
102+
*traitement automatisé de la langue* (TAL) en Français,
103+
vise à extraire de l'information de textes à partir d'une analyse statistique du contenu.
89104
Cette définition permet d'inclure de nombreux champs d'applications au sein
90105
du NLP (traduction, analyse de sentiment, recommandation, surveillance, etc. ) ainsi que de méthodes.
91106

@@ -102,7 +117,7 @@ Si cette tâche n'était pas assez difficile comme ça, on peut ajouter d'autres
102117
* propres à chaque langue : il n'existe pas de règle de passage unique entre deux langues
103118
* grande dimension : des combinaisons infinies de séquences de mots
104119

105-
### Méthode
120+
## Méthode
106121

107122
L’unité textuelle peut être le mot ou encore une séquence de *n*
108123
mots (un *n-gramme*) ou encore une chaîne de caractères (e.g. la
@@ -116,7 +131,7 @@ l’information transformée. Mais les étapes de nettoyage de texte sont indisp
116131

117132

118133

119-
## Nettoyer un texte
134+
# Nettoyer un texte
120135

121136
Les *wordclouds* sont des représentations graphiques assez pratiques pour visualiser
122137
les mots les plus fréquents. Elles sont très simples à implémenter en `Python`
@@ -125,8 +140,8 @@ une image :
125140

126141

127142
```{python}
128-
#| include: false
129143
#| echo: true
144+
130145
import wordcloud
131146
import numpy as np
132147
import io
@@ -158,9 +173,59 @@ d'articles ou mots de liaison qui perturbent l'analyse. Ces mots sont des
158173
de référence dans le domaine du NLP, permet de facilement retirer ces
159174
stopwords (cela pourrait également être fait avec
160175
la librairie plus récente, `spaCy`). Avant cela, il est nécessaire
161-
de transformer notre texte en le découpant par unités fondamentales (les tokens)
176+
de transformer notre texte en le découpant par unités fondamentales (les tokens).
177+
178+
Les exemples suivants, extraits de @galianafuzzy, montrent l'intérêt du
179+
nettoyage de textes lorsqu'on désire comparer des corpus
180+
entre eux. En l'occurrence, il s'agit de comparer un corpus de
181+
noms de produits dans des collectes automatisées de produits
182+
de supermarché (_scanner-data_) avec des noms de produits
183+
dans les données de l'`OpenFoodFacts`, une base de données
184+
contributive. Sans nettoyage, le bruit l'emporte sur le signal
185+
et il est impossible de déceler des similarités entre les jeux
186+
de données. Le nettoyage permet d'harmoniser
187+
un peu ces jeux de données pour avoir une chance d'être en
188+
mesure de les comparer.
189+
190+
::: {layout-ncol=2}
191+
![`OpenFoodFacts` avant nettoyage](wordcloud_openfood_start.png)
192+
193+
![_Scanner-data_ avant nettoyage](wordcloud_relevanc_start.png)
194+
:::
195+
196+
::: {layout-ncol=2}
197+
![`OpenFoodFacts` après nettoyage](wordcloud_openfood_clean.png)
198+
199+
![_Scanner-data_ après nettoyage](wordcloud_relevanc_clean.png)
200+
:::
201+
202+
203+
## Tokenisation
204+
205+
::: {.cell .markdown}
206+
```{=html}
207+
<div class="alert alert-warning" role="alert">
208+
<h3 class="alert-heading"><i class="fa-solid fa-lightbulb"></i> Hint</h3>
209+
```
210+
211+
Lors de la première utilisation de `NLTK`, il est nécessaire de télécharger
212+
quelques éléments nécessaires à la tokenisation, notamment la ponctuation.
213+
Pour cela, il est recommandé d'utiliser la commande suivante:
162214

163-
### Tokenisation
215+
~~~python
216+
import nltk
217+
nltk.download('punkt')
218+
~~~
219+
220+
```{=html}
221+
</div>
222+
```
223+
:::
224+
225+
```{python}
226+
import nltk
227+
nltk.download('punkt')
228+
```
164229

165230
La tokenisation consiste à découper un texte en morceaux. Ces morceaux
166231
pourraient être des phrases, des chapitres, des n-grammes ou des mots. C'est
@@ -169,7 +234,6 @@ cette dernière option que l'on va choisir, plus simple pour retirer les
169234

170235
```{python}
171236
import nltk
172-
nltk.download('punkt')
173237
174238
words = nltk.word_tokenize(dumas, language='french')
175239
words[1030:1050]
@@ -185,34 +249,55 @@ words = [word for word in words if word.isalpha()]
185249
words[1030:1050]
186250
```
187251

188-
{{% box status="hint" title="Hint" icon="fa fa-lightbulb" %}}
189-
Lors de la première utilisation de `NLTK`, il est nécessaire de télécharger
190-
quelques éléments nécessaires à la tokenisation, notamment la ponctuation.
191-
Pour cela,
252+
Comme indiqué ci-dessus, pour télécharger
253+
le corpus de ponctuation, il est
254+
nécessaire d'exécuter la ligne de
255+
commande suivante :
256+
257+
192258

193-
~~~python
194-
import nltk
195-
nltk.download('punkt')
196-
~~~
197-
{{% /box %}}
198259

199260

200-
### Retirer les stopwords
261+
## Retirer les stop-words
201262

202263
Le jeu de données est maintenant propre. On peut désormais retirer les
203-
*stop words*.
264+
mots qui n'apportent pas de sens et servent seulement à faire le
265+
lien entre deux prépositions. On appelle ces mots des
266+
*stop words* dans le domaine du NLP.
204267

205-
{{% box status="hint" title="Hint" icon="fa fa-lightbulb" %}}
268+
::: {.cell .markdown}
269+
```{=html}
270+
<div class="alert alert-warning" role="alert">
271+
<h3 class="alert-heading"><i class="fa-solid fa-lightbulb"></i> Hint</h3>
272+
```
206273
Lors de la première utilisation de `NLTK`, il est nécessaire de télécharger
207274
les stopwords.
208275

209-
```{python}
276+
~~~python
210277
import nltk
211278
nltk.download('stopwords')
279+
~~~
280+
281+
```{=html}
282+
</div>
212283
```
284+
:::
285+
286+
Comme indiqué ci-dessus, pour télécharger
287+
le corpus de stopwords[^2], il est
288+
nécessaire d'exécuter la ligne de
289+
commande suivante :
213290

214-
{{% /box %}}
291+
```{python}
292+
import nltk
293+
nltk.download('stopwords')
294+
```
215295

296+
[^2]: Le corpus de _stop-words_ de `NLTK`
297+
est relativement limité. Il est recommandé
298+
de privilégier celui de `spaCy`, plus
299+
complet, pour éliminer plus de mots
300+
valises.
216301

217302
```{python}
218303
from nltk.corpus import stopwords
@@ -230,8 +315,6 @@ de sens commencent à se dégager, notamment les noms des personnages
230315
(Fernand, Mercédès, Villefort, etc.)
231316

232317

233-
<!-- KA : ne s'affichait pas sur le site sans que je comprenne pourquoi. J'ai ajouté echo=TRUE... -->
234-
235318
```{python}
236319
#| echo: true
237320
wc = make_wordcloud(' '.join(words))
@@ -242,15 +325,11 @@ plt.imshow(wc, interpolation='bilinear')
242325
plt.axis("off")
243326
```
244327

245-
```{python}
246-
#| echo: false
247-
plt.savefig("featured.png")
248-
```
249328

250-
### *Stemming*
329+
## *Stemming*
251330

252331
Pour réduire la complexité d'un texte, on peut tirer partie de
253-
"classes d'équivalence" : on peut
332+
_"classes d'équivalence"_ : on peut
254333
considérer que différentes formes d’un même mot (pluriel,
255334
singulier, conjugaison) sont équivalentes et les remplacer par une
256335
même forme dite canonique. Il existe deux approches dans le domaine :
@@ -271,6 +350,7 @@ conjugaisons ou variations comme les pluriels, on applique une méthode de
271350
nombreuses variantes d’un mot comme un seul et même mot.
272351
Par exemple, une fois que l’on applique un stemming, "chats" et "chat"
273352
deviennent un même mot.
353+
274354
Cette approche a l'avantage de réduire la taille du vocabulaire à maîtriser
275355
pour l'ordinateur et le modélisateur. Il existe plusieurs algorithmes de
276356
*stemming*, notamment le *Porter Stemming Algorithm* ou le
@@ -287,41 +367,72 @@ print(stemmed[1030:1050])
287367
A ce niveau, les mots commencent à être moins intelligibles par un humain.
288368
La machine prendra le relais, on lui a préparé le travail
289369

290-
{{% box status="note" title="Note" icon="fa fa-comment" %}}
291-
Il existe aussi le stemmer suivant :
370+
::: {.cell .markdown}
371+
```{=html}
372+
<div class="alert alert-info" role="alert">
373+
<h3 class="alert-heading"><i class="fa-solid fa-comment"></i> Note</h3>
374+
```
375+
Il existe aussi le _stemmer_ suivant :
292376

293377
~~~python
294378
from nltk.stem.snowball import FrenchStemmer
295379
stemmer = FrenchStemmer()
296380
~~~
297-
{{% /box %}}
381+
```{=html}
382+
</div>
383+
```
384+
:::
298385

299386

300-
### Reconnaissance des entités nommées
387+
# Reconnaissance des entités nommées
301388

302389
Cette étape n'est pas une étape de préparation mais illustre la capacité
303390
des librairies `Python` a extraire du sens d'un texte. La librairie
304391
`spaCy` permet de faire de la reconnaissance d'entités nommées, ce qui peut
305-
être pratique pour extraire rapidement certains personnages de notre oeuvre
392+
être pratique pour extraire rapidement certains personnages de notre oeuvre.
393+
394+
::: {.cell .markdown}
395+
```{=html}
396+
<div class="alert alert-info" role="alert">
397+
<h3 class="alert-heading"><i class="fa-solid fa-comment"></i>La librairie spaCy</h3>
398+
```
399+
400+
`NTLK` est la librairie historique d'analyse textuelle en `Python`. Elle existe
401+
depuis les années 1990. L'utilisation industrielle du NLP dans le monde
402+
de la _data-science_ est néanmoins plus récente et doit beaucoup à la collecte
403+
accrue de données non structurées par les réseaux sociaux. Cela a amené à
404+
un renouvelement du champ du NLP, tant dans le monde de la recherche que dans
405+
sa mise en application dans l'industrie de la donnée.
406+
407+
Le _package_ [`spaCy`](https://spacy.io/) est l'un des packages qui a permis
408+
cette industrialisation des méthodes de NLP. Conçu autour du concept
409+
de _pipelines_ de données, il est beaucoup plus pratique à mettre en oeuvre
410+
pour une chaîne de traitement de données textuelles mettant en oeuvre
411+
plusieurs étapes de transformation des données.
412+
413+
```{=html}
414+
</div>
415+
```
416+
:::
306417

307418
~~~python
308419
#!pip install deplacy
309420
#!python -m spacy download fr_core_news_sm
310-
import pkg_resources,imp
311-
imp.reload(pkg_resources)
312421
import spacy
313422

314423
nlp=spacy.load("fr_core_news_sm")
315424
doc = nlp(dumas)
425+
import spacy
426+
from spacy import displacy
316427
displacy.render(doc, style="ent", jupyter=True)
317428
~~~
318429

319430

320-
## Représentation d'un texte sous forme vectorielle
431+
# Représentation d'un texte sous forme vectorielle
321432

322433
Une fois nettoyé, le texte est plus propice à une représentation vectorielle.
323434
En fait, implicitement, on a depuis le début adopté une démarche *bag of words*.
324-
Il s'agit d'une représentation, sans souci de contexte (ordre, utilisation),
435+
Il s'agit d'une représentation, sans souci de contexte (ordre des mots, contexte d'utilisation),
325436
où chaque *token* représente un élément dans un vocabulaire de taille $|V|$.
326437
On peut ainsi avoir une représentation matricielle les occurrences de
327438
chaque *token* dans plusieurs documents (par exemple plusieurs livres,
@@ -334,3 +445,5 @@ On élimine ainsi certains mots très fréquents ou au contraire très rares.
334445
La pondération la plus simple est basée sur la fréquence des mots dans le document.
335446
C'est l'objet de la métrique **tf-idf** (term frequency - inverse document frequency)
336447
abordée dans un prochain chapitre.
448+
449+
# Références

0 commit comments

Comments
 (0)