贝叶斯邮件分类c语言,朴素贝叶斯在邮件分类的应用及其实现

前文介绍了朴素贝叶斯的简单原理及实现,本文则介绍了其在邮件分类中的简单应用。

原理:将邮件正文分词去处停义词后,统计词在在正常及非正常情况下的频数。最终根据贝叶斯定理推断出在指定词下分为正常和非正常的概率,如果P(T)>P(F)且P(T)小于0.8(该阀值可以自己设定),则在判别为正常邮件的同时,需要将该正文写入到正常训练表。同理,如果​P(T)<P(F)且P(F)小于0.9(该阀值可以自己设定),也需要将该正文写入到错误训练表。当训练表新增了n份记录时,需要重新训练模型,训练表只保存m份最新记录。通过该方法,则能保证贝叶斯分类器在随着变化而不断更新,处于自我的不断学习。

源码:分为2个,Mail_Bayes_1.R:贝叶斯分类器的生成。

​Mail_Bayes_2.R:贝叶斯分类器的实际调用。

​Mail_Bayes_1.R

#邮件识别 利用分词 和贝叶斯的方法

setwd("/home/r/work/mail")

library(rJava)

library(Rwordseg)

#增加停用词

stop_word

readLines("../stop_word.dat")

insertWords(stop_word)

library(RMySQL)

library(plyr)

conn

"test",

username="××××",

password="",

host="127.0.0.1",

port=3306)

dbSendQuery(conn,'SET NAMES utf8')

corpus_data

flg, text from bad_mail")

# 分词去处停用词

segmentCN1

temp

segmentCN(string)

temp[! temp %in% stop_word]

}

#计算邮件在不同类型下的频数

BayesTrainMail

function(corpus_data){

temp

table(corpus_data$flg)

temp

as.data.frame(temp)

names(temp)

"freq")

temp$ratio

temp$freq/sum(temp$freq)

temp

}

#计算各个词在不同类型下的频数

BayesTrainWord

function(corpus_data){

flg

unique(corpus_data$flg)

temp

function(x){ unlist(sapply(subset(corpus_data, flg==x)$text,

segmentCN1))})

flg

unlist(sapply(names(temp), function(x){ rep(x,

length(temp[[x]]))}))

word

unlist(sapply(names(temp), function(x){ temp[[x]]}))

names(flg)

NULL

names(word)

NULL

train_data

data.frame(flg, word, stringsAsFactors = F)

train_data

ddply(train_data, .(flg, word), summarize,

freq=length(word))

train_data

}

train_data_mail

BayesTrainMail(corpus_data)

train_data_word

BayesTrainWord(corpus_data)

BayesClassify

function(test_data){

test_word

unique(unlist(segmentCN1(test_data)))

#计算每个词的条件概率 默认都加1 防止未出现

freq

unlist(sapply(train_data_mail$flg, function(y){

sapply(test_word,

function(x){ifelse(length(subset(train_data_word,

word==x&flg==y)$freq)==0,

1, subset(train_data_word,

word==x&flg==y)$freq+1)})}))

colnames(freq)

train_data_mail$flg

p_prob1

sapply(colnames(freq), function(x){ prod(freq[,

x])/(sum(subset(train_data_word, flg==x)$freq)+

sum(train_data_word$freq))})

# 连乘条件概率后再乘以总的类别概率

p_prob

sapply(names(p_prob1),

function(x){p_prob1[x]*subset(train_data_mail,

flg==x)$ratio})

names(p_prob)

p_prob

p_prob/(sum(p_prob))

p_prob

}

Mail_Bayes_2.R

​​setwd("/home/r/work/mail")

library(rJava)

library(Rwordseg)

#增加停用词

stop_word

readLines("../stop_word.dat")

insertWords(stop_word)

library(RMySQL)

library(plyr)

conn

"test",

username="×××",

password="",

host="127.0.0.1",

port=3306)

dbSendQuery(conn,'SET NAMES utf8')

source("./Mail_Bayes_1.R")

#邮件分类默认存放位置

write.table(data.frame("mail", "flg",

"time"),

file="./mail_result.dat", sep="---", row.names=F,

col.names=F)

#默认计数 如果基础词义库新增记录达到50条 重新训练模型

num  

# 实际应用中  初始的词义库是不够全的

需要模型的继续学习 基础词义库只保留100条记录,按插入时间先后来删除历史

# 对于P(N) >

P(Y)但是P(N)<0.8的mail 将其扔入基础词义库训练

# 对于P(N) <

P(Y)但是P(Y)<0.9的mail 将其扔入基础词义库训练

Classify

prob

BayesClassify(test_data$word)

if(prob["N"]>prob["Y"]){

write.table(data.frame(mail=test_data$num, flg="正常邮件",

time=as.character(Sys.time())),

file="./mail_result.dat",

sep="---", row.names=F, append=T, col.names=F)

if(prob["N"]<0.8){

cnt

bad_mail where flg='N'")

if(cnt$cnt==100){

dbSendQuery(conn, "delete  from

bad_mail where flg='N' and insert_time in ( select min(insert_time)

from bad_mail where flg='N')")

dbCommit(conn)

}

dbSendQuery(conn, paste(paste("insert into bad_mail values('N ",

gsub("'", "", test_data$word),

as.character(Sys.time()),

sep="','"), "')", sep=""))

dbCommit(conn)

num <

}

}else{

write.table(data.frame(mail=test_data$num, flg="垃圾邮件",

time=as.character(Sys.time())),

file="./mail_result.dat",

sep="---", row.names=F, append=T, col.names=F)

if(prob["Y"]<0.9){

cnt

bad_mail where flg='Y'")

if(cnt$cnt==100){

dbSendQuery(conn, "delete  from

bad_mail where flg='Y' and insert_time in ( select min(insert_time)

from bad_mail where flg='Y')")

dbCommit(conn)

}

dbSendQuery(conn, paste(paste("insert into bad_mail values('Y ",

gsub("'", "", test_data$word),

as.character(Sys.time()),

sep="','"), "')", sep=""))

dbCommit(conn)

num <

}

}

#新增记录大于预设值

重新训练模型

if(num>=50){

write.table(data.frame(mail="开始训练模型", flg="训练模型",

time=as.character(Sys.time())),

file="./mail_result.dat",

sep="---", row.names=F, append=T, col.names=F)

corpus_data

bad_mail")

train_data_mail

<

BayesTrainMail(corpus_data)

train_data_word

<

num

<

write.table(data.frame(mail="结束训练模型", flg="训练模型",

time=as.character(Sys.time())),

file="./mail_result.dat",

sep="---", row.names=F, append=T, col.names=F)

}

}

​总结:此处只是朴素贝叶斯分类器在分类中的简单实现,实际应用中需要添加和业务相关的限制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值