理论

什么是朴素贝叶斯算法?

朴素贝叶斯分类器是一种基于贝叶斯定理的弱分类器,所有朴素贝叶斯分类器都假定样本每个特征与其他特征都不相关。举个例子,如果一种水果其具有红,圆,直径大概3英寸等特征,该水果可以被判定为是苹果。尽管这些特征相互依赖或者有些特征由其他特征决定,然而朴素贝叶斯分类器认为这些属性在判定该水果是否为苹果的概率分布上独立的。

朴素贝叶斯分类器很容易建立,特别适合用于大型数据集,众所周知,这是一种胜过许多复杂算法的高效分类方法。

贝叶斯公式提供了计算后验概率P(X|Y)的方式:

其中,

  • P(c|x)是已知某样本(c,目标),(x,属性)的概率。称后验概率。

  • P(c)是该样本“c”的概率。称先验概率。

  • P(x|c)是已知该样本“x”,该样本“c”的概率。

  • P(x)是该样本“x”的概率。

朴素贝叶斯算法的分类流程

举一个例子。下面设计了一个天气和响应目标变量“玩”的训练数据集(计算“玩”的可能性)。我们需要根据天气条件进行分类,判断这个人能不能出去玩,以下是步骤:

步骤1:将数据集转换成频率表;

步骤2:计算不同天气出去玩的概率,并创建似然表,如阴天的概率是0.29;

步骤3:使用贝叶斯公式计算每一类的后验概率,数据最高那栏就是预测的结果。

问题:如果是晴天,这个人就能出去玩。这个说法是不是正确的?

P(是|晴朗)=P(晴朗|是)×P(是)/P(晴朗)

在这里,P(晴朗|是)= 3/9 = 0.33,P(晴朗)= 5/14 = 0.36,P(是)= 9/14 = 0.64

现在,P(是|晴朗)=0.33×0.64/0.36=0.60,具有较高的概率。

朴素贝叶斯适合预测基于各属性的不同类的概率,因此在文本分类上有广泛应用。

朴素贝叶斯的优缺点

优点:

  • 既简单又快速,预测表现良好;

  • 如果变量独立这个条件成立,相比Logistic回归等其他分类方法,朴素贝叶斯分类器性能更优,且只需少量训练数据;

  • 相较于数值变量,朴素贝叶斯分类器在多个分类变量的情况下表现更好。若是数值变量,需要正态分布假设。

缺点:

  • 如果分类变量的类别(测试数据集)没有在训练数据集总被观察到,那这个模型会分配一个0(零)概率给它,同时也会无法进行预测。这通常被称为“零频率”。为了解决这个问题,我们可以使用平滑技术,拉普拉斯估计是其中最基础的技术。

  • 朴素贝叶斯也被称为bad estimator,所以它的概率输出predict_proba不应被太认真对待。

  • 朴素贝叶斯的另一个限制是独立预测的假设。在现实生活中,这几乎是不可能的,各变量间或多或少都会存在相互影响。

朴素贝叶斯的4种应用

实时预测:毫无疑问,朴素贝叶斯很快。

多类预测:这个算法以多类别预测功能闻名,因此可以用来预测多类目标变量的概率。

文本分类/垃圾邮件过滤/情感分析:相比较其他算法,朴素贝叶斯的应用主要集中在文本分类(变量类型多,且更独立),具有较高的成功率。因此被广泛应用于垃圾邮件过滤(识别垃圾邮件)和情感分析(在社交媒体平台分辨积极情绪和消极情绪的用户)。

推荐系统:朴素贝叶斯分类器和协同过滤结合使用可以过滤出用户想看到的和不想看到的东西。

关于朴素贝叶斯分类器的几个黑科技

以下是一些小方法,可以提升朴素贝叶斯分类器的性能:

  • 如果连续特征不是正态分布的,我们应该使用各种不同的方法将其转换正态分布。

  • 如果测试数据集具有“零频率”的问题,应用平滑技术“拉普拉斯估计”修正数据集。

  • 删除重复出现的高度相关的特征,可能会丢失频率信息,影响效果。

  • 朴素贝叶斯分类在参数调整上选择有限。我建议把重点放在数据的预处理和特征选择。

  • 大家可能想应用一些分类组合技术 如ensembling、bagging和boosting,但这些方法都于事无补。因为它们的目的是为了减少差异,朴素贝叶斯没有需要最小化的差异。

