Implementieren Sie Naive Bayes in Python 3.3

** Dies ist der erste Tagesartikel von Real Escape Advent Calendar 2013 **

Beginnen wir mit dem maschinellen Lernen Implementieren wir den 3. Basilian-Filter Implementierte die eingeführten naiven Buchten.

Der Code in diesem Artikel ist jedoch etwas verwirrend. Insbesondere gibt es viele Traps, z. B. ist der Variablenname ein einzelnes Wort namens word, aber der Typ ist list. Darüber hinaus wurde in Liste 7 auf Seite 3 ein häufiger Fehler festgestellt, dass der Vergleichsoperator falsch war. Es war. Vielleicht führen Sie den Code nicht selbst aus.

Also, der in diesem Artikel vorgestellte basilianische Filter

Neu implementiert.

Nachtrag

Mit dem in diesem Artikel erstellten Basian-Filter haben wir mithilfe der mit der Bing-API erfassten Webseite gelernt und klassifiziert. http://qiita.com/katryo/items/62291ba328de9d12bd30

Code

naive_bayes.py


#coding:utf-8
# http://gihyo.jp/dev/serial/01/machine-learning/Python3 mit 0003 Basin Filter Implementierung.Verbessert, um für 3 lesbar zu sein
import math
import sys
import MeCab


class NaiveBayes():
    def __init__(self):
        self.vocabularies = set()
        self.word_count = {}  # {'Maßnahmen gegen Pollinose': {'Sugi Pollen': 4, 'Medizin': 2,...} }
        self.category_count = {}  # {'Maßnahmen gegen Pollinose': 16, ...}

    def to_words(self, sentence):
        """
Eingang: 'Alles für mich'
Ausgabe: tuple(['alles', 'mich selber', 'von', 'Wie', 'Was'])
        """
        tagger = MeCab.Tagger('mecabrc')  #Sie können einen anderen Tagger verwenden
        mecab_result = tagger.parse(sentence)
        info_of_words = mecab_result.split('\n')
        words = []
        for info in info_of_words:
            #Wenn Sie durch Macab teilen, steht "" am Ende des Satzes davor'EOS'Kommt
            if info == 'EOS' or info == '':
                break
                # info => 'Nana\t Assistent,Letzte Hilfe,*,*,*,*,Nana,N / a,N / a'
            info_elems = info.split(',')
            #Sechstens gibt es Wörter, die nicht verwendet werden. Wenn der sechste ist'*'Wenn ja, geben Sie die 0 ein
            if info_elems[6] == '*':
                # info_elems[0] => 'Van Rossam\t Substantiv'
                words.append(info_elems[0][:-3])
                continue
            words.append(info_elems[6])
        return tuple(words)

    def word_count_up(self, word, category):
        self.word_count.setdefault(category, {})
        self.word_count[category].setdefault(word, 0)
        self.word_count[category][word] += 1
        self.vocabularies.add(word)

    def category_count_up(self, category):
        self.category_count.setdefault(category, 0)
        self.category_count[category] += 1

    def train(self, doc, category):
        words = self.to_words(doc)
        for word in words:
            self.word_count_up(word, category)
        self.category_count_up(category)

    def prior_prob(self, category):
        num_of_categories = sum(self.category_count.values())
        num_of_docs_of_the_category = self.category_count[category]
        return num_of_docs_of_the_category / num_of_categories

    def num_of_appearance(self, word, category):
        if word in self.word_count[category]:
            return self.word_count[category][word]
        return 0

    def word_prob(self, word, category):
        #Berechnung des Bayes'schen Gesetzes. Normalerweise ein Bruchteil sehr nahe bei Null.
        numerator = self.num_of_appearance(word, category) + 1  # +1 ist die Laplace-Methode zur additiven Glättung
        denominator = sum(self.word_count[category].values()) + len(self.vocabularies)

        #In Python3 wird die Division automatisch verschoben
        prob = numerator / denominator
        return prob

    def score(self, words, category):
        #Es ist ein Wort, um ein Protokoll zu führen_prob ist 0.000....Weil es eine kleine Zahl von ungefähr 01 wird
        score = math.log(self.prior_prob(category))
        for word in words:
            score += math.log(self.word_prob(word, category))
        return score

    #Wenn Sie nicht protokollieren, ist der Wert möglicherweise zu klein und läuft zu wenig.
    def score_without_log(self, words, category):
        score = self.prior_prob(category)
        for word in words:
            score *= self.word_prob(word, category)
        return score

    def classify(self, doc):
        best_guessed_category = None
        max_prob_before = -sys.maxsize
        words = self.to_words(doc)

        for category in self.category_count.keys():
            prob = self.score(words, category)
            if prob > max_prob_before:
                max_prob_before = prob
                best_guessed_category = category
        return best_guessed_category

