.. _chap-tpLemmatisationFr:
##################################################################################
TP++ - Etiquetage morpho-syntaxique et lemmatisation pour le français
##################################################################################
(les TP++ sont des compléments à l'enseignement de base et ne font pas partie des séances de travaux pratiques avec encadrement)
Références externes utiles :
* `Apache OpenNLP `_
* `Ahmet Aker: POS taggers and lemmatizers for English, German, Dutch, Spanish, Italian and French `_
* `Documentation langage Scala `_
Dans Stanford Core NLP (framework utilisé dans le `TP fouille de données textuelles `_), l'implémentation de la lemmatisation pour le français est en cours et donc pas disponible actuellement. On peut utiliser cependant une solution basée sur Apache OpenNLP et les travaux de Ahmet Aker (voir référence plus haut) qui a développé des outils d'étiquetage morpho-syntaxique et de lemmatisation pour plusieurs langues européennes (français, hollandais, anglais, allemand, italien et espagnol).
Pour ce faire, sur la base du projet RCP216 de Fabrice Lebel, nous avons crée un paquetage (fichier ``.jar``) qui permet d'employer ces outils directement dans Spark (les sources java de cette bibliothèque se trouvent dans le répertoire ``src/`` du ``.jar``). **Attention**, le ``.jar`` a été obtenu avec un ``jdk1.8.x``, si vous avez une version antérieure (par ex. ``jdk1.7.y``) il sera nécessaire de passer au ``jdk1.8.x`` pout pouvoir vous servir du ``.jar``.
Voici un exemple qui montre comment lemmatiser le texte en français d'un fichier :
.. code-block:: bash
[cloudera@quickstart ?]$ cd
[cloudera@quickstart ~]$ mkdir -p tptexte
[cloudera@quickstart ~]$ cd tptexte
Récupérez ensuite le fichier ``.jar`` modifié qui permet d'utiliser le lemmatiseur français avec OpenNLP :
.. code-block:: bash
[cloudera@quickstart data]$ wget http://cedric.cnam.fr/~ferecatu/RCP216/tp/tptexte/myopennlp.jar
Et le fichier avec le texte français à lemmatiser :
.. code-block:: bash
[cloudera@quickstart data]$ wget http://cedric.cnam.fr/~ferecatu/RCP216/tp/tptexte/articlefr.txt
On lance ``spark-shell`` dans ``/home/cloudera/tptexte``, avec un peu plus de mémoire à sa disposition (1Go) et en ajoutant le fichier ``.jar`` avec les bonnes librairies et dépendances dans le chemin d'accès de ``Spark`` :
.. code-block:: bash
[cloudera@quickstart tptexte]$ spark-shell --driver-memory 1g --jars myopennlp.jar
Dans ``spark-shell`` on commence par importer les paquetages nécessaires :
.. code-block:: scala
scala> import fllemmatizer.FLLemmatizer
scala> import scala.collection.JavaConversions._
Lecture du fichier et création d'un RDD :
.. code-block:: scala
scala> val lines = sc.textFile("articlefr.txt")
Application du lemmatiseur (par partition et non par item, pour plus d'efficacité) :
.. code-block:: scala
scala> val words = lines.mapPartitions(iter => {
val lemmatizer = new FLLemmatizer("fr");
iter.map{s => lemmatizer.lemmatize(s, true)};
})
Affichage des premiers 5 éléments de la 1ère ligne :
.. code-block:: scala
scala> words.map(s => s(0)).take(5)
> res11: Array[Array[String]] = Array(Array(Méthodes, NOUN, méthode), Array(débat, NOUN, débat),
Array(fiables, ADJ, fiable), Array(Nous, PRON, nous), Array(centaine, NOUN, centaine))
Chaque mot, en 1ère position dans les vecteurs résultat, est annoté par sa catégorie syntaxique (par exemple NOUN pour les noms) en 2ème position ; ensuite on trouve la forme canonique en 3ème position. Par exemple, dans l'élément ``Array(Méthodes, NOUN, méthode)``, ``Méthodes`` est le mot trouvé dans le texte, ``NOUN`` est sa catégorie et ``méthode`` est sa forme canonique (lemme).
Ensuite on supprime les ponctuations et on récupère les lemmes (on garde seulement certaines unités morphologiques : noms, verbes, adverbes et adjectifs).
.. code-block:: scala
scala> val lemmas:org.apache.spark.rdd.RDD[String] = words.flatMap(s => s).filter(s =>
s(1) == "NOUN" || s(1) == "VERB" || s(1) == "ADV" || s(1) == "ADJ").map(s => s(2))
L'objet *lemmas* est un ``RDD[String]`` et contient les formes canoniques des mots retenus.
Affichage des 5 premiers lemmes :
.. code-block:: scala
scala> lemmas.take(5)
> res1: Array[String] = Array(méthode, lecture, verdict, évaluation, débat)