Ceci est un mémo pour moi pendant que je lis Introduction aux applications de traitement du langage naturel en 15 étapes. Cette fois, au chapitre 2, étape 02, j'écrirai mes propres points.
J'ai créé un agent de dialogue simple dans le chapitre précédent, mais il ne gère pas les phrases similaires de la même manière et traite les mots (tels que les mots auxiliaires) et les différences (majuscules et minuscules de l'alphabet) qui ne sont pas à l'origine importantes comme des caractéristiques. Apprenez les techniques suivantes et appliquez-les aux agents de dialogue.
Formatez correctement le texte avant d'entrer dans le processus de classification de texte.
#Ne peut pas être traité comme la même phrase
Aimez-vous Python
Aimez-vous Pyson
#Caractérise la similitude des mots auxiliaires et des verbes auxiliaires
#étiquette,Phrase
0,je vous aime bien
1,J'aime les ramen!
# ↓
#Étiquetez la phrase "J'aime les ramen"=Il peut être considéré comme 0
#Étiquette sémantique=Je veux le juger comme 1
Le processus d'absorption des fluctuations de notation et de l'unification de celle-ci en une certaine notation est appelé normalisation de chaîne de caractères. Le but est d'obtenir le même BoW en obtenant le même résultat de l'écriture même s'il y a une fluctuation dans la notation. La normalisation approximative est effectuée par neologdn, et la normalisation (abaissement et normalisation Unicode) qui manque à neologdn est gérée individuellement.
neologdn Il existe une bibliothèque appelée neologdn qui résume plusieurs processus de normalisation. Il s'agit du processus de normalisation utilisé pour générer des données NEologd, un type de dictionnaire MeCab. L'avantage de neologdn est qu'il est facile à utiliser car le processus de normalisation est intégré dans une seule fonction, et il est rapide car il est implémenté en langage C.
Exemple d'utilisation
import neologdn
print(neologdn.normalize(<Phrase>))
neologdn.normalize n'inclut pas la conversion inférieure / supérieure des alphabets. Par conséquent, pour absorber la fluctuation de notation, utilisez .lower () et .upper (), qui sont des méthodes intégrées de type Python str, pour unifier la notation en minuscules ou majuscules.
Cependant, ** une nomenclature appropriée peut être importante pour faire la distinction entre les alphabets inférieur et supérieur, nous y répondrons donc si nécessaire **.
Unicode est maintenant si largement utilisé qu'il est la norme de facto pour les codes de caractères. "De" et "Co., Ltd." et "de", qui est une combinaison des caractères uniques "de" et "te et" même s'ils sont les mêmes "de", sont traités comme des caractères différents, de sorte que le résultat de Bow est naturellement différent. Je vais finir.
En Unicode, les caractères sont représentés par des ** points de code **. (Notation hexaire) Ils peuvent être convertis l'un à l'autre à l'aide des fonctions Python intégrées ord () et chr (), respectivement.
Exemples d'Unicode et de point de code
>>> hex(ord('Ah'))
'0x3042'
>>> chr(0x3042)
'Ah'
#À propos, il est également possible en notation décimale
>>> ord('Ah')
12354
>>> chr(12354)
'Ah'
Ensuite, pour le caractère "de", vérifiez les points de code pour un caractère et pour la chaîne de caractères combinée (caractère de base et caractère combiné).
Confirmation du point de code
#Une lettre
>>> chr(0x30C7)
'De'
#Chaîne combinée
>>> chr(0x30C6)
'Te'
>>> chr(0x3099)
'S'
>>> chr(0x30C6) + chr(0x3099)
'De'
Comme mentionné ci-dessus, Unicode a traité ce problème, ce qui signifie qu'il existe plusieurs façons d'exprimer le même caractère, en ** "définissant un ensemble de points de code qui doivent être traités comme le même caractère" **. C'est ce qu'on appelle l'équivalence Unicode, et il y a les deux suivants.
La normalisation Unicode consiste à décomposer et synthétiser des caractères synthétisés sur la base de cette équivalence, et il y a les quatre suivants. Canonical signifie canonique et Compatibilité signifie compatible.
Lors de la normalisation Unicode, il est nécessaire de ** décider de la normalisation à utiliser en fonction du problème traité par l'application et de la nature des données **.
La correction des modifications de la forme des mots dues à l'utilisation, etc., et leur correction sous la forme répertoriée dans l'en-tête du dictionnaire s'appelle la conversion de mots clés. Cependant, à ce stade, les mêmes caractéristiques n'ont pas encore été extraites en «lisant un livre» et en «lisant un livre». En correspondant au mot d'arrêt dans la section suivante, il peut être traité comme la même caractéristique.
je lis un livre
je lis un livre
↓ écrit+Conversion de mots clés
Lire un livre
je lis un livre
Elle est similaire à la normalisation mentionnée ci-dessus en termes d'absorption des fluctuations de notation, mais elle est souvent décrite avec le processus d'écriture afin de corriger l'écriture.
Si vous utilisez node.feature obtenu à partir de parseToNode de MeCab, vous pouvez obtenir la forme d'origine ** à partir du 6ème élément séparé par des virgules.
Cependant, ** les mots dont la forme originale n'est pas enregistrée utilisent la forme de surface **.
** BOS / EOS ** est un pseudo mot qui représente le début et la fin d'une phrase suite à MeCab, il ne doit donc pas être inclus dans le résultat de l'écriture.
Dans la section précédente, le mot est le même jusqu'à «lire un livre» suite à l'écriture de mots séparés, mais après cela, «da» et «masuta» sont différents, donc le BoW est également différent. Il n'a pas d'effet significatif sur la signification du texte et il n'est pas souhaitable de l'inclure dans le vocabulaire du point de vue de la mémoire et de l'efficacité de stockage.
Préparez à l'avance une liste de mots à exclure, comme indiqué ci-dessous, et faites un jugement en utilisant l'énoncé if. Dans certains cas, vous pouvez préparer la liste de mots vides nécessaire à partir du net, comme slothlib.
~~
stop_words = ['main', 'À', 'À', 'Est', 'est', 'Masu']
~~
if token not in stop_words:
result.append(token)
Les mots auxiliaires et les verbes auxiliaires sont des parties importantes pour écrire des phrases, mais ils ne sont pas nécessaires pour exprimer le sens d'une phrase (dans un agent de dialogue, les caractéristiques nécessaires à la classification des ID de classe sont acquises).
~~
if features[0] not in ['Particule', 'Verbe auxiliaire']:
~~
Comme dans la section précédente, il est important en tant que phrase, mais comme "valeur numérique et date et heure" peut ne pas avoir beaucoup de sens pour exprimer le sens de la phrase, remplacez-la par une chaîne de caractères spécifique.
#Avant la conversion
J'ai acheté un œuf
J'ai acheté deux œufs
J'ai acheté 10 œufs
#Après la conversion
J'ai acheté des œufs SOMENUMBER
J'ai acheté des œufs SOMENUMBER
J'ai acheté des œufs SOMENUMBER
――Bien que les informations sur le nombre soient perdues, la signification de «j'ai acheté un œuf» reste la même et la différence dans le nombre peut être unifiée. --Incluant des espaces demi-largeur avant et après "SOME NUMBER" pour éviter qu'il ne soit combiné avec les caractères avant et après celui-ci ―― Le même résultat peut être obtenu même si vous incluez un espace demi-largeur avec "QUELQUE NOMBRE", mais évitez-le car le nombre de dimensions augmentera inutilement d'une unité.
Comme mentionné au début, appliquez les techniques suivantes apprises dans ce chapitre à l'agent de dialogue.
~~
# _tokenize()Amélioration de
def _tokenize(self, text):
text = unicodedata.normalize('NFKC', text) #Normalisation Unicode
text = neologdn.normalize(text) #Normalisation par neologdn
text = text.lower() #Abaisser l'alphabet
node = self.tagger.parseToNode(text)
result = []
while node:
features = node.feature.split(',')
if features[0] != 'BOS/EOS':
if features[0] not in ['Particule', 'Verbe auxiliaire']: #Arrêter la suppression des mots par partie
token = features[6] \
if features[6] != '*' \
else node.surface #Conversion de mots clés
result.append(token)
node = node.next
return result
Résultat d'exécution
# evaluate_dialogue_agent.Correction du nom du module de chargement de py
from dialogue_agent import DialogueAgent
↓
from dialogue_agent_with_preprocessing import DialogueAgent
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python evaluate_dialogue_agent.py
0.43617021
Recommended Posts