机器学习 jupyter Python 监督学习 贝叶斯定理 朴素贝叶斯分类器

1.贝叶斯定理

在这里插入图片描述
其中𝑃(H│𝑋)表示给定观测样本X,假设H成立时的概率;
𝑃(H│𝑋)是后验概率;(例如:包含特定特征的邮件属于垃圾邮件的先验概率)
𝑃(𝐻)是H的先验概率。(例如:垃圾邮件的先验概率)
𝑃(𝑋)是X的先验概率。

2.条件概率

如果两个事件A和B不是互相独立的,并且知道事件B中的一个事件已经发生,我们就能得到关于P(A)的信息。这反映为A在B中的条件概率,记为P(A|B):
在这里插入图片描述
如果A和B是独立的:
在这里插入图片描述

条件概率:就是已知一个事件发生的情况下,另外一个事件发生的概率。
贝叶斯定理是一个交换概率的公式;条件概率就是一个概率。

例子
在这里插入图片描述

“在已知石头出自B桶的条件下, 取出灰色石头的概率”?
这个概率可以记作P(gray|bucketB) ,这就是所谓的条件概率(计算从B桶取到灰色石头的概率) 。
就是已知一个事件发生的情况下,另外一个事件发生的概率
P(gray|bucketB)=1/3

3.朴素贝叶斯分类器

3.1 朴素贝叶斯分类器的由来

要得到好的分类器,就需要足够的数据样本 。由统计学知,如果每个特征需要N个样本,那么对于10个特征将需要𝑁^10个样本, 对于包含1000个特征的词汇表将需要 𝑁 ^1000个样本。可以看到,所需要的样本数会随着特征数目增大而迅速增长。如果特征之间相互独立,那么样本数就可以从𝑁 ^1000减少到1000×N。
所谓独立(independence),指的是统计意义上的独立,即一个特征或者单词出现的可能性与它和其他单词相邻没有关系。举个例子讲,假设单词bacon出现在unhealthy后面与出现在delicious后面的概率相同。当然,我们知道这种假设并不正确, bacon常常出现delicious附近,而很少出现在unhealthy附近,这个假设正是朴素贝叶斯分类器中朴(naive)一词的含义 。
总结,就是一句话表达什么意思我们不关心,我们只关心出现那些词汇。
尽管上述假设存在一些小的瑕疵,但朴素贝叶斯的实际效果却很好。

3.2 用于解决那些问题?

新闻分类
评论分析-好评还是差评
邮件分类

3.3 理论支撑是贝叶斯定理

在这里插入图片描述

3.4 例子

(简单的)垃圾邮件分类问题
邮件:总体100,正常70,垃圾30.
“办证”在正常邮件中的出现10次,在垃圾邮件中出现25次。
现在有一个问题,当一个邮件包含”办证”这个词,它属于垃圾邮件的概率?
假设X为”办证”,H为垃圾邮件,则P(H|X),即为我们所要求的概率(当一个邮件包含”办证”这个词,它属于垃圾邮件的概率)?
我们就可以借助贝叶斯定理:𝑃(𝐻│𝑋)=(𝑃(𝑋|𝐻)𝑃(𝐻))/(𝑃(𝑋))

因为P(X|H)=25/30=5/6,P(H)=30/100=3/10,p(x)=35/100=7/20

𝑃(𝐻│𝑋)=(𝑃(𝑋|𝐻)𝑃(𝐻))/(𝑃(𝑋))=(5/6×3/10)/(7/20)=5/7

还是刚刚的垃圾邮件分类问题,我们现在考虑的不是当一份邮件包含“办证”的时候它属于垃圾邮件的概率(P(H|X)),现在我们考虑的是当一份邮件包含“办证”、“理财”, “投资”的时候属于垃圾邮件的概率。也就是考虑的特征不止一个的时候,朴素贝叶斯就显得非常重要;
假设:假设X1为“办证”,X2为“投资”,X3为“理财”,H为垃圾邮件,那么我们刚刚所要求的概率即为:
在这里插入图片描述
推广到n个特征:
在这里插入图片描述

