Introduction

François HU - ENSAE - 14/04/20 - https://curiousml.github.io/

In [1]:
from jyquickhelper import add_notebook_menu
add_notebook_menu()
Out[1]:
run previous cell, wait for 2 seconds

Organisation des parties :

  • introduction : définitions et processing + une première approche de vectorisation des données textuelles ($\color{red}{\text{ce notebook}}$)
  • partie 1 : NLP dans un contexte non-supervisé (Notebook : $\color{red}{\text{Représentations vectorielles}}$)
  • partie 2 : NLP dans un contexte supervisé (Notebook : $\color{red}{\text{Deep Learning pour NLP}}$)
  • partie 3 : NLP dans un contexte semi-supervisé (Notebook : $\color{red}{\text{Problèmes d'annotation}}$)

1. Quelques prérequis

$\color{grey}{\text{*cacher le code}}$

In [3]:
from IPython.display import HTML, Image
HTML('''<script>code_show=true; function code_toggle() {if (code_show){$('div.input').hide();} else {$('div.input').show();}code_show = !code_show} $( document ).ready(code_toggle);</script><form action="javascript:code_toggle()"><input type="submit" value="cacher / afficher code"></form>''')
Out[3]:

Machine learning

  • $\color{#228B22}{\text{Machine Learning}}$ (apprentissage machine ou automatique) : la science de programmer les ordinateurs de sorte qu'ils puissent apprendre à partir des données (que nous notons $X$)
  • $\color{#228B22}{\text{Apprentissage supervisé}}$ : apprentissage machine où les données d'entraînement sont étiquetées $ \to (X,y)$
    • classification ($\color{#228B22}{\text{régression logistique}}$, $\color{#228B22}{\text{régression softmax}}$, $\dots$),
    • régression, $\dots$
  • $\color{#228B22}{\text{Apprentissage non-supervisé}}$ : apprentissage machine où les données d'entraînement ne sont pas étiquetées $ \to X$
    • partitionnement (ou clustering),
    • réduction de dimensionalité, $\dots$
  • phases d'un système de Machine Learning : phase d'apprentissage, phase d'inférence / de prédiction
  • comment entraîner un modèle ? créer un modèle prédictif puis régler ses paramètres (souvent minimisation d'une $\color{#228B22}{\text{métrique}}$ par $\color{#228B22}{\text{descente de gradient}}$)

Deep learning

Régression logistique

In [10]:
Image("img/logreg.png", width=700, height = 200)
Out[10]:

Quelques fonctions d'activation

In [11]:
Image("img/factivations.png", width=800, height = 200)
Out[11]:

Réseau de neurones

In [14]:
Image("img/RNA.png", width=750, height = 200)
Out[14]:

Deep Learning (apprentissage profond)

In [18]:
Image("img/DL.png", width=850, height = 200)
Out[18]:

2. Définitions et préprocessing

$\color{grey}{\text{*afficher le code}}$

In [299]:
from IPython.display import HTML, Image
HTML('''<script>code_show=true; function code_toggle() {if (code_show){$('div.input').hide();} else {$('div.input').show();}code_show = !code_show} $( document ).ready(code_toggle);</script><form action="javascript:code_toggle()"><input type="submit" value="cacher / afficher code"></form>''')
Out[299]:

Tokenization

  • $\color{#228B22}{\text{Texte}}$ : séquence de mots
  • $\color{#228B22}{\text{Mot}}$ : séquence logique de caractères
  • $\color{#228B22}{\text{Tokenization}}$ : processus qui sépare une séquence (texte) en une liste de tokens (mots)
  • question : comment trouver les limites d'un mot ? En français / anglais, nous pouvons séparer les mots par les espaces et les ponctuations
  • input : "Devons-nous, mon collègue et moi, vous recontacter?"
  • output : ["Devons", "nous", "mon", "collègue", "et", "moi", "vous", "recontacter"]
In [123]:
from nltk.tokenize import WhitespaceTokenizer, WordPunctTokenizer, word_tokenize
text = "J'ai une question : devons-nous, mon collègue et moi, vous recontacter?"

Implémentations avec python

  • exemple 1 : tokenization par les espaces
In [64]:
tokenizer = WhitespaceTokenizer()
print(tokenizer.tokenize(text))
["J'ai", 'une', 'question', ':', 'devons-nous,', 'mon', 'collègue', 'et', 'moi,', 'vous', 'recontacter?']
  • exemple 2 : tokenization par les ponctuations
In [61]:
tokenizer = WordPunctTokenizer()
print(tokenizer.tokenize(text))
['J', "'", 'ai', 'une', 'question', ':', 'devons', '-', 'nous', ',', 'mon', 'collègue', 'et', 'moi', ',', 'vous', 'recontacter', '?']
  • exemple 3 : tokenization par un ensemble de règles
In [62]:
print(word_tokenize(text, language='french'))
["J'ai", 'une', 'question', ':', 'devons-nous', ',', 'mon', 'collègue', 'et', 'moi', ',', 'vous', 'recontacter', '?']

Normalisation des tokens : racinisation et lemmatisation

  • $\color{#228B22}{\text{Stemming}}$ : garder la racine d'un terme (souvent, enlever une partie de la fin du terme)
  • exemple :

continu$\color{red}{\text{a}}$, continu$\color{red}{\text{ait}}$, continu$\color{red}{\text{ant}}$, continu$\color{red}{\text{ation}}$, continu$\color{red}{\text{ation}}$, continu$\color{red}{\text{e}}$ $\to$ continu

  • $\color{#228B22}{\text{Lemmatisation}}$ : ramener un terme à sa forme la plus simple (infinitif ou masculin-singulier)
  • exemple :

continua, continuait, continuant $\to \color{red}{\text{continuer}}$

continuations, continuation $\to \color{red}{\text{continuation}}$

continue $\to \color{red}{\text{continu / continuer}}$ (adjectif / verbe)

Implémentations avec python

  • exemple 1 : racinisation (stemming)
In [122]:
from nltk.stem import SnowballStemmer
fr = SnowballStemmer('french')
" ".join(fr.stem(token) for token in word_tokenize(text))
Out[122]:
"j ' ai une question : devon - nous , mon collègu et moi , vous recontact ?"
  • exemple 2 : Lemmatisation
In [117]:
import spacy
nlp = spacy.load('fr_core_news_md')
" ".join(token.lemma_ for token in nlp(text))
Out[117]:
'je avoir un question : devoir - nous , mon collègue et moi , vous recontacter ?'

Autres types de normalisation

Les expressions régulières en Python nécessitent d'importer le module natif re : https://fr.wikibooks.org/wiki/Programmation_Python/Regex

In [205]:
import re
text_b = ("<b>" + text + "</b>").lower()
print(text_b)
<b>j'ai une question : devons-nous, mon collègue et moi, vous recontacter?</b>
  • supprimer les balises : <...> ... </...>
In [206]:
text_b = re.sub("<.*?>", " ", text_b) # balises <...>
print(text_b)
 j'ai une question : devons-nous, mon collègue et moi, vous recontacter? 
  • supprimer les ponctuations et les grands espaces : -, !, ?, :, ...
In [207]:
import string
text_b = re.sub(r"[" + string.punctuation + r"]", " ", text_b) # ponctuations
text_b = re.sub(r"\s+", " ", text_b) # grands espaces
print(text_b)
 j ai une question devons nous mon collègue et moi vous recontacter 

Stop-words

  • $\color{#228B22}{\text{Stop-words}}$ : ensemble de mots fréquemment utilisés dans une langue et qui n'apportent pas de signification importante
  • exemple : a, à, des, de, et, est, un, ...

implémentations avec python : supprimer les stopwords

In [215]:
from nltk.corpus import stopwords
# Chargement des stopwords pour la langue francaise avec NLTK
stopwords_lst = list(stopwords.words("french"))
re.sub(r"(\s+|^)(" + r"|".join(stopwords_lst) + r")(\s+|$)", " ", text)
Out[215]:
"J'ai question : devons-nous, collègue moi, recontacter?"

Résumé :

  • tokeniser

  • raciniser et lemmatiser

  • stop-words

3. Vectorisation des données textuelles

$\color{grey}{\text{*cacher le code}}$

In [7]:
from IPython.display import HTML, Image
HTML('''<script>code_show=true; function code_toggle() {
            if (code_show){$('div.input').hide();} 
            else {$('div.input').show();}code_show = !code_show} $( document ).ready(code_toggle);
        </script><form action="javascript:code_toggle()">
        <input type="submit" value="cacher / afficher code"></form>''')
Out[7]:

Données textuelles en données tabulaires

  • processus d'apprentissage pour des données tabulaires :
In [302]:
Image("img/MLtab.png", width=600, height = 200)
Out[302]:
  • pour des données textuelles :
In [301]:
Image("img/MLtext.png", width=600, height = 200)
Out[301]:
  • approches : ($\color{red}{\text{section suivante}}$) TF-IDF et ($\color{red}{\text{cours 1}}$) word embedding

Modèles de vectorisation des textes

In [29]:
Image("img/tab.png", width=700, height = 200)
Out[29]:
In [32]:
Image("img/BOW1.png", width=800, height = 200)
Out[32]:
In [33]:
Image("img/BOW2.png", width=800, height = 200)
Out[33]:
In [34]:
Image("img/BOW3.png", width=800, height = 200)
Out[34]:

1. approche bag-of-words

  • vectorise un document en comptant le nombre d'occurences d'un token $t$ dans le document $d$ : $f_{t,d}$
  • exemple : méthode de comptage
In [297]:
Image("img/BOW_example.png", width=1000, height = 200)
Out[297]:
  • problème : pas d'ordre entre les mots
  • solution : approche n-grammes

2. approche n-grammes (n-grams en anglais)

  • vectorise un document en comptant le nombre d'occurences des paires de tokens (2-grams), des triplets de tokens (3-grams), ...
  • exemple : méthode de comptage (1,2)-grammes
In [298]:
Image("img/ngrams_example.png", width=1000, height = 200)
Out[298]:
  • problème : trop de variables
  • solution : supprimer les stop-words et qq n-grammes (très hautes et très basses fréquences)

3. approche TF-IDF

  • $\color{#228B22}{\text{Term Frequency}}$ : nombre d'occurrences d'un token / n-grams $t$ dans le document $d$ $$\text{tf}(t, d) = f_{t,d}$$
  • variantes : $\frac{f_{t,d}}{\sum\limits_{t'\in d}f_{t',d}}$ ou $\mathbb{1}(t\in d)$ ou $(1 + \log{f_{t,d})}$, ...
  • $\color{#228B22}{\text{Inverse Document Frequency}}$ : mesure l'importance du token / n-grams dans l'ensemble du corpus $$\text{idf}(t, D) = \log\frac{|D|}{|\{d \ | \ t\in d\}|} = \log\frac{\text{# documents}}{\text{# documents contenant le terme } t}$$
  • $\color{#228B22}{\text{Term Frequency - Inverse Document Frequency (TF-IDF)}}$ : $$\text{tfidf}(t, d, D) = \text{tf}(t, d)\cdot \text{idf}(t, D)$$
  • exemple : approche TF-IDF (1,2)-grammes
In [8]:
Image("img/TFIDF_example.png", width=1000, height = 200)
Out[8]:
  • implémentations avec python :

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer(min_df=2, max_df=0.5, ngram_range=(1,2))

features = tfidf.fit_transform(texts)

  • voir cours 1 pour des techniques de vectorisation plus avancées

Résumé :

  • méthode 1 : vectorisation par comptage + bag-of-words

  • méthode 2 : vectorisation par comptage + n-grammes

  • méthode 3 : vectorisation par TF-IDF