library(NLP)
library(tm)
library(wordcloud)
library(RColorBrewer)
library(e1071)
library(gmodels)
setwd('C:/Users/E0399448/Desktop/机器学习')
###spam 垃圾短信 ham非垃圾短信
###数据地址:https://github.com/stedy/Machine-Learning-with-R-datasets/commit/72e6b6cc91bc2bb08eb6f99f52c033677cb70c1a
###选择 sms_spam.csv 这个表格
sms_raw <- read.csv("sms_spam.csv",header=TRUE,stringsAsFactors=FALSE)
#str(sms_raw)查看数据结构
sms_raw$type <- factor(sms_raw$type) ####将type设为因子变量
table(sms_raw$type)#产看每个类型的数量
prop.table(table(sms_raw$type))#查看每个类型的占的百分比
######################数据清洗
#1. 创建语料库corpus 只收集test短信内容 为list格式 sms_corpus[[1]]$content
sms_corpus <- Corpus(VectorSource(sms_raw$text))
#2.清理语料库
#2.1 # 所有字母转换成小写
corpus_clean <- tm_map(sms_corpus, tolower)
# 2.2去除text中的数字
corpus_clean <- tm_map(corpus_clean, removeNumbers)
# 2.3去除停用词,例如and,or,until...
corpus_clean <- tm_map(corpus_clean, removeWords, stopwords())
# 2.4去除标点符号
corpus_clean <- tm_map(corpus_clean, removePunctuation)
# 2.5去除多余的空格,使单词之间只保留一个空格
corpus_clean <- tm_map(corpus_clean, stripWhitespace)
###see effect
#inspect(corpus_clean[1:3])
##在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
#2.6 将文本信息转化成DocumentTermMatrix类型的稀疏矩阵 把所有单词转化成0/1/2/34zhiou ,每一条短信百变成单独的文件,terms为所有单词的总数,ncols, nrows为文件总数也就是相当于短信的数量
sms_dtm <- DocumentTermMatrix(corpus_clean)
#
#corpus_clean <- tm_map(corpus_clean, PlainTextDocument) ###下一句出错了用的转格式先
############################数据清理完毕####################
#1. 数据准备——建立train set & test set
#1.1 # split sms_raw
sms_raw_train <- sms_raw[1:4169,]
sms_raw_test <- sms_raw[4170:5574,]
#1.2 #split sms_dtm
sms_dtm_train <- sms_dtm[1:4169,]
sms_dtm_test <- sms_dtm[4170:5574,]
#split corpus_clean
sms_corpus_train <- corpus_clean[1:4169]
sms_corpus_test <- corpus_clean[4170:5574]
####################
#####分别取取垃圾spam短信种类和ham-非垃圾种类短信
spam <- subset(sms_raw_train, type == "spam")
ham <- subset(sms_raw_train, type == "ham")
####查看垃圾短信的最多出现的词语,可视化!!!!!!!!!!!!!!!!
wordcloud(spam$text, max.words=40, scale=c(3,0.5)) ####
####查看非垃圾短信的最多出现的词语,可视化!!!!!!!!!!!!!!!!
wordcloud(ham$text,max.words=40,scale=c(3,0.5))
#########################减少词儿特征#############################
##1.找出出现过5次以上的词语
findFreqTerms(sms_dtm_train,5)
#2.将这些词设置成指示标识,下面建模时用这个指示标识提示模型只对这些词进行计算
#sms_dict <- Dictionary(findFreqTerms(sms_dtm_train,5))
####2.1· 先改文本格式
myfindFreqTerms <- function(x,lowfreq=0,highfreq=Inf){
stopifnot(inherits(x,c("DocumentTermMatrix","TermDocumentMatrix")),
is.numeric(lowfreq),is.numeric(highfreq))
if(inherits(x,"DocumentTermMatrix"))
x<-t(x)
rs <- slam::row_sums(x)
y <- which(rs >= lowfreq & rs<= highfreq)
return(x[y,])
}
###2.2 dictionary 化 把出现过5次以上的词单独组成一个元素
sms_dict <- Terms(myfindFreqTerms(sms_dtm_train,5))
#继续稀疏矩阵 nols
sms_train <- DocumentTermMatrix(sms_corpus_train,list(dictionary=sms_dict))
sms_test <- DocumentTermMatrix(sms_corpus_test, list(dictionary=sms_dict))
#####有的单词在同一条会出现多次,转化为某单词是否出现
convert_counts <- function(x){
x <- ifelse(x>0,1,0)
x <- factor(x, levels=c(0,1),labels=c("No","Yes"))
return(x)
}
###change to table of one document has the words or not format 转为每条信息是否出现某单词的表格i形式
sms_train <- apply(sms_train, MARGIN=2, convert_counts)
sms_test <- apply(sms_test, MARGIN=2, convert_counts)
##################################开始训练模型###############################
#1.建立NaiveBayesClassifier 建立模型
sms_classifier <- naiveBayes(sms_train,sms_raw_train$type)
#2.测试Classifier 预测test信息的判断是否是垃圾短信
sms_prediction <- predict(sms_classifier, sms_test)
##################################开始评估模型是否标准 看对比情况###############################
CrossTable(sms_prediction,sms_raw_test$type,prop.chisq=TRUE,prop.t=FALSE,
dnn=c("predicted","actual"))
##################################优化模型laplace添加 改lapplace的值进行优化,1或者0.5或者其他的###############################
sms_classifier2 <- naiveBayes(sms_train,sms_raw_train$type,laplace=0.5)
sms_predictions2<- predict(sms_classifier2,sms_test)
CrossTable(sms_predictions2,sms_raw_test$type,prop.chisq = FALSE,prop.r = FALSE,dnn=c('predicted','actual'))