多项式朴素贝叶斯MultinomialNB

 

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)#先归一化,保证输入多项式朴素贝叶斯的特征矩阵中不带有负数,多项式朴素贝叶斯拒绝负值输入
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])

y的两种取值的先验概率,基本上一致表示不存在样本不均衡问题

print((Ytrain == 1).sum()/Ytrain.shape[0])
print(mnb.class_log_prior_ .shape)
#可以使用np.exp来查看真正的概率值
print(np.exp(mnb.class_log_prior_))
#重要属性:返回一个固定标签类别下的每个特征的对数概率log(P(Xi|y))
print(mnb.feature_log_prob_)
print(mnb.feature_log_prob_.shape)

结果:

0.49857142857142855
(2,)
[0.50142857 0.49857143]
[[-0.76164788 -0.62903951][-0.72500918 -0.6622691 ]]
(2, 2)
#一些传统的接口
mnb.predict(Xtest_)

结果:

mnb.predict_proba(Xtest_)

结果:

mnb.score(Xtest_,Ytest)
#0.5433333333333333
brier_score_loss(Ytest,mnb.predict_proba(Xtest_)[:,1],pos_label=1)
#0.24977828412546035

效果不太理想,思考一下多项式贝叶斯的性质,我们能够做点什么呢?

多项式贝叶斯处理的是分类型数据而不是连续型数据

#来试试看把Xtiain转换成分类型数据吧
#注意我们的Xtrain没有经过归一化,因为做哑变量之后自然所有的数据就不会又负数了
from sklearn.preprocessing import KBinsDiscretizer  #对连续型变量进行分箱
kbs = KBinsDiscretizer(n_bins=10, encode='onehot').fit(Xtrain)
Xtrain_ = kbs.transform(Xtrain)
Xtest_ = kbs.transform(Xtest)Xtrain_.shape  #把原先的两个特征分了10个箱锁分出来的哑变量
#(700, 20)mnb = MultinomialNB().fit(Xtrain_, Ytrain)
mnb.score(Xtest_,Ytest)
#0.9966666666666667brier_score_loss(Ytest,mnb.predict_proba(Xtest_)[:,1],pos_label=1)
#0.0014593932778211862

可以看出,多项式朴素贝叶斯的基本操作和代码都非常简单。同样的数据,如果采用哑变量方式的分箱处理,多项式贝叶斯的效果会突飞猛进。作为在文本分类中大放异彩的算法,我们将会在案例中来详细讲解多项式贝叶斯的使用, 并为大家介绍文本分类的更多细节。

伯努利朴素贝叶斯BernoulliNB

多项式朴素贝叶斯可同时处理二项分布(抛硬币)和多项分布(掷骰子),其中二项分布又叫做伯努利分布,它是一 种现实中常见,并且拥有很多优越数学性质的分布。因此,既然有着多项式朴素贝叶斯,我们自然也就又专门用来处理二项分布的朴素贝叶斯:伯努利朴素贝叶斯。

伯努利贝叶斯类BernoulliN假设数据服从多元伯努利分布,并在此基础上应用朴素贝叶斯的训练和分类过程。多元伯努利分布简单来说,就是数据集中可以存在多个特征,但每个特征都是二分类的,可以以布尔变量表示,也可以表示 为{0,1}或者{-1,1}等任意二分类组合。因此,这个类要求将样本转换为二分类特征向量,如果数据本身不是二分类的,那可以使用类中专门用来二值化的参数binarize来改变数据。

多项式朴素贝叶斯——这个特征对这个样本而言发生了几次(单词计数)

伯努利朴素贝叶斯——这个特征发生了吗?发生还是没发生(单词出现)

伯努利朴素贝叶斯与多项式朴素贝叶斯非常相似,都常用于处理文本分类数据。但由于伯努利朴素贝叶斯是处理二项分布,所以它更加在意的是“存在与否”,而不是“出现多少次”这样的次数或频率,这是伯努利贝叶斯与多项式贝叶斯的根本性不同。在文本分类的情况下,伯努利朴素贝叶斯可以使用单词出现向量(而不是单词计数向量)来训练分类器。文档较短的数据集上,伯努利朴素贝叶斯的效果会更加好。如果时间允许,建议两种模型都试试看。

