朴素贝叶斯 Naive Bayes

2023-11-15

Naive Bayes


特点


朴素贝叶斯是典型的生成学习方法

朴素贝叶斯的基本假设是条件独立性(强假设)
若条件之间存在概率依存关系,模型变为贝叶斯网络

基于上一条的假设,朴素贝叶斯方法高效,但分类性能受损

将输入的 x 分类到后验概率最大的类 y



原理

对于给定的输入 x
通过学习到的模型计算后验概率分布 P(Y = ck | X = x)
将后验概率最大的类作为x类的输出



朴素贝叶斯分类器 - 数学推导


先验概率分布

 P(Y = ck)   k = 1, 2, 3 … K

条件概率分布

 P(X = x | Y = ck) = P(X1 = x1, X2 = x2, … , Xn = xn | Y = ck)   k = 1, 2, 3 … K在这里插入图片描述



后验概率最大化


朴素贝叶斯法将实例分类到后验概率最大化的类中

后验概率最大的,即期望风险最小化

在这里插入图片描述



贝叶斯参数估计


若使用极大似然估计法
对于某些数量为 0 的训练集数据类
极大似然估计法的分母是 0
不合理

贝叶斯参数估计在随机变量各个取值的频数上赋予正数ƛ
ƛ = 0 时就是极大似然估计
ƛ = 1 时,称为拉普拉斯平滑 Laplacian smoothing
在这里插入图片描述



步骤总结

在这里插入图片描述



Code

'''
----------------
朴素贝叶斯
----------------
数据集Mnist
训练集:60000
测试集:10000
类别:0/1/2/.../9手写体
每个实例为28x28的像素点,已展开为向量
----------------
运行时间:60.13s
准确率:0.84

train time 23s
test time 26s
----------------
'''

import numpy as np
import time

def loadData(fileName):
    '''
    加载数据
    :param filename: 文件路径
    :return: 数据集和标签集
    '''

    dataArr = []
    labelArr = []

    fr = open(fileName)

    for line in fr.readlines():
        curLine = line.strip().split(',')
        dataArr.append([int(int(num) > 128) for num in curLine[1:]])

        labelArr.append(int(curLine[0]))

    return dataArr, labelArr


def NaiveBayes(Py, Px_y, x):
    '''
    朴素贝叶斯进行概率估计
    :param Py: 先验概率分布
    :param Px_y: 条件概率分布
    :param x: 要估计的样本
    :return: 所有label的估计概率
    '''

    # 特征数目
    featureNum = 784
    # 类别数目
    classNum = 10
    # 建立存放所有标记估计概率的数组
    P = [0] * classNum

    # 对于每一个类别,单独估计其概率
    for i in range(classNum):

        # 对于 Py 和 Px_y 进行了log 处理,连乘变成了累加
        # 使用 sum 计算累加值
        sum = 0

        # 获取每一个条件概率值,进行累加
        for j in range(featureNum):
            # 第 i 个标签,第 j 个特征,x 样本的第 j 个特征的值(1/0)
            sum += Px_y[i][j][x[j]]

        # 和先验概率相加(log)
        P[i] = sum + Py[i]

    # 找最大值的索引
    return P.index(max(P))


def model_test(Py, Px_y, testDataArr, testLabelArr):
    '''
    测试测试集
    :param Py: 先验概率分布
    :param Px_y: 条件概率分布
    :param testDataArr: 测试数据集
    :param testLabelArr: 测试标签集
    :return: 准确率
    '''

    # 错误值计数
    errorCnt = 0

    # 循环遍历每一个样本
    for i in range(len(testDataArr)):
        # 获取预测值
        predict = NaiveBayes(Py, Px_y, testDataArr[i])

        # 与答案进行比较
        if predict != testLabelArr[i]:
            errorCnt += 1

    return 1 - (errorCnt / len(testDataArr))


