Dies ist ein Memo für mich, während ich Einführung in Anwendungen zur Verarbeitung natürlicher Sprache in 15 Schritten lese. Notieren Sie sich diesmal in Kapitel 2, Schritt 01, Ihre eigenen Punkte.
Erleben Sie einige Elemente der Programmierung der Verarbeitung natürlicher Sprache mit einem einfachen Dialogagenten als Thema.
--Schreiben
#Skriptdialog, den Sie ausführen möchten_agent.Führen Sie das Verzeichnis aus, in dem py vorhanden ist
#Es wird jedoch davon ausgegangen, dass sich die für die Ausführung erforderliche CSV ebenfalls im selben Verzeichnis befindet.
# docker run -it -v $(pwd):/usr/src/app/ <Docker-Bild>:<Etikett> python <Ausführungsskript>
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python dialogue_agent.py
Was erstellt werden sollte, ist "ein System, das die Klasse vorhersagt, zu der die Anweisung gehört, und die Klassen-ID ausgibt, wenn die Anweisung eingegeben wird". Dies ist eine Problemeinstellung, die als Textklassifizierung bezeichnet wird.
#Ausführungsbild des Dialogagenten-Systems
~~
dialogue_agent = DialogueAgent()
dialogue_agent.train(training_data)
predicted_class = dialogue_agent.predict('Eingabeanweisung')
~~
Das Zerlegen eines Satzes in Wörter wird als Schreiben bezeichnet. Sprachen mit Leerzeichen zwischen Wörtern, wie z. B. Englisch, werden nicht benötigt. ** MeCab ** wird häufig als Software zum Schreiben auf Japanisch verwendet. Das Weidenschreiben, das das Hinzufügen von Teiltextinformationen enthält, wird als ** morphologische Analyse ** bezeichnet.
Wenn Sie nur den Oberflächenebenentyp abrufen möchten, verwenden Sie parseToNode. (Mecab-python3 scheint einen Fehler zu haben, der mit Versionen älter als 0.996.2 nicht richtig funktioniert.)
import MeCab
tagger = MeCab.Tagger()
node = tagger.parseToNode('<Eingabeanweisung>')
#Erster und letzter Knoten.Oberfläche wird eine leere Zeichenfolge sein
while node:
print(node.surface)
node = node.next
** -Owakati ** Wenn Sie MeCab.Tagger () mit einem Argument ausführen, können Sie nur das Ergebnis des Wortlauts geteilt durch ein Leerzeichen ('') ausgeben, wie wenn Sie $ mecab -Owakati in der Befehlszeile ausführen. .. Wenn jedoch ein Wort mit einem Raum halber Breite angezeigt wird, können das Trennzeichen und ein Teil des Raums halber Breite des Wortes nicht unterschieden und nicht korrekt getrennt werden. ** Diese Implementierung sollte vermieden werden. ** (Da einige Wörterbücher Wörter mit Leerzeichen halber Breite verarbeiten)
Durch die Darstellung eines Satzes mit einem Vektor (fester Länge) wird ein computerberechnbares Format.
Bag of Words
Wie unten gezeigt, wird ein Satz durch einen Vektor fester Länge (hier Länge 10) dargestellt.
Bag of Words Beispiel
#Ich mag dich Ich mag dich Ich mag mich
bow0 = [2, 1, 0, 2, 1, 2, 1, 1, 1, 1]
#Ich mag Ramen
bow1 = [1, 0, 1, 1, 0, 1, 1, 0, 0, 1]
Codedetails weggelassen. Überprüfen Sie das Ergebnis der Einschlussnotation.
test_bag_of_words.py
from tokenizer import tokenize
import pprint
texts = [
'Ich mag dich, ich mag mich',
'Ich mag Ramen',
'Der Fuji ist der höchste Berg Japans'
]
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)
Ausführungsergebnis
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python test_bag_of_words.py
[['ich', 'Ist', 'ich', 'Aber', 'Mögen', 'Nana', 'あNanaた', 'Aber', 'Mögen', 'ist'],
['ich', 'Ist', 'Ramen', 'Aber', 'Mögen', 'ist'],
['Fuji Berg', 'Ist', 'Nr. 1 in Japan', 'hoch', 'Berg', 'ist']]
[[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]]
Die Bag of Words kann einfacher implementiert werden, indem die Counter-Klasse des Sammlungsmoduls verwendet wird, bei dem es sich um eine Standard-Python-Bibliothek handelt.
Überprüfen Sie den Fortschritt auf dem Weg. Das Ergebnis der Vektorisierung ist das gleiche wie das Ergebnis der obigen "Implementierung des Wortbeutels".
test_bag_of_words_counter_ver.py
from collections import Counter
from tokenizer import tokenize
import pprint
texts = [
'Ich mag dich Ich mag dich Ich mag mich',
'Ich mag Ramen',
'Der Fuji ist der höchste Berg Japans'
]
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])
Ausführungsergebnis
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python test_bag_of_words_counter_ver.py
# Counter(..)
Counter({'ich': 2, 'Aber': 2, 'Mögen': 2, 'Ist': 1, 'von': 1, 'Ding': 1, 'Nana': 1, 'あNanaた': 1, 'ist': 1})
# [Counter(..) for .. in ..]
[Counter({'ich': 2,
'Aber': 2,
'Mögen': 2,
'Ist': 1,
'von': 1,
'Ding': 1,
'Nana': 1,
'Sie': 1,
'ist': 1}),
Counter({'ich': 1, 'Ist': 1, 'Ramen': 1, 'Aber': 1, 'Mögen': 1, 'ist': 1}),
Counter({'Fuji Berg': 1, 'Ist': 1, 'Nr. 1 in Japan': 1, 'hoch': 1, 'Berg': 1, 'ist': 1})]
# sum(.., Counter())
Counter({'ich': 3,
'Ist': 3,
'Aber': 3,
'Mögen': 3,
'ist': 3,
'von': 1,
'Ding': 1,
'Nana': 1,
'Sie': 1,
'Ramen': 1,
'Fuji Berg': 1,
'Nr. 1 in Japan': 1,
'hoch': 1,
'Berg': 1})
# sum_counts.keys
dict_keys(['ich', 'Ist', 'von', 'Ding', 'Aber', 'Mögen', 'Nana', 'あNanaた', 'ist', 'Ramen', 'Fuji Berg', 'Nr. 1 in Japan', 'hoch', 'Berg'])
# [[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]]
Es kann manuell wie oben beschrieben implementiert werden, aber da scikit-learn ** sklearn.feature_extraction.text.CountVectorizer ** als Klasse mit der Fähigkeit zur Berechnung der BoW bereitstellt, verwendet die Implementierung dies. ..
vectorizer = CountVectorizer(tokenizer = tokenize) #Collable to Tokenizer(Funktionen, Methoden)Festlegen, wie der Satz aufgeteilt werden soll
vectorizer.fit(texts) #Erstellen Sie ein Wörterbuch
bow = vectorizer.transform(texts) #BoW berechnen
Im Kontext des maschinellen Lernens wird die Eingabe eines Merkmalsvektors und die Ausgabe seiner Klassen-ID als Identifikation bezeichnet, und das Objekt oder die Methode, die dies tut, wird als Klassifizierer bezeichnet.
Jede von scikit-learn bereitgestellte Komponente (CountVectorizer, SVC usw.) verfügt über eine einheitliche API wie fit (), Predict (), transform (), ** sklearn.pipeline.Pipeline ** Kann mit zusammengefasst werden.
Pipeline-Beispiel
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) #
Bewertung der Leistung maschineller Lernsysteme anhand quantitativer Indikatoren.
Es gibt verschiedene Indikatoren, aber hier werden wir die Genauigkeit (korrekte Antwortrate) betrachten. Wie im folgenden Beispiel gezeigt, berechnet die Genauigkeit das Verhältnis des Modellidentifikationsergebnisses und des Testdatenetiketts zu den Testdaten.
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))
Ausführungsergebnis
0.37234042...
Die richtige Antwortrate beträgt immer noch nur 37%.
Recommended Posts