注:当A和B相互独立时,𝑃(𝐴𝐵)=𝑃(𝐴)𝑃(𝐵)

3.5 朴素贝叶斯分类器的实现方式(特征模型)

3.5.1 贝(伯)努利模型(常见)

(1)适用数据类型
离散值。
(2)模型介绍
该模型在有些书中也被称为词集模型。其与多项式模型类似,不过该模型中,每个特征取值只能为1或0,表示出现与否(对于文本分类而言,1表示某个单词出现在该文本中,0则表示没有出现)
该实现方式中并不考虑词在文档中出现的次数,只考虑出不出现,因此在这个意义上相当于假设词是等权重的。
(3)例如:“代开发票,增值税发票,正规发票”
分词后的向量:
(“代开”,“发票”,“增值税”,“正规”)
重复的词我们将其视为出现一次

3.5.2 多项式模型(常见)

(1)适用数据类型
离散值。即对应的特征为离散的。比如性别(取值为男、女)、学历(小学、高中、本科、专科、硕士、博士、博士后)。
(2)模型介绍
该模型在一些书中也称为词袋模型。在词袋中,每个单词可以出现多次 ,不仅考虑它是否出现,而且考虑出现的次数(因为出现次数可能和其重要性相关)。
(3)例如:“代开发票,增值税发票,正规发票”
分词后的向量:
(“代开”,“发票”,“增值税”,“发票”,“正规”,“发票”)
重复的词我们将其视为出现多次。

3.5.3 高斯模型

(1))适用数据类型
连续型。比如身高等。
(2)模型介绍
高斯模型假设每一维特征都服从高斯分布(正态分布):
(3)举例:有些特征可能是连续性变量。比如说人的身高,物体的长度,这些特征可以转化为离散型的值。
比如身高在160cm以下的,特征值为1;在160cm和170cm之间,特征值为2;在170cm之上,特征值为3。
也可以这样转换,将身高转化为3个特征,分别为f1,f2,f3如果身高在160cm以下,这3个特征的值分别为1、0、0,在170cm之上,这3个特征的值分别为0、0、1。

4.案列 社区言论(区分善评,还是恶评)

4.1 理论基础

在这里插入图片描述
假设有一个数据集,由两类组成(简化问题),对于每个样本的分类,我们都已经知晓。
现在出现一个新的点new_point (x,y),其分类未知。
我们可以用p1(x,y)表示数据点(x,y)属于红色一类的概率,同时也可以用p2(x,y)表示数据点(x,y)属于蓝色一类的概率。
那要把new_point归在红、蓝哪一类呢?
我们提出这样的规则:
如果p1(x,y) > p2(x,y),则(x,y)为红色一类。
如果p1(x,y) <p2(x,y), 则(x,y)为蓝色一类。
换人类的语言来描述这一规则:选择概率高的一类作为新点的分类。这就是贝叶斯决策理论的核心思想,即选择具有最高概率的决策。

4.2 思路

4.2.1 找到特征属性

现在有6条留言,作为训练样本。经过处理,我们得到6条留言的词汇如下:
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‘]]
注:假设X1,X2,….Xn表示特征,H表示恶意留言,O表示善意留言。则关键是求
𝑃(H│𝑋1,𝑋2……𝑋𝑛)和𝑃(𝑂│𝑋1,𝑋2……𝑋𝑛)
如果𝑃(H│𝑋1,𝑋2……𝑋𝑛)>𝑃(𝑂│𝑋1,𝑋2……𝑋𝑛),则属于恶意留言。
如果𝑃(H│𝑋1,𝑋2……𝑋𝑛)<𝑃(𝑂│𝑋1,𝑋2……𝑋𝑛),则属于善意留言。
我们找到的特征其实就是样本点包含的所有词汇,如下:
[‘please’, ‘mr’, ‘stop’, ‘love’, ‘how’, ‘park’, ‘quit’, ‘problems’, ‘to’, ‘so’, ‘I’, ‘stupid’, ‘buying’, ‘is’, ‘dalmation’, ‘cute’, ‘dog’, ‘ate’, ‘worthless’, ‘garbage’, ‘maybe’, ‘steak’, ‘has’, ‘help’, ‘him’, ‘food’, ‘not’, ‘take’, ‘flea’, ‘posting’, ‘licks’, ‘my’]

