1.理解朴素贝叶斯

1)基本概念

  • 依据概率原则进行分类。如天气预测概率。
  • 朴素贝叶斯(Naive Bayes, NB)适合场景:为估计一个结果的概率,从众多属性中提取的信息应该被同时考虑。
  • 很多算法忽略了弱影响的特征(若有大量弱影响的特征,它们组合在一起的影响可能会很大),但NB算法利用了所有可以获得的证据来修正预测。
  • 贝叶斯方法的基本概念:事件,试验,概率,联合概率,独立事件,相关事件(建立预测模型的基础),条件概率,先验概率,似然概率,边际似然概率,后验概率,频率表
  • 条件概率公式(事件B已经发生的条件下,事件A发生的概率):

  • 后验概率(如商业垃圾邮件过滤器:判断viagra是垃圾邮件spam的概率):

2)朴素贝叶斯算法

  • NB优点:简单快速有效;能处理噪音及缺失值数据;训练集不限大小;容易获得估计概率值。
  • NB缺点:依赖同样重要和独立的特征(错误假设);应用在大量数值特征的数据集中不理想;概率估计值比预测的类更不可靠。
  • “朴素”的含义:基于这样一个假设:数据集的所有特征都具有相同的重要性和独立性,但在大多数实际应用中,假设不成立。
  • 朴素贝叶斯算法具通用性和准确性,在分类学习任务中很强大。

①朴素贝叶斯分类

假设有4个单词的100封邮件的似然表来训练朴素贝叶斯算法(如下表),收到新邮件时(包含了单词viagra和unsubscribe,但不包含money和groceries),通过计算后验概率来判断它是否为垃圾邮件。



原始的基于贝叶斯定理的后验概率:



将4个单词事件视为独立事件(类条件独立),可简化公式:



计算垃圾邮件总似然为:

计算非垃圾邮件总似然为:

是垃圾邮件的概率为:

②拉普拉斯估计

对于类中一个或多个水平,如果一个时间从没有发生过,那它出现的概率为0,从而导致后验概率值也为0(抵消或否决了所有其他的证据)。

比如,这次的新邮件中包含了前述的4个单词,则计算垃圾邮件的似然:

该邮件是垃圾邮件的概率为:

拉普拉斯估计就是给频率表中每个计数加上一个很小的数(一般设为1),保证每一类中每个特征发生的概率是非零的。

拉普拉斯估计后的垃圾邮件似然:

③数值型特征值离散化

前面的频率表要求特征必须为分类变量,如果是数值变量,需要将数值离散化(分段),如根据时间寻找分割点。如果没有明显的分割点,也可利用分位数进行分段。

但将数值特征离散化总是会导致信息量的减少,因为特征的原始粒度减少为几个数目较少的类别。分段太少会导致重要趋势被掩盖,分段太多会导致频率表中的计数值很小,因此需要平衡分段数。

2.朴素贝斯分类应用

示例:基于贝叶斯算法的手机垃圾短信过滤。

1)收集数据

数据下载sms_spam.csv

链接: https://pan.baidu.com/s/1fAufKXCSufwd8It_DHXyWQ 提取码: vgyj

2)探索和准备数据

## Example: Filtering spam SMS messages ----
## Step 2: Exploring and preparing the data ---- # read the sms data into the sms data frame
sms_raw <- read.csv("sms_spam.csv", stringsAsFactors = FALSE) # examine the structure of the sms data
str(sms_raw) # convert spam/ham to factor.
sms_raw$type <- factor(sms_raw$type) # examine the type variable more carefully
str(sms_raw$type)
table(sms_raw$type)

处理和分析文本数据

文本挖掘包tm创建语料库(文本集合),inspect函数查看语料库内容,tm_map函数转换tm语料库(如去数字,变小写等),stopwords函数去除填充词(如to/and/or/but等)。

清理完后标记分解单词形成的组,并创建稀疏矩阵。再进行训练集和测试集划分,并利用词云进行可视化文本数据。最后为高频词创建指示特征。