如何建立朴素贝叶斯的基本模型(Python和R)

scikit learn里有3种朴素贝叶斯的模型:

高斯模型:适用于多个类型变量,假设特征符合高斯分布。

多项式模型:用于离散计数。如一个句子中某个词语重复出现,我们视它们每个都是独立的,所以统计多次,概率指数上出现了次方。

伯努利模型:如果特征向量是二进制(即0和1),那这个模型是非常有用的。不同于多项式,伯努利把出现多次的词语视为只出现一次,更加简单方便。

你可以根据特定数据集选取上述3个模型中的合适模型。下面我们以高斯模型为例,谈谈怎么建立:

  • Python
  •   #Import Library of Gaussian Naive Bayes model
    from sklearn.naive_bayes import GaussianNB
    import numpy as np #assigning predictor and target variables
    x= np.array([[-3,7],[1,5], [1,2], [-2,0], [2,3], [-4,0], [-1,1], [1,1], [-2,2], [2,7], [-4,1], [-2,7]])
    Y = np.array([3, 3, 3, 3, 4, 3, 3, 4, 3, 4, 4, 4]) #Create a Gaussian Classifier
    model = GaussianNB() # Train the model using the training sets
    model.fit(x, y) #Predict Output
    predicted= model.predict([[1,2],[3,4]])
    print predicted Output: ([3,4])
  • R
  •   require(e1071) #Holds the Naive Bayes Classifier
    Train <- read.csv(file.choose())
    Test <- read.csv(file.choose()) #Make sure the target variable is of a two-class classification problem only levels(Train$Item_Fat_Content) model <- naiveBayes(Item_Fat_Content~., data = Train)
    class(model)
    pred <- predict(model,Test)
    table(pred)

      

文本分类的主要流程 

  1. 样本数据的获取
  2. 样本数据清洗和分词
  3. 建模与评估
  4. 部署运行

R实现

完整代码及报告见另一篇博文

分词

一个好用的包:chinese.misc。说明文档:https://github.com/githubwwwjjj/chinese.misc

应用示例:

library(jiebaRD)
library(NLP)
library(chinese.misc)
library(jiebaR)
library(tm)
library(MASS)
library(klaR)
library(e1071) ##样本数据
textData <- teld.ml.rQuery("NewsInformation4BDP")
textData$NewsContent <-as.character(textData$NewsContent) #自定义分词器,将需要特殊识别的纳入分词
myCutter<-worker(write=FALSE)
myWord<-c("XXX","XX","x","xxx","xx")
new_user_word(myCutter,myWord) #去掉英文、字母
slimtextf<-function(x){
x1<-slim_text(x,
mycutter = myCutter,
rm_place = TRUE,
rm_time = TRUE,
rm_eng = TRUE,
rm_alpha = TRUE,
paste = TRUE
)
return (x1)
}
textData$NewsContent <- sapply(as.list(textData$NewsContent),slimtextf,simplify = TRUE); textData$TFlag <-sample(0:1,nrow(textData),replace=T,prob=c(0.7,0.3))#按7:3拆分训练集和测试集
textData.Train <- textData[textData$TFlag==0,]
textData.Test <- textData[textData$TFlag==1,]
dim(textData.Train )
dim(textData.Test)
head(textData.Train) #生成文档-词条矩阵DTM(document term matrix)
#stopPattern <- '(quot|app|ev|km|model|suv)',stop_pattern = stopPattern
#%>%是管道 函数,即将其左边的值发送给右边的表达 式,并作为右边表达式函数的第一个参数,如x<-y %>% f(z) 等价于x<-f(y,z)
dtm.train<-textData.Train$NewsContent%>%
corp_or_dtm(from="v",type="D",stop_word="jiebar",mycutter=myCutter,control = list(wordLengths=c(2,25)))%>%
removeSparseTerms(0.99)%>%
output_dtm(doc_name=textData.Train$SN)
#removeSparseTerms的Sparse参数越小,矩阵越稀疏 dim(dtm.train)# 737 382
#write.csv(dtm.train,'dtm.train10.csv') dtm.test<-textData.Test$NewsContent%>%
corp_or_dtm(from="v",type="D",stop_word="jiebar",mycutter=myCutter,control = list(wordLengths=c(2,25)))%>%
removeSparseTerms(0.99)%>%
output_dtm(doc_name=textData.Test$SN) dim(dtm.test)# 334 386

  