来看看伯努利朴素贝叶斯类的参数:

from sklearn.naive_bayes import BernoulliNB
#普通来说我们应该使用二值化的类sklearn.preprocessing.Binarizer来将特征一个个二值化
#然而这样效率过低,因此我们选择归一化之后直接设置一个阈值
#归一化,消除负数
mms = MinMaxScaler().fit(Xtrain)
Xtrain_ = mms.transform(Xtrain)
Xtest_ = mms.transform(Xtest)#不设置二值化
bnl_ = BernoulliNB().fit(Xtrain_, Ytrain)
bnl_.score(Xtest_,Ytest)
brier_score_loss(Ytest,bnl_.predict_proba(Xtest_)[:,1],pos_label=1)
#0.49666666666666665
#0.25000009482193225#设置二值化阈值为0.5
bnl = BernoulliNB(binarize=0.5).fit(Xtrain_, Ytrain)
bnl.score(Xtest_,Ytest)
brier_score_loss(Ytest,bnl.predict_proba(Xtest_)[:,1],pos_label=1)
#0.9833333333333333
#0.010405875827339534

和多项式贝叶斯一样,伯努利贝叶斯的结果也受到数据结构非常大的影响。因此,根据数据的模样选择贝叶斯,是贝叶斯模型选择中十分重要的一点。

探索贝叶斯:贝叶斯的样本不均衡问题

from sklearn.naive_bayes import MultinomialNB, GaussianNB, BernoulliNB
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_blobs
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.metrics import brier_score_loss as BS,recall_score,roc_auc_score as AUC
class_1 = 50000 #多数类为50000个样本
class_2 = 500 #少数类为500个样本
centers = [[0.0, 0.0], [5.0, 5.0]] #设定两个类别的中心
clusters_std = [3, 1] #设定两个类别的方差
X, y = make_blobs(n_samples=[class_1, class_2],centers=centers,cluster_std=clusters_std,random_state=0, shuffle=False) name = ["Multinomial" ,"Gaussian","Bernoulli"]
models = [MultinomialNB(),GaussianNB(),BernoulliNB()]for name,clf in zip(name,models):Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)if name != "Gaussian":kbs = KBinsDiscretizer(n_bins=10, encode='onehot').fit(Xtrain)Xtrain = kbs.transform(Xtrain)Xtest = kbs.transform(Xtest)clf.fit(Xtrain,Ytrain)y_pred = clf.predict(Xtest)proba = clf.predict_proba(Xtest)[:,1]score = clf.score(Xtest,Ytest)print(name)print("\tBrier:{:.3f}" .format(BS(Ytest,proba,pos_label=1)))print("\tAccuracy:{:.3f}" .format(score))print("\tRecall:{:.3f}" .format(recall_score(Ytest,y_pred)))print("\tAUC:{:.3f}" .format(AUC(Ytest,proba)))

结果:

MultinomialBrier:0.007Accuracy:0.990Recall:0.000AUC:0.991
GaussianBrier:0.006Accuracy:0.990Recall:0.438AUC:0.993
BernoulliBrier:0.009Accuracy:0.987Recall:0.771AUC:0.987

从结果上来看,多项式朴素贝叶斯判断出了所有的多数类样本,但放弃了全部的少数类样本,受到样本不均衡问题影响最严重。高斯比多项式在少数类的判断上更加成功一些,至少得到了43.8%的recall。伯努利贝叶斯虽然整体的准确度和布里尔分数不如多项式和高斯朴素贝叶斯和,但至少成功捕捉出了77.1%的少数类。可见,伯努利贝叶斯最能够忍受样本不均衡问题。

可是,伯努利贝叶斯只能用于处理二项分布数据,在现实中,强行将所有的数据都二值化不会永远得到好结果,在我们有多个特征的时候,我们更需要一个个去判断究竟二值化的阈值该取多少才能够让算法的效果优秀。这样做无疑是非常低效的。那如果我们的目标是捕捉少数类,我们应该怎么办呢?高斯朴素贝叶斯的效果虽然比多项式好,但是也没有好到可以用来帮助我们捕捉少数类的程度——43.8%,还不如抛硬币的结果。因此,孜孜不倦的统计学家们改进了朴素贝叶斯算法,修正了包括无法处理样本不平衡在内的传统朴素贝叶斯的众多缺点,得到了新兴贝叶斯算法:补集朴素贝叶斯。

