第五章 贝叶斯统计 进行分类(4)

全概率公式

物理学家和化学家能够在宏观的层次上系统地阐述带有普遍性的决定论的规律,但机器学习只能系统地阐述统计学上的趋势。在世界上每时每刻都有无数的事情发生,而好知的我们都在思考着一个问题,为什么这些事情会发生,发生这些事情的条件有哪些,哪些条件又是主要的因数呢?

导致一个事件的发生,可能有非常多的条件所控制,条件满足了就会发生。而这些条件的产生也并不是完全确定的,存在着一定的几率,所有条件的组成构建了导致产生这件事情的概率。例如天气的变化,冷空气会影响天气,同样台风也会影响空气,天气的变化就是受到了这些条件的影响,这些条件的总和决定了天气的变化。 用数学的方式来表达上面的描述:

如果事件组,满足

  1. $B_1,B_2,...,B_n$两两互斥,即$B_i \cap B_j = \varnothing , i \ne j,i,j=1,2,...$,且 $P(B_i)>0,i=1,2,...$;

  2. $B_1 \cup B_2\cup ... =\Omega $ 则称时间组$B_1,B_2,...,B_n$是样本空间的一个划分 设$B_1,B_2,...,B_n$是样本空间$\Omega $的一个划分,A为任意一事件,则:

$$P(A)=\sum_{i=1}^\infty P(B_i)P(A/B_i)$$

这也叫做全概率公式。在这个公式中,A表示事件,$B_1,B_2,...,B_n$表示导致A事件产生的原因。

贝叶斯公式

全概率的思想在于把一件事情的发生概率分解成导致它发生的条件概率之和。但是现实中,一件事情发生的原因千千万万,看起来全概率公式并没有多大的用处,因为条件太多,无法构建起全概率公式,但实际通常是简化的,只要抓住导致这件事情产生的主要原因就可以了。

其实在我们的观察中,通常观察到的是一件事情的结果,也就是这件事情已经发生了,我们要来推测是哪个条件导致了这件事情的发生呢?用数学的表达,全概率是一个正向的过程,即某些条件导致了结果的发生,而如果是事件发生了要来推断是哪个条件最有可能导致这件事件的发生呢?这是一个逆过程了,贝叶斯描述的就是这样的一种逆过程。贝叶斯的公式如下:

$$P(B_i/A) = \frac{P(B_iA)}{P(A)} = \frac{P(A|B<>j)}{\sum{j=1}^\infty P(B_j)P(A/B_j)}$$

推导这个公式的过程,主要是利用条件概率公式和全概率公式就能得出这个结果,贝叶斯首先提出了这个公式,后来发现了这个公式特别有用,大家把他叫做贝叶斯公式。

分类原理

仔细分析贝叶斯公式,里面有非常多的意义。 $P(B_i|A)$就是表示为事件A发生了,是因为$P(B_i)$原因的概率,也就是$P(B_i)$在事件A发生了这件事情上起到了多少的作用。想要找到主要的原因,遍历下所有的原因$P(B_i)$,取最大值的那个就是主要因素。 即:

$$arg max P(B_i|A) = arg max \frac{P(B_i)P(A|B<>j)}{\sum{j=1}^\infty P(B_j)P(A/B_j)}$$

在求最大值的时候,我们可以发现分子中$\sum_{j=1}^\infty P(B_j)P(A/B_j)$所有的各式都是一样的,把它去掉不会影响到我们求最大值。

$$arg max P(B_i|A) = arg max \frac{P(B_i)P(A|B<>j)}{\sum{j=1}^\infty P(B_j)P(A/B_j)}=arg max P(B_i)P(A|B_j)$$

也就是回归到全概率公式中$P(B_i)P(A|B_j)$,哪个条件发生的概率大了。只里面有两个因素,一个是$P(B_i)$表示条件$B_i$本身出现的概率,一个是$P(A|B_j)$表示条件$B_i$发生时A发生的概率。