建模

有两个包可用: e1071和klaR

 e1071示例:

#训练朴素贝叶斯模型
model <- naiveBayes(dtm.train,as.factor(textData.Train$AState),laplace = 1) #预测测试集
pre<-predict(model,dtm.test)
#pre<-predict(model,dtm.test,type=c("raw")) #输出概率,因为两个概率悬殊太大,无意义,不采用(见理论篇的缺点部分)
#默认值type = c("class", "raw")

  

 klaR示例:在建模时报错,后带分析说明

#训练朴素贝叶斯模型
model <- NaiveBayes(dtm.train,as.factor(textData.Train$AState),usekernel=FALSE,fL = 1)
#报错:Zero variances for at least one class in variables: 保时捷, 比亚迪, 戴姆勒, 环保, 混合, 集团, 加快, 开发...... #预测测试集
pre<-predict(model,dtm.test)
报错:Zero variances for at least one class in variables: 保时捷, 比亚迪, 戴姆勒, 环保, 混合, 集团, 加快, 开发.....
错误原因:存在0方差的变量
错误信息对应的源码:

  解决方案:如果一定要使用这个包,那就修改源码,把stop代码干掉,让它继续执行。然后自己编译这个包。

评估

在应用案例中采用了10折交叉验证,执行10次取均值。

相关指标的说明见https://www.cnblogs.com/xianhan/p/9277194.html

#性能评价
performance<-prop.table(table(textData.Test$AState,pre))
performance
#准确率:4和5预测正确的比例**
accuracyrate<-(performance[1,1]+performance[2,2])
accuracyrate # 0.5174603->0.5434783
#灵敏度(查全率\召回率):实际5,其中预测正确的比例*****
sensitivity <-performance[2,2]/(performance[2,1]+performance[2,2])
sensitivity #0.8791209->0.816092
#精密性:预测5,其中预测正确的比例**
precision <-performance[2,2]/(performance[1,2]+performance[2,2])
precision # 0.361991-> 0.3514851
#特异性:实际4,其中预测正确的比例*
specificity <-performance[1,1]/(performance[1,1]+performance[1,2])
specificity #0.3705357->0.4425532

20180731后续:

该服务发布上线后,每次调用耗时2-4s不等,超过系统设置的超时阈值而频繁报警。经过分析,是自定义分词器耗时2-3s,将自定义分词器去掉后,耗时50-80ms。


  

 参考

中文文本分析方便工具R包chinese.misc的中文说明

https://github.com/githubwwwjjj/chinese.misc

R语言-贝叶斯分类器-文本情感分析

https://zhuanlan.zhihu.com/p/26735328

R实战——大众点评-汉拿山(深国投店)评论情感浅析

https://mp.weixin.qq.com/s?__biz=MzUyNzU3MTgyOA==&mid=2247483690&idx=1&sn=9b8ea4b159e5885c0b99f3529a25c488&chksm=fa7ccf31cd0b4627d8f7321a392036686c1f59a0e365b3976c8ba4810a407f46b53cff4e63f0#rd

