Байесовский классификатор и реализация Python

искусственный интеллект Python алгоритм Байду

0. Предисловие

Байесовская классификация — это общий термин для класса алгоритмов классификации, основанных на теореме Байеса, поэтому они вместе называются байесовской классификацией. Эта статья состоит из моих заметок в процессе изучения байесовских классификаторов, а также использования Python для классификации текста.

1. Байесовская теория принятия решений

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

Предполагается, что он помечен N возможными классами,\mathcal{Y}={c_1,c_2,\cdots,c_N},\lambda_{ij}это пометить истину какc_jОшибка выборки классифицируется какc_iРезультирующий убыток, основанный на апостериорной вероятностиP(c_i|\boldsymbol{x})образцы доступны\boldsymbol{x}классифицируется вc_iПолученный ожидаемый убыток (ожидаемый убыток), т. е. в выборке\boldsymbol{x}«условный риск» на

R(c_i|\boldsymbol{x})=\sum^{N}_{j=1}\lambda_{ij}P(c_j|\boldsymbol{x})

Основная задача состоит в том, чтобы найти критерий принятия решения.h: \mathcal{X\mapsto Y}минимизировать общий риск

R(h)=\mathbb{E}_x[R(h(\boldsymbol{x})|\boldsymbol{x})]

Очевидно, для каждого образца\boldsymbol x,какhУсловный риск можно минимизироватьR(h(\boldsymbol{x})|\boldsymbol x), то общий рискR(h)также будет сведен к минимуму

Это приводит к решающему правилу Байеса:

Чтобы свести к минимуму общий риск, просто выберите для каждого образца условный риск.R(c|\boldsymbol x)минимальная разметка категории

h^*(\boldsymbol x)=\underset{c \in \mathcal{Y}}{argmin}R(c|\boldsymbol(x))

В настоящее время,h^*(\boldsymbol x)называется оптимальным классификатором Байзе, а соответствующий общий рискR(h^*)Это называется байесовским риском.1-R(h^*)Он отражает наилучшую производительность, которую может достичь классификатор.

Если цель состоит в том, чтобы свести к минимуму частоту ошибок классификации, то потери из-за неправильной классификации\lambda_{ij}можно записать как

\lambda_{ij}=\begin{cases}0, \quad\mathrm{if}\quad i == j \\ 1, \quad otherwise\end{cases}

Условия риска в настоящее время таковы:

R(c|\boldsymbol x)=1-P(c|\boldsymbol x)

Байесовский оптимальный классификатор, который минимизирует частоту ошибок классификации,

h^*(\boldsymbol x)=\underset{c \in \mathcal Y}{argmax}P(c|\boldsymbol x)

На основании теоремы БайесаP(c|\boldsymbol x)=\frac{P(c)P(\boldsymbol x|c)}{P(\boldsymbol x)}

Доказательство этой формулы очень простое.Его можно получить по определению условной вероятности.Заинтересованные читатели могут Baidu. Хотя эта теорема очень проста, она устанавливает мост для взаимного преобразования априорной вероятности и апостериорной вероятности.

P(c)априорная вероятность класса

P(\boldsymbol x|c)условная вероятность или вероятность класса

  • Априорная вероятность: вероятность, основанная на прошлом опыте и анализе.
  • Апостериорная вероятность: Апостериорная вероятность — это оценка вероятности, которая ближе к реальной ситуации после корректировки исходной априорной вероятности на основе новой информации.

Априорная вероятность класса - это доля различных выборок в пространстве выборок.Согласно закону больших чисел (при достаточном количестве выборок частота стремится быть стабильной и равной ее вероятности), так что при достаточном количестве обучающих выборок ,P(c)Вместо этого можно использовать частоту появления каждого типа. Остаются только условные вероятности классаP(\boldsymbol x|c), что означает вероятность появления x в категории c, которая включает в себя совместную вероятность атрибутов. Если имеется только один дискретный атрибут, очень сложно использовать частотную оценку, когда имеется много атрибутов. Поэтому обычно используется максимальное сходство вот тогда оцените.

###2. Оценка максимального правдоподобия

Оценка максимального правдоподобия (MLE) — это классический метод оценки вероятностных распределений на основе выборки данных. Распространенная стратегия состоит в том, чтобы сначала предположить, что популяция имеет определенное распределение вероятностей, а затем оценить параметры распределения вероятностей на основе обучающих выборок. Условная вероятность классаp(\boldsymbol x | c), предполагаяp(\boldsymbol x | c )Следуя распределению с параметром θ, задача становится оцениваемой на основе известных обучающих выборок.\theta. Основная идея метода максимального правдоподобия заключается в том, что оцениваемые параметры максимизируют вероятность известных выборок, то есть максимизируют вероятность обучающих данных.

