ML(4): NavieBayes在R中的应用
朴素贝叶斯方法是一种使用先验概率去计算后验概率的方法, 具体见ML(3): 贝叶斯方法
R包
① e1071::e1071
② klaR::klaR
参考资料:https://en.wikibooks.org/wiki/Data_Mining_Algorithms_In_R/Classification/Na%C3%AFve_Bayes
算法包:e1071
函数:navieBayes(formule,data,laplace=0,...,subset,na.action=na.pass)
- Formule: 公式的形式:class~x1 + x2 + ..... 相互作用是不允许的
- data: 数据集
- lapace: 正面双控制拉普拉期平滑。默认值(0)禁用拉普拉斯平滑。它的思想非常简单,就是对没类别下所有划分的计数为1,这样如果训练样本集数量充分大时,并不会对结果产生影响,并且解决了上述频率为0的局面。【在训练样本中,某一特征的属性值可能没有出现,为了保证一个属性出现次数为0时,能够得到一个很小但是非0的概率值】
R手机短信过滤示例
参考:https://zhuanlan.zhihu.com/p/22615168
原理: http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_two.html
代示示例:
- 首先,导入数据(注:第二列文本中带“...”会导制后面的数据读不进来)
#数据导入
sms <- read.csv("sms.csv",header=TRUE,stringsAsFactors=FALSE)
sms$type <- factor(sms$type)
str(sms)
table(sms$type) - 数据清洗: sms$text 文本中包含着数字、缩略的短语和标点符号等,对于NaiveBayesClassifier而言,这些信息是有干扰的,因此,在建模之前需要在语料库中对数据进行清洗。
- 添加tm包 【参见tm包使用: http://www.cnblogs.com/tgzhu/p/6680525.html】,创建语料库,如下:语料库包含5574个document
#创建语料库
library(NLP)
library(tm)
sms_corpus <- Corpus(VectorSource(sms$text)) #clear corpus
sms_corpus <- tm_map(sms_corpus, PlainTextDocument)
# 所有字母转换成小写
sms_corpus <- tm_map(sms_corpus, tolower)
# 去除text中的数字
sms_corpus <- tm_map(sms_corpus, removeNumbers)
# 去除停用词,例如and,or,until...
sms_corpus <- tm_map(sms_corpus, removeWords, stopwords())
# 去除标点符号
sms_corpus <- tm_map(sms_corpus, removePunctuation)
# 去除多余的空格,使单词之间只保留一个空格
sms_corpus <- tm_map(sms_corpus, stripWhitespace)
#查看一下清理后的语料库文本
inspect(sms_corpus[1]) - 标记化:将文本分解成由单个单词组成的组,实际就是实现语料库向稀疏矩阵的转变 corpus_clean -> sms_dtm,建立训练集和测试集数据
#将文本信息转化成DocumentTermMatrix类型的稀疏矩阵
dtm <- DocumentTermMatrix(sms_corpus)
Sys.setlocale(category = "LC_ALL", locale = "us") #训练集和测试集数据,查看垃圾与正常邮件占比
trainSet <- sms[1:4169,]
testset <- sms[4170:5574,] - 创建可视化词云,通过词云可以大致浏览一下哪些词在spam中经常出现,哪些词在ham中经常出现。当然,前者对于垃圾短信的过滤相对重要一点。绘制词云可以通过添加包wordcloud实现 install.packages("wordcloud")
- 为了查看spam和ham各自的多频词,首先取trainset的子集,如下:
> #创建可视化词云,大致浏览一下哪些词在spam中经常出现
> library(RColorBrewer)
> library(wordcloud)
> #取trainset对spam和ham的子集
> spam <- subset(trainSet, type == "spam")
> ham <- subset(trainSet, type == "ham")
> #创建词云
> wordcloud(spam$text, max.words=40, scale=c(3,0.5)) - 显示结果如下:
- 缩减特征:在面临问题是稀疏矩阵的特征太多了,而且很多词在所有text中可能都没怎么出现过,为减少运算量对特征瘦瘦身。先留下来在所有text中出现至少5次的词
dtm_train <- dtm[1:4169,]
> dtm_test <- dtm[4170:5574,]
> findFreqTerms(dtm_train,5)
[1] "available" "bugis" "cine" "crazy" "got" "great" "point" "wat"
[9] "world" "lar" "wif" "apply" "comp" "cup" "entry" "final"
[17] "free" "may" "receive" "text" "txt" "win" "wkly" "already"
[25] "dun" "early" "say" "around" "goes" "nah" "think" "though"
[33] "usf" "back" "freemsg" "fun" "hey" "like" "now" "send"
[41] "std" "still" "weeks" "word" "xxx" "brother" "even" "speak"
[49] "treat" "callers" "callertune" "copy" "friends" "melle" "per" "press"
........................ 将这些词设置成指示标识,下面建模时用这个指示标识提示模型只对这些词进行计算
> #缩减特征
> d <- findFreqTerms(dtm,5)
> corpus_train = sms_corpus[1:4169]
> corpus_test = sms_corpus[4170:5574]
> dtm_train <- DocumentTermMatrix(corpus_train,list(dictionary=d))
> dtm_test <- DocumentTermMatrix(corpus_test,list(dictionary=d))train和test都是计数矩阵,如果一条text中某个单词出现2次,那么这个单词在这条文本下会被记上2,NB只想知道这个单词出现了或者没出现,因此需要对矩阵进行转化成因子矩阵。
> #对矩阵进行转化成因子矩阵
> convert_counts <- function(x){
+ x <- ifelse(x>0,1,0)
+ x <- factor(x, levels=c(0,1),labels=c("No","Yes"))
+ return(x)
+ }
> dtm_train <- apply(dtm_train, MARGIN=2, convert_counts)
> dtm_test <- apply(dtm_test, MARGIN=2, convert_counts)训练模型
> #需要的包是e1071
> #install.packages("e1071")
> library(e1071)
> sms_classifier <- naiveBayes(dtm_train,trainSet$type)
> sms_prediction <- predict(sms_classifier, dtm_test)
>
评估模型: 用交叉表来看看test中多少预测对了
> library(gmodels)
> CrossTable(sms_prediction,testset$type,prop.chisq=TRUE,prop.t=FALSE, dnn=c("predicted","actual")) Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
|-------------------------| Total Observations in Table: 1405 | actual
predicted | ham | spam | Row Total |
-------------|-----------|-----------|-----------|
ham | 1124 | 150 | 1274 |
| 0.229 | 1.531 | |
| 0.882 | 0.118 | 0.907 |
| 0.920 | 0.820 | |
-------------|-----------|-----------|-----------|
spam | 98 | 33 | 131 |
| 2.229 | 14.886 | |
| 0.748 | 0.252 | 0.093 |
| 0.080 | 0.180 | |
-------------|-----------|-----------|-----------|
Column Total | 1222 | 183 | 1405 |
| 0.870 | 0.130 | |
-------------|-----------|-----------|-----------|
ham-ham和spam-spam是预测正确的,spam-ham:本身不是垃圾短信却被认为是垃圾短信过滤掉,由于Classifier1没有设置拉普拉斯估计,下面再尝试建立classifier2,看结果是否被优化。
> #设置拉普拉斯估计
> sms_classifier <- naiveBayes(dtm_train,trainSet$type,laplace = 1)
> sms_prediction <- predict(sms_classifier, dtm_test)
> CrossTable(sms_prediction,testset$type,prop.chisq=TRUE,prop.t=FALSE, dnn=c("predicted","actual")) Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
|-------------------------| Total Observations in Table: 1405 | actual
predicted | ham | spam | Row Total |
-------------|-----------|-----------|-----------|
ham | 1105 | 132 | 1237 |
| 0.788 | 5.262 | |
| 0.893 | 0.107 | 0.880 |
| 0.904 | 0.721 | |
-------------|-----------|-----------|-----------|
spam | 117 | 51 | 168 |
| 5.803 | 38.747 | |
| 0.696 | 0.304 | 0.120 |
| 0.096 | 0.279 | |
-------------|-----------|-----------|-----------|
Column Total | 1222 | 183 | 1405 |
| 0.870 | 0.130 | |
-------------|-----------|-----------|-----------|spam人预测结果有改进,尝试继续优化,下一步以评论分类进行中文分类模拟
iris分类预测
- 安装加载包
#安装加载e1071
#install.packages("e1071")
library(e1071) - iris数据集分为训练集和测试集
index <-sample(1:nrow(iris), 100)
iris.train <-iris[index, ]
iris.test <-iris[-index, ] - 利用朴素贝叶斯算法构建模型
model.NaiveBayes <-naiveBayes(x =subset(iris.train,select=-Species), y= iris.train$Species)
str(model.NaiveBayes)
summary(model.NaiveBayes) 用模型对测试集做测试
> results.NaiveBayes <-predict(object = model.NaiveBayes, newdata =iris.test, type="class")
> table(results.NaiveBayes, iris.test$Species) results.NaiveBayes setosa versicolor virginica
setosa 14 0 0
versicolor 0 17 2
virginica 0 1 16
ML(4): NavieBayes在R中的应用的更多相关文章
- R中一切都是vector
0.可以说R语言中一切结构体的基础是vector! R中一切都是vector,vecotor的每个component必须类型一致(character,numeric,integer....)!vect ...
- 简单介绍一下R中的几种统计分布及常用模型
统计学上分布有很多,在R中基本都有描述.因能力有限,我们就挑选几个常用的.比较重要的简单介绍一下每种分布的定义,公式,以及在R中的展示. 统计分布每一种分布有四个函数:d――density(密度函数) ...
- R中的par()函数的参数
把R中par()函数的主要参数整理了一下(另外本来还整理了每个参数的帮助文档中文解释,但是太长,就分类之后,整理为图表,excel不便放上来,就放了这些表的截图)
- 关于R中的mode()和class()的区别
本文原创,转载请注明出处,本人Q1273314690(交流学习) 说明:本文曾经在15年11月在CSDN发过,但是由于CSDN不支持为知笔记的发布为博客的API功能,所以,自今天起,转移到博客园(幸好 ...
- R中的name命名系列函数总结
本文原创,转载请注明出处,本人Q1273314690 R中关于给行列赋名称的函数有 dimnames,names,rowname,colname,row.names 这五个函数,初学的时候往往分不清楚 ...
- 总结——R中查看属性的函数
本文原创,转载注明出处,本人Q1273314690 R中知道一个变量的主要内容和结构,对我们编写代码是很重要的,也可以帮我们避免很多错误. 但是,R中有好几个关于属性查看的函数,我们往往不知道什么时候 ...
- R中创建not-yet-evaluated对象
create not-yet-evaluated object在R中创建 not-yet-evaluated(就是some code we will evaluated later!!)对象;然后执行 ...
- R中,去掉dataframe中的NA行
R中使用complete.cases 和 na.omit来去掉包含NA的行 现在有个一data.frame datafile如下所示 Date sulfate nitrate ID 1 ...
- 机器学习:形如抛物线的散点图在python和R中的非线性回归拟合方法
对于样本数据的散点图形如函数y=ax2+bx+c的图像的数据, 在python中的拟合过程为: ##最小二乘法 import numpy as np import scipy as sp import ...
随机推荐
- 【转】svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
svn提交遇到恶心的问题,可能是因为上次cleanup中断后,进入死循环了. 错误如下 解决方法:清空svn的队列 1.下载sqlite3.exe 2.找到你项目的.svn文件,查看是否存在wc.db ...
- Kettle 5.0源码编译
下载源码请参考上一篇博文Kettle4.4.2源码分析 Kettle 5.0以前的库文件通过ant管理,5.0+的库文件通过ant+ivy管理.Eclipse一般都是安装ant插件,不安装ivy插件, ...
- Synchronize执行过程
Synchronize执行过程及原理 在windows原生应用程序开发中,经常伴随多线程的使用,多线程开发很简单,难点就是在于线程的同步,在Delphi中提供了VC中不具备的一个过程Synchroni ...
- jvm系列(八):jvm知识点总览-高级Java工程师面试必备
在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...
- apk反编译方式
一.Apk反编译得到Java源代码 下载上述反编译工具包,打开apk2java目录下的dex2jar-0.0.9.9文件夹,内含apk反编译成java源码工具,以及源码查看工具. apk反编译工具de ...
- 文件的上传(表单上传和ajax文件异步上传)
项目中用户上传总是少不了的,下面就主要的列举一下表单上传和ajax上传!注意: context.Request.Files不适合对大文件进行操作,下面列举的主要对于小文件上传的处理! 资源下载: 一. ...
- Kindle电子阅读器收不到个人文档推送解决方案
最近我的 kindle 固件版本更新到 5.8.7.0.1 ,发现增加了生字注音功能,瞬间变成小学生阅读神器有木有,不过,这个功能可以隐藏.显示,看着碍眼隐藏即可,还可以减少和增加生字注音.感觉对于经 ...
- 【杂】poj2482 Stars in Your Windows 题面的翻译
原地址:http://poj.org/problem?id=2482 神题,被誉为最浪漫的题目,一位acmer以自己独特的方式写下的殷殷情语 你窗前的星星 纵时光飞逝如梭,也我对你的回忆也永不黯然.从 ...
- ArrayList源码剖析
ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...
- 1642: [Usaco2007 Nov]Milking Time 挤奶时间
1642: [Usaco2007 Nov]Milking Time 挤奶时间 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 582 Solved: 33 ...