Использование наивного байесовского классификатора для классификации твитов: некоторые проблемы - PullRequest
4 голосов
/ 03 апреля 2012

Используя, помимо других источников, различные статьи здесь, в Stackoverflow, я пытаюсь реализовать свой собственный PHP-классификатор для классификации твитов в положительный, нейтральный и отрицательный класс.Перед кодированием мне нужно разобраться в процессе.Мой ход мыслей и пример следующие:

                                  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!

Как видите, я «обучил» классификатор с положительным («счастливый выигрыш хороший»), нейтральным («нейтральный»).средний ") и отрицательный (" грустный плохой ") твит.Чтобы избежать проблем с вероятностями нуля из-за отсутствия одного слова во всех классах, я использую сглаживание LaPlace (или ädd one "), см." (0 + 1) ".

У меня в основном естьдва вопроса:

  1. Это правильный план для реализации? Есть ли место для улучшений?
  2. При классификации твита («грустно болтается») ожидается, что он будет равен 100%в классе "neg", потому что он содержит только отрицательные слова. Однако сглаживание LaPlace усложняет ситуацию: класс pos и neg имеют равную вероятность. Есть ли обходной путь для этого?

1 Ответ

3 голосов
/ 15 апреля 2012

В ваших рассуждениях есть два основных элемента, которые нужно улучшить.

Во-первых, вы должны улучшить свой метод сглаживания:

  • При применении сглаживания Лапласа его следует применять ко всем измерениям.не только тем, у кого нулевой знаменатель.
  • Кроме того, сглаживание Лапласа для таких случаев обычно дается выражением (c + 1) / (N + V), где V - размер словаря (например, см. В Wikipedia ).

Поэтому, используя определенную вами функцию вероятности (которая может быть не самой подходящей, см. Ниже):

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

Кроме того, более распространенный способ вычисления вероятностиво-первых, было бы:

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

Например, в приведенном выше ограниченном наборе поездов без учета сглаживания p (sad | pos) = 0/1 = 0 и p (sad |neg) = 1/1 = 1. Когда размер набора поездов увеличивается, числа будут более значимыми.Например, если бы у вас было 10 твитов для отрицательного класса, в 4 из которых появилось «грустное», то p (sad | neg) было бы 4/10.

Относительно фактического числа, выведенного наивным Байесомалгоритм: не следует ожидать, что алгоритм назначит фактическую вероятность каждому классу;скорее, порядок категорий имеет большее значение.Конкретно, использование argmax даст вам лучшее предположение алгоритма для класса, но не вероятность для него.Присвоение вероятностей результатам NB - другая история;например, см. статью , в которой обсуждается эта проблема.

...