if __name__ == '__main__':
    nb = NaiveBayes()
    nb.train('''Python ist eine Open-Source-Programmiersprache, die vom Niederländer Guido Van Rossam entwickelt wurde.
Es ist eine Art objektorientierte Skriptsprache und wird in Europa und den USA zusammen mit Perl häufig verwendet. Benannt nach der Comedy-Show "Flying Monty Python" des britischen Fernsehsenders BBC.
Python bedeutet auf Englisch Reptilien-Nishiki-Schlange und wird manchmal als Maskottchen oder Symbol in der Python-Sprache verwendet. Python ist eine allgemeine Hochsprache. Es wurde mit dem Fokus auf Programmiererproduktivität und Codezuverlässigkeit entwickelt und verfügt über eine große, praktische Standardbibliothek mit minimaler Kernsyntax und Semantik.
Es unterstützt Zeichenfolgenoperationen mit Unicode, und die japanische Verarbeitung ist standardmäßig möglich. Es unterstützt viele Plattformen (Arbeitsplattformen) und verfügt über zahlreiche Dokumente und Bibliotheken, sodass seine Verwendung in der Branche zunimmt.
             ''',
             'Python')
    nb.train('''Schlange (Schlange) ist ein allgemeiner Begriff für Reptilien, die in der Reihenfolge Serpentes klassifiziert sind.
Es zeichnet sich durch seinen schlanken Körper und keine Gliedmaßen aus. Tiere ähnlicher Form existieren jedoch auch in anderen Gruppen.
                ''', 'Snake')
    nb.train('''Ruby ist eine objektorientierte Skriptsprache, die von Yukihiro Matsumoto (allgemein bekannt als Matz) entwickelt wurde.
Realisiert objektorientierte Programmierung in Bereichen, in denen traditionell Skriptsprachen wie Perl verwendet wurden.
Ruby wurde ursprünglich am 24. Februar 1993 geboren und im Dezember 1995 auf fj angekündigt.
Der Name Ruby ist, weil die Programmiersprache Perl dasselbe ausspricht wie Pearl, der Geburtsstein des Juni.
Es wurde nach dem Rubin des Geburtssteins von Matsumotos Kollegen (Juli) benannt.
             ''',
             'Ruby')
    nb.train('''Ruby (Englisch:Ruby, Kodama) ist eine Variante von Corundum (Stahlkugel). Es ist ein Juwel mit einer charakteristischen roten Farbe.
Natürliche Rubine werden in Asien hergestellt und sind in Europa und den USA nicht erhältlich.
Selbst im Produktionsbereich sind die Orte, an denen schöne Steine, die als Juwelen verwendet werden können, erhältlich sind, äußerst begrenzt.
Große Steine über 3 Karat haben ebenfalls einen geringen Ertrag.
             ''', 'Gem')
    doc = 'Open Source von Guido Van Rossam'
    print('%s =>Geschätzte Kategorie: %s' % (doc, nb.classify(doc)))  #Geschätzte Kategorie:Sollte Python sein
    print('Wahrscheinlichkeit, in der Kategorie Python zu sein: %s' % nb.score_without_log(['Guido Van Rossam', 'Aber', 'Hat gemacht'], 'Python'))
    print('Wahrscheinlichkeit, in der Kategorie Ruby zu sein: %s' % nb.score_without_log(['Guido Van Rossam', 'Aber', 'Hat gemacht'], 'Ruby'))

    doc = 'Die Programmiersprache Ruby ist eine reine objektorientierte Sprache.'
    print('%s =>Geschätzte Kategorie: %s' % (doc, nb.classify(doc)))  #Geschätzte Kategorie:Sollte Ruby sein
    print('Wahrscheinlichkeit, in der Kategorie Ruby zu sein: %s' % nb.score_without_log(['Programmiersprache', 'von', 'Ruby', 'Ist', 'rein', 'Nana', 'Objektorientierte Sprache', 'ist', '。'], 'Ruby'))
    print('Wahrscheinlichkeit, in der Kategorie Python zu sein: %s' % nb.score_without_log(['Programmiersprache', 'von', 'Ruby', 'Ist', 'rein', 'Nana', 'Objektorientierte Sprache', 'ist', '。'], 'Python'))

    doc = 'Korund'
    print('%s =>Geschätzte Kategorie: %s' % (doc, nb.classify(doc)))  #Geschätzte Kategorie:Sollte ein Juwel sein
    print('Wahrscheinlichkeit, in der Kategorie Edelsteine zu sein: %s' % nb.score_without_log(['Korund'], 'Gem'))
    print('Wahrscheinlichkeit, in der Kategorie Ruby zu sein: %s' % nb.score_without_log(['Korund'], 'Ruby'))

