Lexicon
Il existe un très grand nombre d’applications pour lesquelles il est nécessaire d’avoir un lexique de mots (correcteurs orthographiques, jeux de lettres, …).
Pour obtenir un lexique, on peut utiliser une des bases de données open source sur le site : http://www.lexique.org/
Ce site met à disposition de nombreuses bases à télécharger ou bien à consulter.
Sur OpenLexicon, Christophe Pallier (Directeur de Recherche au CNRS) met à disposition :
-
- un répertoire des bases de données lexicales,
- des scripts permettant d’interroger, de manipuler ou de créer des bases de données lexicales,
- des applications pour créer des interfaces graphiques dynamiques avec les bases de données lexicales,
- des documents liés au traitement des ressources lexicales.
Voici un petit aperçu de ce que l’on peut faire à l’aide du langage Python …
Tout ce qui suit utilise la bibliothèque pandas, dont la documentation est remarquable !
import pandas as pd
Supposons que nous souhaitions obtenir une liste de mots pour un jeu de lettres (type mots croisés, mots mêlés, Scrabble, jeu du pendu, …). Ces mots devront être :
- des noms ou des verbes à l’infinitif
- sans espace ni tiret
- sans accents
- de longueur supérieure ou égale à 2 mots (et éventuellement inférieure ou égale à un autre nombre)
- en lettres majuscules
Obtenir le lexique de la langue Française
On se propose d’utiliser le Lexique3, que l’on peut obtenir ainsi :
lex = pd.read_csv('http://www.lexique.org/databases/Lexique383/Lexique383.tsv', sep='\t')
lex
est un objetDataFrame
(doc)
Pour avoir un aperçu de son contenu, on utilise tout simplement la console ou bien fonction print()
:
>>> lex ortho phon lemme ... pld20 morphoder nbmorph 0 a a a ... 1.00 a 1 1 a a avoir ... 1.00 avoir 1 2 a a avoir ... 1.00 avoir 1 3 a capella akapEla a capella ... 2.85 a-capella 2 4 a cappella akapEla a cappella ... 2.85 a-cappella 2 ... ... ... ... ... ... ... ... 142689 ôtée ote ôté ... 1.00 ôté 1 142690 ôtées ote ôter ... 1.00 ôter 1 142691 ôtées ote ôté ... 1.00 ôté 1 142692 ôtés ote ôter ... 1.00 ôter 1 142693 ôtés ote ôté ... 1.00 ôté 1 [142694 rows x 35 columns]
Pour connaitre les noms des colonnes :
>>> lex.columns Index(['ortho', 'phon', 'lemme', 'cgram', 'genre', 'nombre', 'freqlemfilms2', 'freqlemlivres', 'freqfilms2', 'freqlivres', 'infover', 'nbhomogr', 'nbhomoph', 'islem', 'nblettres', 'nbphons', 'cvcv', 'p_cvcv', 'voisorth', 'voisphon', 'puorth', 'puphon', 'syll', 'nbsyll', 'cv-cv', 'orthrenv', 'phonrenv', 'orthosyll', 'cgramortho', 'deflem', 'defobs', 'old20', 'pld20', 'morphoder', 'nbmorph'], dtype='object')
Les seuls champs qui nous intéresserons ici seront :
- Lemme (lemme) : forme canonique, c’est à dire l’infinitif pour un verbe, la masculin singulier pour un nom ou un adjectif. Par exemple, l’item « chienne » a pour lemme « chien ».
- Classe grammaticale (cgram) : les principaux codes utilisés pour représenter les catégories grammaticales sont :
- ADJ : adjectif
- ADV : adverbe
- ART : article
- AUX : auxiliaire
- CON : conjonction
- NOM : nom commun
- PRE : préposition
- PRO : pronom
- VER : verbe
Sélectionner une colonne
>>> lex['lemme'] 0 a 1 avoir 2 avoir 3 a capella 4 a cappella ... 142689 ôté 142690 ôter 142691 ôté 142692 ôter 142693 ôté Name: lemme, Length: 142694, dtype: object
Sélectionner selon un critère
>>> mots = lex[lex['cgram'].isin(['NOM','VER'])]['lemme'] 0 a 2 avoir 12 a priori 13 aa 17 abaca ... 142685 ôter 142686 ôter 142688 ôter 142690 ôter 142692 ôter Name: lemme, Length: 113216, dtype: object
Sélectionner selon la taille des chaînes de caractères
>>> mots = mots[mots.str.len() >= 2] >>> mots 2 avoir 12 a priori 13 aa 17 abaca 18 abaisser ... 142685 ôter 142686 ôter 142688 ôter 142690 ôter 142692 ôter Name: lemme, Length: 113187, dtype: object
Sélectionner selon le contenu des chaînes de caractères
On souhaite supprimer les mots avec espace :
>>> mots = mots[~mots.str.contains(' ', na=True)] >>> mots 2 avoir 13 aa 17 abaca 18 abaisser 19 abaisser ... 142685 ôter 142686 ôter 142688 ôter 142690 ôter 142692 ôter Name: lemme, Length: 113062, dtype: object
Remarques :
~
signifie « non »na=True
permet de traiter les valeurs « vides » (NaN), en considérant que.contains
doit renvoyerTrue
On peut faire de même avec les tirets :
>>> mots = mots[~mots.str.contains('-')]
Conversion en lettres majuscules
>>> mots = mots.str.upper() >>> mots 2 AVOIR 13 AA 17 ABACA 18 ABAISSER 19 ABAISSER ... 142685 ÔTER 142686 ÔTER 142688 ÔTER 142690 ÔTER 142692 ÔTER Name: lemme, Length: 109610, dtype: object
Suppression des accents
Pour supprimer les accents, il faut utiliser une des propriétés de l’encodage Unicode qui permet de normaliser les caractères.
Ensuite, une conversion en ASCII puis en Unicode de nouveau permet de s’assurer que l’on n’a bien que de simples lettres de A à Z :
>>> mots = mots.str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8') >>> mots 2 AVOIR 13 AA 17 ABACA 18 ABAISSER 19 ABAISSER ... 142685 OTER 142686 OTER 142688 OTER 142690 OTER 142692 OTER Name: lemme, Length: 109610, dtype: object
Supprimer les doublons
>>> mots = mots.drop_duplicates() >>> mots 2 AVOIR 13 AA 17 ABACA 18 ABAISSER 25 ABAISSE ... 142648 EWE 142659 ILETTE 142660 ILOT 142661 ILOTIER 142664 OTER Name: lemme, Length: 33740, dtype: object
Enregistrer le résultat
Afin de ne pas avoir à tout refaire à chaque fois, d’autant plus que la procédure requière un accès à Internet, on peut enregistrer la DataFrame
obtenue dans un fichier.
Le format le plus simple, mais qui ne donne pas un fichier « lisible » par un utilisateur, est le format pickle (voir sérialisation) :
pd.to_pickle(mots, nom_fichier)
Et pour le lire :
mots = pd.read_pickle(nom_fichier)