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')
lexest 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=Truepermet de traiter les valeurs « vides » (NaN), en considérant que.containsdoit 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)
