2012-04-03 7 views
4

Ich benutze unter anderem verschiedene Beiträge hier auf Stackoverflow, ich versuche meinen eigenen PHP Classier zu implementieren, um Tweets in eine positive, neutrale und negative Klasse zu klassifizieren. Bevor ich programmieren kann, muss ich den Prozess direkt erledigen. Mein Zug-of-gedacht und ein Beispiel sind wie folgt:Einen Naive Bayes Classifier verwenden, um Tweets zu klassifizieren: einige Probleme

        p(class) * p(words|class) 
Bayes theorem: p(class|words) = ------------------------- with 
              p(words) 

assumption that p(words) is the same for every class leads to calculating 
arg max p(class) * p(words|class) with 
p(words|class) = p(word1|class) * p(word2|topic) * ... and 
p(class) = #words in class/#words in total and 

       p(word, class)      1 
p(word|class) = -------------- = p(word, class) * -------- = 
        p(class)      p(class) 

#times word occurs in class #words in total #times word occurs in class 
--------------------------- * --------------- = --------------------------- 
     #words in total   #words in class  #words in class 

Example: 

------+----------------+-----------------+ 
class | words   | #words in class | 
------+----------------+-----------------+ 
pos | happy win nice | 3    | 
neu | neutral middle | 2    | 
neg | sad loose bad | 3    | 
------+----------------+-----------------+ 

p(pos) = 3/8 
p(neu) = 2/8 
p(meg) = 3/8 

Calculate: argmax(sad loose) 

p(sad loose|pos) = p(sad|pos) * p(loose|pos) = (0+1)/3 * (0+1)/3 = 1/9 
p(sad loose|neu) = p(sad|neu) * p(loose|neu) = (0+1)/3 * (0+1)/3 = 1/9 
p(sad loose|neg) = p(sad|neg) * p(loose|neg) =  1/3 *  1/3 = 1/9 

p(pos) * p(sad loose|pos) = 3/8 * 1/9 = 0.0416666667 
p(neu) * p(sad loose|neu) = 2/8 * 1/9 = 0.0277777778 
p(neg) * p(sad loose|neg) = 3/8 * 1/9 = 0.0416666667 <-- should be 100% neg! 

Wie Sie sehen können, habe ich „trainiert“ den Klassifikator mit einem positiven („glücklich schön gewinnen“), eine neutrale („neutral Mitte“) und ein negativer ("traurig loser schlechter") Tweet. Um Probleme mit Wahrscheinlichkeiten von Null zu vermeiden, weil ein Wort in allen Klassen fehlt, verwende ich LaPlace (oder ädd one ") Glättung, siehe" (0 + 1) ".

Ich habe im Grunde zwei Fragen :

  1. ist dies eine für die Umsetzung richtigen Plan gibt es Raum für Verbesserungen
  2. Wenn ein Tweet („traurig lose“) zu klassifizieren, es wird erwartet, dass nur 100% in der Klasse „neg“, weil es zu sein? enthält negative Wörter Die LaPlace-Glättung macht jedoch die Dinge komplizierter: Klasse pos und neg haben eine gleiche Wahrscheinlichkeit Gibt es eine Abhilfe dafür?
+1

'p (Klasse) = #Wörter in der Klasse/#Wörter insgesamt scheint nicht richtig zu sein, wenn Sie Tweets klassifizieren. Es sollte "p (Klasse) = # Tweets in Klasse/# Tweets" sein. Es scheint, als ob viele Ihrer Probleme von dieser Frage herrühren könnten, was genau Sie klassifizieren ... – Xodarap

Antwort

3

Es gibt zwei Hauptelemente, die Sie in Ihrer Argumentation verbessern können.

Zunächst sollten Sie Ihre Glättungsverfahren verbessern:

  • Wenn Laplace Glättung Anwendung, sollte es auf alle Messungen angewendet werden, nicht nur für diejenigen mit Null Nenner.
  • Zusätzlich wird die Laplace-Glättung für solche Fälle üblicherweise durch (c + 1)/(N + V) gegeben, wobei V die Wortschatzgröße ist (siehe z. B. in Wikipedia). Daher

, mit Wahrscheinlichkeitsfunktion Sie definiert haben (die nicht die geeignet sein könnten, siehe unten):

p(sad loose|pos) = (0+1)/(3+8) * (0+1)/(3+8) = 1/121 

p(sad loose|neu) = (0+1)/(3+8) * (0+1)/(3+8) = 1/121 

p(sad loose|neg) = (1+1)/(3+8) * (1+1)/(3+8) = 4/121 <-- would become argmax 

Zusätzlich ist ein häufiger Weg, um die Wahrscheinlichkeit an erster Stelle zu berechnen, wäre durch:

(number of tweets in class containing term c)/(total number of tweets in class) 

Zum Beispiel in dem begrenzten trainset oben angegeben und ohne Berücksichtigung Glättung, p (sAD | po) = 0/1 = 0 und p (sAD | NEG) = 1/1 = 1. Wenn die Größe des Zugverbandes zunimmt, wären die Zahlen mehr Mittelwerte ngful. z.B. Hättest du 10 Tweets für die negative Klasse, mit "traurig" in 4 von ihnen, dann wäre p (traurig | neg) 4/10 gewesen.

In Bezug auf die tatsächliche Zahl, die vom Naive Bayes-Algorithmus ausgegeben wird: Sie sollten nicht erwarten, dass der Algorithmus jeder Klasse die tatsächliche Wahrscheinlichkeit zuweist; Vielmehr ist die Kategorie-Reihenfolge von größerer Bedeutung. Konkret würde die Verwendung von argmax Ihnen die beste Schätzung des Algorithmus für die Klasse geben, aber nicht die Wahrscheinlichkeit dafür. Das Zuweisen von Wahrscheinlichkeiten zu NB-Ergebnissen ist eine andere Geschichte; Sehen Sie sich zum Beispiel eine article an, in der dieses Problem behandelt wird.