Adaboost
NaiveBayesSpamFilter
利用朴素贝叶斯算法实现垃圾邮件的过滤,并结合Adaboost改进该算法。
1 Naive Bayes spam filtering
假设邮件的内容中包含的词汇为Wi,垃圾邮件Spam,正常邮件ham。 判断一份邮件,内容包含的词汇为Wi,判断该邮件是否是垃圾邮件,即计算P(S|Wi)这个条件概率。根据Bayes’ theorem:
Bayes’ theorem
其中:
Pr(S|Wi) 出现词汇Wi的邮件是垃圾邮件的条件概率(即后验概率); Pr(S) 训练阶段邮件数据集中垃圾邮件的概率,或实际调查的垃圾邮件的概率(即先验概率); Pr(Wi|S) 垃圾邮件中词汇Wi出现的概率; Pr(H) 训练阶段邮件数据集中正常邮件的概率,或实际调查的正常邮件的概率; Pr(Wi|H) 正常邮件中词汇Wi出现的概率; 对于邮件中出现的所有词汇,考虑每个词汇出现事件的独立性,计算Pr(S|Wi)的联合概率Pr(S|W),W={W1,W2,…Wn}:
Bayes’ theorem
其中:
P 即Pr(S|W),出现词汇W={W1,W2……Wn}的邮件是垃圾邮件的条件概率; Pi 即Pr(S|Wi),出现词汇Wi的邮件是垃圾邮件的条件概率; 注: 程序中,通过计算出Pr(S|W)和Pr(H|W),比较Pr(S|W)和Pr(H|W)的大小,判断是垃圾邮件还是正常邮件。我们发现Pr(S|W)和Pr(H|W)计算的分母相同,所以我们只需要比较分子即可。
但存在两个问题:
当词汇不存在时,即ni=0,此时Pr(S|Wi) = 0,会造成P=0,无法比较 当Pr(S|Wi)较小时,连乘操作会造成下溢出问题 解决方案:
计算P(Wi|S)和P(Wi|H)时,将所有词汇初始化出现的次数为1,并将分母初始化为2(或根据样本/实际调查结果调整分母的值)。
# 统计语料库中词汇在S和H中出现的次数
wordsInSpamNum = np.ones(numWords)
wordsInHealthNum = np.ones(numWords)
spamWordsNum = 2.0
healthWordsNum = 2.0
计算P(Wi|S)和P(Wi|H)时,对概率取对数 pWordsSpamicity = np.log(wordsInSpamNum / spamWordsNum) pWordsHealthy = np.log(wordsInHealthNum / healthWordsNum) 所以最终比较的是,P(W1|S)P(W2|S)….P(Wn|S)P(S)和P(W1|H)P(W2|H)….P(Wn|H)P(H)的大小。
ps = sum(testWordsMarkedArray pWordsSpamicity) + np.log(pSpam)
ph = sum(testWordsMarkedArray pWordsHealthy) + np.log(1 - pSpam)
测试效果: 5574个样本,采用交叉验证,随机选取4574个作为训练样本,产生词汇列表(语料库),对1000个测试样本,分类的平均错误率约为:2.5%。
2 Running Adaboost on Naive Bayes
我们在计算ps和ph联合后验概率时,可引入一个调整因子DS,其作用是调整词汇表中某一词汇的“垃圾程度”(spamicity),
ps = sum(testWordsMarkedArray * pWordsSpamicity * DS) + np.log(pSpam)
其中DS通过Adaboost算法迭代获取最佳值。原理如下:
设定adaboost循环的次数count 交叉验证随机选择1000个样本 DS初始化为和词汇列表大小相等的全一向量 迭代循环count次: 设定最小分类错误率为inf 对于每一个样本: 在当前DS下对样本分类 如果分类出错: 计算出错的程度,即比较ps和ph的相差alpha 如果样本原本是spam,错分成ham: DS[样本包含的词汇] = np.abs(DS[样本包含的词汇] - np.exp(alpha) / DS[样本包含的词汇]) 如果样本原本是ham,错分成spam: DS[样本包含的词汇] = DS[样本包含的词汇] + np.exp(alpha) / DS[样本包含的词汇] 计算错误率 保存最小的错误率和此时的词汇列表、P(Wi|S)和P(Wi|H)、DS等信息,即保存训练好的最佳模型的信息 测试效果: 5574个样本,获取Adaboost算法训练的最佳模型信息(包括词汇列表、P(Wi|S)和P(Wi|H)、DS等),对1000个测试样本,分类的平均错误率约为:0.5%。
- MVC5 网站开发之九 网站设置
- Redis安全小结
- webpack学习(七)打包压缩图片
- POJ1275 Cashier Employment(差分约束)
- REDIS操作命令小结
- Java发送邮件工具类
- javascript 变量、作用域和内存问题
- 1726: [Usaco2006 Nov]Roadblocks第二短路
- vue小白快速入门
- 算法模板——线段树9(区间加+区间求和+区间方和)
- 1709: [Usaco2007 Oct]Super Paintball超级弹珠
- 2015: [Usaco2010 Feb]Chocolate Giving
- 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛
- 2020: [Usaco2010 Jan]Buying Feed, II
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 07 . ELK Stack7.2一键多机部署脚本
- Kibana配置nginx反代并本地ca加密nginx
- Nginx WebUI管理
- Go之Gorm和BeegoORM简介及配置使用
- msyscuione:基于msys的一体化CUI开发生产环境,支持qt,llvm,ros集成常见web appstack
- monosys as 1ddlang语言选型+1ddcodebase实践选型绿色monodevelope集成常见多语言
- hostguest nativelangsys及uniform cui cross compile system
- 写好 JS 条件语句的 5 条守则
- Python元组中元素怎么删除和修改?
- Jupyter 插件太好用了
- 华为提出十大数学挑战!解出一个就是年薪百万!
- 一道 Google 的面试题
- 生产实践 | 基于 Flink 的短视频生产消费监控
- 图数据库调研
- Swift 类构造器的使用