Краткое введение в теорему Байеса

Теорема Байеса описывает соотношение между условными вероятностями. Обычно она записывается в виде

Pr(A | B) = Pr(B | A) x Pr(A) / Pr(B) В применении к нашему примеру эта формула принимает следующий вид:

Pr(Категория | Документ) = Pr(Документ | Категория) x x Pr(Категория) / Pr(Документ) В предыдущем разделе мы показали, как вычислить Pr(Документ | Категория), но как быть с остальными двумя членами? Ничего сложного. Pr(Категория) – это вероятность попадания случайно выбранного документа в данную категорию, поэтому она просто равна числу документов из этой категории, поделенному на общее число документов. Что касается вероятности Pr(Документ), то ее тоже можно было бы вычислить, но это лишний труд. Напомним, что конечный результат не

будет использоваться как истинная вероятность. Мы лишь по отдельности вычислим вероятности попадания в каждую категорию, а затем сравним их. Поскольку величина Рг(Документ) одна и та же для всех категорий, то ее можно попросту игнорировать. Метод prob вычисляет вероятность попадания в категорию и возвращает произведение Рг(Документ | Категория) и Рг(Категория). Добавьте его в класс naivebayes: def prob(self,item,cat):

catprob=self.catcount(cat)/self.totalcount( )

docprob=self.docprob(item,cat)

return docprob*catprob

Протестируйте эту функцию и посмотрите, как изменяются числа для разных строк и категорий: >>> reload(docclass)

<module ‘docclass’ from ‘docclass.pyc’> >>> cl=docclass.naivebayes(docclass.getwords) >>> docclass.sampletrain(cl) >>> cl.prob(‘quick rabbit’,’good’)

0.15624QQQQQQQQQQQ7

>>> cl.prob(‘quick rabbit’,’bad’)

0.050000000000000003

По результатам обучения оказывается следующее: вероятность того, что фраза quick rabbit является частью хорошего документа, гораздо выше, чем плохого.

Выбор категории

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

В случае фильтрации спама гораздо важнее избежать классификации хороших сообщений как спама, чем отловить все спамные сообщения без исключения. С редкими появлениями спамных сообщений в своем почтовом ящике вы готовы будете смириться, а вот помещение важного письма в ящик «Сомнительные» легко может остаться незамеченным. Если же вы внимательно просматриваете этот ящик в поисках важных сообщений, то к чему тогда вообще антиспамный фильтр? Для решения этой проблемы можно задать для каждой категории минимальное пороговое значение. Чтобы новый образец был отнесен

к некоторой категории, его вероятность должна быть по крайней мере на эту величину больше вероятности попадания в любую другую категорию. Эта величина называется порогом. Для фильтрации спама порог отнесения к категории плохих документов можно было бы установить равным 3. Это означает, что вероятность оказаться хорошим документом должна быть хотя бы в 3 раза выше, чем плохим. Для категории «Хороший» задается порог 1, то есть документ будет признаваться хорошим, если вероятность этого хоть чуть-чуть выше, чем для категории «Плохой». Все сообщения, для которых вероятность оказаться «плохим» выше, чем «хорошим», но менее чем в 3 раза, классифицируются как «Неизвестный».

Для задания порогов добавьте в класс classifier новую переменную экземпляра, изменив метод инициализации:

def __init__(self,getfeatures):

classifier.__init__(self,getfeatures) self.thresholds={}

Добавьте два простых метода для установки и получения значений, причем по умолчанию пусть возвращается значение 1,0:

def setthreshold(self,cat,t): self.thresholds[cat]=t

def getthreshold(self,cat):

if cat not in self.thresholds: return 1.0 return self.thresholds[cat]

Теперь все готово для написания метода classify. Он вычисляет вероятность для каждой категории, ищет среди них максимальную и проверяет, отличается ли она от следующей по порядку более чем в пороговое число раз. Если такую категорию найти не удается, то метод просто возвращает значение по умолчанию. Добавьте в класс classifier такой код: def classify(self,item,default=None): probs={}

#       Найти категорию с максимальной вероятностью max=0.0

for cat in self.categories( ): probs[cat]=self.prob(item,cat) if probs[cat]>max: max=probs[cat] best=cat

#       Убедиться, что найденная вероятность больше чем threshold*следующая по

#       величине

for cat in probs: if cat==best: continue

if probs[cat]*self.getthreshold(best)>probs[best]: return default return best

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

>>> reload(docclass)

<module ‘docclass’ from ‘docclass.pyc’> >>> cl=docclass.naivebayes(docclass.getwords) >>> docclass.sampletrain(cl)

>>> cl.classify(‘quick rabbit’,default=’unknown’)

‘good’

>>> cl.classify(‘quick money’,default=’unknown’)

‘bad’

>>> cl.setthreshold(‘bad’,3.0)

>>> cl.classify(‘quick money’,default=’unknown’)

‘unknown’

>>> for i in range(10): docclass.sampletrain(cl)

>>> cl.classify(‘quick money’,default=’unknown’)

‘bad’

Можете изменить пороги и посмотреть, как это отразится на результатах. Некоторые подключаемые модули фильтрации спама позволяют пользователям подстраивать пороги, если в ящике «Входящие» остается слишком много спама или, напротив, хорошие сообщения часто попадают в спам. Для разных приложений фильтрации документов пороги задаются по-разному; иногда все категории считаются равноценными, а порой отнесение к категории «неизвестные» недопустимо.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100