sklearn机器学习:多项式朴素贝叶斯MultinomialNB

2023-11-19

多项式朴素贝叶斯MultinomialNB

多项式贝叶斯可能是除了高斯之外,最为人所知的贝叶斯算法了。它也是基于原始的贝叶斯理论,但假设概率分布是服从一个简单多项式分布。多项式分布来源于统计学中的多项式实验,这种实验可以具体解释为:实验包括n次重复试验,每项试验都有不同的可能结果。在任何给定的试验中,特定结果发生的概率是不变的。
举个例子,比如,一个特征矩阵表示投掷硬币的结果,则得到正面的概率为P(X=正面|Y) = 0.5,反面的概率为P(X=反面|Y) = 0.5,只有这两种可能,并且两种结果互不干涉,两个随机事件的概率加和为1,这就是二项分布。这种情况下,适合于多项式朴素贝叶斯的特征矩阵应该长这样:
在这里插入图片描述
假设另一个特征X’表示投掷骰子的结果,则 i 就可以在[1,2,3,4,5,6]中取值,六种结果互不干涉,且只要样本量足够大,概率都为1/6,这就是一个多项分布。多项分布的特征矩阵应该长这样:
在这里插入图片描述
可以看出:

  1. 多项式分布擅长的是分类型变量,在其原理假设中,P(xi|Y)的概率是离散的,并且不同xi下的P(xi|Y)相互独立,互不不影响。虽然sklearn中的多项式分布也可以处理连续型变量,但现实中,
    如果我们真的想要处理连续型变量,应当使用高斯朴素贝叶斯。
  2. 多项式实验中的实验结果都很具体,它所涉及的特征往往是次数,频率,计数,出现与否这样的概念,这些概念都是离散的正整数,因此,sklearn中的多项式朴素贝叶斯不接受负值的输入

由于这样的特性,多项式朴素贝叶斯的特征矩阵经常是稀疏矩阵(不一定总是稀疏矩阵),并且它经常被用于文本分类。我们可以使用著名的TF-IDF向量技术,也可以使用常见并且简单的单词计数向量手段与贝叶斯配合使用。这两种手段都属于常见的文本特征提取的方法,可以很简单地通过sklearn来实现。
从数学的角度来看,在一种标签类别Y=c下,有一组分别对应特征的参数向量 θ c = ( θ c 1 , θ c 2 , . . . , θ c n , ) \theta_c=(\theta_{c1},\theta_{c2},...,\theta_{cn},) θc=(θc1,θc2,...,θcn,),其中n表示特征的总数。一个 θ c i \theta_{ci} θci表示这个标签类别下的第i个特征所对应的参数。这个参数被我们定义为:

θ c i = 特 征 X i 在 Y = 特 征 在 c 这 个 分 类 下 的 所 有 样 本 的 取 值 总 和 所 有 特 征 在 Y = 特 征 在 c 这 个 分 类 下 的 所 有 样 本 的 取 值 总 和 \theta_{ci}=\large\frac{特征{X_i}在Y=特征在c这个分类下的所有样本的取值总和}{所有特征在Y=特征在c这个分类下的所有样本的取值总和} θci=Y=cXiY=c

记作P(Xi|Y=c),表示当Y=c这个条件固定的时候,一组样本Xi在这个特征上的取值被取到的概率。
对于一个在标签类别下,结构为(m, n)的特征矩阵来说,我们有:
X y = [ x 11 x 12 … x 1 n x 21 x 22 … x 2 n ⋮ ⋮ ⋱ x m 1 x m 2 … x m n ] X_y =\left[ \begin{array}{c} x_{11} & x_{12} & \ldots & x_{1n} \\ x_{21} & x_{22} & \ldots & x_{2n} \\ \vdots & \vdots & \ddots\\ x_{m1} & x_{m2} & \ldots & x_{mn} \\ \end{array} \right] Xy=x11x21xm1x12x22xm2x1nx2nxmn
其中每个xji都是特征Xi发生的次数。基于这些,通过平滑后的最大似然估计来求解参数 θ y \theta_y θy:
在这里插入图片描述
对于每个特征, ∑ y j = c x j i \mathbf{\sum_{y_j=c}x_{ji}} yj=cxji是特征Xi下所有标签为c的样本的特征取值之和,其实就是特征矩阵中每一列的和。 ∑ i = 1 n ∑ y j = c x j i \mathbf{\sum_{i=1}^n\sum_{y_j=c}x_{ji}} i=1nyj=cxji是所有标签类别为c的样本上,所有特征的取值之和,其实就是特征矩阵Xy中所有元素的和。 λ \lambda λ被称为平滑系数 λ \lambda λ>0来防止训练数据中出现过的一些词汇没有出现在测试集中导致的0概率,以避免让参数 θ \theta θ为0的情况。如果 λ \lambda λ=1,则这个平滑叫做拉普拉斯平滑 λ \lambda λ<1,叫做利德斯通平滑。两种平滑都属于自然语言处理中比较常用的用来平滑分类数据的统计手段。
之前提到,系数 θ c i \theta_{ci} θci其实就是P(Xi|Y=c),这是对于每⼀一个特征而言,在Y=c取值下的概率。
在这里插入图片描述

