Letztes Mal erklärte ich die Naive Bayes-Theorie (mathematische Formel) in Anfänger des maschinellen Lernens versuchen, Naive Bayes (1) - Theorie zu erreichen. tat.
Auf dieser Seite werde ich eine einfache Implementierung mit Python versuchen. Wie üblich wird es durch Nachahmung der Site erstellt, auf die ich verwiesen habe, daher wird es erklärt und diese Erklärung, wenn Sie interessiert sind. Übrigens habe ich Python überhaupt nicht geschrieben, also bitte mit warmen Augen zuschauen ...
Der Beispielcode befindet sich unten.
Die Naive Bayes-Formel könnte ausgedrückt werden als:
P(cat|doc) = \log P(cat) + \prod_{i=0}^k \log P(word_k|cat)
Ich weiß nicht, ob es ein Programm ist ... Ich werde zuerst organisieren, was ich brauche.
< P(cat) >
{'cat1': 1, 'cat2': 1, ...}
< P(word|cat) >
nb = NaiveBayes()
nb.train(data)
Ich möchte es wie oben verwenden, also entwerfe ich es als Klasse. Wenn Sie mit init angeben, was Sie oben benötigen, lautet der Code bis zu init.
class NaiveBayes:
def __init__(self):
self.vocabularies = set() #Nicht doppelte Kategorie
self.categories = set() #Nicht überlappender Wortschatz
self.category_count = {} #Anzahl der Vorkommen der Kategorie, category_count[cat]
self.word_count = {} #Anzahl der Wortvorkommen für jede Kategorie, word_count[cat]
...
set ()
ist ein eindeutiges Array. Wird für Vokabeln und Kategorien verwendet.{}
Ist ein Wörterbuch. Es wird verwendet, um die Anzahl der Kategorien und die Anzahl der Wörter in jeder Kategorie zu zählen.def train(self, data):
self.category_count = defaultdict(lambda: 0)
for d in data:
category = d[0]
self.categories.add(category) #Kategorie hinzufügen
self.category_count[category] += 1
for word in d[1:]: #Vokabeln hinzufügen
self.vocabularies.add(word)
for category in self.categories:
self.word_count[category] = defaultdict(lambda: 0)
for d in data:
category = d[0]
for word in d[1:]:
self.word_count[category][word] += 1
Dies ist eine Vorbereitung. Schon ... das war's.
from collections import defaultdict
hash = {}
hash = defaultdict(lambda: 0)
Sie können defaultdict
verwenden, um den Anfangswert anzugeben, wenn kein Wert vorhanden ist. Ich war besorgt über die Laplace-Glättung, entschied mich jedoch, der Berechnung "+ 1" hinzuzufügen.
P(word|cat)
\prod_{i=0}^k \log P(word_k|cat)
Definieren Sie eine Funktion namens "word_probability", um jeden Term von zu berechnen. Wie finde ich das?
P(word_k|cat) = \frac{Kategorie(cat)Worte in(word)Anzahl der Auftritte+ 1}{Kategorie(cat)Gesamtzahl der Wörter, die in erscheinen+Gesamtzahl der Wörter}
Es war. Hier wenden wir "Laplace Smoothing" an.
def word_probability(self, word, category):
'''Wahrscheinlichkeit, eine Kategorie zu sein, wenn ein Wort gegeben wird, P(word|cat)'''
#Wenden Sie Laplace Smoothing an
word_count = self.word_count[category][word] + 1
vocabulary_count = sum(self.word_count[category].values()) + len(self.vocabularies)
return float(word_count) / float(vocabulary_count)
Berechnen Sie P (cat | doc)
.
P(cat|doc) = \log P(cat) + \prod_{i=0}^k \log P(word_k|cat)
Wenn ein Satz gegeben wird, wird die obige Funktion verwendet, um eine Funktion zu erstellen, die die Punktzahl berechnet, da die Gesamtwahrscheinlichkeit jedes Wortes berechnet werden muss. Bitte beachten Sie jedoch, dass das Produkt von Protokollen mit derselben Basis die Summe der Produkte und nicht das Gesamtprodukt ist. Da die Basis von "log" 10 ist, ist dies bei der Berechnung ein negativer Wert. Ich persönlich mochte es nicht, also habe ich am Ende "x (-1)" gemacht. Ich denke, einer von beiden ist in Ordnung.
Setzen Sie zuerst P (cat)
in score
und fügen Sie dannP (word | cat)
in eine Schleife ein.
def score(self, words, category):
'''Unterlagen(Wort)Wahrscheinlichkeit, eine gegebene Kategorie zu sein'''
documents_count = sum(self.category_count.values())
score = math.log(float(self.category_count[category]) / documents_count)
for word in words:
score += math.log(self.word_probability(word, category))
#Da der untere Rand des Protokolls 10 ist, ist er negativ+Zu
return score * (-1)
Nun, es ist endlich Klassifizierung. In Wirklichkeit werden Sie diese Funktion nach dem Training einfach aufrufen.
def classify(self, words):
'''P(cat|doc)Gibt die größte Kategorie zurück'''
best = None
value = 0
for category in self.categories:
v = self.score(words, category)
if v > value:
best = category
value = v
return best
Die Struktur ist einfach, sie berechnet die Punktzahl für alle Kategorien, die in der Lernphase bestanden wurden, und gibt die höchste zurück.
#coding:utf-8
from collections import defaultdict
import math
class NaiveBayes:
def __init__(self):
self.vocabularies = set() #Nicht doppelte Kategorie
self.categories = set() #Nicht überlappender Wortschatz
self.category_count = {} #Anzahl der Vorkommen der Kategorie, category_count[cat]
self.word_count = {} #Anzahl der Wortvorkommen für jede Kategorie, word_count[cat]
def train(self, data):
self.category_count = defaultdict(lambda: 0)
for d in data:
category = d[0]
self.categories.add(category) #Kategorie hinzufügen
self.category_count[category] += 1
for word in d[1:]: #Vokabeln hinzufügen
self.vocabularies.add(word)
for category in self.categories:
self.word_count[category] = defaultdict(lambda: 0)
for d in data:
category = d[0]
for word in d[1:]:
self.word_count[category][word] += 1
def word_probability(self, word, category):
'''Wahrscheinlichkeit, eine Kategorie zu sein, wenn ein Wort gegeben wird, P(word|cat)'''
#Wenden Sie Laplace Smoothing an
word_count = self.word_count[category][word] + 1
vocabulary_count = sum(self.word_count[category].values()) + len(self.vocabularies)
return float(word_count) / float(vocabulary_count)
def score(self, words, category):
'''Unterlagen(Wort)Wahrscheinlichkeit, eine gegebene Kategorie zu sein'''
documents_count = sum(self.category_count.values())
score = math.log(float(self.category_count[category]) / documents_count)
for word in words:
score += math.log(self.word_probability(word, category))
#Da der untere Rand des Protokolls 10 ist, ist er negativ+Zu
return score * (-1)
def classify(self, words):
'''P(cat|doc)Gibt die größte Kategorie zurück'''
best = None
value = 0
for category in self.categories:
v = self.score(words, category)
if v > value:
best = category
value = v
return best
if __name__ == "__main__":
data = [["yes", "Chinese", "Beijing", "Chinese"],
["yes", "Chinese", "Chinese", "Shanghai"],
["yes", "Chinese", "Macao"],
["no", "Tokyo", "Japan", "Chinese"]]
#Trainiere den Naive Bayes Klassifikator
nb = NaiveBayes()
nb.train(data)
print "P(Chinese|yes) = ", nb.word_probability("Chinese", "yes")
print "P(Tokyo|yes) = ", nb.word_probability("Tokyo", "yes")
print "P(Japan|yes) = ", nb.word_probability("Japan", "yes")
print "P(Chinese|no) = ", nb.word_probability("Chinese", "no")
print "P(Tokyo|no) = ", nb.word_probability("Tokyo", "no")
print "P(Japan|no) = ", nb.word_probability("Japan", "no")
#
# #Vorhersage von Testdatenkategorien
test = ["Chinese", "Chinese", "Chinese", "Tokyo", "Japan"]
print "log P(yes|test) =", nb.score(test, "yes")
print "log P(no|test) =", nb.score(test, "no")
print nb.classify(test)
Ich habe sehr viel auf die folgenden Seiten verwiesen. Vielen Dank.
Recommended Posts