PS:运行过程中tm包的tolower参数一直报错,未解决,因此本示例最终没有用此参数。


# build a corpus using the text mining (tm) package
library(tm)
sms_corpus <- VCorpus(VectorSource(sms_raw$text)) # examine the sms corpus
print(sms_corpus)
inspect(sms_corpus[1:2]) as.character(sms_corpus[[1]])
lapply(sms_corpus[1:2], as.character) # clean up the corpus using tm_map()
# sms_corpus_clean <- tm_map(sms_corpus, content_transformer(tolower)) #Error
sms_corpus_clean <- sms_corpus # show the difference between sms_corpus and corpus_clean
as.character(sms_corpus[[1]])
as.character(sms_corpus_clean[[1]]) sms_corpus_clean <- tm_map(sms_corpus_clean, removeNumbers) # remove numbers
sms_corpus_clean <- tm_map(sms_corpus_clean, removeWords, stopwords()) # remove stop words
sms_corpus_clean <- tm_map(sms_corpus_clean, removePunctuation) # remove punctuation # tip: create a custom function to replace (rather than remove) punctuation
removePunctuation("hello...world")
replacePunctuation <- function(x) { gsub("[[:punct:]]+", " ", x) }
replacePunctuation("hello...world") # illustration of word stemming
library(SnowballC)
wordStem(c("learn", "learned", "learning", "learns")) sms_corpus_clean <- tm_map(sms_corpus_clean, stemDocument) sms_corpus_clean <- tm_map(sms_corpus_clean, stripWhitespace) # eliminate unneeded whitespace # examine the final clean corpus
lapply(sms_corpus[1:3], as.character)
lapply(sms_corpus_clean[1:3], as.character) # create a document-term sparse matrix
sms_dtm <- DocumentTermMatrix(sms_corpus_clean) # alternative solution: create a document-term sparse matrix directly from the SMS corpus
sms_dtm2 <- DocumentTermMatrix(sms_corpus, control = list(
# tolower = TRUE, #注释掉也报错
removeNumbers = TRUE,
stopwords = TRUE,
removePunctuation = TRUE,
stemming = TRUE
)) # alternative solution: using custom stop words function ensures identical result
sms_dtm3 <- DocumentTermMatrix(sms_corpus, control = list(
# tolower = TRUE, #注释掉也报错
removeNumbers = TRUE,
stopwords = function(x) { removeWords(x, stopwords()) },
removePunctuation = TRUE,
stemming = TRUE
)) # compare the result
sms_dtm
sms_dtm2
sms_dtm3 # creating training and test datasets
sms_dtm_train <- sms_dtm[1:4169, ]
sms_dtm_test <- sms_dtm[4170:5558, ] # also save the labels
sms_train_labels <- sms_raw[1:4169, ]$type
sms_test_labels <- sms_raw[4170:5558, ]$type # check that the proportion of spam is similar
prop.table(table(sms_train_labels))
prop.table(table(sms_test_labels)) # word cloud visualization
library(wordcloud)
wordcloud(sms_corpus_clean, min.freq = 50, random.order = FALSE) # subset the training data into spam and ham groups
spam <- subset(sms_raw, type == "spam")
ham <- subset(sms_raw, type == "ham") wordcloud(spam$text, max.words = 40, scale = c(3, 0.5))
wordcloud(ham$text, max.words = 40, scale = c(3, 0.5)) sms_dtm_freq_train <- removeSparseTerms(sms_dtm_train, 0.999)
sms_dtm_freq_train # indicator features for frequent words
findFreqTerms(sms_dtm_train, 5) # save frequently-appearing terms to a character vector
sms_freq_words <- findFreqTerms(sms_dtm_train, 5)
str(sms_freq_words) # create DTMs with only the frequent terms
sms_dtm_freq_train <- sms_dtm_train[ , sms_freq_words]
sms_dtm_freq_test <- sms_dtm_test[ , sms_freq_words] # convert counts to a factor
convert_counts <- function(x) {
x <- ifelse(x > 0, "Yes", "No")
} # apply() convert_counts() to columns of train/test data
sms_train <- apply(sms_dtm_freq_train, MARGIN = 2, convert_counts)
sms_test <- apply(sms_dtm_freq_test, MARGIN = 2, convert_counts)

