基于概率论的分类方法:朴素贝叶斯

        其实朴素贝叶斯分类用一个区分是否是侮辱性句子的应用来说就是:

                我们先通过训练集来算出 当句子是侮辱性句子时,单词(要计算很多个单词)出现的概率W,然后通过概率W来预测测试句子是否是侮辱性句子。


使用朴素贝叶斯进行文档分类:以社区的留言板为例,运用朴素贝叶斯算法,对文本自动分类是否是侮辱性句子

    一,准备数据

            1.生成测试集包括一个文本矩阵,和一个人工标注的是否是侮辱性句子的一维矩阵。

            这里省去了如何将文本转化为下列格式的步骤,为了方便后面的测试,这里直接用函数生成了一个已经数据清洗好的测试集。

def loadDataSet():
        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]  #0代表正常言论,1代表侮辱性句子
        return postingList,classVec

            2.生成词汇表

def createVocablist(dataSet):   #生成一个包含所有不重复单词的列表,
    vocabSet=set([])    #创建一个空集
    for document in dataSet:
        vocabSet=vocabSet | set(document) #求两个集合的并集 
    return list(vocabSet)

         3.构建词向量,这里采用的是词集模型,即只需记录每个词是否出现,而不考虑其出现的次数。需要记录词出现的次数的叫词袋模型。

            设存在一个词汇表list['a','b','c','d'] 和一个文本words['a','c']

            该函数的作用就是将 ['a','c'] 转换为[1,0,1,0] ---对应于list['a','b','c','d']            

def setOfWords2Vec(vocabList,inputSet):
    returnVec=[0]*(len(vocabList))
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]=1
        else:print('the word:%s is not in my Vocabulary!'% word)
    return returnVec
       将所有的句子都转化为词向量
tarinMat=[]
for postinDoc in listOposts:
    tarinMat.append(setOfWords2Vec(myVocabList,postinDoc))


二.训练算法:从词向量计算概率

原理:

                             贝叶斯定理如下式:      

    其中,x,y表示特征变量, 表示分类,即表示在特征为x,y的情况下分入类别的概率,因此,结合条件概率和贝叶斯定理,有:

●     如果,那么分类应当属于类;

●     如果,那么分类应当属于类;

       将x,y变为W,这里W是一个向量表示很多特征值,表示的是词汇表的单词在(侮辱性句子|正常语句)出现的概率。

                                                        

         

用训练集中,属于类别的样本数量除以总的样本数量即可;


可以根据前面的独立性假设,先分别计算等项,再将其结果相乘即可,而的计算公式为:

                                                                                                 

当仅仅是为了比较大小的时候,由于分母相同,因此只需要比较分子即可。

    朴素贝叶斯是基于特征条件独立这个假设的。也就是说,我们假设词汇表中各个单词独立出现,不会相互影响,因此可以将展开成独立事件概率相乘的形式,即:


    这个假设极大地降低了计算的复杂度,这也是朴素贝叶斯中“朴素”一词的由来。


在实现算法时,需要考虑两个问题

       a.当使用连乘计算时,若某一个词的概率为0,那么最终的结果也会为0,这是不正确的。为防止这种情况,需要将所有词项出现的次数都初始化为1,每一类所有词项数量初始化为2;

       b.在连乘时,为防止单项概率过小导致连乘结果下溢,需要对结果求自然对数将其转化为加法,因为


  1.求出ci,w/ci的概率,因为c1=1-c0.所以求一个就好了。

def trainNB0(trainMatrix,trainCategroy):
    numTrainDocs=len(trainMatrix) #留言总数 
    numWords=len(trainMatrix[0]) #单词个数。 
    pAbusive=sum(trainCategroy)/float(numTrainDocs) #侮辱性句子的概率 
    p0num=np.ones(numWords) #单词出现个数初始化为1 
    p1num=np.ones(numWords) 
    p0demon=2.0 #各类别单词出现总数初始化为2 
    p1demon=2.0 
    for i in range(numTrainDocs):
         if trainCategroy[i]==1:
             p1num+=trainMatrix[i] 
             p1demon+=np.sum(trainMatrix[i])
         else: p0num+=trainMatrix[i]
             p0demon+=np.sum(trainMatrix[i]) 
   p1Vect=np.log(p1num/p1demon) #转化为Log 函数 
   p0Vect=np.log(p0num/p0demon) 
   return p0Vect,p1Vect,pAbusive


2.利用上面求出的概率,定义预测函数。
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    p1=np.sum(vec2Classify*p1Vec)+np.log(pClass1)
    p0=np.sum(vec2Classify*p0Vec)+np.log(1-pClass1)
    if p1>p0:
        return 1
    else:
        return 0

其中vec2Classify 表示的是要预测的句子的词向量。

p0Vec,p1Vec,pClass1均为上一步函数的返回值,分别代表公式中的

3.编写测试函数。

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

结果:

                            


参考:Peter Harrington 《机器学习实战》

阅读更多

没有更多推荐了,返回首页