贝叶斯算法--垃圾邮件分类
本摘要介绍了一个利用贝叶斯算法进行垃圾邮件分类的实验项目。任务目标是掌握贝叶斯分类的基本原理及其应用,并通过构建模型对邮件进行自动筛选。实验分为五个步骤:准备Python环境与数据集、中文分词与停用词过滤、高频词分析与特征向量构建、贝叶斯模型训练以及测试邮件分类。文中详细描述了数据预处理方法(如获取文件列表、清洗数据)及模型构建过程(如使用MultinomialNB),并验证了模型在测试邮件上的准确性。整个过程从理论到实践均结合具体代码实现,展示了完整的机器学习流程。
⚠️请注意!未经授权禁止任何形式的转载行为!全文约6804字 大致需时约10分钟 欢迎订阅我的个人微信公众号 不懂开发的程序猿 了解更多信息可以直接联系我
贝叶斯算法--垃圾邮件分类
- 基于贝叶斯理论的垃圾邮件分类系统
- 本项目的任务目标是开发一个高效的垃圾邮件过滤系统
- 对项目的实施逻辑进行深入分析
- 对项目的实施逻辑进行深入分析
- 项目的主要实施步骤包括以下几个方面:
- 在Jupyter环境中创建一个新的Python工程
- 数据准备阶段
- 收集相关文件路径并整理为可执行处理的格式
- 解析已有的邮件数据集以确定其特征属性
- 根据项目需求自定义手写停用词表
-
业务数据处理
- 对文本进行分词处理,并去除无关字符和停用词
- 收集并整理整个训练样本库中的所有单词及其出现频率
- 统计高频词汇在邮件样本中的出现频率
- 4.模型创建
- 5.邮件分类预测
- 说明
贝叶斯算法–垃圾邮件分类
任务需求
进行非工作性质的私人交流是一种既轻松高效且愉悦的方式,在日常生活中我们可以将其灵活运用到不同的场景中。例如,在学术领域的沟通我们暂且将其称为常规邮件。伴随着互联网技术的进步,各种形形色色的垃圾信息不断涌现出来,使得我们不得不在日常生活中投入大量时间和精力去处理这类信息。
通过贝叶斯模型对邮件进行分类处理, 可以帮助识别来邮中的正常邮件与垃圾邮件. 如果是企业内部系统, 在收件人邮箱打开来邮之前就对垃圾邮件进行过滤, 将正常邮件直接发送至个人邮箱是一种合理做法.
任务目标
1.了解贝叶斯分类算法
2.掌握贝叶斯分类的模型建立及应用
任务分析

任务分解
本任务共设定5个子任务,分5大步骤完成。
第1步:准备python环境,创建python工程
第2步:准备实验用到的数据
第3步:数据清洗与处理
第4步:贝叶斯回归模型构建
第5步:贝叶斯模型分类预测
任务环境
Oracle Linux 7.4
Python3
任务实施过程
1.打开Jupyter,并新建python工程
1.桌面空白处右键,点击Konsole打开一个终端
2.切换至/experiment/jupyter目录
cd experiment/jupyter
3.启动Jupyter,root用户下运行需加–allow-root
jupyter notebook --ip=127.0.0.1 --allow-root


4.依次点击右上角的 New,Python 3新建python工程


5.点击Untitled,在弹出框中修改标题名,点击Rename确认

2.数据准备
在贝叶斯分类开始之前,在线客服系统要求对邮件中的无效词汇进行筛选。如‘的’、‘在’、‘于是’等无效词汇以及标点符号,请注意这些标记会干扰邮件内容分析的有效性。接下来的具体操作流程包括:从训练数据集中获取每封待分类邮件,并对其进行读取原始文本信息;随后按照自然语言处理的标准方法对每封邮件的内容进行中文文本拆解;最后针对已经拆解完成的文字库内容执行标点符号清理以及与业务相关的关键词剔除等关键步骤。其中拆解过程指的是将整篇待分类文章分解为独立的文字单元;而关键词筛选则需对经过拆解后的中文词语列表执行标点符号清理以及与业务相关的关键词剔除。
1.获取文件列表
#导入包
import os;
#获取指定路径下文件名列表
def get_File_List(filePath):
filenames = os.listdir(filePath)
return filenames

