邮件过滤及排序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、构建一个判定邮件是否是垃圾邮件的系统,利用SpamAssassin的公开语料库,可以在
http:///publiccorpus/免费下载。根据邮件内容提取相应的特征词,依据特征次将邮件标注为垃圾或非垃圾邮件,特征词的提取可以根据内容、收发邮件的联系人等,这里我们根据内容。在这过程中需要相应的文本处理包(tm)。我们根据条件概率(bayes)将上述提取的特征词转化为相应的概率,从而分类。在这个过程中我们会遇到关于特征词提取,概率计算的问题,模型训练和测试,在贝叶斯中先验概率的选取,先验概率的选取可以通过正则化进行,将结果可视化等
2、加载相应的包和设置工作路径
library('tm') ##文本处理
library('ggplot2') ##作图
下面有两套文件在相应的文件夹中,一套用来训练分类器,一套用来测试分类器,有三类邮件:易识别的正常邮件、不易识别的正常邮件、垃圾邮件。
spam.path <- file.path("D:/R","spam")
spam2.path <- file.path("D:/R","spam_2")
easyham.path <- file.path("D:/R","easy_ham")
easyham2.path <- file.path("D:/R","easy_ham_2")
hardham.path <- file.path("D:/R","hard_ham")
hardham2.path <- file.path("D:/R","hard_ham_2")
设置好路径后,编写函数,构建邮件的特征词项类别知识库,打开每一个文件找到空行,将空行之后的文本返回为一个字符串向量。
get.msg <- function(path)
{
con <- file(path, open = "rt", encoding = "latin1")
text <- readLines(con)
# The message always begins after the first full line break
msg <- text[] ## msg <- text[seq(which(text == " ")[1] + 1, length(text), 1)]
close(con)
return(paste(msg, collapse = "\n"))
}
以垃圾邮件为例,先得到垃圾邮件的文件列表,在列表中剔除cmds的文件,它们是unix 的基本命令表,然后用上述函数得到垃圾邮件的文本向量
spam.docs <- dir(spam.path) ##获得路劲下的文件名
spam.docs <- spam.docs[which(spam.docs != "cmds")] ##得到垃圾邮件名称
all.spam <- sapply(spam.docs,
function(p) get.msg(file.path(spam.path,p))) ##得到文本向量利用tm包的函数,将得到的文本向量转化为TDM矩阵(词项-----------文档矩阵)([i,j]表示词项i在文档j中出现的次数),得到下述函数,注意TermDocumentMatrix函数对变量的要求,注意下面参数控制的含义。
get.tdm <- function(doc.vec)
{
control <- list(stopwords = TRUE,
removePunctuation = TRUE,
removeNumbers = TRUE,
minDocFreq = 2)
doc.corpus <- Corpus(VectorSource(doc.vec))
doc.dtm <- TermDocumentMatrix(doc.corpus, control)
return(doc.dtm)
}
spam.tdm<-get.tdm(all.spam) ####得到垃圾邮件的词项-----------文档矩阵
str(spam.tdm)
构造分类器数据矩阵,将上述的词项-----------文档矩阵构造成一个数据框来保存所有特征词在垃圾邮件中的条件概率,根据多少邮件包含这个特征词项来定义一封邮件是垃圾邮件的条件概率。
spam.matrix <- as.matrix(spam.tdm) ###标准化为矩阵形式
head(spam.matrix)
dim(spam.matrix)
spam.matrix[2,c(2,2)]
colnames(spam.matrix)
spam.counts <- rowSums(spam.matrix) ###每个特征在所有文本中出现的次数
spam.df <- data.frame(cbind(names(spam.counts),
as.numeric(spam.counts)),
stringsAsFactors = FALSE) ##构造词项————频数矩阵names(spam.df) <- c("term", "frequency")
head(spam.df)
dim(spam.df)
spam.df$frequency <- as.numeric(spam.df$frequency)
spam.occurrence <- sapply(1:nrow(spam.matrix),
function(i)
{
length(which(spam.matrix[i, ] > 0)) / ncol(spam.matrix)
}) ##计算一个特征词项出现的文档在所有文档中所占比例spam.density <- spam.df$frequency / sum(spam.df$frequency) #计算比例从来当作特征
词的概率# Add the term density and occurrence rate
spam.df <- transform(spam.df,
density = spam.density,
occurrence = spam.occurrence)
head(spam.df[with(spam.df,order(-occurrence)),]) (这里得到的是垃圾邮件的训练数据)
用易识别的正常邮件来构建训练数据,我们用easy_ham中的前500封来构造训练数据。和上述方法相同。
easyham.docs <- dir(easyham.path)
easyham.docs <- easyham.docs[which(easyham.docs != "cmds")]