朴素贝叶斯的垃圾邮件分类
数据集:本次实验中,所采用的数据集为Enron Email Dataset。该数据集已经对正常邮件和垃圾邮件进行了分类。下载保存到本文件目录中。
代码实现过程:
1.导包
2.读入数据:读入了所有邮件内容和标签,其中邮件内容存储在data中,标签存储在target当中,“1”表示为垃圾邮件,“0”表示为正常邮件。
3.定义一个类对数据进行预处理
4.数据处理:①计算(对数)类先验,即计算P(垃圾邮件)和P(正常邮件);②词汇表(即正常邮件和垃圾邮件中出现的所有单词,方便进行拉普拉斯平滑);③垃圾邮件和非垃圾邮件的词频,即给定词在垃圾邮件和非垃圾邮件中出现的次数。
5.定义一个类 SpamDetector对测试集进行测试
代码:
import os
import re
import string
import math
DATA_DIR = 'enron'
target_names = ['ham', 'spam']
def get_data(DATA_DIR):
subfolders = ['enron%d' % i for i in range(1,7)]
data = []
target = []
for subfolder in subfolders:
# spam
spam_files = os.listdir(os.path.join(DATA_DIR, subfolder, 'spam'))
for spam_file in spam_files:
with open(os.path.join(DATA_DIR, subfolder, 'spam', spam_file), encoding="latin-1") as f:
data.append(f.read())
target.append(1)
# ham
ham_files = os.listdir(os.path.join(DATA_DIR, subfolder, 'ham'))
for ham_file in ham_files:
with open(os.path.join(DATA_DIR, subfolder, 'ham', ham_file), encoding="latin-1") as f:
data.append(f.read())
target.append(0)
return data, target
X, y = get_data(DATA_DIR)
class SpamDetector_1(object):
"""Implementation of Naive Bayes for binary classification"""
#清除空格
def clean(self, s):
translator = str.maketrans("", "", string.punctuation)
return s.translate(translator)
#分开每个单词
def tokenize(self, text):
text = self.clean(text).lower()
return re.split("\W+", text)
#计算某个单词出现的次数
def get_word_counts(self, words):
word_counts = {}
for word in words:
word_counts[word] = word_counts.get(word, 0.0) + 1.0
return word_counts
class SpamDetector_2(SpamDetector_1):
# X:data,Y:target标签(垃圾邮件或正常邮件)
def fit(self, X, Y):
self.num_messages = {}
self.log_class_priors = {}
self.word_counts = {}
# 建立一个集合存储所有出现的单词
self.vocab = set()
# 统计spam和ham邮件的个数
self.num_messages['spam'] = sum(1 for label in Y if label == 1)
self.num_messages['ham'] = sum(1 for label in Y if label == 0)
# 计算先验概率,即所有的邮件中,垃圾邮件和正常邮件所占的比例
self.log_class_priors['spam'] = math.log(
self.num_messages['spam'] / (self.num_messages['spam'] + self.num_messages['ham']))
self.log_class_priors['ham'] = math.log(
self.num_messages['ham'] / (self.num_messages['spam'] + self.num_messages['ham']))
self.word_counts['spam'] = {}
self.word_counts['ham'] = {}
for x, y in zip(X, Y):
c = 'spam' if y == 1 else 'ham'
# 构建一个字典存储单封邮件中的单词以及其个数
counts = self.get_word_counts(self.tokenize(x))
for word, count in counts.items():
if word not in self.vocab:
self.vocab.add(word)#确保self.vocab中含有所有邮件中的单词
# 下面语句是为了计算垃圾邮件和非垃圾邮件的词频,即给定词在垃圾邮件和非垃圾邮件中出现的次数。
# c是0或1,垃圾邮件的标签
if word not in self.word_counts[c]:
self.word_counts[c][word] = 0.0
self.word_counts[c][word] += count
MNB = SpamDetector_2()
MNB.fit(X[100:], y[100:])
class SpamDetector(SpamDetector_2):
def predict(self, X):
result = []
flag_1 = 0
# 遍历所有的测试集
for x in X:
counts = self.get_word_counts(self.tokenize(x)) # 生成可以记录单词以及该单词出现的次数的字典
spam_score = 0
ham_score = 0
flag_2 = 0
for word, _ in counts.items():
if word not in self.vocab: continue
#下面计算P(内容|垃圾邮件)和P(内容|正常邮件),所有的单词都要进行拉普拉斯平滑
else:
# 该单词存在于正常邮件的训练集和垃圾邮件的训练集当中
if word in self.word_counts['spam'].keys() and word in self.word_counts['ham'].keys():
log_w_given_spam = math.log(
(self.word_counts['spam'][word] + 1) / (sum(self.word_counts['spam'].values()) + len(self.vocab)))
log_w_given_ham = math.log(
(self.word_counts['ham'][word] + 1) / (sum(self.word_counts['ham'].values()) + len(
self.vocab)))
# 该单词存在于垃圾邮件的训练集当中,但不存在于正常邮件的训练集当中
if word in self.word_counts['spam'].keys() and word not in self.word_counts['ham'].keys():
log_w_given_spam = math.log(
(self.word_counts['spam'][word] + 1) / (sum(self.word_counts['spam'].values()) + len(self.vocab)))
log_w_given_ham = math.log( 1 / (sum(self.word_counts['ham'].values()) + len(
self.vocab)))
# 该单词存在于正常邮件的训练集当中,但不存在于垃圾邮件的训练集当中
if word not in self.word_counts['spam'].keys() and word in self.word_counts['ham'].keys():
log_w_given_spam = math.log( 1 / (sum(self.word_counts['spam'].values()) + len(self.vocab)))
log_w_given_ham = math.log(
(self.word_counts['ham'][word] + 1) / (sum(self.word_counts['ham'].values()) + len(
self.vocab)))
# 把计算到的P(内容|垃圾邮件)和P(内容|正常邮件)加起来
spam_score += log_w_given_spam
ham_score += log_w_given_ham
flag_2 += 1
# 最后,还要把先验加上去,即P(垃圾邮件)和P(正常邮件)
spam_score += self.log_class_priors['spam']
ham_score += self.log_class_priors['ham']
# 最后进行预测,如果spam_score > ham_score则标志为1,即垃圾邮件
if spam_score > ham_score:
result.append(1)
else:
result.append(0)
flag_1 += 1
return result
MNB = SpamDetector()
MNB.fit(X[100:], y[100:])
pred = MNB.predict(X[:100])
true = y[:100]
accuracy = 0
for i in range(100):
if pred[i] == true[i]:
accuracy += 1
print(accuracy) # 0.98
运行截图:测试集的分类的正确率达到98%
朴素贝叶斯的垃圾邮件分类相关推荐
- Python实现基于朴素贝叶斯的垃圾邮件分类 标签: python朴素贝叶斯垃圾邮件分类 2016-04-20 15:09 2750人阅读 评论(1) 收藏 举报 分类: 机器学习(19) 听说
Python实现基于朴素贝叶斯的垃圾邮件分类 标签: python朴素贝叶斯垃圾邮件分类 2016-04-20 15:09 2750人阅读 评论(1) 收藏 举报 分类: 机器学习(19) 听说朴 ...
- 机器学习--使用朴素贝叶斯进行垃圾邮件分类
一.学习背景 垃圾邮件的问题一直困扰着人们,传统的垃圾邮件分类的方法主要有"关键词法"和"校验码法"等,然而这两种方法效果并不理想.其中,如果使用的是" ...
- 朴素贝叶斯法 - 垃圾邮件分类
本文基于朴素贝叶斯构建一个分类垃圾邮件的模型,研究对象是英文的垃圾邮件. 邮件内容保存在txt文件中,其中分为训练样本train和测试样本test. 在训练样本中正常邮件命名为:pos:垃圾邮件命名为 ...
- [CS229学习笔记] 5.判别学习算法与生成学习算法,高斯判别分析,朴素贝叶斯,垃圾邮件分类,拉普拉斯平滑
本文对应的是吴恩达老师的CS229机器学习的第五课.这节课介绍了判别学习算法和生成学习算法,并给出了生成学习算法的一个实例:利用朴素贝叶斯进行垃圾邮件分类. 判别学习(Discriminative L ...
- AI基础:朴素贝叶斯与垃圾邮件分类
来,继续回顾基础算法 文章目录 背景&贝叶斯原理 贝叶斯分类器 朴素贝叶斯分类器 西瓜数据集下的朴素贝叶斯示例 朴素贝叶斯分类的优缺点 朴素贝叶斯关键问题 朴素贝叶斯企业中的应用案例 基于朴素 ...
- 朴素贝叶斯(垃圾邮件分类)
一.基于贝叶斯决策理论的分类方法 朴素贝叶斯是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法.对于大多数的分类算法,在所有的机器学习分类算法中,朴素贝叶斯和其他绝大多数的分类算法都不同.比 ...
- 基于朴素贝叶斯的垃圾邮件分类-着重理解拉普拉斯变换
1. 引言 在正式学习朴素贝叶斯之前,需要明确的是机器学习所要实现的是基于有限的训练样本集尽可能准确地估计出后验概率P(c|x),即根据特征得到所属类别的概率,首先引入两个概念. 判别式模型(disc ...
- Python微调文本顺序对抗朴素贝叶斯算法垃圾邮件分类机制
封面图片:<Python可以这样学>,ISBN:9787302456469,董付国,清华大学出版社 图书详情(京东): ================= 关于朴素贝叶斯算法中文垃圾邮件分 ...
- 第六次实验:使用朴素贝叶斯对垃圾邮件分类(CUST)
1.实验目的和要求 会用Python创建朴素贝叶斯模型 使用朴素贝叶斯模型对垃圾邮件分类 会把文本文件变成向量 会用评价朴素贝叶斯模型的分类效果 2.实验环境 pycharm2021.3.1.Win1 ...
- 朴素贝叶斯与垃圾邮件分类
垃圾邮件识别问题,也即对给定样本(包含垃圾邮件,非垃圾邮件)判断是否为垃圾邮件,根据贝叶斯定理: ⎧⎩⎨⎪⎪⎪⎪⎪⎪p(y=1|x)=p(y=1,x)p(x)p(y=0|x)=p(y=0,x)p(x) ...
最新文章
- android exchange服务,带有“ Service com.android.exchange.ExchangeService
- 甲骨文指控 Google Android 复制其代码
- C语言太简单?这14道C语言谜题,你能答对几个?
- Maven精选系列--classifier元素妙用
- 【Leetcode】113. 路径总和 II
- 学习中遇到的c++问题,持续更新
- arcgis批量处理nc文件_ArcGIS处理NetCDF(.nc)的多维科学数据
- linq 获取实体列表中的某个字段返回iliststring
- Android Studio支持Java1.8的解决方案
- 安装成功后python报错_python安装mysql的依赖包mysql-python操作
- python爬虫--requests模块
- 软件建模与分析--共享单车管理系统
- 怎么用计算机画外观设计图片,以实例教你如何绘制外观设计专利3D线条图
- 仓储物流系统初级架构
- java hypot_static double hypot(double x, double y)
- kali 运行wifite时遇到的问题及解决办法
- C++的成员函数指针简要
- OpenGL-纹理读取BMP图片-代码
- About Variables
- excel表格文件损坏 无法打开解决方法
热门文章
- 共振峰检测matlab百度文库,毕业设计论文-基于MATLAB的语音共振峰的估计.doc
- linux 2.6.39 ext3 ext4 更快 tf,ext3,ext4,xfs,jfs,reiserfs和btrfs文件系统性能对比(转载)...
- w5500跨网段_基于STM32F1的局域网通信模块W5500驱动
- springboot使用kafka发送消息,消息过大报错
- AEC行业那些开源的软件在这里
- 网络终极卫士 NetworkKiller V1.5
- 游戏制作-联网对战丛林战争制作笔记(一)
- 世界时区与北京时间的时差表
- 当马斯克打开潘多拉魔盒
- 计算机控制原理跟自动控制原理,上海交大考研自动控制理论和自动控制原理有什么区..._在职考研_帮考网...