分别收集正常邮件与垃圾邮件样本库的文件列表,并对后续的 emails 进行分类标记处理作为完成任务所需的工作安排
2.查看邮件列表
# 邮件数据路径所在路径
url='/root/experiment/data/bayes/dataDemo/' # 设置文件存储路径
# 分别获得正常邮件、垃圾邮件数据集中文件名称列表
normFileList = get_File_List(url+"normal")
normFileList
spamFileList = get_File_List(url+"spam")
spamFileList

从结果可以看出,在该目录下的邮件分为两种类型:一种是正常的常规邮件列表 normal 文件夹中包含 normal-train1.txt 和 normal-train2.txt 文件;另一种是非正常的垃圾邮件列表 Sparm 文件夹中包含 spam-train1.txt 和 spam-train2.txt 文件。
3.获取手写停用词
#获取手写停用词
def getStopWords():
#定义停用词集合
stopList = []
#读取停用词文件
for line in open("/root/experiment/data/bayes/dataDemo/zh-stop-words.txt"):
#将停用词加入到停用词集合中
stopList.append(line[:len(line) - 1])
return stopList;
# 获得停用词表,用于对停用词过滤
topList = getStopWords()
print('获得停用词表的内容:', topList)

手动编写这份停词文件内容, 旨在根据业务定义筛选出无意义的词语. 例如, 在本次案例中, 我们命名为 zh-stop-words.txt.
3.业务数据处理
中文文本的拆分、非特殊字符筛选以及停用词去除等操作均涉及将邮件内容读取并进行分词处理。随后对分离出来的每一项词语进行筛选判断:若该词语既不属于特殊字符也不属于停用词,则会将这些词语加入集合中以便后续使用。
1.中文切分与字符过滤及停词处理
import os;
from re import sub
from collections import Counter
from itertools import chain
from numpy import array
from jieba import cut
from sklearn.naive_bayes import MultinomialNB
#导入中文分词包
from jieba import cut
# 获取指定文件txtFile中单词,删除干扰字符或长度为1的单词
def getWordsFromFile(txtFile,stopList):
#定义词语列表
wordsList=[]
#打开邮件文件
with open(txtFile, encoding='utf8') as fp:
#逐行读取邮件中的内容
for line in fp:
#去掉邮件单词的左右空格
line = line.strip()
#过滤干扰字符或无效字符
line = sub(r'[.【】0-9、—。,!~\*]', '', line)
#提取词语
line = cut(line)
# 过滤长度为1的词
line = filter(lambda word: len(word) > 1, line)
#添加到集合wordsList中
wordsList.extend(line)
# 过滤掉停词,剩余有效单词
words = []
#遍历邮件词语列表
for i in wordsList:
#如果词语不是停用词并且不等于空字符串和空
if i not in stopList and i.strip() != '' and i != None:
#将词语添加到words中
words.append(i)
return words
#指定邮件进行中文切分,字符过滤和停用词过滤
getWordsFromFile('/root/experiment/data/bayes/dataDemo/normal/normal-train1.txt', topList)