4.2.2 找到特征属性值

找到样本的特征属性之后,我们就可以确定每条留言的特征属性值(词汇向量)。
[[1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]]

4.2.3 每个词汇在每种类别出现的概率

n个特征X1,X2,…….Xn:
𝑃(𝐻𝑖│𝑋1,𝑋2……𝑋𝑛)=(𝑃(𝑋1,𝑋2…𝑋𝑛|𝐻)𝑃(𝐻))/(𝑃(𝑋1,𝑋2…𝑋𝑛))=(𝑃(𝑋1│𝐻)𝑃(𝑋2│𝐻)…𝑃(𝑋𝑛|𝐻)𝑃(𝐻𝑖))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛))

那么现在关键点就是求出来
𝑃(𝑋1│𝐻),𝑃(𝑋2│𝐻),…𝑃(𝑋𝑛|𝐻)

在这里插入图片描述
例如:
x1为”please”,H为恶意留言,则𝑃(X1│𝐻)=X1在恶意留言出现的总次数/恶意留言总的词汇数。

4.2.4 更改初始值,取对数

我们用H代表恶意留言,O代表善意留言
𝑃(𝑋1│𝐻),𝑃(𝑋2│𝐻),…𝑃(𝑋𝑛|𝐻),𝑃(𝑋1│O),𝑃(𝑋2│𝑂),…𝑃(𝑋𝑛|𝑂)
𝑃(𝐻│𝑋1,𝑋2……𝑋𝑛)=(𝑃(𝑋1│𝐻)𝑃(𝑋2│𝐻)…𝑃(𝑋𝑛|𝐻)𝑃(𝐻))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛))
𝑃(𝑂│𝑋1,𝑋2……𝑋𝑛)=(𝑃(𝑋1│𝑂)𝑃(𝑋2│𝑂)…𝑃(𝑋𝑛|𝑂)𝑃(𝑂))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛))
在这里插入图片描述
从上图可以看出,在计算的时候已经出现了概率为0的情况。如果新实例文本,包含这种概率为0的分词,那么最终的文本属于某个类别的概率也就是0了。显然,这样是不合理的,为了降低这种影响,可以将所有词的出现数初始化为1,并将分母初始化为2。这种做法就叫做拉普拉斯平滑(Laplace Smoothing)又被称为加1平滑,是比较常用的平滑方法,它就是为了解决0概率问题。
除此之外,另外一个遇到的问题就是下溢出,这是由于太多很小的数相乘造成的。学过数学的人都知道,两个小数相乘,越乘越小,这样就造成了下溢出。在程序中,在相应小数位置进行四舍五入,计算结果可能就变成0了。为了解决这个问题,对乘积结果取自然对数。通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。
在这里插入图片描述
在这里插入图片描述
对数转化
𝑃(𝑋1│𝐻),𝑃(𝑋2│𝐻),…𝑃(𝑋𝑛|𝐻),𝑃(𝑋1│O),𝑃(𝑋2│𝑂),…𝑃(𝑋𝑛|𝑂)
𝑃(𝐻│𝑋1,𝑋2……𝑋𝑛)=(𝑃(𝑋1│𝐻)𝑃(𝑋2│𝐻)…𝑃(𝑋𝑛|𝐻)𝑃(𝐻))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛))
𝑃(𝑂│𝑋1,𝑋2……𝑋𝑛)=(𝑃(𝑋1│𝑂)𝑃(𝑋2│𝑂)…𝑃(𝑋𝑛|𝑂)𝑃(𝑂))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛))
比如上面的恶意留言筛选问题,如果𝑃(𝐻│𝑋1,𝑋2……𝑋𝑛)>𝑃(𝑂│𝑋1,𝑋2……𝑋𝑛),则我们判断当一个留言包含X1,x2,…Xn时,我们把它归类为恶意留言,否则就是善意留言。
经过对数转化,我们比较的结果即为:
log⁡(𝑃(𝐻│𝑋1,𝑋2……𝑋𝑛))=𝑙𝑜𝑔{(𝑃(𝑋1│𝐻)𝑃(𝑋2│𝐻)…𝑃(𝑋𝑛│𝐻)𝑃(𝐻))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛) )}=log⁡(𝑃(𝑋1│𝐻))+log⁡(𝑃(𝑋2│𝐻))+…+log⁡(𝑃(𝑋𝑛│𝐻))+log⁡(𝑃(𝐻))−𝑀
其中 M=log⁡(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛))

