Lors de l’article précédent, nous avons réussi à générer un fichier contenant tous les mots de la langue française. Il nous faut maintenant exploiter celui-ci pour le rendre utilisable par notre futur automate.
LexiconGOW.py
Dans le répertoire software/tools, vous trouverez le script python LexiconGOW.py. Ce script génère plusieurs fichiers intermédiaires avant de générer le fichier final.
https://github.com/Angorange/Garden-Of-Words/blob/master/software/tools/LexiconGOW.py
Ça dépend, ça dépasse
La fonction « trim_lexicon » n’a pas vraiment besoin d’explication il me semble. Elle ouvre le fichier source contenant les mots à traiter, pour chacun d’eux vérifie s’ils ont entre 3 et 7 lettres inclus, si c’est le cas le mot est sauvé dans le fichier destination.
Nous passons de 402503 mots à 60363 mots.
Taille du fichier source Lexique_fr.txt : 4780 KB
Taille du fichier destination Lexicon_fr_3_7.txt : 489 KB
La perte de poids s’explique simplement par l’élimination de tous les mots de moins de 3 lettres et de plus de 7 lettres.
Le même mais dans le désordre
La seconde étape est de regrouper les mots possédant exactement les mêmes lettres, mais dans un ordre différent. Par exemple CHIEN et NICHE seraient dans le même groupe. C’est le rôle de la fonction « group_by_anagrams ».
Pour chaque mot de notre lexique nous allons calculer la clé correspondante. Elle doit être la même pour tous les mots partageant exactement les mêmes lettres. La solution la plus naïve est de trier les lettres du mot donné par ordre alphabétique. Ce qui pour NICHE et CHIEN donne CEHIN.
def hash_word(word): result = "" return result.join(sorted(word))
Ensuite le mot est ajouté dans un dictionnaire python à la clé correspondante. Enfin ce dictionnaire est simplement sauvé dans un fichier en utilisant la librairie pickle.
def group_by_anagrams(src_name, dst_name): print("Generate:", dst_name) srcFile = open(src_name, "r") allLines = srcFile.readlines() srcFile.close() d = dict() for line in allLines: word = line.strip() key = hash_word(word) if key not in d: d[key] = [] # Creates the entry if it does not exist yet d[key].append(word) dstFile = open(dst_name,"wb") pickle.dump(d, dstFile, pickle.HIGHEST_PROTOCOL) dstFile.close()
Nous avons maintenant un fichier contenant ce dictionnaire contenant 41638 entrées.
Taille du fichier source lexicon_fr_3_7.txt : 489 KB
Taille du fichier destination anagrams_fr_3_7.bin : 1058 KB
Le gain de poids est dû à deux choses : le stockage de la clé, qui correspond à l’équivalent de 41638 mots soit l’équivalent de deux tiers des mots valides, et le stockage des méta-données.
Conclusion
Nous avons maintenant un fichier contenant tous les mots qui nous intéressent ainsi que les liens entre les mots étant des anagrammes.
La prochaine fois, nous utiliseront ce fichier pour vérifier s’il fournit ce dont nous avons besoin.