P(Y=1|X)+P(Y=0|X)=1
但在最大后验估计中需要的是P(xi|Y=c),这是对于一个样本来说取到Y=c时的概率,那么,如何将一个特征上的概率变成一个样本在一个特征取值下的概率呢?其实很简单:
P(xi|Y=c)= θ c i x i \theta_{ci}x_i θcixi
对于像掷骰子或者抛硬币这样的“是否发生”类型的实验而言,特征取值xi往往只有0和1两种选择,如果为0,则这个样本在这个特征下的概率取值就为0,如果为1,则这个样本在这个特征取值下的概率就为 θ c i x i \theta_{ci}x_i θcixi
在sklearn中,用来执行多项式朴素贝叶斯的类MultinomialNB包含如下的参数和属性:
class sklearn.naive_bayes.MultinomialNB (alpha=1.0,fit_prior=True, class_prior=None)
其中:
alpha : 浮点数, 可不填 (默认为1.0)
拉普拉斯或利德斯通平滑的参数 λ \lambda λ,如果设置为0则表示完全没有平滑选项。但是需要注意的是,平滑相当于人为给概率加上一些噪音,因此 λ \lambda λ设置得越大,多项式朴素贝叶斯的精确性会越低(虽然影响不是非常大)。
fit_prior : 布尔值, 可不填 (默认为True)
是否学习先验概率P(Y=c)。如果设置为false,则所有的样本类别输出都有相同的类别先验概率。即认为每个标签类出现的概率是 1 n _ c l a s s e s \frac1{n\_classes} n_classes1
class_prior:形似数组的结构,结构为(n_classes, ),可不填(默认为None)
类的先验概率P(Y=c)。如果没有给出具体的先验概率则自动根据数据来进行计算。
布尔参数fit_prior表示是否要考虑先验概率,如果是False,则所有的样本类别输出都有相同的类别先验概率。否则,可以用第三个参数class_prior输入先验概率,或者不输入第三个参数class_prior让
MultinomialNB自己从训练集样本来计算先验概率,此时的先验概率为P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出为第k个类别的训练集样本数。总结如下:
在这里插入图片描述
通常,在实例化多项式朴素贝叶斯的时候,会让所有的参数保持默认。先来简单建一个多项式朴素贝叶斯的例子试试看:

#导⼊入需要的模块和库
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_blobs
from sklearn.metrics import brier_score_loss
#建立数据集
class_1 = 500 
class_2 = 500 #两个类别分别设定500个样本
centers = [[0.0, 0.0], [2.0, 2.0]] #设定两个类别的中心
clusters_std = [0.5, 0.5] #设定两个类别的方差
X, y = make_blobs(n_samples=[class_1, class_2],
                  centers=centers,
                  cluster_std=clusters_std,
                  random_state=0, shuffle=False)

Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y
                                                ,test_size=0.3
                                                ,random_state=420)
np.unique(Ytrain)
array([0, 1])
(Ytrain==1).sum()/Ytrain.shape[0]
0.49857142857142855
#归一化,确保输入多项式朴素贝叶斯的特征矩阵不带有负数
mms = MinMaxScaler().fit(Xtrain)
Xtrain_ = mms.transform(Xtrain)
Xtest_ = mms.transform(Xtest)
#建立一个多项式朴素贝叶斯分类器
mnb = MultinomialNB().fit(Xtrain_, Ytrain)
#重要属性:调⽤用根据数据获取的,每个标签类的对数先验概率log(P(Y))
#由于概率永远是在[0,1]之间,因此对数先验概率返回的永远是负值
mnb.class_log_prior_
array([-0.69029411, -0.69600841])
#可以使用np.exp来查看真正的概率值
np.exp(mnb.class_log_prior_)
array([0.50142857, 0.49857143])
#重要属性:返回一个固定标签类别下的每个特征的对数概率log(P(Xi|y))
mnb.feature_log_prob_
array([[-0.76164788, -0.62903951],
       [-0.72500918, -0.6622691 ]])