观察到,在对normal-train1.txt的邮件进行分析时,在停词之前发现存在一个词汇'于是'('于是'),该词汇已经被预先定义好的停用词列表所包含。因此,在执行完全部的停用词剔除操作后,'于是'这一词汇就会被过滤掉。在后续的垃圾邮件过滤过程中,我们可以通过对每一封电子邮件的内容进行类似的预处理步骤,从而得到一份经过筛选后的单词数据集合,这些数据集合才是有效的且可用于后续分析的研究素材。
分别从正常 emails 和 spam emails 中提取出频率最高的词汇集合,并以此作为判断依据对待 incoming emails 进行分类判断。即首先统计并获取 spam emails 中关键词频次信息(如 '教材' 这一特定词汇在 spam 电子邮件中出现频率较低),接着同步完成 normal emails 关键词频次数据的收集(如 '教材' 在 normal emails 中出现频率较高)。在此基础上完成两份完整的关键词频次数据对比分析后,在不改变原有 email 顺序的前提下进行高频词汇分析工作。
2.获取全部训练集中单词列表和频次最高的单词集
#导入包
from collections import Counter
from itertools import chain
# 获取并返回url路径下正常邮件和垃圾邮件出现频次最多的前topN个单词
def getTopNWords(topN,normFileList,spamFileList,url,stopList):
# 存放所有文件中的单词
allWords = []
# 存放垃圾邮件的单词列表,每个文件对应一个列表
for txtspamFile in spamFileList:
allWords.append(getWordsFromFile(url+"spam/"+txtspamFile,stopList))
for txtnormFile in normFileList:
allWords.append(getWordsFromFile(url+"normal/"+txtnormFile,stopList))
# 获取并返回出现次数最多的前topN个单词
frep = Counter(chain(*allWords))
return [w[0] for w in frep.most_common(topN)], allWords
#获得停用词表,用于对停用词过滤
stopList = getStopWords()
#全部训练集中出现次数最多的前10个单词和所有单词列表
topWords, allWords = getTopNWords(10, normFileList, spamFileList,url,stopList)
print('频次最高的前10个单词',topWords)
print('所有词数据集:',allWords )

分析结果显示,在所有邮件中频率最高的十个关键词被统计得出。其中常见的正常邮件用语包括"您好"和"教材",其余则属于垃圾邮件内容。
3.获取高频词数据集在邮件中的频次
#获取特征向量,前topWords个单词的每个单词在每个邮件中出现的频率
def getTestWordstopWords(topWords, allWords):
vector = []
for words in allWords:
# 统计每个邮件中的单词数量
temp = list(map(lambda x: words.count(x), topWords))
#添加到集合vector中
vector.append(temp)
vector = array(vector)
return vector
#获取特征向量,即topWords单词的每个单词在每个邮件中出现的频率
vector = getTestWordstopWords(topWords, allWords)
print('W特征向量的值:',vector)

运行结果描述了10个高频词在每一封邮件中的每个单词出现的频次。

第一列列举了四封邮件的文件名称。第一行列出了求解过程中的十个关键术语。正文部分呈现了运行数据,即每个邮件中各个关键术语出现的频率情况。
4.模型创建
建立贝叶斯模型,对已有数据进行训练。
# 创建贝叶斯模型,使用已有数据进行训练
def setBayesModel(vector, normFilelengh, spamFilelengh):
# 打标签,1表示垃圾邮件,0表示正常邮件
labels = array([1] * spamFilelengh + [0] * normFilelengh)
# 创建模型,使用已知训练集进行训练
model = MultinomialNB()
model.fit(vector, labels)
return model
#获取训练集中正常邮件与垃圾邮件的数量
normFilelengh = len(normFileList)
spamFilelengh = len(spamFileList)
#创建贝叶斯模型,使用已有数据进行训练
model = setBayesModel(vector, normFilelengh, spamFilelengh)
print('贝叶斯模型',model)

构建模型后,我们就可以使用改模型来进行邮件分类预测。
5.邮件分类预测
下面我们采用贝叶斯分类模型来完成待识别邮件内容的分类任务。其中包含了normal-test.txt文件(正常邮件样本)以及spam-test.txt文件(垃圾邮件样本),总共有2个测试样本。
# 使用训练好的模型对未知邮件内容进行分类
def predict(txtFile, model, topWords,stopList):
# 获取指定邮件文件内容,返回分类结果
words = getWordsFromFile(txtFile,stopList)
#单词计算数量
currentVector = array(tuple(map(lambda x: words.count(x), topWords)))
#模型预测
result = model.predict(currentVector.reshape(1, -1))
return '垃圾邮件' if result == 1 else '正常邮件'
#使用训练好的模型对未知邮件内容进行分类
# 获得测试邮件数据集文件名称列表
testFileList = get_File_List(url + "test")
for testFile in testFileList:
print(testFile+'是:',predict(url+'test/'+testFile, model, topWords,stopList))

这两封测试邮件的预测准确率达到100%。具体而言,在整个垃圾邮件分类系统的运行过程中
–end–
说明
本实验(项目)/论文若有需要,请后台私信或【文末】个人微信公众号联系我
