朴素贝叶斯方法是一种使用先验概率去计算后验概率的方法, 具体见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://github.com/stedy/Machine-Learning-with-R-datasets/tree/72e6b6cc91bc2bb08eb6f99f52c033677cb70c1a

参考:https://zhuanlan.zhihu.com/p/22615168

原理: http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_two.html

代示示例:

  • 首先,导入数据(注:第二列文本中带“...”会导制后面的数据读不进来)

    1. #数据导入
    2. sms <- read.csv("sms.csv",header=TRUE,stringsAsFactors=FALSE)
    3. sms$type <- factor(sms$type)
    4. str(sms)
    5. table(sms$type)
  • 数据清洗: sms$text 文本中包含着数字、缩略的短语和标点符号等,对于NaiveBayesClassifier而言,这些信息是有干扰的,因此,在建模之前需要在语料库中对数据进行清洗。
  • 添加tm包 【参见tm包使用: http://www.cnblogs.com/tgzhu/p/6680525.html】,创建语料库,如下:语料库包含5574个document
    1. #创建语料库
    2. library(NLP)
    3. library(tm)
    4. sms_corpus <- Corpus(VectorSource(sms$text))
    5.  
    6. #clear corpus
    7. sms_corpus <- tm_map(sms_corpus, PlainTextDocument)
    8. # 所有字母转换成小写
    9. sms_corpus <- tm_map(sms_corpus, tolower)
    10. # 去除text中的数字
    11. sms_corpus <- tm_map(sms_corpus, removeNumbers)
    12. # 去除停用词,例如and,or,until...
    13. sms_corpus <- tm_map(sms_corpus, removeWords, stopwords())
    14. # 去除标点符号
    15. sms_corpus <- tm_map(sms_corpus, removePunctuation)
    16. # 去除多余的空格,使单词之间只保留一个空格
    17. sms_corpus <- tm_map(sms_corpus, stripWhitespace)
    18. #查看一下清理后的语料库文本
    19. inspect(sms_corpus[1])
  • 标记化:将文本分解成由单个单词组成的组,实际就是实现语料库向稀疏矩阵的转变 corpus_clean -> sms_dtm,建立训练集和测试集数据
    1. #将文本信息转化成DocumentTermMatrix类型的稀疏矩阵
    2. dtm <- DocumentTermMatrix(sms_corpus)
    3. Sys.setlocale(category = "LC_ALL", locale = "us")
    4.  
    5. #训练集和测试集数据,查看垃圾与正常邮件占比
    6. trainSet <- sms[1:4169,]
    7. testset <- sms[4170:5574,]
  • 创建可视化词云,通过词云可以大致浏览一下哪些词在spam中经常出现,哪些词在ham中经常出现。当然,前者对于垃圾短信的过滤相对重要一点。绘制词云可以通过添加包wordcloud实现  install.packages("wordcloud")
  • 为了查看spam和ham各自的多频词,首先取trainset的子集,如下:
    1. > #创建可视化词云,大致浏览一下哪些词在spam中经常出现
    2. > library(RColorBrewer)
    3. > library(wordcloud)
    4. > #取trainset对spam和ham的子集
    5. > spam <- subset(trainSet, type == "spam")
    6. > ham <- subset(trainSet, type == "ham")
    7. > #创建词云
    8. > wordcloud(spam$text, max.words=40, scale=c(3,0.5))
  • 显示结果如下:
  • 缩减特征:在面临问题是稀疏矩阵的特征太多了,而且很多词在所有text中可能都没怎么出现过,为减少运算量对特征瘦瘦身。先留下来在所有text中出现至少5次的词
    1. dtm_train <- dtm[1:4169,]
    2. > dtm_test <- dtm[4170:5574,]
    3. > findFreqTerms(dtm_train,5)
    4. [1] "available" "bugis" "cine" "crazy" "got" "great" "point" "wat"
    5. [9] "world" "lar" "wif" "apply" "comp" "cup" "entry" "final"
    6. [17] "free" "may" "receive" "text" "txt" "win" "wkly" "already"
    7. [25] "dun" "early" "say" "around" "goes" "nah" "think" "though"
    8. [33] "usf" "back" "freemsg" "fun" "hey" "like" "now" "send"
    9. [41] "std" "still" "weeks" "word" "xxx" "brother" "even" "speak"
    10. [49] "treat" "callers" "callertune" "copy" "friends" "melle" "per" "press"
    11. ........................
  • 将这些词设置成指示标识,下面建模时用这个指示标识提示模型只对这些词进行计算

    1. > #缩减特征
    2. > d <- findFreqTerms(dtm,5)
    3. > corpus_train = sms_corpus[1:4169]
    4. > corpus_test = sms_corpus[4170:5574]
    5. > dtm_train <- DocumentTermMatrix(corpus_train,list(dictionary=d))
    6. > dtm_test <- DocumentTermMatrix(corpus_test,list(dictionary=d))
  • train和test都是计数矩阵,如果一条text中某个单词出现2次,那么这个单词在这条文本下会被记上2,NB只想知道这个单词出现了或者没出现,因此需要对矩阵进行转化成因子矩阵。

    1. > #对矩阵进行转化成因子矩阵
    2. > convert_counts <- function(x){
    3. + x <- ifelse(x>0,1,0)
    4. + x <- factor(x, levels=c(0,1),labels=c("No","Yes"))
    5. + return(x)
    6. + }
    7. > dtm_train <- apply(dtm_train, MARGIN=2, convert_counts)
    8. > dtm_test <- apply(dtm_test, MARGIN=2, convert_counts)
  • 训练模型

    1. > #需要的包是e1071
    2. > #install.packages("e1071")
    3. > library(e1071)
    4. > sms_classifier <- naiveBayes(dtm_train,trainSet$type)
    5. > sms_prediction <- predict(sms_classifier, dtm_test)
    6. >
  • 评估模型: 用交叉表来看看test中多少预测对了

    1. > library(gmodels)
    2. > CrossTable(sms_prediction,testset$type,prop.chisq=TRUE,prop.t=FALSE, dnn=c("predicted","actual"))
    3.  
    4. Cell Contents
    5. |-------------------------|
    6. | N |
    7. | Chi-square contribution |
    8. | N / Row Total |
    9. | N / Col Total |
    10. |-------------------------|
    11.  
    12. Total Observations in Table: 1405
    13.  
    14. | actual
    15. predicted | ham | spam | Row Total |
    16. -------------|-----------|-----------|-----------|
    17. ham | 1124 | 150 | 1274 |
    18. | 0.229 | 1.531 | |
    19. | 0.882 | 0.118 | 0.907 |
    20. | 0.920 | 0.820 | |
    21. -------------|-----------|-----------|-----------|
    22. spam | 98 | 33 | 131 |
    23. | 2.229 | 14.886 | |
    24. | 0.748 | 0.252 | 0.093 |
    25. | 0.080 | 0.180 | |
    26. -------------|-----------|-----------|-----------|
    27. Column Total | 1222 | 183 | 1405 |
    28. | 0.870 | 0.130 | |
    29. -------------|-----------|-----------|-----------|
  • ham-ham和spam-spam是预测正确的,spam-ham:本身不是垃圾短信却被认为是垃圾短信过滤掉,由于Classifier1没有设置拉普拉斯估计,下面再尝试建立classifier2,看结果是否被优化。

    1. > #设置拉普拉斯估计
    2. > sms_classifier <- naiveBayes(dtm_train,trainSet$type,laplace = 1)
    3. > sms_prediction <- predict(sms_classifier, dtm_test)
    4. > CrossTable(sms_prediction,testset$type,prop.chisq=TRUE,prop.t=FALSE, dnn=c("predicted","actual"))
    5.  
    6. Cell Contents
    7. |-------------------------|
    8. | N |
    9. | Chi-square contribution |
    10. | N / Row Total |
    11. | N / Col Total |
    12. |-------------------------|
    13.  
    14. Total Observations in Table: 1405
    15.  
    16. | actual
    17. predicted | ham | spam | Row Total |
    18. -------------|-----------|-----------|-----------|
    19. ham | 1105 | 132 | 1237 |
    20. | 0.788 | 5.262 | |
    21. | 0.893 | 0.107 | 0.880 |
    22. | 0.904 | 0.721 | |
    23. -------------|-----------|-----------|-----------|
    24. spam | 117 | 51 | 168 |
    25. | 5.803 | 38.747 | |
    26. | 0.696 | 0.304 | 0.120 |
    27. | 0.096 | 0.279 | |
    28. -------------|-----------|-----------|-----------|
    29. Column Total | 1222 | 183 | 1405 |
    30. | 0.870 | 0.130 | |
    31. -------------|-----------|-----------|-----------|
  • spam人预测结果有改进,尝试继续优化,下一步以评论分类进行中文分类模拟

 iris分类预测


  • 安装加载包

    1. #安装加载e1071
    2. #install.packages("e1071")
    3. library(e1071)
  • iris数据集分为训练集和测试集
    1. index <-sample(1:nrow(iris), 100)
    2. iris.train <-iris[index, ]
    3. iris.test <-iris[-index, ]
  • 利用朴素贝叶斯算法构建模型
    1. model.NaiveBayes <-naiveBayes(x =subset(iris.train,select=-Species), y= iris.train$Species)
    2. str(model.NaiveBayes)
    3. summary(model.NaiveBayes)
  • 用模型对测试集做测试

    1. > results.NaiveBayes <-predict(object = model.NaiveBayes, newdata =iris.test, type="class")
    2. > table(results.NaiveBayes, iris.test$Species)
    3.  
    4. results.NaiveBayes setosa versicolor virginica
    5. setosa 14 0 0
    6. versicolor 0 17 2
    7. virginica 0 1 16