'''重要属性:在fit时每个标签类别下包含的样本数。
当fit接口中的sample_weight被设置时,
该接口返回的值也会受到加权的影响'''
mnb.class_count_
array([351., 349.])

分类器的效果如何呢?用一些传统的接口试试:

mnb.predict(Xtest_)
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0,
       1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
       ...
       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
mnb.predict_proba(Xtest_)
array([[0.49847128, 0.50152872],
       [0.50065987, 0.49934013],
       [0.50122363, 0.49877637],
       ...
       [0.50156107, 0.49843893],
       [0.50078711, 0.49921289],
       [0.50197128, 0.49802872]])
mnb.score(Xtest_,Ytest)
0.5433333333333333

效果不太理想,思考一下多项式贝叶斯的性质,我们能够做点什么呢?来试试看把Xtiain转换成分类型数据吧:注意我们的Xtrain没有经过归一化,因为做哑变量之后自然所有的数据就不会有负数了

'''KBinsDiscretizer()是将连续型变量划分为分类变量的类,
能够将连续型变量排序后按顺序分箱后编码'''
from sklearn.preprocessing import KBinsDiscretizer
kbs = KBinsDiscretizer(n_bins=10, encode='onehot').fit(Xtrain)
Xtrain_ = kbs.transform(Xtrain)
Xtest_ = kbs.transform(Xtest)
mnb = MultinomialNB().fit(Xtrain_, Ytrain)
mnb.score(Xtest_,Ytest)
0.9966666666666667

可以看出,多项式朴素贝叶斯的基本操作和代码都非常简单。同样的数据,如果采用哑变量方式的分箱处理,多项式贝叶斯的效果会突飞猛进。

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

sklearn机器学习:多项式朴素贝叶斯MultinomialNB 的相关文章