4.2.5 判断类别

log⁡(𝑃(𝐻│𝑋1,𝑋2……𝑋𝑛))=𝑙𝑜𝑔{(𝑃(𝑋1│𝐻)𝑃(𝑋2│𝐻)…𝑃(𝑋𝑛│𝐻)𝑃(𝐻))/(𝑃(𝑋1)𝑃(𝑋2)…𝑃(𝑋𝑛) )}=log⁡(𝑃(𝑋1│𝐻))+log⁡(𝑃(𝑋2│𝐻))+…+log⁡(𝑃(𝑋𝑛│𝐻))+log⁡(𝑃(𝐻))−𝑀=𝐿−𝑀
经过上述处理,我们最终比较的是N和L的值;其中
log⁡(𝑃(𝑋1│𝑂))+log⁡(𝑃(𝑋2│𝑂))+…+log⁡(𝑃(𝑋𝑛│𝑂))+log⁡(𝑃(𝑂))=𝑁
log⁡(𝑃(𝑋1│𝐻))+log⁡(𝑃(𝑋2│𝐻))+…+log⁡(𝑃(𝑋𝑛│𝐻))+log⁡(𝑃(𝐻))=𝐿

4.3 代码实现

4.3.1 找到所有的特征(所有言论总词汇和标签)