基于Naive Bayes算法的文本分类的更多相关文章

  1. Spark ML下实现的多分类adaboost+naivebayes算法在文本分类上的应用

    1. Naive Bayes算法 朴素贝叶斯算法算是生成模型中一个最经典的分类算法之一了,常用的有Bernoulli和Multinomial两种.在文本分类上经常会用到这两种方法.在词袋模型中,对于一 ...

  2. (转载)微软数据挖掘算法:Microsoft Naive Bayes 算法(3)

    介绍: Microsoft Naive Bayes 算法是一种基于贝叶斯定理的分类算法,可用于探索性和预测性建模. Naïve Bayes 名称中的 Naïve 一词派生自这样一个事实:该算法使用贝叶 ...

  3. Microsoft Naive Bayes 算法——三国人物身份划分

    Microsoft朴素贝叶斯是SSAS中最简单的算法,通常用作理解数据基本分组的起点.这类处理的一般特征就是分类.这个算法之所以称为“朴素”,是因为所有属性的重要性是一样的,没有谁比谁更高.贝叶斯之名 ...

  4. Chinese-Text-Classification,用卷积神经网络基于 Tensorflow 实现的中文文本分类。

    用卷积神经网络基于 Tensorflow 实现的中文文本分类 项目地址: https://github.com/fendouai/Chinese-Text-Classification 欢迎提问:ht ...

  5. 基于Text-CNN模型的中文文本分类实战 流川枫 发表于AI星球订阅

    Text-CNN 1.文本分类 转眼学生生涯就结束了,在家待就业期间正好有一段空闲期,可以对曾经感兴趣的一些知识点进行总结. 本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个基于T ...

  6. 基于Text-CNN模型的中文文本分类实战

    Text-CNN 1.文本分类 转眼学生生涯就结束了,在家待就业期间正好有一段空闲期,可以对曾经感兴趣的一些知识点进行总结. 本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个基于T ...

  7. 【十大算法实现之naive bayes】朴素贝叶斯算法之文本分类算法的理解与实现

    关于bayes的基础知识,请参考: 基于朴素贝叶斯分类器的文本聚类算法 (上) http://www.cnblogs.com/phinecos/archive/2008/10/21/1315948.h ...

  8. 基于keras中IMDB的文本分类 demo

      本次demo主题是使用keras对IMDB影评进行文本分类: import tensorflow as tf from tensorflow import keras import numpy a ...

  9. 基于Huggingface使用BERT进行文本分类的fine-tuning

    随着BERT大火之后,很多BERT的变种,这里借用Huggingface工具来简单实现一个文本分类,从而进一步通过Huggingface来认识BERT的工程上的实现方法. 1.load data tr ...

随机推荐

  1. 使用JSON实现分页

    使用JSON实现分页可直接用 Fenye.html <!DOCTYPE html> <html> <head> <title>JSON分页</ti ...

  2. 关于YII中layout中的布局和view中数据的关系

    1. view中解释php脚本后显示出的内容会在layout中以<?php echo $content?>输出. 2. view是对应的controller的实例,所以可以通过$this- ...

  3. bzoj P4870: [Shoi2017]组合数问题——solution

    题意:求解—— $$(C^{r}_{nk}+C^{r+k}_{nk}+C^{r+2k}_{nk}+...+C^{r+(n-1)k}_{nk}+...)mod(P)$$ 其中$C^{m}_{n}$表示从 ...

  4. 当碰到需要调试打包后的js

    在react中经常开发碰到不能热更中进行调试的,如IE之类的 这个时候我们就需要打包才能运行看到效果, 但是往往每次打包都需要很长的时间: 这个时候我们就可以直接找到打包后的文件,直接在改文件中修改: ...

  5. Flutter的教程:ListView

    本文学习一下列表widget,是最常见的需求 在Flutter中,用ListView来显示列表项,支持垂直和水平方向展示,通过一个属性我们就可以控制其方向 1.水平的列表 2.垂直的列表 3.数据量非 ...

  6. HTTP请求封装:Ajax与RESTful API

    一.HTTP请求 HTTP即超文本传输协议,用以进行HTML 文件. 图片文件. 查询结果等的网络传输. 一个完整的HTTP请求包括:请求行.请求头.空行和请求数据(请求数据可以为空) HTTP1.1 ...

  7. PyQt4(简单布局)

    import sys from PyQt4 import QtCore, QtGui app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget ...

  8. GoldenGate搭建与运维

    GolenGate介绍 GoldenGate软件是一种基于日志的结构化数据复制软件,它通过解析源数据库在线日志或归档日志获得数据的增删改变化,再将这些变化应用到目标数据库,实现源数据库与目标数据库实时 ...

  9. mysql执行计划常用说明

    MYSQL执行计划顺序原则上是:在所有组中,id值越大,优先级越高,越先执行,id如果相同,可以认为是一组,从上往下顺序执行做执行计划之前,要了解下表统计信息情况:mysql.innodb_table ...

  10. Linux系统管理员命令:sudo

    sudo是个统管一切的命令.它的字面意思是代表“超级用户才能做!”(super user do!)对Linux系统管理员或高级用户而言,它是必不可少的最重要的命令之一.你可曾有过这样的经历:在终端中试 ...