ML(4): NavieBayes在R中的应用的更多相关文章

  1. R中一切都是vector

    0.可以说R语言中一切结构体的基础是vector! R中一切都是vector,vecotor的每个component必须类型一致(character,numeric,integer....)!vect ...

  2. 简单介绍一下R中的几种统计分布及常用模型

    统计学上分布有很多,在R中基本都有描述.因能力有限,我们就挑选几个常用的.比较重要的简单介绍一下每种分布的定义,公式,以及在R中的展示. 统计分布每一种分布有四个函数:d――density(密度函数) ...

  3. R中的par()函数的参数

    把R中par()函数的主要参数整理了一下(另外本来还整理了每个参数的帮助文档中文解释,但是太长,就分类之后,整理为图表,excel不便放上来,就放了这些表的截图)

  4. 关于R中的mode()和class()的区别

    本文原创,转载请注明出处,本人Q1273314690(交流学习) 说明:本文曾经在15年11月在CSDN发过,但是由于CSDN不支持为知笔记的发布为博客的API功能,所以,自今天起,转移到博客园(幸好 ...

  5. R中的name命名系列函数总结

    本文原创,转载请注明出处,本人Q1273314690 R中关于给行列赋名称的函数有 dimnames,names,rowname,colname,row.names 这五个函数,初学的时候往往分不清楚 ...

  6. 总结——R中查看属性的函数

    本文原创,转载注明出处,本人Q1273314690 R中知道一个变量的主要内容和结构,对我们编写代码是很重要的,也可以帮我们避免很多错误. 但是,R中有好几个关于属性查看的函数,我们往往不知道什么时候 ...

  7. R中创建not-yet-evaluated对象

    create not-yet-evaluated object在R中创建 not-yet-evaluated(就是some code we will evaluated later!!)对象;然后执行 ...

  8. R中,去掉dataframe中的NA行

    R中使用complete.cases 和 na.omit来去掉包含NA的行 现在有个一data.frame  datafile如下所示 Date        sulfate nitrate ID 1 ...

  9. 机器学习:形如抛物线的散点图在python和R中的非线性回归拟合方法

    对于样本数据的散点图形如函数y=ax2+bx+c的图像的数据, 在python中的拟合过程为: ##最小二乘法 import numpy as np import scipy as sp import ...

随机推荐

  1. 微信小程序开发入门

    微信小程序 首先说下结构吧,看看小程序到底长什么样子 这是一个微信提供的自己的开发工具,相当于xcode吧,由此也可以看出腾讯的野心并不小啊,左边的就是编辑调试什么的,往右就是一个模拟器,你可以选择i ...

  2. mfc---添加背景图

    添加背景图: CDC m_dcMem CBitmap m_bmpMem CDC * pDC = GetDC(); m_dc.CreateComparableDC(pDC); m_bmpMem.Load ...

  3. 解决行内元素间隙bug问题

    行内元素之间会产生间隙bug问题的场景: 1.当行内元素之间有“回车”.“tab”.“空格”时就会出现间隙. 如下代码: <div>   <a>1</a>   &l ...

  4. 一篇文章为你深度解析HTTPS 协议

    一.前言 微信小程序如期发布,开发者在接入微信小程序过程中,会遇到以下问题: 小程序要求必须通过 HTTPS 完成与服务端通信,若开发者选择自行搭建 HTTPS 服务,那需要自行 SSL 证书申请.部 ...

  5. Caffe学习系列(一)Ubuntu16.04下搭建编译Caffe环境,并运行MNIST示例(仅CPU)

    前言: 正文: 1.安装必要依赖包: sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev l ...

  6. 调试时a标签禁止跳转方法

    a.setAttribute("onclick",'');

  7. 使用es6特性封装async-mysql

    node.js的mysql模块本身没有提供返回promise的函数,即是说都是用的回调函数,那么对于我们使用async函数是很不方便的一件事.node.js有一个mysql封装库叫mysql-prom ...

  8. 3555: [Ctsc2014]企鹅QQ

    3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 696  Solved: 294[Submit][Status ...

  9. 算法模板——Tarjan强连通分量

    功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量 原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点 这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有 ...

  10. [Spark] - SparkCore程序优化总结

    http://spark.apache.org/docs/1.6.1/tuning.html1) 代码优化 a. 对于多次使用的RDD,进行数据持久化操作(eg: cache.persist) b. ...