当前位置:   article > 正文

朴素贝叶斯分类(python实现)_朴素贝叶斯python

朴素贝叶斯python

朴素贝叶斯算法

1.基本概念

朴素贝叶斯算法是基于统计学概率的分类方法,通过计算样本发生的概率来实现分类。这里必须知道贝叶斯公式
p ( X Y ) = p ( X ∣ Y ) ∗ p ( Y ) = p ( Y ∣ X ) ∗ p ( X ) ( 1 ) p(XY)=p(X|Y)*p(Y)=p(Y|X)*p(X)\quad\quad\quad(1) p(XY)=p(XY)p(Y)=p(YX)p(X)(1)
有些时候在直接计算P(Y|X)的条件概率时显得很困难,但是使用朴素贝叶斯公式就可以间接求解。当然使用贝叶斯公式求解问题的前提是,各个事件相互独立。举个例子吧

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QdIPg4Yu-1689589824200)(D:\学习资料\机器学习实战\朴素贝叶斯算法\截图\数据集.png)]

在这份数据集中,事件年龄和有工作是互不影响的,两者没有任何关系,他们之间就是相互独立的,当然在现实生活中肯定会有一些影响。记事件年龄为0的情况下同意贷款的概率为P(Y|x1),直接求这个概率就显得很棘手,但是使用贝叶斯公式后,就很简单了
p ( Y ∣ x 1 ) = p ( X 1 ∣ Y ) ∗ p ( Y ) p ( x 1 ) = 2 9 ∗ 9 15 5 15 ( 2 ) p(Y|x_1)=\frac{p(X_1|Y)*p(Y)}{p(x_1)}=\frac{\frac{2}{9}*\frac{9}{15}}{\frac{5}{15}}\quad\quad\quad(2) p(Yx1)=p(x1)p(X1Y)p(Y)=15592159(2)

2.朴素贝叶斯分类

朴素贝叶斯分类器就是分别计算在该数据样本中的情况下是类别A的概率
p ( A ∣ X ) = p ( X ∣ A ) ∗ p ( A ) p ( X ) ( 3 ) p(A|X)=\frac{p(X|A)*p(A)}{p(X)}\quad\quad\quad(3) p(AX)=p(X)p(XA)p(A)(3)
是该数据样本中的情况下是类别B的概率
p ( B ∣ X ) = p ( X ∣ B ) ∗ p ( B ) p ( X ) ( 4 ) p(B|X)=\frac{p(X|B)*p(B)}{p(X)}\quad\quad\quad(4) p(BX)=p(X)p(XB)p(B)(4)
然后比较两种大小,取概率大的作为该数据样本的类别。当然这是一个二分类问题,多分类问题也是类似比较各个分类的条件概率,然后取概率大作为数据样本的分类。

对于多个特征维度X的情况下,P(X|A)计算时需要拆分成P(x1|A)*P(x1|A)*P(x1|A),但是如果其中一项概率为零,会影响整个概率计算结果,为了解决这个问题,初始化过程中设为1,不要设为0.同时还存在另外一个问题就是如果各个概率过小,计算时可能会出现下溢出(很多小数相乘会四舍五入为0),为了解决这个问题,计算过程中取对数
l n ( p ( X ∣ A ) ) = l n ( p ( x 1 ∣ A ) ) + l n ( p ( x 2 ∣ A ) ) + l n ( p ( x 3 ∣ A ) ) + . . . ( 5 ) ln(p(X|A))=ln(p(x_1|A))+ln(p(x_2|A))+ln(p(x_3|A))+...\quad(5) ln(p(XA))=ln(p(x1A))+ln(p(x2A))+ln(p(x3A))+...(5)
在观察公式3,4我们发现分母都是一样的,所以这里可以简化计算,只比较分子的大小

3.使用朴素贝叶斯过滤垃圾邮件

#导入第三方科学计算包
import random

from numpy import *
#导入正则表达式模块
import re

#统计文档中所有单词
def createVocabList(dataSet):
    #定义并初始化词汇列表
    vocabSet=set([])
    #对于数据集中每一句话迭代
    for document in dataSet:
        #将每一句话中的单词与词汇集合并并去重
        vocabSet=vocabSet|set(document)
    #返回词汇列表
    return list(vocabSet)
