Manipulation des données textuelles
utilisation des outils JAVA pour le projet MAIAD
Vincent Guigue
Laboratoire d’Informatique de Paris 6 (LIP6)
Traitements pour la classification de textes
Les données textuelles sont difficiles à gérer :
1 Les corpus sont volumineux, le vocabulaire est grand : - il faut des algorithmes rapides,
- les données ne sont pas toujours stockables en mémoire.
2 La structure des phrases est difficile à gérer.
3 Les mots peuvent prendre plusieurs formes (pluriels...)
4 Les algorithmes de machine learning ont du mal sur des données de grande dimension
Traitements pour la classification de textes
Les données textuelles sont difficiles à gérer :
1 Les corpus sont volumineux, le vocabulaire est grand : - il faut des algorithmes rapides,
- les données ne sont pas toujours stockables en mémoire.
Le boosting est recommandé dans ce cas !
2 La structure des phrases est difficile à gérer.
On supprime la structure...
3 Les mots peuvent prendre plusieurs formes (pluriels...) Plusieurs approches possibles... (cf plus loin)
4 Les algorithmes de machine learning ont du mal sur des données de grande dimension
On cherche des heuristiques pour supprimer les mots inutiles.
Sacs de mots
Ne sachant pas prendre efficacement en compte la structure des phrases... On l’élimine totalement !
Un document devient alors un comptage des différents mots qui le composent :
Représentationbag of words
SoitV le vocabulaire etd un document :d ∈N|V|
NB :d est (presque toujours) un vecteursparse, c’est à dire composé essentiellement de 0.
Elimination du bruit : mots similaires
Etant donnée la représentation en sac de mots, il est pénalisant de compter les occurrences deprésidentetprésidentsdans deux cases séparées... Nous allons donc traiter les mots du textes pour les ramener à leurs radicaux :
◦ mangeait, mangera, mangeoire,...→ manger
Lemmatisation : approche basée sur un dictionnaire efficace/il faut un dictionnaire...
Exemple d’outil : treetagger (gratuit, récupérable sur internet)
Stemmatisation : approche statistique de suppression des suffixes rapide, facile à utiliser/ parfois approximatif
cf outils fournis dans le projet
Traitements discriminants : réduction de la dimensionnalité
Les algorithmes de machine learning sont mis en difficulté sur les problèmes de grandes dimensions... Nous cherchons donc à réduire la dimension des données :
Heuristiques :
◦ Elimination des mots peu fréquents
◦ Elimination des mots courts (articles...)
◦ Elimination de tous les éléments inutiles a priori (chiffres...)
Traitements discriminants
Le codagetf-idf permet de faire apparaître les motssaillants, caractéristiques d’un document.
Soit le documentdj tiré de l’ensembleD,ni,j désigne le nombre d’occurrences du motti dansdj :
tfi,j= ni,j P
knk,j, idfi=log |D|
|{d :ti ∈d}|
tfi,j : fréquence de ti dans le document j.
idfi : pourcentage des documents oùti apparaît (log de l’inverse).
On remplace le codageni,j par le codage tf−idf(i,j) =tfi,j×idfi http://fr.wikipedia.org/wiki/TF-IDF
Traitements discriminants : sélection de variables
Il est possible d’utiliser des critères discriminants (donnant un score à chaque mot) pour choisir un sous-ensemble du dictionnaire sur lequel travailler.
Parmi les classiques :
◦ Saillance : Stf−idf(i) =
P
jtf−idf(i,j)
|{tf−idf(i,j)6=0}|
◦ Odds ratio : Sodds(i) = pqi/(1−pi)
i/(1−qi) = pqi(1−qi)
i(1−pi).(souvent utilisé en log). Oùpi est la probabilité d’observer le mot ti dans la classe 1 etqi est la probabilité d’observer ti dans la classe 2.
Présentation des données
Données d’apprentissage :
<100:1:C> Quand je dis chers amis, ...
<100:2:C> D’abord merci de cet ...
...
<100:14:M> Et ce sentiment ...
Le format est le suivant : <ID-Discours :ID-phrase :Etiquette>, C
→Chirac, M → Mitterrand
Données de test, sans les étiquettes :
<100:1> Quand je dis chers amis, ...
<100:2> D’abord merci de cet ...
...
Outils JAVA mis à disposition
◦ Contraire aux bonnes pratiques...
◦ Pas de Javadoc ! ! !
◦ Mais un tutoriel
◦ En un prof. pour répondre aux questions
Bref, il faut regarder dansTutorielPerceptron.java
Organisation générale du code
OfflineSet Structure de donnée
Classifier Algorithmes Factories
Importation des données
Dictionary String_processor
Pré-traitements Projection en sac de mots
Organisation générale du code (2)
data.preprocessing data.dico
algo.classif.binary data.set
data.factory
Package
OfflineSet Structure de donnée
Classifier Algorithmes Importation des données
Dictionary_Memory String_processor
OfflineSetBuilderFrom DEFT05File
OfflineSet_Memory PerceptronLossRandomized _Regularized
Dictionary
TutorielPerceptron.java
Usage de base : chargement d’un corpus DEFT :
b o o l e a n l e a r n i n g S e t = t r u e;
P a i r < O f f l i n e S e t <S t r i n g >, O f f l i n e S e t <S t r i n g > > c =
O f f l i n e S e t B u i l d e r F r o m D E F T 0 5 F i l e . b u i l d ( f i l e n a m e , l e a r n i n g S e t ) ; O f f l i n e S e t <S t r i n g > c o r p u s = c . g e t X ( ) ;
O f f l i n e S e t <S t r i n g > l a b e l s = c . g e t Y ( ) ; //===================
// e x e m p l e d ’ u t i l i s a t i o n :
// 1 ) d e f i n i t i o n d ’ i t e r a t e u r s u r l e s d o c u m e n t s e t l e s l a b e l s O f f l i n e S e t I t e r a t o r <S t r i n g > i t e r = c o r p u s . i n p u t s e t i t e r a t o r ( ) ; O f f l i n e S e t I t e r a t o r <S t r i n g > i t e r L a b e l s = l a b e l s . i n p u t s e t i t e r a t o r ( ) ; // A f f i c h e r l e p r e m i e r document :
i t e r . n e x t ( ) ; i t e r L a b e l s . n e x t ( ) ;// p a s s e r au p r e m i e r
S y s t e m . o u t . p r i n t l n ("Doc␣ : ␣ \ n ␣ " + i t e r . g e t C u r r e n t O b j e c t ()+" \n−−−\n ") ;
S y s t e m . o u t . p r i n t l n (" L a b e l ␣ : ␣ \ n ␣ " + i t e r L a b e l s . g e t C u r r e n t O b j e c t ()+" \n−−−\n ") ;
Pre-processing dans TutorielPerceptron.java
Construction :
S t r i n g P r o c e s s o r _ F r o m S t r i n g P r o c e s s o r s s p 2 = new S t r i n g P r o c e s s o r _ F r o m S t r i n g P r o c e s s o r s ( ) ; s p 2 . add (new S t r i n g P r o c e s s o r _ R e m o v e L i n e A n d S p a c e ( ) ) ; s p 2 . add (new S t r i n g P r o c e s s o r _ L o w e r C a s e ( ) ) ;
s p 2 . add (new S t r i n g P r o c e s s o r _ R e m o v e P u n c t u a t i o n ( ) ) ; s p 2 . add (new S t r i n g P r o c e s s o r _ T r e e T a g g e r (" t r e e t a g g e r ",
" t r e e t a g g e r / m o d e l s / f r e n c h . p a r : i s o 8 8 5 9−1", n u l l) ) ; s p = s p 2 ;
Définition de l’interface :
p u b l i c i n t e r f a c e S t r i n g P r o c e s s o r { p u b l i c S t r i n g map ( S t r i n g s t r ) ; }
Dictionnaire dans TutorielPerceptron.java
S y s t e m . o u t . p r i n t l n (" C o n s t r u c t i o n ␣ du ␣ d i c t i o n n a i r e ␣ à ␣ p a r t i r ␣ du ␣ c o r p u s ") ; d i c o = D i c t i o n a r y B u i l d e r F r o m O f f l i n e S e t . b u i l d ( c o r p u s , s p ) ;
// s i l e mot n ’ a p p a r a i t qu ’ une f o i s −> e l i m i n é i n t l i m i t e A p p a r i t i o n = 2 ;
D i c t i o n a r y S a v e r W i t h o u t R a r e W o r d s . s a v e ( d i c o F i l e , d i c o , l i m i t e A p p a r i t i o n ) ;
Définition de l’interface :
p u b l i c i n t e r f a c e D i c t i o n a r y <X> e x t e n d s O f f l i n e S e t <X>
{
p u b l i c i n t i n d e x O f (X x ) ; p u b l i c i n t s i z e ( ) ;
p u b l i c O f f l i n e S e t I t e r a t o r <X> o f f l i n e s e t i t e r a t o r ( ) ; }
Format de sauvegarde octave
Dans le code JAVA, nous sauvegarderons les données numériques au format octave ainsi que le dictionnaire. Les classes de
sauvegardes sont fournies.
load("../data/dicoInOctave.dat");
dico {
[1,1] = quand [2,1] = cher [3,1] = amis [4,1] = agit [5,1] = formul [6,1] = diplomat [7,1] = mais [8,1] = express
Bibliographie intéressante
Références, code...
http://www.cs.princeton.edu/~schapire/boost.html http://cseweb.ucsd.edu/~yfreund/
Mots/idées clés :
◦ Maximisation AUC
◦ Ranking
◦ Sélection de variables
◦ Précision, Rappel, score F1