Dein eigener Kommentar

Wir werden erklären, was dieser Code tut, ihn in Training aufteilen und klassifizieren.

Was machst du im Training?

Die Zugmethode (self, doc, category) von NaiveBayes gibt die Zeichenfolge doc und die Kategorie ein, zu der die Zeichenfolge gehört, und fügt das Dokument mit diesem Wort in diese Kategorie im NaiveBayes-Objekt ein. "Sollte ich?"

Das Folgende ist eine Zusammenfassung.

  1. Zerlegen Sie die Eingabezeichenfolge mit MeCab ** to_words () ** in eine Liste von Wörtern
  2. Zählen Sie, wie oft jedes Wort erscheint. ** word_count_up () **
  3. Zählen Sie, wie oft die eingegebene Kategorie eingegeben wurde ** category_count_up () **

Was Sie mit klassifizieren machen

Von den bisher in der Lernphase eingegebenen Kategorien wird "Welche ist am plausibelsten, um den eingegebenen Text aufzunehmen?" Berechnet.

Mit anderen Worten, die Bewertungsmethode wird für jede Kategorie verwendet, um die Wahrscheinlichkeit zu berechnen (das Protokoll wird verwendet, um die Berechnung zu vereinfachen).

Die Kategorie mit der höchsten Punktzahl unter allen Kategorien wird als die Kategorie mit der höchsten Wahrscheinlichkeit beurteilt, und diese Kategorie wird schließlich ausgegeben. Zu diesem Zeitpunkt wird die Laplace-Methode zur Additionsglättung verwendet.

Informationen zur Verwendung von log in NaiveBayes.score

Warum verwenden Sie log in der Score-Funktion und berechnen die mit prior_prob und word_prob berechnete Wahrscheinlichkeit logarithmisch?

Wie in Originalartikel der technischen Überprüfung angegeben, wird die Wahrscheinlichkeit nach der Formel des Bayes'schen Gesetzes berechnet Der Wert von liegt sehr nahe bei 0. Die Gesamtzahl der Wörter, die in einem Dokument erscheinen, ist enorm, und die Häufigkeit, mit der ein bestimmtes Wort (wie "Python", "rein" oder "gemacht") erscheint, ist im Vergleich sehr gering. Daher wird der Logarithmus mit e genommen, so dass er auch dann berechnet werden kann, wenn er nahe bei 0 liegt.

Was ist, wenn wir diese Wahrscheinlichkeit ohne Protokollierung berechnen? Lass es uns versuchen.

    def score(self, words, category):
        #Es ist ein Wort, um ein Protokoll zu führen_prob ist 0.000....Weil es eine kleine Zahl von ungefähr 01 wird
        score = math.log(self.prior_prob(category))
        for word in words:
            score += math.log(self.word_prob(word, category))
        return score

    #Wenn Sie nicht protokollieren, ist der Wert möglicherweise zu klein und läuft zu wenig.
    def score_without_log(self, words, category):
        score = self.prior_prob(category)
        for word in words:
            score *= self.word_prob(word, category)
        return score

score_without_log ist eine Version, die die Wahrscheinlichkeit berechnet, ohne den Logarithmus zu verwenden. Wenn man den Logarithmus von a * b * c nimmt, erhält man log (a) + log (b) + log (c). Bei der Bewertungsmethode wurde das Berechnungsergebnis von word_prob wiederholt zur Bewertung in der Schleife für Wort in Wörtern hinzugefügt, bei der Methode score_without_log wird es jedoch wiederholt multipliziert.

Wenn Sie den Code in naive_bayes.py so ausführen, wie er ist, können Sie die Auswirkungen der Protokollierung sehen.

Übrigens trainiert dieser Teil des Codes vier Kategorien: "Python, Snake, Gem, Ruby".

