朴素贝叶斯

本文主要讲朴素贝叶斯算法(naiveBayes)

1.基本方法

朴素贝叶斯发是基于贝叶斯定理与特征条件独立假设的分类方法。所谓朴素即是特征条件独立。

对于给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。

2.后验概率最大化

3.算法

 

下面简单举个栗子:

4.朴素贝叶斯应用:文档分类及其实现

在文本中获取特征,需要先拆分文本。将每个文本变成词向量,其中1表示词条出现在文档中,0表示词条未出现在文档中。

计算每个词条在侮辱性和非侮辱性条件下的概率,最后相乘再乘以先验概率即可。

思路:

对每个类别:

         如果词条出现在文档中,就增加该词条的计数值

         增加所有词条的计数值

对每个类别:

          对每个词条:

                   将该词条的数目除以总词条数目得到条件概率

代码如下:


import numpy as np
# 过滤网站的恶意留言  侮辱性:1     非侮辱性:0
# 创建一个实验样本
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]      #分类标签
    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)        # 创建一个其中所含元素都为0的向量
    for word in inputSet:
        if word in vocabList:
            # returnVec[vocabList.index(word)] = 1     # index函数在字符串里找到字符第一次出现的位置  词集模型
            returnVec[vocabList.index(word)] += 1      # 文档的词袋模型    每个单词可以出现多次
        else: print("the word: %s is not in my Vocabulary!" % word)
        #其实现在所有的词条都在集合里面,因为前面已经将所有不重复的词构造了一个列表
    return returnVec

# 朴素贝叶斯分类器训练函数   从词向量计算概率
def trainNB0(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)   #样本数目
    numWords = len(trainMatrix[0])    #每个词向量的长度
    pAbusive = sum(trainCategory)/float(numTrainDocs)  #侮辱性词汇的先验概率
    #sum()就是将列表中的元素的值相加所得的和,因为类别是0和1,所以相加的也就是侮辱性词的数量
    # p0Num = zeros(numWords); p1Num = zeros(numWords)
    # p0Denom = 0.0; p1Denom = 0.0
    #用拉普拉斯平滑改进
    p0Num = np.ones(numWords);   # 避免一个概率值为0,最后的乘积也为0
    p1Num = np.ones(numWords);   # 用来统计两类数据中,各词的词频
    p0Denom = 2.0;  # 用于统计0类中的总数
    p1Denom = 2.0  # 用于统计1类中的总数
    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 = np.log(p1Num / p1Denom)    # 在类1中,每个次的发生概率
    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.0-pClass1)
    if p1 > p0:
        return '侮辱性'
    else:
        return '非侮辱性'

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))

# 调用测试
testingNB()
这里好好体会下怎么算条件概率的。因为转换成了词向量,需要用出现的次数除以这个类别的词条总数。还有这里的条件概率都用矩阵存储起来了,方便多了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值