#将词汇表转换为文档向量
def setOfWordsVec(vocabList,inputSet):
    #定义并初始化返回的词汇向量
    returnVec=[0]*len(vocabList)
    #对于传入的话的每一个单词迭代
    for word in inputSet:
        #如果该单词在词汇列表中
        if word in vocabList:
            #对相应的词汇向量加一
            returnVec[vocabList.index(word)]+=1
    #返回词汇向量
    return returnVec
#贝叶斯分类器
def trainNB(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
#使用朴素贝叶斯分类器进行分类
def classifyNB(vecClassify,p0Vec,p1Vec,pClass1):
    #计算条件概率:在该邮件的情况下,是垃圾邮件的概率(计算时由于两者分母相同,故省去了分母)
    p1=sum(vecClassify*p1Vec)+log(pClass1)
    #计算条件概率:在该邮件的情况下,是正常邮件的概率(计算时由于两者分母相同,故省去了分母)
    p0=sum(vecClassify*p0Vec)+log(1.0-pClass1)
    #比较两者概率,返回概率大的哪个类别
    if p1>p0:
        return 1
    else:
        return 0
#邮件文件解析
def textParse(bigString):
    #使用正则表达式处理数据文件
    regEx=re.compile(r'\W')
    listOfTokens=regEx.split(bigString)
    #筛选出字符长度大于2单词,并且改为小写
    return [tok.lower() for tok in listOfTokens if len(tok)>2]
#垃圾邮件测试
def spamTest():
    #定义邮件内容数据集
    docList=[]
    #定义邮件种类
    classList=[]
    #
    fullText=[]
    #对26封邮件迭代处理
    for i in range(1,26):
        #对邮件内容处理
        wordList=textParse(open("D:/学习资料/机器学习实战/《机器学习实战》源代码/machinelearninginaction/Ch04/email/spam/%d.txt" % i).read())
        #将每一封邮件作为一个数据样本存入邮件数据集
        docList.append(wordList)
        #
        fullText.extend(wordList)
        #定义邮件种类为垃圾邮件
        classList.append(1)
        #对邮件内容处理
        wordList=textParse(open("D:/学习资料/机器学习实战/《机器学习实战》源代码/machinelearninginaction/Ch04/email/ham/%d.txt" %i).read())
        # 将每一封邮件作为一个数据样本存入邮件数据集
        docList.append(wordList)
        fullText.extend(wordList)
        # 定义邮件种类为垃圾邮件
        classList.append(0)
    #获取所有邮件的词汇表
    vocabList=createVocabList(docList)
    #定义并初始化训练集
    trainingSet=list(range(50))
    #定义并初始测试集
    testSet=[]
    #从0-9迭代
    for i in range(10):
        #在1-50间生成分布均匀的随机数
        randIndex =int(random.uniform(0,len(trainingSet)))
        # 在测试数据集中添加随机生成下标所对应的训练数据集
        testSet.append(trainingSet[randIndex])
        #在训练数据集中删除添加的测试数据集
        del (trainingSet[randIndex])
    # 初始化训练集词汇向量表
    trainMat=[]
    # 定义并初始化训练集标签
    trainClasses=[]
    #对训练集中的每一份邮件样本迭代
    for docIndex in trainingSet:
        #将样本邮件中的词汇向量添加到存储词汇向量表
        trainMat.append(setOfWordsVec(vocabList,docList[docIndex]))
        #将样本邮件类别添加到存储邮件类别的列表中
        trainClasses.append(classList[docIndex])
    #在非垃圾邮件概率的情况下,各个单词出现的概率,在垃圾邮件的情况下,各个单词出现的概率,获取垃圾邮件概率
    p0v,p1v,pSpm=trainNB(array(trainMat),array(trainClasses))
    #定义并初始话错误数目
    errorCount=0.0
    #对测试集中每一份邮件样本迭代
    for docIndex in testSet:
        #获取测试邮件样本的词汇向量表
        wordVector=setOfWordsVec(vocabList,docList[docIndex])
        #如果预测结果与实际不符
        if classifyNB(array(wordVector),p0v,p1v,pSpm)!=classList[docIndex]:
            errorCount+=1
    print(f"错误率是{float(errorCount)/len(testSet)}")

#测试
if __name__=='__main__':

    spamTest()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146

4.总结

朴素贝叶斯分类常用于垃圾邮件检测,污秽语言检测,它要求各个时间之间相互独立,互不影响.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/679456
推荐阅读
相关标签
  

闽ICP备14008679号