朴素贝叶斯1(学习记录)

以下内容来源于《Machine Learning in Action》

朴素贝叶斯

优点:在数据较少的情况下仍然有效,可以处理多类别问题。
缺点:对于输入数据的准备方式较为敏感。
适用数据类型:标称型数据

朴素贝叶斯的一般过程
(1) 收集数据:可以使用任何方法。本章使用RSS源。
(2) 准备数据:需要数值型或者布尔型数据。
(3) 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。
(4) 训练算法:计算不同的独立特征的条件概率。
(5) 测试算法:计算错误率。
(6) 使用算法:一个常见的朴素贝叶斯应用是文档分类。可以在任意的分类场景中使用朴
素贝叶斯分类器,不一定非要是文本。

准备数据:从文本中构建词向量

from numpy import *
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]    #1代表侮辱性语言, 0代表正常
    return postingList,classVec

#createVocabList()会创建一个包含在所有文档中出现的不重复词的列表
def createVocabList(dataSet):
    vacabSet=set([])
    for document in dataSet:
        #操作符|用于求两个集合的并集,这也是一个按位或( OR)操作符
        vacabSet=vacabSet | set(document)
    return list(vacabSet)

#统计inputSet的单词是否出现在vocabList中,返回向量(值只为0或1)
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

训练算法:从词向量计算概率
朴素贝叶斯分类器训练函数

#文档矩阵trainMatrix,以及由每篇文档类别标签所构成的向量trainCategory
def trainNB0(trainMatrix,trainCategory):
    numTrainDocs=len(trainMatrix)#获取文档矩阵中有几篇文档
    numWords=len(trainMatrix[0])#获取第一篇文档的单词长度
    pAbusive=sum(trainCategory)/float(numTrainDocs)#sum() 方法对序列进行求和计算。 类别为1的样本数量/样本总数
    #numpy.zeros()的作用:通常是把数组转换成想要的矩阵
    # p0Num=zeros(numWords)
    # p1Num=zeros(numWords)
    # p0Denom = 0.0
    # p1Denom = 0.0
    # 利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概
    # 率,即计算p(w0|1)p(w1|1)p(w2|1)。如果其中一个概率值为0,那么最后的乘积也为0。为降低
    # 这种影响,可以将所有词的出现数初始化为1,并将分母初始化为2
    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])
    # 当计算乘积p(w0|ci)p(w1|ci)p(w2|ci)...p(wN|ci)时,由于大部分因子都非常小,所以程序会下溢出或者得到不正确的答案
    # 一种解决办法是对乘积取自然对数。在代数中有ln(a * b) = ln(a) + ln(b),于是通过求对数可以
    # 避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。
    # p1Vect=p1Num/p1Denom
    # p0Vect=p0Num/p0Denom
    p1Vect = log(p1Num / p1Denom)
    p0Vect=log(p0Num/p0Denom)
    return  p0Vect,p1Vect,pAbusive

关于 # p1Vect=p1Num/p1Denom
# p0Vect=p0Num/p0Denom
p1Vect = log(p1Num / p1Denom)
p0Vect=log(p0Num/p0Denom)
在这里插入图片描述

测试算法:根据现实情况修改分类器

def classifierNB(vec2Classify,p0Vec,p1Vec,pClass1):
    #这里的相乘是指对应元素相乘,即先将两个向量中的第1个元素相乘,然后将第2个元素相乘,以此类推
    p1=sum(vec2Classify*p1Vec)+log(pClass1)
    p0=sum(vec2Classify*p0Vec)+log((1-pClass1))
    if p1>p0:
        return 1
    else:
        return 0

def testingNB():
    listOPosts,listClasses=loadDataSet()
    myVocabList=createVocabList(listOPosts)
    trainMat=[]
    #生成值只为0或者1的矩阵
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
    p0V,p1V,pAb=trainNB0(trainMat,listClasses)
    testEntry=['love','my','dalmation']
    thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
    print(testEntry,'classified as :',classifierNB(thisDoc,p0V,p1V,pAb))
    testEntry=['stupid','garbage']
    thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
    print(testEntry, 'classified as :', classifierNB(thisDoc, p0V, p1V, pAb))

testingNB()

测试结果
在这里插入图片描述

准备数据:文档词袋模型

目前为止,我们将每个词的出现与否作为一个特征,这可以被描述为词集模型( set-of-words
model)。如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现在文档中所不能表
达的某种信息,这种方法被称为词袋模型( bag-of-words model)。在词袋中,每个单词可以出现
多次,而在词集中,每个词只能出现一次。为适应词袋模型,需要对函数setOfWords2Vec()
稍加修改,修改后的函数称为bagOfWords2Vec()。
下面的程序清单给出了基于词袋模型的朴素贝叶斯代码。它与函数setOfWords2Vec()几乎
完全相同,唯一不同的是每当遇到一个单词时,它会增加词向量中的对应值,而不只是将对应的
数值设为1。
朴素贝叶斯词袋模型

#朴素贝叶斯词袋模型
def bagOfWords2VecMN(vocabList,inpustSet):
    returnVec=[0]*len(vocabList)
    for word in len(vocabList):
        if word in vocabList:
            returnVec[vocabList.index(word)]+=1
    return returnVec
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值