机器学习笔记6-朴素贝叶斯基础

一、朴素贝叶斯理论

1、贝叶斯决策理论

在这里插入图片描述贝叶斯决策理论核心思想:

  • 如果p1(x,y) > p2(x,y),那么类别为1
  • 如果p1(x,y) < p2(x,y),那么类别为2

哪个概率高则选择哪一个类别。其中,p1(x,y)表示数据点(x,y)属于类别1的概率。

2、贝叶斯准则-条件概率(conditional probability)计算

P ( A ∣ B ) = P ( A ∩ B ) P ( B ) P(A|B)={{P(A∩B)}\over{P(B)}} P(AB)=P(B)P(AB)

  • 第一种条件概率计算式:
    可得 P ( A ∩ B ) = P ( A ∣ B ) P ( B ) P(A∩B)=P(A|B)P(B) P(AB)=P(AB)P(B) 同理可得 P ( A ∩ B ) = P ( B ∣ A ) P ( A ) P(A∩B)=P(B|A)P(A) P(AB)=P(BA)P(A)所以 P ( A ∣ B ) P ( B ) = P ( B ∣ A ) P ( A ) P(A|B)P(B)=P(B|A)P(A) P(AB)P(B)=P(BA)P(A) P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B)={{P(B|A)P(A)}\over{P(B)}} P(AB)=P(B)P(BA)P(A)

  • 第二种条件概率计算公式(全概率):
    在这里插入图片描述样本空间由红色部分的A和绿色部分的A’组成
    其中 P ( B ) = P ( B ∩ A ) + P ( B ∩ A ′ ) P(B)=P(B∩A)+P(B∩A') P(B)=P(BA)+P(BA)由上节推导可知 P ( B ∩ A ) = P ( B ∣ A ) P ( A ) P(B∩A)=P(B|A)P(A) P(BA)=P(BA)P(A)可得全概率公式 P ( B ) = P ( B ∣ A ) P ( A ) + P ( B ∣ A ′ ) P ( A ′ ) P(B)=P(B|A)P(A)+P(B|A')P(A') P(B)=P(BA)P(A)+P(BA)P(A)其含义是:如果A和A’构成样本空间,那么事件B的概率,就等于A和A’的概率分别乘以B对这两个事件的条件概率之和。 P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ∣ A ) P ( A ) + P ( B ∣ A ′ ) P ( A ′ ) P(A|B)={{P(B|A)P(A)}\over{P(B|A)P(A)+P(B|A')P(A')}} P(AB)=P(BA)P(A)+P(BA)P(A)P(BA)P(A)

3、两种推断

  • 贝叶斯推断 P ( A ∣ B ) = P ( A ) P ( B ∣ A ) P ( B ) P(A|B)=P(A){{P(B|A)}\over{P(B)}} P(AB)=P(A)P(B)P(BA)其中,P(A)称为“先验概率(prior probability)”,即在B事件发生之前,我们对A事件概率的一个判断。
    P(A|B)称为“后验概率(posterior probability)”,即在B事件发生之后,我们对事件概率的重新评估。
    P(B|A)/{P(B)称为“可能性函数(likelyhood),这是一个调整因子,使得预估概率更接近真实概率。

后验概率 = 先验概率 x 调整因子

  • 朴素贝叶斯推断
    朴素贝叶斯对条件概率分布做了条件独立性假设。 P ( a ∣ X ) = p ( X ∣ a ) p ( a ) = p ( x 1 , x 2 , . . . . . , x n ∣ a ) p ( a ) P(a|X)=p(X|a)p(a)=p(x1,x2,.....,xn|a)p(a) P(aX)=p(Xa)p(a)=p(x1,x2,.....,xna)p(a)假设每个特征独立,则进一步拆分公式 P ( a ∣ X ) = p ( X ∣ a ) p ( a ) = p ( x 1 ∣ a ) ∗ p ( x 2 ∣ a ) ∗ . . . . . ∗ p ( x n ∣ a ) p ( a ) P(a|X)=p(X|a)p(a)={p(x1|a)*p(x2|a)*.....*p(xn|a)}p(a) P(aX)=p(Xa)p(a)=p(x1a)p(x2a).....p(xna)p(a)

4、贝叶斯定理分类思想

基于概率,通过某对象的先验概率,利用贝叶斯公式计算出其后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类。

5、贝叶斯分类方法种类

朴素贝叶斯:各特征间独立,直接计算条件概率进行分类,是最简单的一种贝叶斯分类算法。
贝叶斯网络:不满足各特征独立条件时,使用贝叶斯网络分类。贝叶斯网络也称为信念网络,或有向无环图模型,是一种概率图模型。

6、贝叶斯分类典型应用

垃圾邮件过滤
文本情感分类:电影影评
论坛真实账号监测
浏览器输入自动提示

7、朴素贝叶斯优缺点

基于概率论进行分类,朴素的含义是:各样本特征间独立
优点:可以处理小样本情况,可以处理多分类问题
缺点:对于输入数据比较敏感

8、朴素贝叶斯的三种实现

  • 离散:基于伯努力模型实现,即先验为伯努力分布的朴素贝叶斯
    伯努力模型中,对于一个样本来说,其特征用的是全局的特征,每一个特征的取值是布尔型,即true和false或者1和0.在文本分类中,就是一个特征有没有在一个文档中出现,而不考虑其出现的次数。在文本里面对应的就是词集模型:单词构成的集合,集合自然每个元素都只有一个,也即词集中的每个单词都只有一个。
  • 离散:基于多项式模型实现,即先验为多项式分布的朴素贝叶斯
    该模型常用于文本分类,特征是单词,取值是单词的出现次数,对应的就是词袋模型:如果一个单词在文档中出现不止一次,并统计其出现的次数(频数)。是在自然语言处理和信息检索中的一种简单假设。在这种模型中,文本(段落或文档)被看作是无序的词汇集合,忽略语法甚至是单词的顺序。
  • 连续:基于高斯模型实现,即先验为高斯分布的朴素贝叶斯
    当特征是连续变量的时候,运用多项式模型就会导致很多条件概率为0,此时即使做平滑,所得到的条件概率也难以描述真实情况,存在较大偏差,在处理连续的特征变量,应采用高斯模型。连续变量高斯离散化计算过程:利用样本的特征列计算出均差和方差,然后构造概率密度函数,将每个具体样本值代入到密度函数中,得到概率值,该概率值可以反映各个值的相对可能性。

朴素贝叶斯改进

  • 拉普拉斯平滑:防止由于某一个概率为0,导致分类概率为0的不合理情形
  • 条件概率对数化:防止小数相乘出现的下溢问题

二、朴素贝叶斯功能块实现

def loadDataSet(): # 导入数据
def createVocabList(dataSet): # 建立基于训练集的词汇表
def setOfWords2Vec(vocabList,inputSet): # 将训练集向量化
def trainNB0(trainMatrix,trainCategory): # 基于训练集和类别标签训练算法输出概率集合
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): # 输入测试集和训练后的概率集测试算法
def testingNB(): # 主函数
#!/user/bin/env python
# -*- coding:utf-8 -*-
#@Time  : 2020/3/7 16:28
#@Author: fangyuan
#@File  : 朴素贝叶斯构建词向量.py



def loadDataSet():
    """

    @return:
    """
    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']]
    # 1 代表侮辱性文字,0 代表正常言论
    classVec = [0,1,0,1,0]
    return postingList,classVec

def createVocabList(dataSet):
    """

    @param dataSet:
    @return:创建一个包含所有文档中出现的不重复词的列表,将切分的实验样本词条整理成不重复的词条列表,也就是词汇表
    """
    # set()返回一个不重复词表
    # 首先,创建一个空集合vocabSet,然后,将每篇文档返回的新词集合添加到该集合中
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

def setOfWords2Vec(vocabList,inputSet):
    """

    @param vocabList:参考的词汇表
    @param inputSet:输入文档
    @return:根据vocabList词汇表,将inputSet向量化,输出文档向量,向量的每一个元素为1或0,分别表示词汇表中的单词在输入文档中是否出现
    """
    # 首先创建一个和词汇表等长的向量,并将其元素都设置为0
    returnVec = [0]*len(vocabList)
    # 遍历文档中所有单词,如果出现了词汇表中的单词,则将输出的文档向量中的对应值设为1
    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

if __name__ == '__main__':
    postingList,classVec = loadDataSet()
    print('postingList:\n',postingList)
    myVocabList = createVocabList(postingList)
    print('myVocabList:\n',myVocabList)
    trainMat = []
    for postinDoc in postingList:
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
    print('trainMat:\n',trainMat)
#!/user/bin/env python
# -*- coding:utf-8 -*-
#@Time  : 2020/3/9 11:24
#@Author: fangyuan
#@File  : 朴素贝叶斯分类.py

import numpy as np
from functools import reduce
from math import log

def loadDataSet():
    """

    @return:
    """
    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']]
    # 1 代表侮辱性文字,0 代表正常言论
    classVec = [0,1,0,1,0,1]
    return postingList,classVec

# 创建词汇表-文档向量化的第一步
def createVocabList(dataSet):
    """

    @param dataSet:
    @return:创建一个包含所有文档中出现的不重复词的列表,将切分的实验样本词条整理成不重复的词条列表,也就是词汇表
    """
    # set()返回一个不重复词表
    # 首先,创建一个空集合vocabSet,然后,将每篇文档返回的新词集合添加到该集合中
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

# 词集法-文档向量化第二步
def setOfWords2Vec(vocabList,inputSet):
    """

    @param vocabList:参考的词汇表
    @param inputSet:输入文档
    @return:根据vocabList词汇表,将inputSet向量化,输出文档向量,向量的每一个元素为1或0,分别表示词汇表中的单词在输入文档中是否出现
    """
    # 首先创建一个和词汇表等长的向量,并将其元素都设置为0
    returnVec = [0]*len(vocabList)
    # 遍历文档中所有单词,如果出现了词汇表中的单词,则将输出的文档向量中的对应值设为1
    for word in inputSet:
        # 如果词条存在于词汇表中,则词汇表对应置1
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:print("the word:%s is not in my Vocabulary!" % word)
    # 返回文档向量,其长度为词汇表长度
    return returnVec

"""
条件概率计算;
P(侮辱类|stupid,garbage)=P(stupid|侮辱类)*P(garbage|侮辱类)*P(侮辱类)/P(stupid,garbage)
P(非侮辱类|stupid,garbage)=P(stupid|非侮辱类)*P(garbage|非侮辱类)*P(非侮辱类)/P(stupid,garbage)
由于我们只需要比较大小,且分母相同,固只需要计算分子即可
P(stupid|侮辱类)计算:首先找出所有的侮辱类样本,构造子空间,然后在该子空间中计算stupid单词出现的概率即可
[take,help,stop,posting,food,park,so,worthless,garbage,how,is,him,mr,licks......]
"""
def trainNB0(trainMatrix,trainCategory):
    """

    @param trainMatrix: 经转化后得到的向量矩阵,每一行的长度为单词表长度
    @param trainCategory: 给定的类别,classVec = [0,1,0,1,0,1]
    @return:
    """
    # 计算训练的文档数量,矩阵为6行,即为6个样本
    numTrainDocs = len(trainMatrix)
    # 计算每篇文档的词条数,32个,即有32个特征
    numWords = len(trainMatrix[0])
    # 文档属于侮辱类的概率,P(侮辱类),3/6=0.5
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    # 创建numpy.one数组,词条出现数初始化为1,拉普拉斯平滑
    # p0Num存放非侮辱类概率即非侮辱类中take,help,stop.....的概率,初始化长度为32,且值都为1,如P(garbage|非侮辱类)
    # p1Num存放侮辱类概率如P(garbage|侮辱类)
    p0Num = np.ones(numWords)
    p1Num = np.ones(numWords)
    # p0Num = np.zeros(numWords)
    # p1Num = np.zeros(numWords)
    # 分母初始化为2,拉普拉斯平滑
    p0Denom = 2.0
    p1Denom = 2.0
    # p0Denom = 0.0;
    # p1Denom = 0.0
    for i in range(numTrainDocs):
        # 将文档中数据归类,为1则放在侮辱类数组中,为0则放在非侮辱类数组中
        if trainCategory[i] == 1:
            # p1Num是数组
            # 向量化算法都是32个特征概率一起算的,不用for循环
            # 将标签为1侮辱类的样本数据全部加到一起,即将第2,4,6行数据加到一起,变成只包括1行数据,32个特征
            # 将2,4,6列单词个数加起来(包括重复单词)
            # [1,2,1,1,1,1,2,2,4,2,2,3,2,1,1,1,1,2,2,2,2,1,2,1,1,1,2,1,3,1,1,1]
            p1Num += trainMatrix[i]
            # p1Denom是数:第2,4,6行元素个数21
            p1Denom += sum(trainMatrix[i])
        else:
            #[2,1,4,2,2,2,1,2,1,3,1,1,1,2,2,2,2,1,1,1,2,2,1,2,2,2,1,2,2,2,2,2]
            p0Num += trainMatrix[i]
            # 第1,3,5行元素个数24个
            p0Denom += sum(trainMatrix[i])
    # 取对数,防止下溢出
    p1Vect = np.log(p1Num/p1Denom)
    p0Vect = np.log(p0Num/p0Denom)
    # p1Vect = p1Num/p1Denom
    # p0Vect = p0Num/p0Denom
    # 返回属于侮辱类的条件概率数组,属于非侮辱类的条件概率数组,文档属于侮辱类的概率
    return p0Vect,p1Vect,pAbusive


def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    # P(stupid|侮辱类)*P(garbage|侮辱类)*P(侮辱类)
    # sum(vec2Classify * p1Vec)表示P(stupid|侮辱类)*P(garbage|侮辱类),log(pClass1)表示P(侮辱类)
    # 其中,p1Vec本身是由log表示,所以sum和+表示了概率计算式的*
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

def testingNB():
    listOPosts,listClasses = loadDataSet()
    # 创建词汇表,文档向量化第一步
    myVocabList = createVocabList(listOPosts)
    trainMat = []
    # 向量化-文档向量化第二步
    for postinDoc in listOPosts:
        # 将一个一个样本,利用词汇表转换成词向量
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
    # 训练-计算条件概率 0-非侮辱类条件概率集 1-侮辱类条件概率集
    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))

if __name__ == '__main__':
    testingNB()

引用链接
B站up主

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值