得到的sms_trainsms_test的单词稀疏矩阵如下表所示:

3)训练模型

上例已经将原始短信转换为可以用一个统计模型代表的形式,因此用NB算法根据单词的存在与否来估计一条给定的短信是垃圾短信的概率。

使用e1071::naiveBays()klaR::NaiveBayes()函数。

## Step 3: Training a model on the data ----
library(e1071)
sms_classifier <- naiveBayes(sms_train, sms_train_labels)

4)评估模型性能

基于测试集中的未知短信来检验分类器的预测值。比较预测值和真实值,仍然通过混淆矩阵来计算。

## Step 4: Evaluating model performance ----
sms_test_pred <- predict(sms_classifier, sms_test) library(gmodels)
CrossTable(sms_test_pred, sms_test_labels,
prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,
dnn = c('predicted', 'actual'))

没怎么处理效果也比较好,所以NB是文本分类的一种标准算法。同样地,假阴性问题带来的代价较大(把正常短信过滤掉了),进一步提升模型性能试试。

5)提升模型性能

上面训练时,没有设置拉普拉斯估计,此处设为1,性能有所提升。

## Step 5: Improving model performance ----
sms_classifier2 <- naiveBayes(sms_train,
sms_train_labels,
laplace = 1) #拉普拉斯估计值 sms_test_pred2 <- predict(sms_classifier2, sms_test)
CrossTable(sms_test_pred2, sms_test_labels,
prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,
dnn = c('predicted', 'actual'))


机器学习与R语言系列推文汇总:

【机器学习与R语言】1-机器学习简介

【机器学习与R语言】2-K近邻(kNN)

【机器学习与R语言】3-朴素贝叶斯(NB)

【机器学习与R语言】4-决策树

【机器学习与R语言】5-规则学习

【机器学习与R语言】6-线性回归

【机器学习与R语言】7-回归树和模型树

【机器学习与R语言】8-神经网络

【机器学习与R语言】9-支持向量机

【机器学习与R语言】10-关联规则

【机器学习与R语言】11-Kmeans聚类

【机器学习与R语言】12-如何评估模型的性能?

【机器学习与R语言】13-如何提高模型的性能?