随机推荐

  • 创业的真谛是顺势而为,借船过海!

    追寻成功的路上 顺势最易 借势稍难 造势境界最高 创业者 或者创业团队 积极争取优惠政策 打造自身适宜环境 努力营造外在氛围 最大化有效使用身边各种资源 懂得聚合放大 顺势是为了 为 顺势而为 最终是为了顺势大为 一 顺势而为 无论商场战场
  • Python opencv学习-13 直方图反向投影(用于图像分割)

    代码和图片大量参考https blog csdn net tengfei461807914 article details 77075567 自己跑了下验证了下 个人理解 直方图反向投影用来做图像分割 或者说知道了一个目标的图片的一部分 去
  • 利用Redis bitmap签到功能

    1 简介 BitMap 存储的是连续的二进制数字 0 和 1 通过 bitmap 只需要一个 bit 位来表示某个元素对应的值或者状态 key 就是对应元素本身 我们知道 8 个 bit 可以组成一个 Byte 所以bitmap 本身会极大
  • 为什么程序员都喜欢安静?

    大家回顾一下上学期间 你在上晚自习想完成今天老师布置的作业 但是你的班级却非常的吵闹 跟置身在菜市场一样 你能专心完成作业吗 不受周围吵闹环境的影响吗 相信大部分的人都难以静下心来认真完成作业 有时候好不容易想到一个思路 结果旁边的人拍你一
  • Windows系统常用命令

    Windows常用命令 1 echo 用法 输出一个字符到终端 当加上 gt 后就可输出到文本文件 例如 echo 1 在终端显示一个1 echo 20 gt gt 1 txt 在当前目录下的1 txt文件后面追加一行数据值20 如果没有1
  • AT24C02芯片使用介绍

    AT24C02简介 AT24C02是一个2K位串行CMOS E2PROM 内部含有256个8位字节 有一个16字节页写缓冲器 该器件通过IIC总线接口进行操作 有专门的写保护功能 应用于AT24C02制造过程的先进CMOS技术实质上减少了器
  • 咬牙切齿的按钮

    先看效果 再看代码 查看更多 import url https fonts googleapis com css2 family Roboto wght 500 display swap root sz 9vmin on 4CAF50 of
  • ftp服务器性能对比,ftp服务器软件 性能对比

    ftp服务器软件 性能对比 内容精选 换一换 Java性能分析是鲲鹏性能分析工具的子工具 本章节以openEuler离线环境安装工具 登录 创建Guardian和分析任务 卸载工具为例 指导您快速上手Java性能优分析 由于root用户拥有
  • 机器学习毕设题目有哪些_毕设开源了,126个star,39个fork

    毕设题目 我是去年毕业的 软件工程专业 学校给的毕设题目是实现一个电影院订票系统 如图 嗯 题目一看很简单 其实就是实现一个web版的影票在线订票系统罢了 因此当天接到毕设后的我就大刀阔斧的准备开干了 技术方案选择 先说个大前提 我们学校评
  • c++动态数组(二)之allocator类

    new在灵活性上面一些局限性 以方便它将内存分配和对象构造组合在了一起 delete将内存释放和对象析构组合在一起 当分配一大块内存时 我们通常计划在这块内存上面按需构造对象 在这种情况下 我们希望内存分配和对象构造分离 这意味着我们可以分
  • Python学习之cookies及session用法

    当想利用Python在网页上发表评论的时候 需要一些账号密码登录的信息 这个时候用requests get 请求的话 账号密码全部会显示在网址上 这显然不科学 这个时候需要用post请求 可以这么理解 get是明文显示 post是非明文显示
  • cad等比例缩放快捷键_终于领会CAD缩放(放大与缩小)快捷键

    终于领会CAD缩放 放大与缩小 快捷键 日期 2019 10 09 19 15 01 浏览 9 核心提示 CAD缩放 放大与缩小 快捷键 这个非常简单 鼠标的中键也就是滚轮 双击两下中键图形会适合平面显示全部滚轮前后滚动是缩放 不需要什么快
  • error: “自定义函数XXX” must take exactly one argument

    主要问题在于 类里面的重载的二元运算符时 只需要一个参数 另一个参数由this指针传入 这里如果需要传入两个参数 需要放到类外定义 声明友元 访问私有数据和函数 如下 class myTask public myTask int a int
  • windbg remote stub方式远程调试

    windbg远程调试时 有两种方式 一种为remote session 另一种为remote stub 具体详情请google 我下面说说我在使用remote stub方式时遇到的一些困惑 按照教程 我在target machine启动了s
  • .NET C# 世界日期格式转换为yyyyMMdd

    本文分享了一个按照不同国家的语言生成相应时间格式的案例 有需要做国外网站或者多国语言网站的朋友可以参考一下 本文在引用 C DateTime ToString根据不同语言生成相应的时间格式 基础上做了一个Demo测试 旨在给更多有需要的人能
  • C++设计模式-State状态模式

    State状态模式作用 当一个对象的内在状态改变时允许改变其行为 这个对象看起来像是改变了其类 UML图如下 State类 抽象状态类 定义一个接口以封装与Context的一个特定状态相关的行为 ConcreteState类 具体状态 每一
  • Nodejs-Express框架

    1 认识Web框架 目前在Node中比较流行的Web服务器框架是express koa express早于koa出现 并且在Node社区中迅速流行起来 可以基于express快速 方便的开发自己的Web服务器 并且可以通过一些实用工具和中间
  • HttpResponse响应、render 响应、redirect 响应、JsonResponse 响应

    目录 HttpResponse介绍 常用属性 content 返回的内容 编辑 content type 返回给数据的MIME类型 status code 返回的HTTP响应状态码 render 返回网页 给网页传值 1 指名道姓方式传值
  • Mysql推荐书籍

    一 初级 1 MySQL必知必会 这本书英文原版名是很标题党的 Teach Yourself SQL in 10 Minutes 却是最好的数据库入门书 在Amazon上长期排在数据库销售榜首 建议想快速了解数据库原理和MySQL的新手阅读
  • sklearn机器学习:多项式朴素贝叶斯MultinomialNB

    多项式朴素贝叶斯MultinomialNB 多项式贝叶斯可能是除了高斯之外 最为人所知的贝叶斯算法了 它也是基于原始的贝叶斯 论 但假设概率分布是服从一个简单多项式分布 多项式分布来源于统计学中的多项式实验 这种实验可以具体解释为 实验包括