def getAllProbability(trainDataArr, trainLabelArr):
    '''
    计算先验概率分布和条件概率分布
    :param trainDataArr: 训练集数据
    :param trainLabelArr: 训练集标签
    :return: 先验概率分布和条件概率分布
    '''

    # 数据集中手写图片像素为 28 * 28,转换为向量是 784
    featureNum = 784
    # 类别数目
    classNum = 10
    # 先验概率
    Py = np.zeros((classNum, 1))

    # 对每个类别进行一次循环,计算他们的先验概率分布
    for i in range(classNum):
        # 将标签转化成矩阵的形式
        # 里面的每一位与 i 比较,若相等,该位为 True,否则为 False
        # 计算共有多少个True,并加一(贝叶斯估计,lambda取1
        TrueNum = (np.sum(np.mat(trainLabelArr) == i)) + 1

        # 先验概率分布(Sj=10)
        Py[i] = TrueNum / (len(trainLabelArr) + 10)

    # 转换成对数形式
    # 先验概率分布可以转也可以不转
    # 条件概率分布由于乘项很多,结果可能会下溢出,故转成 log 形式
    Py = np.log(Py)

    # 计算条件概率分布
    Px_y = np.zeros((classNum, featureNum, 2))
    # 对标记进行遍历
    for i in range(len(trainLabelArr)):
        label = trainLabelArr[i]
        x = trainDataArr[i]
        for j in range(featureNum):
            # 在矩阵中对应位置加 1
            Px_y[label][j][x[j]] += 1


    # 循环每一个标记
    for label in range(classNum):
        # 循环每一个标记对应的每一个特征
        for j in range(featureNum):
            # 标记为label,第j个特征为0的个数
            Px_y0 = Px_y[label][j][0]
            # 标记为label,第j个特征为1的个数
            Px_y1 = Px_y[label][j][1]

            #  贝叶斯估计
            Px_y[label][j][0] = np.log((Px_y0 + 1) / (Px_y0 + Px_y1 + 2))
            Px_y[label][j][1] = np.log((Px_y1 + 1) / (Px_y0 + Px_y1 + 2))

    return Py, Px_y

if __name__ == "__main__":

    start = time.time()

    print("Start to read train set")
    trainDataArr, trainLabelArr = loadData("/Users/bigstone/Downloads/code/Statistical/Mnist/Mnist_train.csv")

    print("Start to read test set")
    testDataArr, testLabelArr = loadData("/Users/bigstone/Downloads/code/Statistical/Mnist/Mnist_test.csv")

    end1 = time.time()
    print("Time spend in reading data: ", end1 - start)
    start2 = time.time()

    # 学习先验概率分布和条件概率分布
    print("Start to train")
    Py, Px_y = getAllProbability(trainDataArr, trainLabelArr)

    end2 = time.time()
    print("Time spend in training model: ", end2 - start2)
    start3 = time.time()

    # 进行测试
    print("Start to test")
    accuracy = model_test(Py, Px_y, testDataArr, testLabelArr)

    end3 = time.time()
    print("Time spend in testing model: ", end3 - start3)

    # 输出准确率
    print("The accuracy is: ", accuracy)

    # 运行时间
    end = time.time()
    print("time spend: ", end - start)


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

朴素贝叶斯 Naive Bayes 的相关文章