【机器学习与R语言】3-概率学习朴素贝叶斯(NB)的更多相关文章

  1. R语言︱贝叶斯网络语言实现及与朴素贝叶斯区别(笔记)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 一.贝叶斯网络与朴素贝叶斯的区别 朴素贝叶斯的 ...

  2. 【机器学习速成宝典】模型篇05朴素贝叶斯【Naive Bayes】(Python版)

    目录 先验概率与后验概率 条件概率公式.全概率公式.贝叶斯公式 什么是朴素贝叶斯(Naive Bayes) 拉普拉斯平滑(Laplace Smoothing) 应用:遇到连续变量怎么办?(多项式分布, ...

  3. Stanford大学机器学习公开课(六):朴素贝叶斯多项式模型、神经网络、SVM初步

    (一)朴素贝叶斯多项式事件模型 在上篇笔记中,那个最基本的NB模型被称为多元伯努利事件模型(Multivariate Bernoulli Event Model,以下简称 NB-MBEM).该模型有多 ...

  4. 机器学习Matlab打击垃圾邮件的分类————朴素贝叶斯模型

    该系列来自于我<人工智能>课程回顾总结,以及实验的一部分进行了总结学习机 垃圾分类是有监督的学习分类最经典的案例,本文首先回顾了概率论的基本知识.则以及朴素贝叶斯模型的思想.最后给出了垃圾 ...

  5. 机器学习Sklearn系列:(四)朴素贝叶斯

    3--朴素贝叶斯 原理 朴素贝叶斯本质上就是通过贝叶斯公式来对得到类别概率,但区别于通常的贝叶斯公式,朴素贝叶斯有一个默认条件,就是特征之间条件独立. 条件概率公式: \[P(B|A) = \frac ...

  6. 【Spark机器学习速成宝典】模型篇04朴素贝叶斯【Naive Bayes】(Python版)

    目录 朴素贝叶斯原理 朴素贝叶斯代码(Spark Python) 朴素贝叶斯原理 详见博文:http://www.cnblogs.com/itmorn/p/7905975.html 返回目录 朴素贝叶 ...

  7. 机器学习之朴素贝叶斯&贝叶斯网络

    贝叶斯决决策论       在所有相关概率都理想的情况下,贝叶斯决策论考虑基于这些概率和误判损失来选择最优标记,基本思想如下: (1)已知先验概率和类条件概率密度(似然) (2)利用贝叶斯转化为后验概 ...

  8. 100天搞定机器学习|Day15 朴素贝叶斯

    Day15,开始学习朴素贝叶斯,先了解一下贝爷,以示敬意. 托马斯·贝叶斯 (Thomas Bayes),英国神学家.数学家.数理统计学家和哲学家,1702年出生于英国伦敦,做过神甫:1742年成为英 ...

  9. 吴裕雄--天生自然python机器学习:朴素贝叶斯算法

    分类器有时会产生错误结果,这时可以要求分类器给出一个最优的类别猜测结果,同 时给出这个猜测的概率估计值. 概率论是许多机器学习算法的基础 在计算 特征值取某个值的概率时涉及了一些概率知识,在那里我们先 ...

随机推荐

  1. abstract使用方式

    springMVC中的 LocalContextHolder是一个 abstract类.里边方法都是static 的. 不能被继承.不能实例化.只能调用其定义的static 方法.这种 abstrac ...

  2. UltraSoft Scrum Meeting 博客汇总

    一.Alpha阶段 UltraSoft - Alpha - Scrum Meeting 1 UltraSoft - Alpha - Scrum Meeting 2 UltraSoft - Alpha ...

  3. springboot读取配置文件中的信息

    在一个项目中,我们有时候会把一些配置信息写入到一个配置文件中,在java代码中读取配置文件的信息.在此记录下读取属性文件中的内容. 在springboot项目中,springboot的配置文件可以使用 ...

  4. Pogo-Cow S

    这题出在单调队列优化dp里,就离谱好吧...... 对不住了上来先喷一波,不过离谱是确实的 dp的含义也很简单,就是说从j到i的分数最大值 直接上代马,里面说的很详细了 1 #include<b ...

  5. 数位dp & 热身训练7

    数位dp 数位dp是一种计数用的dp,一般就是要统计一段区间$[L,R]$内,满足一定条件的数的个数,或者各个数位的个数. 数位dp使得暴力枚举变为满足一定状态的记忆化,更加优秀. 数位dp常常会考虑 ...

  6. Hdu P1394 Minimum Inversion Number | 权值线段树

    题目链接 题目翻译: 约定数字序列a1,a2,...,an的反转数是满足i<j和ai>aj的数对(ai,aj)的数量. 对于给定的数字序列a1,a2,...,an,如果我们将第1到m个数字 ...

  7. Tarjan算法离线 求 LCA(最近公共祖先)

    本文是网络资料整理或部分转载或部分原创,参考文章如下: https://www.cnblogs.com/JVxie/p/4854719.html http://blog.csdn.net/ywcpig ...

  8. hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

    题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个 ...

  9. redis 集群环境搭建

    原理: 1,每个Redis群集的节点都需要打开两个TCP连接,由于这两个连接就需要两个端口,分别是用于为客户端提供服务的常规Redis TCP命令端口(例如6379)以及通过将10000和命令端口相加 ...

  10. MySQL:互联网公司常用分库分表方案汇总!

    一.数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值.在业务Service来看就是,可用数据库连接少甚至无连接可用.接下来就 ...