准备
    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. 朴素贝叶斯算法--垃圾邮件过滤

    文章目录 一.朴素贝叶斯概述 1.贝叶斯决策理论 2.条件概率 3.朴素贝叶斯 4.朴素贝叶斯一般过程 二.朴素贝叶斯算法--垃圾邮件 1.准备数据:从文本中构建词向量 2.训练算法:从词向量计算概率 ...

  2. 数据嗨客 | 第3期:朴素贝叶斯和垃圾邮件过滤 机器学习 2016-11-01 0 摘要:概率论只不过是把常识用数学公式表达了出来。 概率论只不过是把常识用数学公式表达了出来。 —

    数据嗨客 | 第3期:朴素贝叶斯和垃圾邮件过滤 机器学习 2016-11-01 0 摘要:概率论只不过是把常识用数学公式表达了出来. 概率论只不过是把常识用数学公式表达了出来. ----拉普拉斯 由于 ...

  3. 机器学习之朴素贝叶斯实现垃圾邮件过滤

    一.朴素贝叶斯概述 朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法.对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯法这种通过学习得到模型的机制,显然属于生 ...

  4. Python微调文本顺序对抗朴素贝叶斯算法垃圾邮件分类机制

    封面图片:<Python可以这样学>,ISBN:9787302456469,董付国,清华大学出版社 图书详情(京东): ================= 关于朴素贝叶斯算法中文垃圾邮件分 ...

  5. 基于贝叶斯算法的邮件过滤管理系统的设计和实现(Vue+SpringBoot)

    作者主页:Designer 小郑 作者简介:Java全栈软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue.SpringBoot和微信小程序).系统定制.远程技术指导. ...

  6. 【机器学习】朴素贝叶斯实现垃圾邮件过滤

    朴素贝叶斯法概述 朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法.对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯法这种通过学习得到模型的机制,显然属于生成 ...

  7. 基于朴素贝叶斯的垃圾邮件过滤实现

    重点 1 目的是计算P(内容|正常)与P(内容|垃圾)的概率,所以需要计算出字典中所有此在正常.垃圾条件下出现的概率 2 如果词典中的某个词未在正常/垃圾邮件中出现会导致P(内容|正常/垃圾)=0,所 ...

  8. [CS229学习笔记] 5.判别学习算法与生成学习算法,高斯判别分析,朴素贝叶斯,垃圾邮件分类,拉普拉斯平滑

    本文对应的是吴恩达老师的CS229机器学习的第五课.这节课介绍了判别学习算法和生成学习算法,并给出了生成学习算法的一个实例:利用朴素贝叶斯进行垃圾邮件分类. 判别学习(Discriminative L ...

  9. 贝叶斯反垃圾邮件技术

    一. 贝叶斯反垃圾邮件技术介绍 贝叶斯是基于概率的一种算法,是Thomas Bayes:一位伟大的数学大师所创建的,目前此种算法用于过滤垃圾邮件得到了广泛地好评.贝叶斯过滤器是基于"自我学习 ...

  10. 基于朴素贝叶斯的垃圾邮件识别

    在网上看到很多用朴素贝叶斯算法来实现垃圾邮件分类的,有直接调用库的,也有自己写的.出于对贝叶斯算法的复习,我也想用贝叶斯算法写写邮件识别,做一个简单的识别系统. 一.开发环境 Python3.6,邮件 ...

最新文章

  1. 利用python实现IP扫描
  2. I.MX6 android 源码下载
  3. java hashedmap_Java基础 - Map接口的实现类 : HashedMap / LinkedHashMap /TreeMap 的构造/修改/遍历/ 集合视图方法/双向迭代输出...
  4. map:map是否为空?元素数量?删除元素?
  5. Google邮局可以实时开通了
  6. UBoot讲解和实践-------------讲解(二)
  7. Request method 'GET' not supported解决方式
  8. 看电影也花屏,谁是幕后元凶
  9. Python-02-基础知识
  10. spark sql建表的异常
  11. 网络工程师干货:华为设备故障管理命令大全
  12. 百战程序员python900集资源_尚学堂百战程序员:盘点那些实用的Python代码
  13. HTTP请求详细过程
  14. matlab 浮动波动率,Matlab计算股票价格波动率
  15. Python实现奇数阶幻方(不用numpy)
  16. AT命令的简单介绍和使用
  17. 生产环境Centos LNMP编译安装nginx-1.6 MySQL-5.6 php-5.5
  18. / ./ ../路径含义
  19. Direct3D基础——Direct3D概述
  20. [从头读历史] 第264节 春秋诸侯国分布图

热门文章

  1. C语言/gets()函数和scanf()函数关于字符串的输入
  2. 暗黑破坏神练Key方法详解
  3. 创建微信机器人和女朋友聊天_创建聊天机器人
  4. 初级会计实务--第七章第三节、产品成本的归集和分配
  5. 用NavicatPremium导出数据
  6. BUG的优先级(Priority)和严重程度(Severity)Blocker, Critical, Major, Minor/Trivial
  7. 公司即将要倒闭的征兆
  8. Guns V3.0简介
  9. Go语言web开发入门
  10. html加载类失败,css样式为什么会加载失败?