随机推荐

  • 结构体对函数指针的高级封装应用

    分层设计考虑 作用 降低对底层应用程序的高耦合度 示例 include mac h typedef struct phy t char channel char snd fail count char name char open flag
  • 软件测试用例覆盖率怎么算,如何计算增量测试覆盖率

    为了保证代码质量 一般会要求提交的源码要有测试用例覆盖 并对测试覆盖率有一定的要求 在实践中不仅会考核存量代码覆盖率 总体覆盖率 还会考核增量代码的覆盖率 或者说增量覆盖率更有实际意义 测试用例要随源码一并提交 实时保证源码的质量 而不是代
  • 进程和线程的区别,以及应用场景

    什么是线程 Linux下线程用进程PCB模拟描述 也叫轻量级进程 线程是进程内部的一个执行流 也就是线程在进程的地址空间内运行 一个进程内的所有线程共享进程资源 线程是CPU调度的基本单位 CPU调度是按照PCB进行调度的 创建 销毁一个线
  • Mule入门——DB、Rest、Soap接口开发

    一 DB查询接口开发 这里我用的mysql数据库 首先我们先查询下我们的数据库这里有很多数据 然后我们用AnypointStudio进行我们的接口开发 首先我们先新建一个Mule工程 File gt New gt Mule project
  • 计算机网络---传输层

    两个端的会话层之间提供建立 维护和取消传输连接的功能 这一层 数据传送的协议单元成为报文 网络层只是根据网络地址将源节点发出的数据包送到目的终点 而传输层负责将数据可靠的传送到相应的端口 传输层负责将上层数据分段提供端到端 可靠不可靠的传输
  • vue3-admin-template页面

    vue3 admin template 本人学习视频网址为 视频地址 源码 github 网页采用技术框架 本管理模板采用vue3开发 使用vue router来作为路由跳转 将登录成功后产生的菜单 token放入到vuex中存储 通过ax
  • 一般Python开发面试中可能会问到的大部分问题

    python语法以及其他基础部分 可变与不可变类型 浅拷贝与深拷贝的实现方式 区别 deepcopy如果你来设计 如何实现 new 与 init 的区别 你知道几种设计模式 编码和解码你了解过么 列表推导list comprehension
  • Linux嵌入式学习——c语言选择结构设计

    Linux嵌入式学习 c语言选择结构设计 一 if语句 1 1if语句的一般格式 1 2if语句常用的3种形式 1 3if语句的嵌套 二 关系运算符和关系表达式 2 1关系运算符及其优先次序 2 2关系表达式 三 逻辑运算符和逻辑表达式 3
  • @ControllerAdvice注解使用及原理探究

    最近在新项目的开发过程中 遇到了个问题 需要将一些异常的业务流程返回给前端 需要提供给前端不同的响应码 前端再在次基础上做提示语言的国际化适配 这些异常流程涉及业务层和控制层的各个地方 如果每个地方都写一些重复代码显得很冗余 然后查询解决方
  • PowerBI入门学习笔记

    下载安装 Win10系统 在微软商店里直接下载PowerBI desktop 打开即可 界面如下 接下来导入后面要用到的数据 我目前用的都是Excel文件 获取数据 选中后选择要导入的若干个工作表 点击 加载数据 就进入到power que
  • vue+element实现双向描点 反向联动

    前端项目里经常会有锚点得操作 以及反向联动的效果 就是一个菜单 点击会定位到一个块上 滚动的当前块的时候 菜单会出现定位的效果 差不多就是这种动起来的效果 由于不太懂之前的逻辑 今天又从重新看了下 上代码 html 滚动的区域
  • 关于Python中pip install 各种包下载不下来的问题解决办法

    你们有可能报安装不成功或者下面这个问题 已经安装了但并非在你的Python安装路径下 C Users xxx gt pip install ddt Requirement already satisfied ddt in e anacond
  • redis 实现乐观锁

    redis是单线程程序但是支持多进程同时访问同一个redis服务 这个时候就需要锁机制来处理一些并发问题 redis提供了watch指令来实现乐观锁 watch和事务配合使用 往往写在multi之前 用来监视一个key 比如watch mo
  • 实战wxPython:047 - Book控件(第一部分)

    在wxPython中 book控件允许用户在各种面板之间切换 最常见的例子是带有选项卡界面的浏览器和系统选项对话框 本文将向您介绍这些控件的创建和基本配置 wxPython目前内置了多个这样的控件 除文章 wxPython 高级控件之选项卡
  • 看完这篇 教你玩转渗透测试靶机Vulnhub——Grotesque:3.0.1

    Vulnhub靶机Grotesque 3 0 1渗透测试详解 Vulnhub靶机介绍 Vulnhub靶机下载 Vulnhub靶机安装 信息收集 漏洞发现 LFI漏洞利用 本地文件包含漏洞 SSH登入 提权 获取FLAG Vulnhub靶机渗
  • pyqt 万能简易模板(四)

    本文将介绍一些pyqt5基本使用技巧 不借助Qtdesigner 而是全部用代码编写 将实现页面布局 窗口自适应 字体自适应等功能 一般的简易工程均可使用 简单高效 对于pyqt5的一些基本技巧 本文内容基本够用 可以快速实现自己想要的界面
  • Java中的如何检测字符串是否相等

    文章目录 0 写在前面 1 介绍 2 举例 3 写在后面 0 写在前面 实际业务中有时候得检测字符串是否相等的场景 例如在数据库中提取uuid 检测两个uuid是否相等就需要用到这个地方 1 介绍 可以使用equals方法检测两个字符串是否
  • 数据预处理、特征工程和特征学习

    神经网络的数据预处理 数据预处理的目的是使原始数据更适于用神经网络处理 包括向量化 标准化 处理缺失值和特征提取 1 向量化 神经网络的所有输入和目标都必须是浮点数张量 特定情况下为整数张量 无论处理什么数据 都必须先将其转换为张量 这一步
  • Spring getBean方法源码解析

    User user User beanFactory getBean user 注 User为一普通bean 查看方法 AbstractBeanFactory getBean public Object getBean String nam
  • 朴素贝叶斯 Naive Bayes

    Naive Bayes 特点 朴素贝叶斯是典型的生成学习方法 朴素贝叶斯的基本假设是条件独立性 强假设 若条件之间存在概率依存关系 模型变为贝叶斯网络 基于上一条的假设 朴素贝叶斯方法高效 但分类性能受损 将输入的 x 分类到后验概率最大的