贝叶斯算法:垃圾邮件过滤
准备
100封邮件,50封垃圾邮件和50封正常邮件
参考 :
贝叶斯算法原理
程序过程解释
垃圾邮件分类的数学基础是贝叶斯推断(bayesian inference)。整个程序过程主要有以下几个部分构成:
step 1 : 提取邮件并处理
1、使用 TDirectory.GetFiles(xPath) 获得 xPath 指示的文件夹下的所有文件的路径。
2、用 TStringList 根据路径读取文件内容。
3、使用 Split 方法将TStringList读取的内容以空格和“#13”分割开,并将所有单词放入数组中。
以上三个步骤全部包含在 getEmail(emailClass) 函数 和 processEmail(emailpath) 函数中。
step 2 : 获得在 normal 和 junk中每个单词的频数
这个步骤在代码中只是一个函数 getWordFrequency(emailClass) 。emailClass 表示邮件类别,即 normal 或者 junk 。返回的是一个字典,字典的 key值是单词,value值是这个单词的频数。
注意,这里的频数并不是指这个单词出现了多少次,而是指这个单词在多少封邮件当中出现过。例如:一个单词 sex 出现在3封邮件中,分别出现了5次,6次,4次,则这个单词 sex 的频数我们这里确定为3(因为它出现在3封邮件中),而不是 5 + 6+ 4 = 15 。
step 3 : 计算每个单词的后验概率
这一段代码包含在(某种意义上的)“主函数”当中 :
1、通过step 1和 step 2定义的函数取得 normal 和 junk 中每个单词的频数;
2、创建单词的先验概率字典 GPosteriorProbabilityDict ,并初始化每一个单词的先验概率为0.00;
3、使用 for...in... 循环得到每个单词的先验概率:
P(S|W) = P(W|S)P(S) / P(W|S)P(S) + P(W|H)P(H)
因为 normal 和 junk 的邮件数量相同,所以其先验概率 P(S) 和 P(H) 是相同的,均为 50%, 所以公式简化为 :
P(S|W) = P(W|S) / P(W|S) + P(W|H)
在代码中 P(W|S) 用 xJunkPro 变量表示, P(W|H)用 xNormalPro 表示。
如果当前单词在某个类别当中没有出现过,则可规定这个单词在这个类别中的后验概率是 0.01。
step 4 : 分类函数
这步骤主要体现在 testEmail(emailpath, threshold = 0.7) 函数中。email 参数表示email文件, threshold参数表示阀值,当计算得到的结果大于threshold时表示这是一封垃圾邮件(junk), 否则这是一封正常邮件(normal), 这里默认 threshold = 0.7。
对于给定的测试email,计算过程如下 :
1、使用 processEmail() 函数处理得到这封email的单词集合xWordArr 。
2、将这封邮件中每个单词和它的后验概率放入数组 xPosteriorProbabilityArr 中 ,如果这个单词在字典 GPosteriorProbabilityDict 中并没有出现过,则指定其值为 0.4。
3、按照每个单词的概率值从小到大排序。
4、最后,计算联合概率。这里只取出先验概率最大的前15个词计算联合概率,公式为:
这里 用 变量xFracTop 在for...in...循环中累乘表示, 用变量xFracBottom累乘表示 。
6、返回判定结果,如果xFracTop / (xFracTop + xFracBottom) 的值大于阀值threshold则判定为junk, 否则判定为 normal 。
step 5 : 准备工作完成,开始测试
对新收到的邮件进行测试,将收到的邮件存为txt文件,把路径赋给testEmail()函数中进行测试。然后,就等待判定结果。
完整代码
uses System.Generics.Collections ,System.Generics.Defaults;
type
TArrayB = array of TArray<string> ;
# step 1 : get E-mail and process them
class function TJunkBayes.processEmail(emailpath: string): TArray<string> ;
var
xWordLst: TStringList ;
xWordArr: TArray<string> ;
const xSep: array[0..1] of string = (' ' ,#13);
begin
xWordLst := TStringList.Create ;
xWordLst.LoadFromFile(emailpath) ;
xWordArr := xWordLst.Text.Split(xSep) ;
Result := xWordArr ;
end;
class function TJunkBayes.getEmail(emailClass: string): TArrayB ;
var
xPath: string ;
I : Integer ;
xFileArr: TArray<string> ;
xEmailArr : TArrayB ;
xLen: Integer ;
begin
xPath := g_BayesPath + '\' + emailClass ;
xFileArr := TDirectory.GetFiles(xPath) ;
xLen := Length(xFileArr) ;
SetLength(xEmailArr ,xLen);
for I := Low(xFileArr) to High(xFileArr) do
begin
xEmailArr[I] := processEmail(xFileArr[I]) ;
end;
Result := xEmailArr ;
end;
# step 2 : get word frequency of the email's class
class function TJunkBayes.getWordFrequency(emailClass: string): TDictionary<string,Integer> ;
var
xWordFrequencyDict : TDictionary<string ,Integer> ;
xEmailArr: TArrayB ;
I ,k: Integer;
xWord : string ;
xWordLst: TStringList ;
begin
xEmailArr := getEmail(emailClass) ;
xWord := '';
xWordLst := TStringList.Create ;
xWordFrequencyDict := TDictionary<string,Integer>.Create();
for I := Low(xEmailArr) to High(xEmailArr) do //遍历每封邮件
begin
xWordLst.Clear ;
for k := Low(xEmailArr[I]) to High(xEmailArr[I]) do //遍历一封邮件里的内容
begin
xWord := Trim(LowerCase(xEmailArr[I][k])) ;
if xWord = '' then Continue ;
if xWordLst.IndexOf(xWord) = -1 then
xWordLst.Add(xWord) ;
end;
for k := 0 to xWordLst.Count - 1 do
begin
xWord := xWordLst[k] ;
try
xWordFrequencyDict.Items[xWord] := xWordFrequencyDict.Items[xWord] + 1 ;
except
xWordFrequencyDict.Add(xWord ,1) ;
end;
end;
end;
Result := xWordFrequencyDict ;
end;
# step 4 : calculate classified result of test email
class function TJunkBayes.TestEmail(emailpath: string ;Threshold: Double) : Boolean ;
var
xWordArr: TArray<string> ;
xWord : string ;
xProbability : Double ;
xPosteriorProbabilityArr: array of Double ;
xCount: Integer ;
I : Integer ;
xFracTop,xFracBottom : Double ;
begin
Result := False ;
xWordArr := processEmail(emailpath) ;
SetLength(xPosteriorProbabilityArr ,Length(xWordArr));
xCount := 0 ;
for xWord in xWordArr do
begin
try
xProbability := GPosteriorProbabilityDict[xWord] ;
except //当这个单词不存在时
xProbability := 0.4 ;
end;
xPosteriorProbabilityArr[xCount] := xProbability ;
xCount := xCount + 1;
end;
TArray.Sort<Double>(xPosteriorProbabilityArr); //从小到大排序
xFracTop := 1 ;
xFracBottom := 1 ;
for I := High(xPosteriorProbabilityArr) downto Length(xPosteriorProbabilityArr) - 15 do
begin
xFracTop := xFracTop * xPosteriorProbabilityArr[I] ;
xFracBottom := xFracBottom * (1 - xPosteriorProbabilityArr[I]) ;
end;
if (xFracTop / (xFracTop + xFracBottom) > Threshold) then
Result := True
else
Result := False ;
end;
#step 3: calculate posterior probability
class procedure TJunkBayes.CalculateWordPosteriorProbability ;
var
xNormalDict: TDictionary<string ,Integer> ;
xJunkDict: TDictionary<string ,Integer> ;
xNormalEmailCount ,xJunkEmailCount: Integer ;
xWord : string ;
I: Integer;
xNormalPro ,xJunkPro : Double ;
begin
xNormalEmailCount := Length(TDirectory.GetFiles(g_BayesPathNormal)) ;
xJunkEmailCount := Length(TDirectory.GetFiles(g_BayesPathJunk)) ;
GPosteriorProbabilityDict := TDictionary<string ,Double>.Create() ;
//正常邮件集 里所有的单词和频数
xNormalDict := getWordFrequency('NormalBayes') ;
//垃圾邮件集里所有的单词和频数
xJunkDict := getWordFrequency('JunkBayes') ;
for xWord in xNormalDict.Keys do
begin
GPosteriorProbabilityDict.Add(xWord ,0);
end;
for xWord in xJunkDict.Keys do
begin
try
GPosteriorProbabilityDict.Add(xWord ,0);
except
end;
end;
for xWord in GPosteriorProbabilityDict.Keys do
begin
try
xNormalPro := xNormalDict[xWord] / xNormalEmailCount ;
except
xNormalPro := 0.01 ;
end;
try
xJunkPro := xJunkDict[xWord] / xJunkEmailCount ;
except
xJunkPro := 0.01 ;
end;
GPosteriorProbabilityDict[xWord] := xJunkPro / (xNormalPro + xJunkPro) ;
end;
end;
#step 5 : test start
调用以下两个过程
TJunkBayes.CalculateWordPosteriorProbability ;
TJunkBayes.TestEmail('testemailpath' ,0.7) ;
贝叶斯算法:垃圾邮件过滤相关推荐
- 朴素贝叶斯算法--垃圾邮件过滤
文章目录 一.朴素贝叶斯概述 1.贝叶斯决策理论 2.条件概率 3.朴素贝叶斯 4.朴素贝叶斯一般过程 二.朴素贝叶斯算法--垃圾邮件 1.准备数据:从文本中构建词向量 2.训练算法:从词向量计算概率 ...
- 数据嗨客 | 第3期:朴素贝叶斯和垃圾邮件过滤 机器学习 2016-11-01 0 摘要:概率论只不过是把常识用数学公式表达了出来。 概率论只不过是把常识用数学公式表达了出来。 —
数据嗨客 | 第3期:朴素贝叶斯和垃圾邮件过滤 机器学习 2016-11-01 0 摘要:概率论只不过是把常识用数学公式表达了出来. 概率论只不过是把常识用数学公式表达了出来. ----拉普拉斯 由于 ...
- 机器学习之朴素贝叶斯实现垃圾邮件过滤
一.朴素贝叶斯概述 朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法.对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯法这种通过学习得到模型的机制,显然属于生 ...
- Python微调文本顺序对抗朴素贝叶斯算法垃圾邮件分类机制
封面图片:<Python可以这样学>,ISBN:9787302456469,董付国,清华大学出版社 图书详情(京东): ================= 关于朴素贝叶斯算法中文垃圾邮件分 ...
- 基于贝叶斯算法的邮件过滤管理系统的设计和实现(Vue+SpringBoot)
作者主页:Designer 小郑 作者简介:Java全栈软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue.SpringBoot和微信小程序).系统定制.远程技术指导. ...
- 【机器学习】朴素贝叶斯实现垃圾邮件过滤
朴素贝叶斯法概述 朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法.对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯法这种通过学习得到模型的机制,显然属于生成 ...
- 基于朴素贝叶斯的垃圾邮件过滤实现
重点 1 目的是计算P(内容|正常)与P(内容|垃圾)的概率,所以需要计算出字典中所有此在正常.垃圾条件下出现的概率 2 如果词典中的某个词未在正常/垃圾邮件中出现会导致P(内容|正常/垃圾)=0,所 ...
- [CS229学习笔记] 5.判别学习算法与生成学习算法,高斯判别分析,朴素贝叶斯,垃圾邮件分类,拉普拉斯平滑
本文对应的是吴恩达老师的CS229机器学习的第五课.这节课介绍了判别学习算法和生成学习算法,并给出了生成学习算法的一个实例:利用朴素贝叶斯进行垃圾邮件分类. 判别学习(Discriminative L ...
- 贝叶斯反垃圾邮件技术
一. 贝叶斯反垃圾邮件技术介绍 贝叶斯是基于概率的一种算法,是Thomas Bayes:一位伟大的数学大师所创建的,目前此种算法用于过滤垃圾邮件得到了广泛地好评.贝叶斯过滤器是基于"自我学习 ...
- 基于朴素贝叶斯的垃圾邮件识别
在网上看到很多用朴素贝叶斯算法来实现垃圾邮件分类的,有直接调用库的,也有自己写的.出于对贝叶斯算法的复习,我也想用贝叶斯算法写写邮件识别,做一个简单的识别系统. 一.开发环境 Python3.6,邮件 ...
最新文章
- 利用python实现IP扫描
- I.MX6 android 源码下载
- java hashedmap_Java基础 - Map接口的实现类 : HashedMap / LinkedHashMap /TreeMap 的构造/修改/遍历/ 集合视图方法/双向迭代输出...
- map:map是否为空?元素数量?删除元素?
- Google邮局可以实时开通了
- UBoot讲解和实践-------------讲解(二)
- Request method 'GET' not supported解决方式
- 看电影也花屏,谁是幕后元凶
- Python-02-基础知识
- spark sql建表的异常
- 网络工程师干货:华为设备故障管理命令大全
- 百战程序员python900集资源_尚学堂百战程序员:盘点那些实用的Python代码
- HTTP请求详细过程
- matlab 浮动波动率,Matlab计算股票价格波动率
- Python实现奇数阶幻方(不用numpy)
- AT命令的简单介绍和使用
- 生产环境Centos LNMP编译安装nginx-1.6 MySQL-5.6 php-5.5
- / ./ ../路径含义
- Direct3D基础——Direct3D概述
- [从头读历史] 第264节 春秋诸侯国分布图
热门文章
- C语言/gets()函数和scanf()函数关于字符串的输入
- 暗黑破坏神练Key方法详解
- 创建微信机器人和女朋友聊天_创建聊天机器人
- 初级会计实务--第七章第三节、产品成本的归集和分配
- 用NavicatPremium导出数据
- BUG的优先级(Priority)和严重程度(Severity)Blocker, Critical, Major, Minor/Trivial
- 公司即将要倒闭的征兆
- Guns V3.0简介
- Go语言web开发入门
- html加载类失败,css样式为什么会加载失败?