改进多项式朴素贝叶斯:补集朴素贝叶斯ComplementNB

from sklearn.naive_bayes import ComplementNB
from time import time
import datetimename = ["Multinomial","Gaussian","Bernoulli","Complement"]
models = [MultinomialNB(),GaussianNB(),BernoulliNB(),ComplementNB()]
for name,clf in zip(name,models):times = time()Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)#预处理if name != "Gaussian":kbs = KBinsDiscretizer(n_bins=10, encode='onehot').fit(Xtrain)Xtrain = kbs.transform(Xtrain)Xtest = kbs.transform(Xtest)clf.fit(Xtrain,Ytrain)y_pred = clf.predict(Xtest)proba = clf.predict_proba(Xtest)[:,1]score = clf.score(Xtest,Ytest)print(name)print("\tBrier:{:.3f}".format(BS(Ytest,proba,pos_label=1)))print("\tAccuracy:{:.3f}".format(score))print("\tRecall:{:.3f}".format(recall_score(Ytest,y_pred)))print("\tAUC:{:.3f}".format(AUC(Ytest,proba)))print(datetime.datetime.fromtimestamp(time()-times).strftime("%M:%S:%f"))

结果:

MultinomialBrier:0.007Accuracy:0.990Recall:0.000AUC:0.991
00:00:060486
GaussianBrier:0.006Accuracy:0.990Recall:0.438AUC:0.993
00:00:018604
BernoulliBrier:0.009Accuracy:0.987Recall:0.771AUC:0.987
00:00:028316
ComplementBrier:0.038Accuracy:0.953Recall:0.987AUC:0.991
00:00:030288

可以发现,补集朴素贝叶斯牺牲了部分整体的精确度和布里尔指数,但是得到了十分高的召回率Recall,捕捉出了98.7%的少数类,并且在此基础上维持了和原本的多项式朴素贝叶斯一致的AUC分数。和其他的贝叶斯算法比起来,我们的补集朴素贝叶斯的运行速度也十分优秀。如果我们的目标是捕捉少数类,那我们毫无疑问会希望选择补集朴素贝叶斯作为我们的算法。