这样就非常清楚了,一个条件是否是这件事件的主要原因,有两个因素起作用的,一个是这个条件是否平凡出现,一个是这个条件在导致产生事件发生的概率。两者共同决定,这在现实中有非常多的这种情况。 解释清楚了各项的意义后,就能够用到分类。 所谓的朴素贝叶斯分类,这里称他为 “朴素”贝叶斯的缘由,在现实环境中,很难达到两个特征值之间绝对的相互独立。 如何进行分类呢?基础的知识就在上面了,只要把概念稍微的换一下就能够进行分类,把上面所说的原因变为类别,就能够分类了,取最大的原因,也就是最大的分类,最有可能的分类了。 朴素贝叶斯的分类,用途很广,较为常见的是在文本分类上,把文章进行分类,有属于科技,体育,娱乐等,通常的做法是这样的,把文章中的关键词抽取出来,分别判断这些词属于哪里分类,再把所有的词综合起来,取最大值,即为分类。所以通常朴素贝叶斯写成如下:

$$y={arg max}<>{\overline{y}}P(\overline{y})\prod{i=1}^{n}P(x_i|\overline{y})$$

其中$\overline{y}$ 代表了各个不同的分类情况,$P(\overline{y})$为该分类出现的概率,$\prod_{i=1}^{n}P(x_i|\overline{y})$ 为各个原因综合成的概率因素。这就是我们一直在讲的,贝叶斯由两部分组成,其中一部部分是先验概率。另外一部分是各个因素组成的概率。也就是像我们之前讲的一部分是“像不像”,一部分是“可能性有多大”

不同的贝叶斯分类器

对于特征的可能性选择的方法不一样可以得到不一样的贝叶斯分类器。

特征的可能性(即概率)假设为高斯分布:

$$P(x_i|y)=\frac{1}{\sqrt{2\pi\sigma _y^2}}exp(-\frac{(x_i-\mu _y)^2}{2\sigma _y^2})$$

先使用最大似然估计求得参数$\sigma _y$和$\mu _y$。

同样的还有多项分布朴素贝叶斯伯努利朴素贝叶斯

训练贝叶斯分类器

各个因素组成的概率可以使用如下的图来进行表示,这里简单的列举出两个分类。

贝叶斯各个因素

在python中可以用一个一维矩阵来表示各个因素,而我们进行训练就是为了得到各个因素在分类中起到的作用,也就是概率$P(x_i|\overline{y})$。

贝叶斯训练

用pyton来表示为:

def _trainNBO(trainMatrix,trainCategory):
    numTrainDocs=len(trainMatrix)
    numWords=len(trainMatrix[0])
    pAbusive=sum(trainCategory)/float(numTrainDocs)

    p0Num=ones(numWords)
    p1Num=ones(numWords)
    p0Denom=2.0
    p1Denom=2.0
    for i in range(numTrainDocs):
        if trainCategory[i]==1:
            p1Num+=trainMatrix[i]
            p1Denom+=sum(trainMatrix[i])
        else:
            p0Num+=trainMatrix[i]
            p0Denom+=sum(trainMatrix[i])
    p1Vect=log(p1Num/p1Denom)
    p0Vect=log(p0Num/p0Denom)

    return p0Vect,p1Vect,pAbusive

其中把各个实验数据格式化为各个因素的表示形式,如果这个因素在这个实验中没有出现,那么用0来表示,出现的话,用1来进行表示

整个代码过程可以参看这里的代码

sklearn下使用贝叶斯分类

sklearn下同样实现了贝叶斯分类器,在这里我们使用的是朴素贝叶斯分类器MultinomialNB,在naive_bayes模块 中可以导入相关的贝叶斯分类器,实现的具体代码如下:

from sklearn.naive_bayes import MultinomialNB
from numpy import *

def loadDatSet():
    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):
    vocabSet=set([])
    for document in dataSet:
        vocabSet=vocabSet|set(document)
    return list(vocabSet)

def setOfWords2Vec(vocabList,inputSet):
    returnVec=[0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]+=1
        else:
            print('')
    return returnVec

#train
listOPosts,listClasses=loadDatSet()
myVocabList=createVocabList(listOPosts)
trainMat=[]
for postinDoc in listOPosts:
    trainMat.append(setOfWords2Vec(myVocabList,postinDoc))

model = MultinomialNB()
model.fit(array(trainMat),array(listClasses))

#test

testEntry=['dog','my','stupid']
testMat=[]
testMat.append(setOfWords2Vec(myVocabList,testEntry))
s = array(testMat)
result = model.predict(array(testMat))

print result

PS: 如本文对您有帮助,不妨通过一下方式支持一下博主噢 ^_^

官方
微信
官方微信
Q Q
咨询
意见
反馈
返回
顶部