Ich werde den Algorithmus des Naive Bayes-Klassifikators (Beckenfilter) anhand konkreter numerischer Werte erläutern. Ich habe es auch in Python implementiert. Ich habe es als mein eigenes Studienmemo geschrieben, aber ich hoffe, es wird anderen Menschen nützlich sein.
Es ist eine der überwachten Lernmethoden des maschinellen Lernens, mit der Sie bestimmen können, zu welcher Kategorie bestimmte Daten (Sätze) gehören. Es wird häufig für Spam-Mail-Filter und die Kategorisierung von WEB-Nachrichtenartikeln verwendet.
Es ist eine einfache Methode, die den Satz von Bayes verwendet, und der Schwierigkeitsgrad ist niedrig. Ich habe versucht zu erklären, ohne so viele mathematische Formeln wie möglich zu verwenden.
Ich werde die Berechnungslogik zur Bestimmung der Kategorie, in die der Zielsatz fällt, anhand konkreter numerischer Werte erläutern.
Wenn die Trainingsdaten wie folgt sind, berechnen Sie, in welche Kategorie der Zielsatz fällt.
** Lerndaten **
*Fußball[Ball|Sport|Weltmeisterschaft|Ball] *Baseball[Ball|Sport|Handschuhe|Schläger] *Tennis[Ball|Schläger|Mantel]
Fußball [Ball | Sport]
Es wird angenommen, dass das Innere von [] ein verbundenes Dokument ist.
** Zieldokument ** "Ballsport"
Der Wert, der durch Teilen der Anzahl der Dokumente in jeder Kategorie von Trainingsdaten durch die Gesamtzahl der Dokumente erhalten wird, ist definiert als "** Erscheinungsrate der Kategorie P (C) **".
Fußball | Baseball | Tennis | |
---|---|---|---|
Wahrscheinlichkeit des Auftretens der Kategorie |
Zählen Sie die Anzahl der Wörter in jeder Kategorie in den Trainingsdaten. Duplikate sind nicht ausgeschlossen und Fußball ist total.
Fußball | Baseball | Tennis | |
---|---|---|---|
Anzahl der Wörter |
Zählen Sie die Anzahl der Vorkommen in jeder Kategorie von "Ball" und "Sport" und dividieren Sie durch die Anzahl der Wörter in jeder oben gezählten Kategorie. Dies sei "** Wortvorkommensrate P (Wn | C) ** in der Kategorie".
Fußball | Baseball | Tennis | |
---|---|---|---|
Ball | |||
Sport |
Der Wert, der durch Multiplizieren des berechneten "Ballwerts" und "Sportwerts" erhalten wird, ist definiert als "** Dokumenterscheinungsrate in Kategorie P (D | C) **".
Fußball | Baseball | Tennis | |
---|---|---|---|
Erscheinungsrate des Dokuments in der Kategorie |
1 oben.Und 2.Ausgestellt in "Kategorie Erscheinungsrate P.(C)"Wann"**Dokumentpräsentationsrate in Kategorie P.(D|C)**Wahrscheinlichkeit, dass das Produkt von "" zu jeder Kategorie für das Dokument gehört (文章内のKategorie Erscheinungsrate P.(C|D)) ist.
Der mit dem höchsten Wert wird als Zieldokumentkategorie klassifiziert.
Fußball | Baseball | Tennis | |
---|---|---|---|
Kategorie Erscheinungsrate in Sätzen | $\frac{2}{4} \times \frac{6}{36} $ | $\frac{1}{4} \times \frac{1}{16} $ | $\frac{1}{4} \times \frac{0}{9} $ |
Berechnungsergebnis |
Infolgedessen wurde "Ballsport" als "Fußball" eingestuft! !!
(Da es nur ein Beispiel ist, ist es alles Ballsport)
In diesem Beispiel beträgt die Tenniswahrscheinlichkeit jetzt $ 0 $. Dies liegt daran, dass das Wort "Sport" nicht in den Lerndaten für "Tennis" enthalten war.
Wenn es ein neues Wort gibt, das in den Trainingsdaten nicht vorhanden ist, beträgt die Wahrscheinlichkeit der Kategorie $ 0 $. Dies wird als "** Nullfrequenzproblem **" bezeichnet.
Um dies zu lösen, verwenden wir eine Methode namens additive Glättung zur Neuberechnung.
Fügen Sie einfach die unten fett gedruckte Verarbeitung zum Berechnungsteil "Wortauftrittsrate P (Wn | C) in Kategorie" in 2 hinzu.
Zählen Sie die Anzahl der Vorkommen jeder Kategorie von "Ball" und "Sport" und addieren Sie ** 1 ** und dividieren Sie durch ** die Anzahl der Wörter in jeder oben gezählten Kategorie plus ** die Gesamtzahl der Lerndatenwörter ** ..
Die Gesamtzahl der Wörter in den Trainingsdaten beträgt 8, da sie dedupliziert sind.
"Wortauftrittsrate P (Wn | C) in Kategorie" ist in der Tabelle erneut zusammengefasst.
Fußball | Baseball | Tennis | |
---|---|---|---|
Ball | |||
Sport |
Berechnen Sie den Bruch.
Fußball | Baseball | Tennis | |
---|---|---|---|
Ball | |||
Sport |
Dies zeigt, dass selbst wenn das Wort "Sport" nicht in den Trainingsdaten für "Tennis" enthalten ist, die Wahrscheinlichkeit nicht Null ist.
Berechnen Sie dann die Fortsetzung so wie sie ist.
Die in 1. berechnete "Kategorieerscheinungsrate P (C)" bleibt gleich. "Dokumenterscheinungsrate P (D | C) in Kategorie" ist das Produkt der Werte von "Ball" und "Sport", berechnet in den obigen Brüchen.
Fußball | Baseball | Tennis | |
---|---|---|---|
Wahrscheinlichkeit des Auftretens der Kategorie | |||
Erscheinungsrate des Dokuments in der Kategorie | |||
Kategorie Erscheinungsrate in Sätzen | |||
Berechnungsergebnis |
Das Ergebnis wurde als Fußball eingestuft, wobei die Wahrscheinlichkeit, dass Tennis nicht $ 0 $ beträgt, beträgt! !!
Ich denke jedoch, dass sich die Genauigkeit der additiven Glättung aufgrund des großen Effekts des Werts der "Kategorie-Erscheinungsrate P (C)" verschlechtert. Dies muss bei der Einstellung der Trainingsdaten sorgfältig berücksichtigt werden.
Aus Gründen der Übersichtlichkeit haben wir die Anzahl der Wörter und Datensätze im Beispiel reduziert, aber es handelt sich tatsächlich um mehr Wörter. Daher wird der Nenner des Berechnungsergebnisses zu einer sehr großen Zahl, und es besteht eine hohe Wahrscheinlichkeit, dass ein Unterlauf auftritt.
Die Problemumgehung ist die ** logarithmische Vergleichsmethode **.
$ 0.001 $ kann auch ausgedrückt werden als $ \ frac {1} {10} $ × $ \ frac {1} {10} $ × $ \ frac {1} {10} $, was $ 10 $ für die $ -3 $ Potenz entspricht. Gut, ** -3 ** ist der Logarithmus von $ 0,001 $. (Unten ist $ 10 $) $ 0,0001 $ kann auch als $ \ frac {1} {10} $ × $ \ frac {1} {10} $ × $ \ frac {1} {10} $ × $ \ frac {1} {10} $ ausgedrückt werden Ja, es heißt $ 10 $ für die $ -4 $ Potenz und ** - 4 ** ist der Logarithmus von $ 0,001 $. (Unten ist $ 10 $)
Die Größenrelation von $ X $, $ Y $ und $ Z $ ist dieselbe wie die Größenrelation des Logarithmus von $ X $, des Logarithmus von $ Y $ und des Logarithmus von $ Z $. (Wenn der Boden gleich und größer als 1 ist) Der Logarithmus ist größer als der ursprüngliche Wert. (Wenn der Wert kleiner als 1 ist und die Basis größer als 1 ist)
Die Größe der Wertemultiplikation entspricht auch der Größe der logarithmischen Addition. 2 x 2 x 2: Protokoll 3 2 x 2 x 2 ** x 2 **: Log 3 ** + 1 **
Die Geschichte geht auf das Beispiel zurück "Dokumenterscheinungsrate in Kategorie P.(D|C)"Ball" und "Sport" "Wortauftrittsrate in Kategorie P"(Wn|C)Berechnet als Addition des Logarithmus der "Kategorie Erscheinungswahrscheinlichkeit P"(C)Ich werde es dem Logarithmus von hinzufügen.
Fußball | Baseball | Tennis | |
---|---|---|---|
Wahrscheinlichkeit des Auftretens der Kategorie | |||
Wortauftrittsrate in der Kategorie(Ball) | |||
Wortauftrittsrate in der Kategorie(Sport) | |||
Kategorie Erscheinungsrate in Sätzen |
Damit ist der Naive Bayes-Klassifikator vervollständigt! !!
Ich habe es tatsächlich in Python mit Bezug auf die folgende Seite geschrieben. http://yaju3d.hatenablog.jp/entry/2016/10/31/222307
Ich habe versucht, in den Kommentaren so viel wie möglich zu beschreiben, wo die oben erläuterten Werte übereinstimmen. Ich benutze Janome für die morphologische Analyse.
naivebayes.py
class NaiveBayes:
#Konstrukteur
def __init__(self):
#Ein Satz aller Wörter von Trainingsdaten(Für zusätzliche Glättung)
self.vocabularies = set()
#Für Wortsätze für jede Kategorie von Trainingsdaten
self.word_count = {}
#Für eine Reihe von Dokumenten für jede Kategorie von Trainingsdaten
self.category_count = {}
#Lernen
def train(self, document, category):
#Morphologische Analyse von Lerndokumenten
ma = MorphologicalAnalysis()
word_list = ma.get_word_list(document)
for word in word_list:
#Erhöhen Sie die Anzahl der Wortvorkommen in einer Kategorie
self.__word_count_up(word, category)
#Erhöhen Sie die Anzahl der Dokumente in der Kategorie
self.__category_count_up(category)
#Erhöhen Sie die Anzahl der Wortvorkommen in der Trainingsdatenkategorie
def __word_count_up(self, word, category):
#Wenn neue Kategorie hinzufügen
self.word_count.setdefault(category, {})
#Fügen Sie der Kategorie neue Wörter hinzu
self.word_count[category].setdefault(word, 0)
#Erhöhen Sie die Anzahl der Wortvorkommen in einer Kategorie
self.word_count[category][word] += 1
#Zum gesamten Wortsatz der Trainingsdaten hinzufügen(Deduplizierung)
self.vocabularies.add(word)
#Erhöhen Sie die Anzahl der Dokumente in der Kategorie Trainingsdaten
def __category_count_up(self, category):
#Wenn neue Kategorie hinzufügen
self.category_count.setdefault(category, 0)
#Erhöhen Sie die Anzahl der Dokumente in der Kategorie
self.category_count[category] += 1
#Einstufung
def classifier(self, document):
#Nächste Kategorie
best_category = None
#Stellen Sie den minimalen ganzzahligen Wert ein
max_prob = -sys.maxsize
#Morphologische Analyse des Zieldokuments
ma = MorphologicalAnalysis()
word_list = ma.get_word_list(document)
#Erscheinungsrate der Kategorie in Dokumenten für jede Kategorie P.(C|D)Ich suche
for category in self.category_count.keys():
#Erscheinungsrate der Kategorie im Dokument P.(C|D)Ich suche
prob = self.__score(word_list, category)
if prob > max_prob:
max_prob = prob
best_category = category
return best_category
#Erscheinungsrate der Kategorie im Dokument P.(C|D)Berechnung
def __score(self, word_list, category):
#Kategorie Erscheinungsrate P.(C)Erhalten(Nehmen Sie eine logarithmische Messung gegen Unterlauf und fügen Sie hinzu)
score = math.log(self.__prior_prob(category))
#Suchen Sie die Häufigkeit von Wörtern in einer Kategorie für alle Wörter in einem Dokument
for word in word_list:
#Wortauftrittsrate in Kategorie P.(Wn|C)Berechnung(Nehmen Sie eine logarithmische Messung gegen Unterlauf und fügen Sie hinzu)
score += math.log(self.__word_prob(word, category))
return score
#Kategorie Erscheinungsrate P.(C)Berechnung
def __prior_prob(self, category):
#Anzahl der Dokumente in der Zielkategorie der Trainingsdaten/Gesamtzahl der Trainingsdatendokumente
return float(self.category_count[category] / sum(self.category_count.values()))
#Wortauftrittsrate in Kategorie P.(Wn|C)Berechnung
def __word_prob(self, word, category):
#Anzahl der Vorkommen in einer Wortkategorie+ 1 /Anzahl der Wörter in der Kategorie+Gesamtzahl der Wörter in Trainingsdaten(Additionsglättung)
prob = (self.__in_category(word, category) + 1.0) / (sum(self.word_count[category].values())
+ len(self.vocabularies) * 1.0)
return prob
#Gibt zurück, wie oft ein Wort in einer Kategorie vorkommt
def __in_category(self, word, category):
if word in self.word_count[category]:
#Anzahl der Vorkommen in einer Wortkategorie
return float(self.word_count[category][word])
return 0.0
Ich habe das Lernen und Klassifizieren der oben genannten Klassen aus Sicht aufgerufen.
view.py
def matching(request):
if request.method == 'POST':
#Erfassung des Zieldokuments
words = request.POST['words']
nb = NaiveBayes()
#Trainingsdatensatz
nb.train('Ball Sport WM Ball', 'Fußball')
nb.train('Ballsporthandschuhschläger', 'Baseball')
nb.train('Ballschlägerplatz', 'Tennis')
nb.train('Ballsport', 'Fußball')
#Holen Sie sich das Klassifizierungsergebnis
category = nb.classifier(words)
dictionary = {'category': category}
return render(request, 'matching.html', dictionary)
elif request.method == 'GET':
return render(request, 'matching.html')
Maschinelles Lernen fängt gerade erst an zu lernen und es gibt viele Dinge, die ich nicht verstehe. Da ich Python seit einigen Tagen verwende, kann der Schreibstil auch seltsam sein.
Wenn Sie in der obigen Erklärung Fehler finden, würde ich mich freuen, wenn Sie darauf hinweisen könnten.
Außerdem hat Janome die Wörter, die Katakana folgen, nicht getrennt. Ich wollte mein eigenes Memo sein, aber ich hoffe, es hilft jemandem: erröten: