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

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972

   个人介绍: 研一|统计学|干货分享
         擅长Python、Matlab、R等主流编程软件
         累计十余项国家级比赛奖项,参与研究经费10w、40w级横向

1 目的

   我们的目标是利用机器学习技术,根据样本的特征来有效地过滤和识别垃圾信息。通过训练机器学习模型,我们可以使其学会区分正常信息和垃圾信息的特征,从而自动过滤掉不需要的、无用的或有害的信息,提高信息处理的效率和准确性。这将有助于减少信息过载和提高用户体验,特别是在处理大量信息的场景中,如电子邮件、社交媒体和在线论坛等。通过不断优化模型和提高过滤准确率,我们可以为用户提供更加智能、高效和个性化的信息服务。

2 数据来源

  该演示数据来源于: 机器学习和智能系统中心

3 案例演示

3.1 探索数据

3.1.1 读取数据并查看数据类型

   运行代码:

1.	data<-read.csv("G:\\sms_spam.csv",stringsAsFactors = F)  
2.	str(data) 

   结果展示:

> str(data)
'data.frame':	5559 obs. of  2 variables:
 $ type: chr  "ham" "ham" "ham" "spam" ...
 $ text: chr  "Hope you are having a good week. Just checking in" "K..give back my thanks." "Am also doing in cbe only. But have to pay." "complimentary 4 STAR Ibiza Holiday or £10,000 cash needs your URGENT collection. 09066364349 NOW from Landline"| __truncated__ ...
    通过运行结果我们可以发现type是字符向量,需要利用将其转化为因子。

3.1.2 修改数据格式

   运行代码:

1.	data$type<-factor(data$type)  
2.	str(data$type)  
3.	table(data$type)  

   结果展示:

> str(data$type)
 Factor w/ 2 levels "ham","spam": 1 1 1 2 2 1 1 1 2 1 ...
> table(data$type)

 ham spam 
4812  747 

  由运行结果我们可以观察到,type的数据类型已转为为因子,并且案例中垃圾信息、非来及信息数量分别为747,4812。

3.2 数据预处理

3.2.1 清理和标准化数据

1)加载包及语料库创建
  运行代码:

1.	library("NLP")  #加载包  
2.	library("tm")   #加载包  
3.	data2<-VCorpus(VectorSource(data$text))  #创建语料库  
4.	print(data2)        #打印语料库信息  

  结果展示:

<<VCorpus>>
Metadata:  corpus specific: 0, document level (indexed): 0
Content:  documents: 5559

  由运行结果显示,新建语料库包含训练数据中5559条短信的每一条短信文档。

2)前两条短信信息概要查看

  运行代码:

1.	lapply(data2[1:2],as.character)

  结果展示:

$`1`
[1] "Hope you are having a good week. Just checking in"

$`2`
[1] "K..give back my thanks."

  我们可以通过语料库信息查看每条短信文本信息,需要将这些短信划分为单个单词。

3)单词书写规范
  
运行代码:

1.	data2_clearn<-tm_map(data2,content_transformer(tolower))  
2.	#清理后文本信息(删除标点影响或其他影响字符并返回小写)  
3.	as.character(data2[[1]])  
4.	as.character(data2_clearn[[1]])  
5.	#对比清理前后数据效果  

  结果展示:

> as.character(data2[[1]])
[1] "Hope you are having a good week. Just checking in"
> as.character(data2_clearn[[1]])
[1] "hope you are having a good week. just checking in"

  通过运行结果显示,我们已使用小写字母字符标准化单词。

4)去除文本多余标点及停用词
   运行代码:

1.	data2_clearn2<-tm_map(data2_clearn,removeNumbers)  #去除文本信息中的数字  
2.	data2_clearn3<-tm_map(data2_clearn2,removeWords,stopwords()) #去除文本信息中的停用词  
3.	data2_clearn4<-tm_map(data2_clearn3,removePunctuation)
4.	 #去除文本信息中的标点符号  
5.	removePunctuation("hello...world")  #查看removePunctuation函数效果  

  结果展示:

[1] "helloworld"

   通过运行结果,我们可以发现removePunctuation的函数效果,去除了多余标点符号。

5)提取文本词干及去除多余空格

  运行代码:

1.	library("SnowballC")    #加载包  
2.	wordStem(c("learning","learn","learned","learns"))#词干提取法测试效果  
3.	data2_clearn5<-tm_map(data2_clearn4,stemDocument) #提取文本词干内容  
4.	data2_clearn6<-tm_map(data2_clearn5,stripWhitespace)#去除多余空格  
5.	lapply(data2[1:3],as.character)   
6.	lapply(data2_clearn6[1:3],as.character)   

  结果展示:

$`1`
[1] "Hope you are having a good week. Just checking in"

$`2`
[1] "K..give back my thanks."

$`3`
[1] "Am also doing in cbe only. But have to pay."

> lapply(data2_clearn6[1:3],as.character) 
$`1`
[1] "hope good week just check"

$`2`
[1] "kgive back thank"

$`3`
[1] "also cbe pay"

  前三条信息是处理前信息,后三条信息为标准化单词后信息内容。

3.2.2 将文本文档拆分成词语

   运行代码:

1.	data3<-DocumentTermMatrix(data2_clearn6) #将数据转化为单词矩阵(DTM稀疏矩阵)  
2.	data3  #信息概要  

  结果展示:

> data3  #信息概要
<<DocumentTermMatrix (documents: 5559, terms: 6553)>>
Non-/sparse entries: 42135/36385992
Sparsity           : 100%
Maximal term length: 40
Weighting          : term frequency (tf)

  为了将消息拆分为由单个单词组成的组,我们创建DTM稀疏矩阵。

3.2.3 建立训练数据集和测试数据集

   运行代码:

1.	data3_train<-data3[1:4169,] #创建训练集  
2.	data3_test<-data3[4170:5559,]  #创建测试集  
3.	data3_train_labels<-data[1:4169,]$type #提取训练集标签  
4.	data3_test_labels<-data[4170:5559,]$type #提取测试集标签  
5.	prop.table(table(data3_train_labels)) #训练集垃圾信息比例  
6.	prop.table(table(data3_test_labels))#测试集垃圾信息比例 

  结果展示:

> prop.table(table(data3_train_labels)) #训练集垃圾信息比例
data3_train_labels
      ham      spam 
0.8647158 0.1352842 
> prop.table(table(data3_test_labels))#测试集垃圾信息比例
data3_test_labels
      ham      spam 
0.8683453 0.1316547 

  可以看到,训练集和测试集的垃圾信息数量大约含13%,说明垃圾信息被平均分配在两个数据集。

3.2.4 词云图

1)所有邮件信息词云

  运行代码:

1.	library("RColorBrewer")  
2.	library("wordcloud")  
3.	wordcloud(data2_clearn6,min.freq = 50,random.order = F) #数据处理后词云图  

  结果展示:
在这里插入图片描述
  由运行结果显示:数据处理后call、now、get、can等单词出现频率相对较高。

2)垃圾/非垃圾信息词云

  运行代码:

1.	spam<-subset(data,type=="spam")      #提取垃圾信息  
2.	ham<-subset(data,type=="ham")       #提取非垃圾信息  
3.	wordcloud(spam$text,max.words = 40,scale = c(3,0.5)) #垃圾信息词云图  
4.	wordcloud(ham$text,max.words = 40,scale = c(3,0.5)) #非垃圾信息词云图  

  结果展示:
在这里插入图片描述

垃圾信息词云图

在这里插入图片描述

非垃圾信息词云图
  由运行结果显示:数据处理后call、now、can等单词出现频率相对较高,通过对垃圾信息及非垃圾信息词云图我们可以看出,垃圾信息中多包含mobile、free,非垃圾信息多包含just、can等单词。

3.2.5 为频繁出现的单词创建指示特征

1)取训练集中出现5次的单词
  运行代码:

1.	data3_freq_words<-findFreqTerms(data3_train,5)  #取训练集中出现5次的单词  
2.	str(data3_freq_words)  

  结果展示:

> str(data3_freq_words)
 chr [1:1137] "£wk" "abiola" "abl" "abt" "accept" "access" "account" "across" "act" "activ" ...

  由运行结果显示,有1137个的单词至少出现了5次。

2)提取单词特征

  运行代码:

1.	data3_freq_train<-data3_train[,data3_freq_words]  
2.	data3_freq_test<-data3_test[,data3_freq_words]  #提取频繁包含频繁出现的词  
3.	covert_counts<-function(x){  
4.	  x<-ifelse(x>0,"Yes","No")  
5.	}        #创建函数,将计数转化为字符串Yes或No  
6.	data3_train1<-apply(data3_freq_train,MARGIN =2,covert_counts)  
7.	data3_test1<-apply(data3_freq_test,MARGIN =2,covert_counts)#转化稀疏矩阵数据形式  

  我们已经过滤DTM,将训练集、测试集设置仅包含出现至少5个单词的特征,并用Yes和No替代稀疏矩阵中的数值。

4 模型建立及优化

4.1 基于数据训练模型

   运行代码:

1.	library("e1071")      #加载包  
2.	data_classifier<-naiveBayes(data3_train1,data3_train_labels) #创建分类器    

  我们已经成功创建贝叶斯分类器。

4.2 评估模型性能

  运行代码:

1.	library("e1071")      #加载包  
2.	data_classifier<-naiveBayes(data3_train1,data3_train_labels) #创建分类器  
3.	data_pred<-predict(data_classifier,data3_test1) #预测测试集  
4.	library("gmodels") #加载包  
5.	CrossTable(data_pred,data3_test_labels,  
6.	           prop.chisq = F,  
7.	           prop.t = F,  
8.	           dnn=c("predicted","actual"))  #测试集预测结果  

   结果展示:

actual
predictedhamspamRow Total
ham1201301231
0.9760.0240.886
0.9950.164
spam6153159
0.0380.9620.114
0.0050.836
Column Total12071831390
0.8680.132

  由运行结果显示可以知道,共有36条信息未被正确分类,分类器正确率为97.4%。

4.3 提高模型性能

  我们将像之前所做的那样建立朴素贝叶斯模型,但这次我们设置1aplace=1。
  运行代码:

1.	data_classifier<-naiveBayes(data3_train1,data3_train_labels,1aplace=1) #创建分类器  
2.	data_pred<-predict(data_classifier,data3_test1) #预测测试集  
3.	CrossTable(data_pred,data3_test_labels,  
4.	           prop.chisq = F,  
5.	           prop.t = F,  
6.	           dnn=c("predicted","actual"))  #测试集预测结果  

  结果展示:

actual
predictedhamspamRow Total
ham1202281230
0.9770.0230.885
0.9960.153
spam5155160
0.0310.9690.115
0.0040.847
Column Total12071831390
0.8680.132

  由运行结果显示可以知道,共有33条信息未被正确分类,分类器正确率为97.6%。利用拉普拉斯估计优化分类器后,分类器预测正确率被得以提升。

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值