Sklearn(v3)——朴素贝叶斯(3)相关推荐

  1. 基于sklearn的朴素贝叶斯_朴素贝叶斯分类实战:对文档进行分类

    朴素贝叶斯分类最适合的场景就是文本分类.情感分析和垃圾邮件识别.其中情感分析和垃圾邮件识别都是通过文本来进行判断.所以朴素贝叶斯也常用于自然语言处理 NLP 的工具. sklearn 机器学习包 sk ...

  2. 基于sklearn的朴素贝叶斯_Sklearn参数详解—贝叶斯

    在开始学习具体的贝叶斯参数前,你可以先看看:朴素贝叶斯详解​mp.weixin.qq.com 朴素贝叶斯一共有三种方法,分别是高斯朴素贝叶斯.多项式分布贝叶斯.伯努利朴素贝叶斯,在介绍不同方法的具体参 ...

  3. python调用sklearn中朴素贝叶斯踩坑

      调用结构: from sklearn.naive_bayes import MultinomialNB # 从sklean.naive_bayes里导入朴素贝叶斯模型 from sklearn.f ...

  4. Python+sklearn使用朴素贝叶斯算法识别中文垃圾邮件

    总体思路与步骤: 1.从电子邮箱中收集垃圾和非垃圾邮件训练集. 2.读取全部训练集,删除其中的干扰字符,例如[]*..,等等,然后分词,删除长度为1的单个字. 3.统计全部训练集中词语的出现次数,截取 ...

  5. [python机器学习及实践(2)]Sklearn实现朴素贝叶斯

    1.朴素贝叶斯简介 朴素贝叶斯(Naive Bayes)是一个基于贝叶斯理论的分类器.它会单独考量每一唯独特征被分类的条件概率,进而综合这些概率并对其所在的特征向量做出分类预测. 因此,朴素贝叶斯的基 ...

  6. sklearn学习-朴素贝叶斯(二)

    文章目录 一.概率类模型的评估指标 1.布里尔分数Brier Score 对数似然函数Log Loss 二. calibration_curve: 校准可靠性曲线 三.多项式朴素贝叶斯以及其变化 四. ...

  7. 使用Sklearn学习朴素贝叶斯算法

    目录 1,sklearn中的贝叶斯分类器 1.1,高斯朴素贝叶斯GaussianNB 1.1.1,认识高斯朴素贝叶斯 1.1.2,参数说明 1.1.3,高斯朴素贝叶斯建模案例 1.1.4,探索高斯朴素 ...

  8. sklearn学习-朴素贝叶斯

    文章目录 一.概述 1.真正的概率分类器 2.sklearn中的朴素贝叶斯 二.不同分布下的贝叶斯 1.高斯朴素贝叶斯GaussianNB 2.探索贝叶斯:高斯朴素贝叶斯擅长的数据集 3.探索贝叶斯: ...

  9. 基于sklearn的朴素贝叶斯_sklearn 朴素贝叶斯

    朴素贝叶斯是基于贝叶斯理论的一种监督学习算法,『朴素』意思是假设所有特征两两相互独立,给出类别y和一组依赖特征[x1..xn],根据贝叶斯理论,他们有如下的关系. P(y|x1,...xn)=P(y) ...

  10. 监督学习 | 朴素贝叶斯之Sklearn实现

    文章目录 1. Sklearn 实现朴素贝叶斯 1.1 数据导入 1.2 数据预处理 1.3 拆分训练集和测试集 1.4 Bag of Words 1.4.1 Sklearn 实现 Bag of Wo ...

最新文章

  1. 置信区间(Confidence Intervals)是什么?如何计算置信区间?置信区间的两种计算方法是什么?二值样本置信区间如何计算?如何基于bootstrap抽样进行置信区间计算?
  2. vim在退出时,处理隐藏缓冲区的方式
  3. 隐藏式抽屉SlidingDrawer(无法实现垂直)
  4. redis linux 文件位置,Linux下Redis的安装和部署
  5. C++ 标准库类型 vector
  6. Centos7安装netstat及简单使用
  7. SVN错误:Attempted to lock an already-locked dir及不能提交.so文件
  8. android版本英文,Android API Level与sdk版本中英文对照表
  9. Linux开发_退格符的花样用法
  10. chrome devTool
  11. 射频放大电路的优化及ADS仿真
  12. 前端如何来做权限管理?
  13. 使用IIS Live Smooth Streaming技术搭建流媒体直播系统
  14. 关于腾讯应用宝上架的应用版本回退的问题
  15. vsphere虚拟服务器备份,使用云祺虚拟机备份软件快速备份VMware vSphere虚拟机
  16. 如何破坏服务器系统,如何修正文件系统超块中毁坏的幻数
  17. mac创建.开头的文件夹
  18. mysql如何查看事务日记_详解 Mysql 事务和Mysql 日志
  19. 机械臂matlab运动学仿真,matlab建立机械臂运动学仿真
  20. PEEK薄膜特性与各型号性能特征分析

热门文章

  1. 戴维南定律和诺顿定律
  2. oracle job如何执行存储过程,oracle定时执行存储过程的job
  3. gitlab更新配置无效_GitMaster 发布 v1.11.0 版本,支持 GitLab 多级分组,Gist支持文件列表...
  4. win10怎么用Linux命令,教你Windows10系统使用Linux命令的技巧
  5. java web项目的目录结构以及各文件夹的功能是什么eclipse的web目录及各作用
  6. caffe apt install
  7. tf.nn.embedding_lookup函数的用法
  8. 知识图谱( 知识图谱管理)
  9. 项目当中套一个自己的小库的方式问题记录
  10. 点云网络的论文理解(一)-点云网络的提出 PointNet : Deep Learning on Point Sets for 3D Classification and Segmentation