сделатьD_cпредставляет обучающий наборDБcНабор выборок класса, если предположить, что эти выборки независимы и одинаково распределены, то параметр\boldsymbol \theta_cв наборе данныхD_cкажется

P(D_c|\boldsymbol \theta_c)=\underset{\boldsymbol x\in D_c}{\prod}P(\boldsymbol x|\boldsymbol \theta_c)

правильно\boldsymbol \theta_cОценка максимального правдоподобия состоит в том, чтобы найти максимальное правдоподобиеP(D_c|\boldsymbol \theta_c)значение параметра\hat{{\boldsymbol \theta_c}}, Интуитивно, оценка максимального правдоподобия - это представление в\boldsymbol \theta_cСреди всех возможных значений найдите то, которое максимизирует «правдоподобие» данных.

Операция умножения усложняет решение (легко вызвать недополнение), обычно мы используем логарифмическое правдоподобие (логарифмическое правдоподобие)

LL(\boldsymbol \theta_c)=logP(D_c|\boldsymbol\theta_c)=\underset{\boldsymbol x\in D_c}{\sum}logP(\boldsymbol x| \boldsymbol\theta_c)

Параметры на данный момент\boldsymbol \theta_cоценка максимального правдоподобия\hat {\boldsymbol \theta_c}за

\hat {\boldsymbol \theta_c}=\underset{\boldsymbol \theta_c}{argmax}LL(\boldsymbol \theta_c)

Следовательно, процесс обучения байесовского классификатора представляет собой оценивание параметров. Обобщая процесс оценки параметров методом максимального правдоподобия, его обычно делят на следующие четыре этапа:

  • 1. Напишите функцию правдоподобия;
  • 2. Возьмем логарифм функции правдоподобия и упорядочим его;
  • 3. Найдите производную, пусть частная производная равна 0, и получите систему уравнений правдоподобия;
  • 4. Решите систему уравнений правдоподобия, и получите все параметры, которые требуются.

3. Наивный байесовский классификатор

Наивная байесовская классификация — это очень простой алгоритм классификации.Он называется наивной байесовской классификацией, потому что идея этого метода действительно проста.Идеологическая основа наивной байесовской классификации заключается в следующем: Пункт, узнайте вероятность появления каждой категории при условии, что этот элемент появляется, в зависимости от того, какой из них больше, рассмотрите, к какой категории принадлежит классифицируемый элемент. Говоря простым языком, это так, вы видите на улице негра, и я вас спрашиваю, откуда, по-вашему, этот парень взялся, наверное, из Африки. Зачем? Поскольку у чернокожих самая высокая доля африканцев, конечно, они также могут быть американцами или азиатами, но при отсутствии другой доступной информации мы выберем класс с наибольшей условной вероятностью, которая является основой Наивного Байеса.

Исходя из предположения об условной независимости атрибутов, мы можем получить

P(c|\boldsymbol x)=\frac{P(c)P(\boldsymbol x|c)}{P(\boldsymbol x)}=\frac{P(c)}{P(\boldsymbol x)}\prod^d_{i=1}P(x_i|c)

dколичество атрибутов,x_iза\boldsymbol xвiстоимость недвижимости

h_{nb}(\boldsymbol x)=\underset{c\in \mathcal{Y}}{argmax}P(c)\prod^d_{i=1}P(x_i|c)

Это выражение для наивного Байеса

Таким образом, оценка условных вероятностей класса для каждой выборки становится оценкой условных вероятностей класса для каждого атрибута каждой выборки.

задискретные свойстваусловную вероятность признака можно оценить как:P(x_i|c)=\frac{|D_{c,x_i}|}{|D_c|}

заНепрерывное свойство, если предполагается, что атрибут подчиняется нормальному распределению, условная вероятность может быть оценена как:

p(x_i|c)=\frac{1}{\sqrt{2\pi}\sigma_{c,i}}exp(-\frac{(x_i-\mu_{}c,i)^2}{2\sigma^2_{c,i}})

Пример

Вот пример набора данных арбуза 3.0.

-- "Книга Чжоу Чжихуа-Арбуз"