naive_bayes.py


if __name__ == '__main__':
    nb = NaiveBayes()
    nb.train('''Python ist eine Open-Source-Programmiersprache, die vom Niederländer Guido Van Rossam entwickelt wurde.
Es ist eine Art objektorientierte Skriptsprache und wird in Europa und den USA zusammen mit Perl häufig verwendet. Benannt nach der Comedy-Show "Flying Monty Python" des britischen Fernsehsenders BBC.
Python bedeutet auf Englisch Reptilien-Nishiki-Schlange und wird manchmal als Maskottchen oder Symbol in der Python-Sprache verwendet. Python ist eine allgemeine Hochsprache. Es wurde mit dem Fokus auf Programmiererproduktivität und Codezuverlässigkeit entwickelt und verfügt über eine große, praktische Standardbibliothek mit minimaler Kernsyntax und Semantik.
Es unterstützt Zeichenfolgenoperationen mit Unicode, und die japanische Verarbeitung ist standardmäßig möglich. Es unterstützt viele Plattformen (Arbeitsplattformen) und verfügt über zahlreiche Dokumente und Bibliotheken, sodass seine Verwendung in der Branche zunimmt.
             ''',
             'Python')
    nb.train('''Schlange (Schlange) ist ein allgemeiner Begriff für Reptilien, die in der Reihenfolge Serpentes klassifiziert sind.
Es zeichnet sich durch seinen schlanken Körper und keine Gliedmaßen aus. Tiere ähnlicher Form existieren jedoch auch in anderen Gruppen.
                ''', 'Snake')
    nb.train('''Ruby ist eine objektorientierte Skriptsprache, die von Yukihiro Matsumoto (allgemein bekannt als Matz) entwickelt wurde.
Realisiert objektorientierte Programmierung in Bereichen, in denen traditionell Skriptsprachen wie Perl verwendet wurden.
Ruby wurde ursprünglich am 24. Februar 1993 geboren und im Dezember 1995 auf fj angekündigt.
Der Name Ruby ist, weil die Programmiersprache Perl dasselbe ausspricht wie Pearl, der Geburtsstein des Juni.
Es wurde nach dem Rubin des Geburtssteins von Matsumotos Kollegen (Juli) benannt.
             ''',
             'Ruby')
    nb.train('''Ruby (Englisch:Ruby, Kodama) ist eine Variante von Corundum (Stahlkugel). Es ist ein Juwel mit einer charakteristischen roten Farbe.
Natürliche Rubine werden in Asien hergestellt und sind in Europa und den USA nicht erhältlich.
Selbst im Produktionsbereich sind die Orte, an denen schöne Steine, die als Juwelen verwendet werden können, erhältlich sind, äußerst begrenzt.
Große Steine über 3 Karat haben ebenfalls einen geringen Ertrag.
             ''', 'Gem')
    doc = 'Open Source von Guido Van Rossam'
    print('%s =>Geschätzte Kategorie: %s' % (doc, nb.classify(doc)))  #Geschätzte Kategorie:Sollte Python sein
    print('Wahrscheinlichkeit, in der Kategorie Python zu sein: %s' % nb.score_without_log(['Guido Van Rossam', 'Aber', 'Hat gemacht'], 'Python'))
    print('Wahrscheinlichkeit, in der Kategorie Ruby zu sein: %s' % nb.score_without_log(['Guido Van Rossam', 'Aber', 'Hat gemacht'], 'Ruby'))

    doc = 'Die Programmiersprache Ruby ist eine reine objektorientierte Sprache.'
    print('%s =>Geschätzte Kategorie: %s' % (doc, nb.classify(doc)))  #Geschätzte Kategorie:Sollte Ruby sein
    print('Wahrscheinlichkeit, in der Kategorie Ruby zu sein: %s' % nb.score_without_log(['Programmiersprache', 'von', 'Ruby', 'Ist', 'rein', 'Nana', 'Objektorientierte Sprache', 'ist', '。'], 'Ruby'))
    print('Wahrscheinlichkeit, in der Kategorie Python zu sein: %s' % nb.score_without_log(['Programmiersprache', 'von', 'Ruby', 'Ist', 'rein', 'Nana', 'Objektorientierte Sprache', 'ist', '。'], 'Python'))

    doc = 'Korund'
    print('%s =>Geschätzte Kategorie: %s' % (doc, nb.classify(doc)))  #Geschätzte Kategorie:Sollte ein Juwel sein
    print('Wahrscheinlichkeit, in der Kategorie Edelsteine zu sein: %s' % nb.score_without_log(['Korund'], 'Gem'))
    print('Wahrscheinlichkeit, in der Kategorie Ruby zu sein: %s' % nb.score_without_log(['Korund'], 'Ruby'))

