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 01, notez vos propres points.
Découvrez certains des éléments de la programmation de traitement du langage naturel avec un simple agent de dialogue comme sujet.
--L'écriture
#Dialogue de script que vous souhaitez exécuter_agent.Exécuter dans le répertoire où py existe
#Cependant, on suppose que le csv requis pour l'exécution se trouve également dans le même répertoire.
# docker run -it -v $(pwd):/usr/src/app/ <image de docker>:<marque> python <Script d'exécution>
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python dialogue_agent.py
Ce qui devrait être créé est «un système qui prédit la classe à laquelle appartient l'instruction et qui sort l'ID de classe lorsque l'instruction est entrée». Il s'agit d'un paramètre de problème appelé classification de texte.
#Image d'exécution du système d'agent de dialogue
~~
dialogue_agent = DialogueAgent()
dialogue_agent.train(training_data)
predicted_class = dialogue_agent.predict('Déclaration d'entrée')
~~
Décomposer une phrase en mots s'appelle l'écriture. Les langues avec des espaces entre les mots, comme l'anglais, ne sont pas nécessaires. ** MeCab ** est largement utilisé comme logiciel d'écriture en japonais. L'écriture en osier qui comprend l'ajout d'informations sur les paroles de partie est appelée ** analyse morphologique **.
Si vous souhaitez obtenir uniquement le type de couche de surface, utilisez parseToNode. (Mecab-python3 semble avoir un bogue qui ne fonctionne pas correctement avec les versions antérieures à 0.996.2)
import MeCab
tagger = MeCab.Tagger()
node = tagger.parseToNode('<Déclaration d'entrée>')
#Premier et dernier nœud.surface sera une chaîne vide
while node:
print(node.surface)
node = node.next
** -Owakati ** Si vous exécutez MeCab.Tagger () avec un argument, vous ne pouvez afficher que le résultat du libellé divisé par un espace ('') comme lorsque vous exécutez $ mecab -Owakati
sur la ligne de commande. ..
Cependant, lorsqu'un mot contenant un espace demi-largeur apparaît, le délimiteur et une partie de l'espace demi-largeur du mot ne peuvent pas être distingués et ne peuvent pas être correctement séparés. ** Cette implémentation doit être évitée. ** (Parce que certains dictionnaires traitent des mots qui incluent des espaces demi-largeur)
En représentant une phrase avec un vecteur (de longueur fixe), il devient un format calculable par ordinateur.
Bag of Words
Comme indiqué ci-dessous, une phrase est représentée par un vecteur de longueur fixe (ici, longueur 10).
Exemple de sac de mots
#Je t'aime je t'aime je m'aime
bow0 = [2, 1, 0, 2, 1, 2, 1, 1, 1, 1]
#J'aime les ramen
bow1 = [1, 0, 1, 1, 0, 1, 1, 0, 0, 1]
Détails du code omis. Vérifiez le résultat de la notation d'inclusion.
test_bag_of_words.py
from tokenizer import tokenize
import pprint
texts = [
'Je t'aime j'aime je',
'J'aime les ramen',
'Le mont Fuji est la plus haute montagne du Japon'
]
tokenized_texts = [tokenize(text) for text in texts]
pprint.pprint(tokenized_texts)
bow = [[0] * 14 for i in range(len(tokenized_texts))]
pprint.pprint(bow)
Résultat d'exécution
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python test_bag_of_words.py
[['je', 'Est', 'je', 'Mais', 'Comme', 'Nana', 'あNanaた', 'Mais', 'Comme', 'est'],
['je', 'Est', 'ramen', 'Mais', 'Comme', 'est'],
['Mont Fuji', 'Est', 'N ° 1 au Japon', 'haute', 'Montagne', 'est']]
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Le Bag of Words peut être implémenté plus simplement en utilisant la classe Counter du module collections, qui est une bibliothèque Python standard.
Vérifiez les progrès sur le chemin. Le résultat de la vectorisation est le même que le résultat de "Implémentation d'un sac de mots" ci-dessus.
test_bag_of_words_counter_ver.py
from collections import Counter
from tokenizer import tokenize
import pprint
texts = [
'Je t'aime je t'aime je m'aime',
'J'aime les ramen',
'Le mont Fuji est la plus haute montagne du Japon'
]
tokenized_texts = [tokenize(text) for text in texts]
print('# Counter(..)')
print(Counter(tokenized_texts[0]))
counts = [Counter(tokenized_text) for tokenized_text in tokenized_texts]
print('# [Counter(..) for .. in ..]')
pprint.pprint(counts)
sum_counts = sum(counts, Counter())
print('# sum(.., Counter())')
pprint.pprint(sum_counts)
vocabulary = sum_counts.keys()
print('# sum_counts.keys')
print(vocabulary)
print('# [[count[..] for .. in .. ] for .. in ..]')
pprint.pprint([[count[word] for word in vocabulary] for count in counts])
Résultat d'exécution
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python test_bag_of_words_counter_ver.py
# Counter(..)
Counter({'je': 2, 'Mais': 2, 'Comme': 2, 'Est': 1, 'de': 1, 'chose': 1, 'Nana': 1, 'あNanaた': 1, 'est': 1})
# [Counter(..) for .. in ..]
[Counter({'je': 2,
'Mais': 2,
'Comme': 2,
'Est': 1,
'de': 1,
'chose': 1,
'Nana': 1,
'tu': 1,
'est': 1}),
Counter({'je': 1, 'Est': 1, 'ramen': 1, 'Mais': 1, 'Comme': 1, 'est': 1}),
Counter({'Mont Fuji': 1, 'Est': 1, 'N ° 1 au Japon': 1, 'haute': 1, 'Montagne': 1, 'est': 1})]
# sum(.., Counter())
Counter({'je': 3,
'Est': 3,
'Mais': 3,
'Comme': 3,
'est': 3,
'de': 1,
'chose': 1,
'Nana': 1,
'tu': 1,
'ramen': 1,
'Mont Fuji': 1,
'N ° 1 au Japon': 1,
'haute': 1,
'Montagne': 1})
# sum_counts.keys
dict_keys(['je', 'Est', 'de', 'chose', 'Mais', 'Comme', 'Nana', 'あNanaた', 'est', 'ramen', 'Mont Fuji', 'N ° 1 au Japon', 'haute', 'Montagne'])
# [[count[..] for .. in .. ] for .. in ..]
[[2, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1]]
Il peut être implémenté manuellement comme décrit ci-dessus, mais comme scikit-learn fournit ** sklearn.feature_extraction.text.CountVectorizer ** en tant que classe avec la capacité de calculer BoW, l'implémentation l'utilise. ..
vectorizer = CountVectorizer(tokenizer = tokenize) #Collable en tokenizer(Fonctions, méthodes)Pour spécifier comment diviser la phrase
vectorizer.fit(texts) #Créer un dictionnaire
bow = vectorizer.transform(texts) #Calculer BoW
Dans le contexte de l'apprentissage automatique, la saisie d'un vecteur de caractéristiques et la sortie de son identifiant de classe s'appellent identification, et l'objet ou la méthode qui le fait s'appelle un classificateur.
Chaque composant fourni par scikit-learn (CountVectorizer, SVC, etc.) est conçu pour avoir une API unifiée telle que fit (), predict (), transform (), ** sklearn.pipeline.Pipeline ** Peut être résumé avec.
exemple de pipeline
from sklearn.pipeline import Pipeline
pipeline = Pipeline([
('vectorizer', CountVectorizer(tokenizer = tokenizer),
('classifier', SVC()),
])
# vectorizer.fit() +
# vectorizer.transform() +
# classifier.fit()
pipeline.fit(texts, labels)
# vectorizer.transform() +
# classifier.predict()
pipeline.predict(texts) #
Évaluez les performances des systèmes d'apprentissage automatique avec des indicateurs quantitatifs.
Il existe différents indicateurs, mais ici nous examinerons la précision (taux de réponse correct). Comme le montre l'exemple ci-dessous, la précision calcule le rapport entre le résultat de l'identification du modèle et l'étiquette des données de test et les données de test.
from dialogue_agent import DialogueAgent
dialogue_agent = DialogueAgent()
dialogue_agent.train(<train_text>, <train_label>)
predictions = dialogue_agent.predict(<test_text>)
print(accuracy_score(<test_label>, predictions))
Résultat d'exécution
0.37234042...
Le taux de réponse correcte n'est toujours que de 37%.
Recommended Posts