编号,色泽,根蒂,敲声,纹理,脐部,触感,密度,含糖率,好瓜  
1,青绿,蜷缩,浊响,清晰,凹陷,硬滑,0.697,0.46,是  
2,乌黑,蜷缩,沉闷,清晰,凹陷,硬滑,0.774,0.376,是  
3,乌黑,蜷缩,浊响,清晰,凹陷,硬滑,0.634,0.264,是  
4,青绿,蜷缩,沉闷,清晰,凹陷,硬滑,0.608,0.318,是  
5,浅白,蜷缩,浊响,清晰,凹陷,硬滑,0.556,0.215,是  
6,青绿,稍蜷,浊响,清晰,稍凹,软粘,0.403,0.237,是  
7,乌黑,稍蜷,浊响,稍糊,稍凹,软粘,0.481,0.149,是  
8,乌黑,稍蜷,浊响,清晰,稍凹,硬滑,0.437,0.211,是  
9,乌黑,稍蜷,沉闷,稍糊,稍凹,硬滑,0.666,0.091,否  
10,青绿,硬挺,清脆,清晰,平坦,软粘,0.243,0.267,否  
11,浅白,硬挺,清脆,模糊,平坦,硬滑,0.245,0.057,否  
12,浅白,蜷缩,浊响,模糊,平坦,软粘,0.343,0.099,否  
13,青绿,稍蜷,浊响,稍糊,凹陷,硬滑,0.639,0.161,否  
14,浅白,稍蜷,沉闷,稍糊,凹陷,硬滑,0.657,0.198,否  
15,乌黑,稍蜷,浊响,清晰,稍凹,软粘,0.36,0.37,否  
16,浅白,蜷缩,浊响,模糊,平坦,硬滑,0.593,0.042,否  
17,青绿,蜷缩,沉闷,稍糊,稍凹,硬滑,0.719,0.103,否  

Используйте приведенные выше данные для обучения наивного байесовского классификатора для классификации тестового примера «Тест 1»:

编号,色泽,根蒂,敲声,纹理,脐部,触感,密度,含糖率,好瓜  
测1,青绿,蜷缩,浊响,清晰,凹陷,硬滑,0.697,0.46,是  

В действии — классификация текста с помощью Python

Чтобы получить функции из текста, вам нужно сначала разбить текст. Как это сделать? Функции здесь — это токены из текста, а токен — это любая комбинация символов. Вы можете думать о терминах как о словах или использовать несловесные термины, такие как URL-адреса, IP-адреса или любую другую строку.

Возьмем, к примеру, доску объявлений в онлайн-сообществе. Чтобы не влиять на развитие сообщества, нам необходимо блокировать ненормативную лексику, поэтому необходимо построить быстрый фильтр, если в сообщении используется негативная или оскорбительная лексика, то сообщение должно быть помечено как неприемлемое. Фильтрация такого рода контента является очень распространенной потребностью. Создайте для этого вопроса две категории: оскорбительный и не оскорбительный, используя 1 и 0 соответственно.

данные:

"my","dog","has","flea","problems","help","please","null"
"maybe","not","take","him","to","dog","park","stupid","null"
"my","dalmation","is","so","cute","I","love","him","null"
"stop","posting","stupid","worthless","garbage","null"
 "mr","licks","ate","my","steak","how","to","stop","him","null"
"quit","buying","worthless","dog","food","stupid","null"

Реализация Python:

# _*_ coding:utf-8 _*_
import numpy as np

def loadDataSet():
    """
    导入数据, 1代表脏话
    @ return postingList: 数据集
    @ return classVec: 分类向量
    """
    postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                   ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                   ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                   ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                   ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                   ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0, 1, 0, 1, 0, 1]  
    return postingList, classVec

def createVocabList(dataSet):
    """
    创建词库
    @ param dataSet: 数据集
    @ return vocabSet: 词库
    """
    vocabSet = set([])
    for document in dataSet:
        # 求并集
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

def setOfWords2Vec(vocabList, inputSet):
    """
    文本词向量.词库中每个词当作一个特征,文本中就该词,该词特征就是1,没有就是0
    @ param vocabList: 词表
    @ param inputSet: 输入的数据集
    @ return returnVec: 返回的向量
    """
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print("单词: %s 不在词库中!" % word)
    return returnVec


def trainNB0(trainMatrix, trainCategory):
    """
    训练
    @ param trainMatrix: 训练集
    @ param trainCategory: 分类
    """
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    #防止某个类别计算出的概率为0,导致最后相乘都为0,所以初始词都赋值1,分母赋值为2.
    p0Num = np.ones(numWords) 
    p1Num = np.ones(numWords)
    p0Denom = 2
    p1Denom = 2
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    # 这里使用log函数,方便计算,因为最后是比较大小,所有对结果没有影响。
    p1Vect = np.log(p1Num / p1Denom)
    p0Vect = np.log(p0Num / p0Denom)
    return p0Vect, p1Vect, pAbusive

def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    """
    判断大小
    """
    p1 = sum(vec2Classify*p1Vec)+np.log(pClass1)
    p0 = sum(vec2Classify*p0Vec)+np.log(1-pClass1)
    if p1>p0:
        return 1
    else:
        return 0

def testingNB():
    listOPosts,listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    trainMat=[]
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses))
    testEntry = ['love', 'my', 'dalmation']
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
    testEntry = ['stupid', 'garbage']
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))

if __name__=='__main__':
    testingNB()