L’étiquetage morphosyntaxique (ou POS-tagging) est une étape habituelle dans la constitution d’un corpus textuel, assez étroitement liée à la langue dans laquelle le texte est écrit.
Il n’y a pas très longtemps, j’ai réalisé deux versions de l’étiquetage d’un corpus écrit en chinois, sous Python. Je vais donc partager successivement la façon dont j’ai procédé avec chacun des deux étiqueteurs, à savoir PyNLPIR (implémentation Python du logiciel NLPIR/ICTCLAS) et Jieba.
Deux étiqueteurs ?
Je précise que j’en suis venu à utiliser deux étiqueteurs différents sur le même corpus pour les besoins du projet sur lequel je travaillais, mais bien entendu en général on peut en choisir un seul en amont selon le résultat souhaité. Le comparatif entre PyNLPIR et Jieba proposé en fin d’article vous donne un aperçu des différences entre ces deux étiqueteurs. Vous pouvez d’ailleurs remarquer qu’il y a des divergences dans le choix des étiquettes appliquées, mais aussi au niveau de la segmentation (on a par exemple 問/n 題/n
avec PyNLPIR mais 問題/n
avec Jieba).
Voici d’abord la procédure suivie pour réaliser la segmentation et l’étiquetage avec PyNLPIR.
L’étiquetage avec PyNLPIR
Je ne commente ici que certaines parties du script permettant de réaliser l’étiquetage. Le script complet, son fichier d’entrée et son fichier de sortie sont disponibles sur Github.
Pour cet exemple, j’ai utilisé une extraction du texte principal de cette page Wikipedia (皇帝企鹅, manchot empereur)1. Pour pouvoir utiliser les fonctions de la librairie PyNLPIR, il ne faut pas oublier d’ouvrir (et refermer) l’API via les fonctions open()
et close()
. Le script de base ressemblera donc à ceci :
import pynlpir
pynlpir.open()
# (...)
pynlpir.close()
Pour segmenter et étiqueter le texte, il suffit de faire appel à la fonction segment()
: celle-ci prend en premier argument la chaîne de caractères à traiter, et en deuxième argument le type d’étiquetage souhaité. Ici, je veux traiter le fichier ligne par ligne (j’ai créé une variable line
pour cet usage) en lui appliquant l’étiquetage de base (c’est-à-dire les abréviations listées sur cette page) :
postag = pynlpir.segment(line, pos_names='raw')
Comme l’indique la documentation de PyNLPIR, on peut choisir assez précisément le type d’étiquettes souhaitées : il est par exemple possible d’avoir des étiquettes en chinois plutôt qu’en anglais (pos_english=False
), ou même simplement segmenter le texte sans l’étiqueter (pos_tagging=False
).
Techniquement à ce stade l’étiquetage est fait. Cependant, en fonction du résultat souhaité le traitement ne s’arrête pas forcément là, parce que ce que retourne la fonction segment()
, c’est une liste de tuples. En sachant ça, il n’est pas très compliqué de traiter cette liste pour obtenir n’importe quelle structure pour les données de sortie.
Pour avoir quelque chose de type item/étiquette comme dans l’extrait ci-dessous, j’ai procédé comme ceci :
for word, part_of_speech in postag:
try:
tagged_word = f"{word}/{part_of_speech} "
except TypeError:
tagged_word = f"{word}/None "
Il y a deux choses à remarquer :
- Pour certains items il n’y a pas d’étiquette disponible, ce qui fera planter le script puisqu’il essaiera alors de récupérer un élément qui n’existe pas (et aura donc le type
None
). Récupérer les erreurs (TypeError
) permet d’éviter ce problème (ici en créant une étiquette None). - Dans mon fichier de sortie les groupes item/étiquette sont séparés par un espace. Ce n’est pas généré par l’étiqueteur, je l’ai moi-même ajouté en l’intégrant à la chaîne de caractère associée à la variable
tagged_word
.
Comparatif PyNLPIR vs Jieba
La description du processus d’étiquetage avec Jieba est disponible dans cet article.
Les deux étiqueteurs utilisent le même jeu d’étiquettes, dont la liste est disponible sur cette page. Vous pouvez consulter le fichier dont est issu cet extrait sur Github : version PyNLPIR et version Jieba (à venir).
PyNLPIR
本/rz 條/n 目/ng 存在/v 以下/f 問/n 題/n ,/wd 請/n 協/n 助/v 改善/v 本/rz 條/n 目/ng 或/c 在/p 討/n 論/n 頁/n 針/n 對/n 議/n 題/n 發/n 表/vg 看法/n 。/wj
Jieba
本/r 條目/n 存在/v 以下/f 問題/n ,/x 請/v 協助/v 改善/v 本/r 條目/n 或/c 在/p 討論/v 頁/m 針對/p 議題/n 發表/v 看法/v 。/x
- Le texte des pages Wikipedia est disponible sous licence CC BY-SA 3.0 [↩]