Dies ist das Ausführungsergebnis.

Open Source von Guido Van Rossam=>Geschätzte Kategorie: Python
Wahrscheinlichkeit, in der Kategorie Python zu sein: 5.05740150710565e-08
Wahrscheinlichkeit, in der Kategorie Ruby zu sein: 2.592066486298008e-08
Die Programmiersprache Ruby ist eine reine objektorientierte Sprache. =>Geschätzte Kategorie: Ruby
Wahrscheinlichkeit, in der Kategorie Ruby zu sein: 1.0568043348436783e-20
Wahrscheinlichkeit, in der Kategorie Python zu sein: 1.4013428667584096e-21
Korund=>Geschätzte Kategorie: Gem
Wahrscheinlichkeit, in der Kategorie Edelsteine zu sein: 0.0018248175182481751
Wahrscheinlichkeit, in der Kategorie Ruby zu sein: 0.0008143322475570033

** 1.0568043348436783e-20 ** …… (゚ Д ゚;)

10 minus 20. Potenz. Es ist eine sehr nahe Zahl an 0.

Je länger die Eingabezeichenfolge ist, desto weniger wahrscheinlich ist es, dass sie in eine bestimmte Kategorie fällt. Im Gegenteil, das letzte Beispiel besteht darin, die eingegebene Zeichenfolge zu verkürzen und die Wahrscheinlichkeit der Eingabe einer bestimmten Kategorie nur durch "Korund" zu berechnen. Die Wahrscheinlichkeit, in der wahrscheinlichsten Kategorie "Edelstein" zu sein, beträgt jedoch nur ** 0,0018248175182481751 **. 0,18%. Es ist viel größer als die Chance von 0,0008143322475570033, in der Kategorie "Ruby" zu sein, aber immer noch sehr klein. Sie sehen, dass die Berechnung schwierig ist.

Referenz

Japanischer Artikel über Naive Bays http://aidiary.hatenablog.com/entry/20100613/1276389337

Nachtrag

Mit dem in diesem Artikel erstellten Basian-Filter haben wir mithilfe der mit der Bing-API erfassten Webseite gelernt und klassifiziert. Klicken Sie hier für die Fortsetzung http://qiita.com/katryo/items/62291ba328de9d12bd30

Recommended Posts

Implementieren Sie Naive Bayes in Python 3.3
Implementieren Sie XENO mit Python
Implementieren Sie sum in Python
Implementieren Sie Traceroute in Python 3
Implementieren Sie alte Chiffren in Python
Implementieren Sie Redis Mutex in Python
Implementieren Sie die Erweiterung in Python
Implementieren Sie schnelles RPC in Python
Implementieren Sie den Dijkstra-Algorithmus in Python
Implementieren Sie den Slack Chat Bot in Python
Implementieren Sie das Stacking-Lernen in Python [Kaggle]
Implementieren Sie die Funktion power.prop.test von R in Python
Implementieren Sie das Singleton-Muster in Python
Implementieren Sie die REST-API schnell in Python
Quadtree in Python --2
Python in der Optimierung
CURL in Python
Ich habe versucht, PLSA in Python zu implementieren
Metaprogrammierung mit Python
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Implementieren Sie __eq__ usw. generisch in der Python-Klasse
Metaanalyse in Python
Unittest in Python
Implementieren Sie den FIR-Filter in Python und C.
Implementieren Sie gemeinsam statistische Hypothesentests in Python
Ich habe versucht, PLSA in Python 2 zu implementieren
Epoche in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
N-Gramm in Python
Programmieren mit Python
Plink in Python
Ich habe versucht, ADALINE in Python zu implementieren
Konstante in Python
Ich habe versucht, PPO in Python zu implementieren
FizzBuzz in Python
SQLite in Python
Schritt AIC in Python
LINE-Bot [0] in Python
CSV in Python
Reverse Assembler mit Python
Reflexion in Python
Konstante in Python
nCr in Python.
Format in Python
Scons in Python 3
Puyopuyo in Python
Python in Virtualenv
PPAP in Python
Textfilterung mit naiven Buchten von sklearn