#找到所有的特征(所有言论的总词汇)
import numpy as np
def loadDataSet():
    postingList=[['my','dog','has','flea','problems','help','please'],
                ['maybe','not','take','him','to','dog','park','stupid'],
                 ['stop','dalmation','is','so','cute','I','love','him'],
                 ['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
listOPosts,listclasses=loadDataSet()
print('言论内容:',listOPosts)
def createVocaList(dataSet):
    #创建空的set集合,set集合无序不重复的元素,支持交并补差集合运算
    vocabSet=set([])
    for document in dataSet:
        vocabSet=vocabSet|set(document)#\并集,把重复的元素过滤
    return list(vocabSet)#列表有索引,set集合没有
MyvocabList=crateVocalList(listOPosts)
print('特征属性:',MyvocabList)

运行结果:
在这里插入图片描述

4.3.2 找到每条言论对应的词汇向量,每一条词汇向量是一个列表的形式

#找到每条言论对应的词汇向量,每一条词汇向量是一个列表的形式
def setofwords2vec(feature,inputset):
    returnVec=[0]*len(feature)
#     print(returnVec)
    for word in inputset:
        #print(word)
        if word in feature:
            returnVec[feature.index(word)] = 1
        else:
            print('the word:%s is not in myvocabList'%word)
    return returnVec
trainMatrix=[]
for postinDoc in listPosts:
    trainMatrix.append(setofwords2vec(MyvocabList,postinDoc))
print(trainMatrix)

运行结果:
在这里插入图片描述

4.3.3 根据词汇向量,求出每个特征在每种标签对应的概率

#根据词汇向量,求出每个特征在每种标签对应的概率
def trainNBO(wordSetVec,labels):
    numDataSet=len(wordSetVec)#样本数
    pAbusive =sum(labels)/numDataSet
    featureNum=len(wordSetVec[0])#特征数
    #初始化零(行)向量,存放每个特征在每种标签下出现的次数,0表示善意的言论
    p0Num=np.ones(featureNum);p1Num=np.ones (featureNum)
    #初始化分母,分母代表每种标签里面的单词数
    p0Denom=2;p1Denom=2
    for i in range(numDataSet):
        if labels[i]==1:
            p1Num += wordSetVec[i]#对应位置上相加,累加即可求得每个特征出现的次数
            p1Denom += sum(wordSetVec[i])#累加即可求得1标签下所有的单词数
        else:
            p0Num+= wordSetVec[i]#对应位置上相加,累加即可求得每个特征出现的次数
            p0Denom+=sum(wordSetVec[i])#累加即可求得1标签下所有的单词数
    p0Vec=np.log(p0Num/p0Denom) #求出每个特征在0类别下的概率
    p1Vec=np.log(p1Num/p1Denom) #求出每个特征在0类别下的概率
    return p0Vec,p1Vec,pAbusive
p0,p1,pA=trainNBO(trainMatrix,listclasses)
print('p0:',p0)
print('p1:',p1)
print('pA:',pA)

运行结果:
在这里插入图片描述

4.3.4 由上面的概率值,我们定义朴素贝叶斯分类

#由上面的概率值,我们定义朴素贝叶斯分类
def NBC(TestWordVec,p0Vec,p1Vec,pclasses):
    p1=sum(TestWordVec*p1Vec)+np.log(pclasses)
    p0=sum(TestWordVec*p1Vec)+np.log(1-pclasses)
    if p1>p0:
        return "1标签"
    if p1<p0:
        return "0标签"

4.3.5 测试算法

#测试算法
def testingNBC():
    listOPosts,listclasses=loadDataSet()
    print('词汇列表:',listOPosts)
    MyvocabList=createVocaList(listOPosts)
    print('特征属性:',MyvocabList)
    trainMatrix=[]
    for postinDoc in listOPosts:
        # print(postinDoc)
        trainMatrix.append(setofwords2vec(MyvocabList,postinDoc))
    print('特征向量:',trainMatrix)
    p0,p1,pA=trainNBO(trainMatrix,listclasses)
    print('概率:',p0,p1,pA)
#     testEntry=['love','my','dalmation']
#     testVec=setofwords2vec(MyvocabList,testEntry)
#     print('分类器分类的类别为:',NBC(testVec,p0,p1,pA))
    testEntry1=['stupid','garbage']
    testVec1=setofwords2vec(MyvocabList,testEntry1)
    print('分类器分类的类别为:',NBC(testVec1,p0,p1,pA))
testingNBC()

运行结果:
在这里插入图片描述

5.使用sklearn模块的朴素贝叶斯分类器

5.1 导入相关模块、包和数据集

import numpy as np
from sklearn import datasets#训练集
from sklearn.model_selection import train_test_split#划分测试集,训练集
# from sklearn.metrics import classification_report,confusion_matrix
#性能指标(Metrics)是衡量一个模型好坏的关键
#sklearn中的classification_report函数用于显示主要分类指标的文本报告
from sklearn.naive_bayes import MultinomialNB,BernoulliNB,GaussianNB
#高斯模型主要用于处理连续性数据;前两种模型主要用于处理离散型数据
from sklearn.metrics import accuracy_score

5.2 载入数据集

#载入数据集
iris = datasets.load_iris()
print(type(iris))
print('特征值:',iris.data)

运行结果:
在这里插入图片描述
在这里插入图片描述

5.3 划分数据、建立模型、训练模型

这里采用高斯模型

x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target)#划分测试集,训练集
print(len(x_train))
print(len(x_test))
# mul_nb = MultinomialNB()
# mul_nb = BernoulliNB()
mul_nb = GaussianNB()
mul_nb.fit(x_train,y_train)
prediction = mul_nb.predict(x_test)
accuracy_score(prediction,y_test)#accuracy=分对的样本数/总的测试的样本数

运行 结果:
在这里插入图片描述

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值