Förderung des Verständnisses für maschinelles Lernen Eine klassische Methode zum automatischen Erstellen eines Klassifizierungsmodells aus Daten: Ich habe einen Naive Bayes-Klassifikator implementiert. In letzter Zeit ist die Bildanalyse wie Cloud Vision API populär geworden. Die Schwelle schien für Anfänger hoch zu sein, daher ist der erste Schritt die Verarbeitung natürlicher Sprache.
Dieses Mal werden wir die Twitter-API verwenden, um Angebote vom Bot-Konto zu sammeln. ** Hanyu-Klassifikator ** implementiert, um Hanyu-san und Hanyu-kun zu klassifizieren.
Der API-Client ist in Ruby implementiert, und der Klassifizierer ist in Python implementiert. MeCab wird zur morphologischen Analyse verwendet.
Auch wo beide Mr. Hanyu heißen sollten, Erlauben Sie bitte, dass Herr Hanyu, ein Eiskunstläufer, als Herr Hanyu bezeichnet wird.
APIClient wird mithilfe von Twitter Ruby Gem wie folgt implementiert. Die Twitter-API hat ein Limit für die Anzahl der Ausführungen pro Stunde, das als [Ratenlimits] bezeichnet wird (https://dev.twitter.com/rest/public/rate-limiting). Wenn Sie viele Tweets erhalten möchten, müssen Sie ein Intervall von ca. 15 Minuten festlegen. Bitte machen Sie von Zeit zu Zeit eine Kaffeepause.
require 'twitter'
client = Twitter::REST::Client.new do |config|
config.consumer_key = 'XXX'
config.consumer_secret = 'YYY'
config.access_token = 'hoge'
config.access_token_secret = 'fuga'
end
client.user_timeline('TwitterUserID',{ count: 150}).each_with_index do |tl,i|
tw = client.status(tl.id)
tweet = tw.text
#Vermeiden Sie Doppelarbeit
if !tweets.include?(tweet)
puts tweet
end
end
Verarbeiten wir nun die zuvor erfassten Daten. Wie ich später erläutern werde, zerlegen Sie zuerst die gesammelten Tweets in zwei Tweets, um zu quantifizieren und zu klassifizieren, ob die Tweets Wörter enthalten, die Herr Hanyu und Herr Hanyu wahrscheinlich sagen. Die 50 häufigsten Wörter, die häufig vorkommen, werden erfasst, und insgesamt 100 Wörter werden als Variablen für die Klassifizierung erfasst. (Tatsächlich gab es Duplikate, also gibt es 91 Fälle.)
Zunächst wurden diesmal nur ** Nomenklaturen, Verben und Adjektive ** gezählt. (Die Verwendung von Verben und Adjektiven wurde auf die Grundform korrigiert.)
Formale Nomenklatur, die für das personenbezogene Vokabular wie unten gezeigt irrelevant zu sein scheint Es scheint, dass es durch die Trennung von verbalisierter Nomenklatur und Adjektiven verursacht wurde, Ich habe einige Listen von Wörtern festgelegt, die nicht gezählt werden.
ng_noun = ["Ding", "von", "もvon", "Es", "Wann", "、", ",", "。", "¡", "(", ")", "."]
ng_verb = ["Machen", "Ist", "Werden", "Gibt es"]
ng_adjective = ["Yo"]
Das Paket * Sammlungen * ist nützlich, um gegenläufige Listen (Taples) zu generieren. Ich habe auch natto für die Bindung zwischen Python und MeCab verwendet.
import collections
from sets import Set
from natto import MeCab
def mostFrequentWords(file, num):
words = collections.Counter()
f = open(file)
line = f.readline()
while line:
#Substantiv:surface="Schlittschuh", feature="Substantiv,Allgemeines,*,*,*,*,Schlittschuh,Schlittschuh,Schlittschuh"
#Verb:surface="Unterhose", feature="Verb,Unabhängigkeit,*,*,Ein Schritt,Unvollkommene Form,Unterhoseる,Sklave,Sklave"
for node in mecab.parse(line, as_nodes=True):
features = node.feature.split(",")
if features[0] == "Substantiv" and node.surface not in ng_noun:
words[node.surface] += 1
elif features[0] == "Verb" and features[6] not in ng_verb:
words[features[6]] += 1
elif features[0] == "Adjektiv" and features[6] not in ng_adjective:
words[features[6]] += 1
line = f.readline()
return words.most_common(num
words["hanyu"] = mostFrequentWords("hanyu_train.txt", 50)
words["habu"] = mostFrequentWords("habu_train.txt", 50)
tpl = words["hanyu"] + words["habu"]
vocabulary = set([])
for word in tpl:
vocabulary.add(word[0])
Hier ist eine kurze Erklärung des mathematischen Hintergrunds.
Erstens ist der Naive Bayes-Klassifikator ein wahrscheinlichkeitsbasierter Klassifikator. Was ich diesmal fragen möchte, ist, wenn ein bestimmtes Dokument (hier jeder Tweet) * d * gegeben wird. Ob es eine hohe Wahrscheinlichkeit gibt, zu welcher Klasse zu gehören (Herr Hanyu oder Herr Hanyu) * c *. Dies kann als * P (c | d) * als bedingte Wahrscheinlichkeit für einen Tweet ausgedrückt werden. Da es jedoch schwierig ist, diese hintere Wahrscheinlichkeit direkt zu erhalten, wird sie unter Verwendung des ** Bayes'schen Theorems ** berechnet.
P(c|d) = \frac{P(c)P(d|c)}{P(d)}
Berechnen Sie hier die rechte Seite für jede Klasse, dh Hanyu-san / Hanyu-kun, Finden Sie heraus, zu welchem Tweet der Tweet am wahrscheinlichsten gehört. Der Nenner * P (d) * ist jedoch unabhängig von der Klasse konstant, sobald der Klassifikator konstruiert ist. ** Es wäre gut, nur das Molekül zu berechnen **.
P(c) Dieses Mal erhielten wir jeweils 100 Tweets für Herrn Hanyu und Herrn Hanyu, und 70 trainierten Daten für den Bau eines Klassifikators. 30 Fälle werden als Testdaten zur Überprüfung der Genauigkeit des Klassifikators verwendet.
P(d|c) Wenn Sie nun über die Bedeutung dieser bedingten Wahrscheinlichkeit nachdenken * P (d | c) *, Herr Hanyu, Hanyu-Kun, abhängig von der Kombination der Wortarten, die jeder sagen kann Sie müssen die Wahrscheinlichkeit finden, dass jeder Tweet auftritt, aber es ist unmöglich. Daher wird es unter Verwendung eines vereinfachten Modells ausgedrückt, das für die Klassifizierung von Dokumenten geeignet ist. Hier ** Über die Wortgruppe * V *, die Herr Hanyu und Herr Hanyu wahrscheinlich sagen werden Überlegen Sie, ob sie in den klassifizierten Tweets enthalten sind oder nicht **.
Die Verteilung von stochastischen Variablen, die zwei Werte annehmen, wie z. B. sagen / nicht sagen, ist die ** Bernoulli-Verteilung **.
{P_{w,c}}^{\delta_{w,d}}(1-{P_{w,c}})^{1-\delta_{w,d}}
Dieser Exponentialteil wird als Delta-Funktion bezeichnet, und 0 wird ausgegeben, wenn * w * = * d *, und 1 wird ansonsten ausgegeben. Du denkst es gut.
Betrachten Sie hier die Bernoulli-Verteilung für jedes Wort * w *, das zur Menge * V * gehört. Das ** multivariate Bernoulli-Modell ** repräsentiert * P (d | c) *.
\prod_{w \in V}{P_{w,c}}^{\delta_{w,d}}(1-{P_{w,c}})^{1-\delta_{w,d}}
Übrigens können die folgenden zwei Punkte aus den obigen Ausführungen als Merkmale des multivariaten Bernoulli-Modells abgelesen werden.
Zusammenfassend kann es wie folgt ausgedrückt werden: Berechnen Sie also die rechte Seite für jeden von Herrn Hanyu und Herrn Hanyu. Höherer Wert = ** Bestimmt, welche Annahme mit größerer Wahrscheinlichkeit Daten generiert **. Dieses "Produkt der Wahrscheinlichkeiten, mit denen Beobachtung d unter Hypothese c auftritt" wird als ** Wahrscheinlichkeit ** bezeichnet, und der Ansatz, das wahrscheinlichste c zu finden, das diese Wahrscheinlichkeit maximiert, ist ** wahrscheinlichste Methode **. Wird genannt.
P(D) = {P(c)P(d|c)} = p_c\prod_{w \in V}({P_{w,c}}^{\delta_{w,d}}(1-{P_{w,c}})^{1-\delta_{w,d}})
Da die Beschreibung der Formel nicht der Zweck ist, wird die Formel in der Mitte gefaltet, aber wenn sie transformiert wird,
\log P(D) = \sum N_c \log p_c + \sum_c \sum_{w \in V} N_{w,c} \log p_{w,c} + \sum_c \sum_{w \in V} (N_c - N_{w,c}) \log(1 - p_{w,c})
Es wird so sein. Es fühlt sich so an, als ob die Delta-Funktion dahin gegangen wäre, aber wie oben erwähnt, hat sie die Eigenschaft, 0 zu sein, wenn * w * = * d *, und ansonsten 1, so dass das Wort * w * und die Klasse * c * gleichzeitig vorkommen. Es wird durch Multiplizieren der Anzahl ausgedrückt. Das Lesen mag unangenehm erscheinen, aber der Punkt ist, dass die Verteilung durch zwei Parameter bestimmt wird, ** Pw, c und Pc **.
Es wäre schön, c zu finden, das das obige logP (D) maximiert, wenn die zu klassifizierenden Daten angegeben werden. Hier wird angenommen, dass alle Tweets der Welt von Herrn Hanyu oder Herrn Hanyu ** geschrieben wurden. Es ist notwendig, die durch die folgende Formel ausgedrückte Bedingung zu erfüllen, dass die Summe der Wahrscheinlichkeiten für die Klassifizierung in jede Klasse 1 ist.
\sum_c p_c = 1
(Dies ist auch nicht das Hauptthema, daher werde ich es falten.) Dies wird als konvexes Planungsproblem mit Gleichungsbeschränkungen bezeichnet. Für die Lagrange-Funktion, die durch die als unbestimmte Multiplikatormethode von Lagrange bezeichnete Methode definiert wird, Der Maximalwert kann wie folgt erhalten werden, indem für jeden Parameter ein partielles Differential genommen wird.
p_{w,c} = \frac {N_{w,c}} {N_c} , p_c = \frac {N_c} {\sum_c N_c}
Nachdem wir nun wissen, wie die Parameter zu finden sind, ist es Zeit, mit der Implementierung zu beginnen.
Die folgenden Trainingsdaten wurden übrigens aus den Tweets generiert, die einer morphologischen Analyse unterzogen wurden.
cls = ["habu", "hanyu"]
#Es ist ein Bild, weil ich es der Einfachheit halber nicht zeigen kann. Wie oben erwähnt, wird der Tweet durch Anwendung einer morphologischen Analyse generiert.
vocabulary = ["Schlittschuh", "Pruschenko", "Spiel", "Gottes Bewegung"]
#Ähnlich
documents["habu"] = [["Titelverteidiger ","70", "Mann", "Hälfte", "Hanyu"],[...]]
documents["hanyu"] = [["Toll","4 Umdrehungen", "Erfolgreich", "Gewinner"],[...]]
Berechnen Sie aus den obigen Daten und der berechneten Formel die gleichzeitige Wahrscheinlichkeit * p (w, c) *, dass für jede Klasse ein Wort vorkommt.
def train(cls, vocabulary, documents):
#Anzahl der Vorkommen jedes Schulungsdokuments
n_cls = {}
total = 0.0
for c in cls:
n_cls[c] = len(documents[c])
total += n_cls[c]
#Auftrittswahrscheinlichkeit jedes Trainingsdokuments
p_cls = {}
for c in cls:
p_cls[c] = n_cls[c] / total
#Anzahl der Wortvorkommen für jede Klasse
for c in cls:
for d in documents[c]:
for word in vocabulary:
if word in d:
n_word[c][word] += 1
#Vorkommenswahrscheinlichkeit von Wörtern für jede Klasse
for c in cls:
p_word[c] = {}
for word in vocabulary:
p_word[c][word] = \
(n_word[c][word] + 1) / (n_cls[c] + 2)
Es ist ein wenig beiseite. In dem Teil, in dem die Wahrscheinlichkeit des Auftretens eines Wortes für jede Klasse berechnet wird, wird 1 zum Molekül und 2 zum Nenner addiert. Dies ist der Fall, wenn die Wahrscheinlichkeit das Produkt von Wahrscheinlichkeiten ist und das Wort im Vokabular * V * zufällig nicht im Tweet erscheint. Dies soll verhindern, dass die Wahrscheinlichkeit, dass das Integrationsergebnis 0 wird, 0 wird. (Da es sich um einen sehr kleinen Wert handelt, liegt er in Form einer Summe vor, indem bei der Implementierung ein logarithmischer Wert verwendet wird. Da 0 im logarithmischen Definitionsbereich nicht vorhanden ist, wird das Programm mit einem mathematischen Domänenfehler versehen.
Daher nehmen wir normalerweise eine Wahrscheinlichkeitsverteilung an, die als Diricre-Verteilung bezeichnet wird, was es schwierig macht, 0 zu nehmen, um das Erscheinungsbild von Wörtern zu vereinfachen. Dies wird als ** Glättung ** bezeichnet, da es die Extremwerte mildert, die häufig mit der wahrscheinlichsten Methode erzeugt werden.
Dieser Ansatz, der versucht, die Wahrscheinlichkeit zu maximieren, nachdem Daten angegeben wurden, indem die vorherige Verteilung und nicht die Leichtigkeit des Auftretens exakter Daten berücksichtigt werden, wird als ** MAP-Schätzung ** bezeichnet.
Nachdem wir endlich einen Klassifikator erstellt haben, lassen Sie uns ihn ausführen.
Unter Verwendung des von mir erstellten Klassifikators waren die Tweets, die ich gab, Herr Hanyu und Herr Hanyu, Eine Funktion, die klassifiziert, von welchem Dokument geschrieben wurde.
def classify(data):
#LogP für jede Klasse(D)Ich suche
pp = {}
for c in cls:
pp[c] = math.log(p_cls[c])
for word in vocabulary:
if word in data:
pp[c] += math.log(p_word[c][word])
else:
pp[c] += math.log((1 - p_word[c][word]))
#LogP erhalten(D)Urteil, das das größte ist
for c in cls:
maxpp = maxpp if 'maxpp' in locals() else pp[c]
maxcls = maxcls if 'maxcls' in locals() else c
if maxpp < pp[c]:
maxpp = pp[c]
maxcls =c
return (maxcls, maxpp)
Wenden wir von den erfassten Tweets die Tweets für 30 x 2 Personen an, die für die Überprüfung der Genauigkeit auf den Klassifizierer reserviert sind.
def test(data, label):
i = 0.0
for tweet in data:
if nb.classify(tweet)[0] == label:
i += 1
return (i / len(data))
# bags_of_Wörter geben eine zweidimensionale Anordnung von Teilen jedes Tweets zurück
test(bags_of_words("hanyu_test.txt"), "hanyu")
test(bags_of_words("habu_test.txt"), "habu")
Klasse | ① Anzahl der Testdaten | ② Anzahl der richtigen Antworten | Richtige Antwortrate(②/①) |
---|---|---|---|
Herr Hanyu | 30 | 28 | 93.33% |
Hanyu-Kun | 30 | 28 | 93.33% |
Es kann mit ziemlich hoher Genauigkeit bestimmt werden, Es scheint, dass dies daran liegt, dass Herr Hanyu und Herr Hanyu viele einzigartige Vokabeln enthielten. Weil es sinnvoll ist, Daten mit Verteilungen zu klassifizieren, die das gleiche Vokabular, aber unterschiedliche Häufigkeiten haben. In dieser Hinsicht waren die Testdaten möglicherweise nicht sehr gut.
Analysieren Sie als Nächstes Bild von Herrn Hanyu und Herrn Hanyu Ich möchte es probieren.
Einführung in maschinelles Lernen für die Sprachverarbeitung Unterschied zwischen Yuzuru Hanyu und Zenji Hanyu
Recommended Posts