基于朴素贝叶斯算法实现邮件分类

摘要

​ 随着互联网的迅猛发展,电子邮件成为了现代通信的主要手段,在给用户带来很大方便的同时,也产生了一个新的问题。即许多垃圾邮件也在网络中蔓延,给广大用户带来了大量的麻烦。因此能够有效地防治垃圾邮件是一个有重要意义的现实问题。目前,应对垃圾邮件的主要方法是通过反垃圾邮件方法和邮件过滤技术进行处理,现如今已经出现了许多邮件过滤技术,如常用的黑名单技术、基于内容分析的方法等。本论文对垃圾邮件的特点进行了比较系统的分析和研究,结合贝叶斯理论和logistic理论,BP神经往来款,构造基于朴素贝叶斯和Logistic回归,BP神经网络的垃圾邮件过滤模型,然后三者进行对比分析。

​ 针对任务一,任务二,观察原数据,发现只有一列特征即邮件正文,且邮件正文内容均为英文,但具有少部分符号,由于由于这里做分类模型,而大多符号在两个类别中出现频率相差不大,因此对于分类作用微乎其微,在第一步分词中,将使用正则过滤掉符号,只保留英文字符。再仔细观察,会发现一些词语经常出现,如冠词,连词等,像 "and"、"the"、”him" 这样的词,这些词在表示文本内容时被认为是没有信息的,无意义的,在邮件分类问题上作用微乎其微,于是这里选择删除它们,不将其加入词典。

​ 针对任务三,任务四,分别使用词袋模型建立朴素贝叶斯分类器,使用TF-IDF方法创建词典并建立Logist回归,使用预训练文本嵌入层作为首层,并且为了解决BP神经网络容易过拟合等问题,从训练集中划分出一半作为验证集,这样做的好处是,可以及时发现模型或者参数的问题,比如在验证集上发散等问情况,这时可以及时终止训练,重新调参,或者调整模型,而不需要等到训练完成,同时,还可以通过验证集对比不同的模型。最后用测试集评估模型,对比三者在邮件分类问题上的成果。

关键词:贝叶斯算法;特征值提取;文本分类;词向量特征

1. 背景与目标任务

1.1 问题背景

​ 垃圾邮件的泛滥不仅极大地浪费了网络资源,占用了用户的电子邮箱空间,降低了网络使用效率,影响了互联网的正常使用,侵犯了用户的个人权利,甚至还影响到青少年的健康成长。用户收到了大量不需要的欺诈性的,或令人讨厌的邮件,不得不浪费大量的时间去删除这些垃圾邮件。即使有一些相应的邮件过滤软件,也担心重要的邮件被误认为垃圾邮件。滤除垃圾邮件是具有相当难度的工作,垃圾邮件每天都在增加和变化。因此,必须采用一种新的技术来克服静态反垃圾邮件的弱点,这种技术应该对垃圾邮件发送者的各种特征了如指掌,还要能适应不同用户对于反垃圾邮件的个性化需求,这种技术就是贝叶斯过滤技术。

1.2 任务目标

本次任务是根据已有标签的电子邮件数据集,完成以下目标:

  1. 利用数据创建词典

  2. 进行特征提取

  3. 训练分类器

  4. 性能测试

1.3 分析流程

图1 分析流程图

2. 数据预处理

通过分析原始数据,发现数据标签列存在异常情况,由于是分类任务,这里采用删除不正确标签(既不为Spam 也不为 Non-Spam)所在行,并且由于标签列为文本数据,由于任务是二分类问题,因此分别将 Spam、Non-Spam 映射为 1, 0 数值型标签,便于之后模型的建立。

3. 数据探索性分析

3.1 邮件类别分析

通过对不同垃圾邮件,正常邮件计数并统计比例,正常邮件占据多数可以大多数人使用电子邮件还是用于正常交流沟通,用于广告,营销还是处于少数,人们的生活不会因此受严重影响。使用 matplotlib 分别绘制训练集,测试集上邮件分类所占比例如图2,图3所示。

图2 训练集上 邮件分类占比饼图

图3 测试集上 邮件分类占比饼图

3.2 邮件正文分析

​ 对所有邮件正文分词并计算词频,绘制词云图,如图4所示

图4 全部数据集 词云图

​ 对正常邮件正文分词并计算词频,绘制词云图,如图5所示,可以发现正常邮件高频词为日常生活用语,反映大多数人邮件交流话题为日常生活。

图5 正常邮件 词云图

​ 对垃圾邮件正文分词并计算词频,绘制词云图,如图6所示,可以发现垃圾邮件高频词 mobile,call, free,可以推测垃圾邮件大多数为电商推销。

图6 垃圾邮件 词云图

4. 分词并建立词典

4.1 切割文本

​ 观察数据可知,这里的特征是来自邮件正文的文本的词条(token),一个词条是字符的任意组合,而邮件正文内容大多为英文,只有少数符号,而英文语句由单词组成,一般由空格分割,于是首先可以按空格分割词汇,其次由于英文逗号,点号等也其分割作用,于是最后可以按正则表达式 \W+ 切割邮件正文文本,再仔细观察,可以发现句子中的第一个单词是大写的,如果目的是句子查找,那么这个特点会很有用,但这里的文本只看成词袋,所以我们希望所有词的形式都是统一的,不论它们出现在句子中间、结尾还是开头,于是这里使用 Python中lower()统一将所有词汇转为小写。

4.2 使用停用词

​ 停用词是像 "and"、"the"、”him" 这样的词,这些词在表示文本内容时被认为是没有信息的,无意义的,在邮件分类问题上作用微乎其微,可以删除它们,

​ 在原生实现贝叶斯代码中,考虑到邮件正文内容少以及样本少,为避免问题的不必要复杂化,原生实现贝叶斯代码中仅去除长度小于2的词汇,而在使用 sklearn实现多项式贝叶斯与sklearn实现Logistic回归时,使用了sklearn自带的停用词表,在TensorFlow实现神经网络中直接使用了预训练的嵌入式词表。

4.3 建立词典

​ 建立词典就是将词汇存于一个字典的过程,词汇的索引将直接作用于转换成数值的词向量,但它也可以有多种做法,在原生实现贝叶斯中,从训练集,测试集中提取所有词汇建立全词典,而在TensorFlow实现神经网络中,使用了已经准备好的嵌入层,自动完成将文本分词并转换为词向量,它是预训练好的层,当然这也意味着这可能并不能很好适用于本数据集,在自然语言处理中,常常需要建立对应的专业领域词典也是出于这个原因。

5. 转为词向量

5.1 词集模型

​ 将每一个文本片段表示为一个词条向量,其中值为1表示词条出现在文档中,0表示词条未出现,将每个词的出现与否作为一个特征,这可以被描述为词集模型(set-of-words model)。词集模型所建立的词向量通常较大,假设词典拥有M个词汇,共有N个样本需要训练,那么词集模型所建立单个词向量就有M个,建立所有即M*N矩阵,这是一个one-hot编码的0,1 稀疏矩阵,每个词条1出现的位置说明出现对应词典词汇,0则代表此样本没有出现词典中出现的此词汇。巨大的稀疏矩阵也代表着巨大的内存开销,毫无疑问,词集模型不适合大数据,大样本。

5.2 词袋模型

​ 词袋模型(Bag of words)故名思议,忽略其词序和语法,句法,将其仅仅看做是一个词集合,使用词袋模型将文本做特征表征就是一个根据词频(term frequency)表示成ones-hot的过程,词袋模型可以说是词集模型的改进,词集模型只关注此单词出没出现,而词袋模型对单词的出现计算了词频,对文本情感分析,上下文联系等问题效果更好。在使用sklearn实现多项式贝叶斯代码中,CountVectorizer即是词袋模型的实现,

5.3 TF-IDF 方法

​ 根据词语出现次数 构建词袋 会出现一问题,长邮件词语出现次数比短邮件词语出现次数多,而实际上两封邮件可能同一主题。

于是,本文用 TF(term frequencies):单词出现次数除以邮件总单词数,这样的方法来代替出现次数构建词袋字典。除此之外,还有一问题:若一个词在许多邮件中均有出现,那么它对于区分邮件类别的作用就微乎其微了。于是,有了 TF-IDF(Term Frequency times Inverse Document Frequency) :每个词再加上权重来构建词标记。在使用sklearn实现Logistic回归代码中, TfidfTransformer即是TF-IDF算法的实现。

6. 建立分类模型

​ 为了取得更好的分类成果,讨论模型的优劣性,本论文附件中代码共使用了4种方法,分别如下:

  1. 使用sklearn且采用TF-IDF方法实现Logistic回归
  2. 使用sklearn且采用词袋模型实现朴素贝叶斯
  3. 使用TensorFlow且采用预训练文本嵌入(text embedding)作为首层构建BP神经网络
  4. 基于贝叶斯决策理论构建朴素贝叶斯分类器

6.1 朴素贝叶斯

6.1.1 基于贝叶斯决策理论的分类方法

​ 朴素贝叶斯是贝叶斯决策理论的一部分,而贝叶斯决策理论的核心思想,就是选择具有最高概率的决策。

​ 基于概率论的分类方法:朴素贝叶斯,要求分类器给出一个最优的类别猜测结果,同时给出这个猜测的概率估计值。一种有效计算条件概率的方法称为贝叶斯准则,贝叶斯准则告诉我们如何交换条件概率中的条件与结果,即如果已知 \(P(x|c)\),要求 \(P(c|x)\),那么可以使用下面的计算方法: \[ P(c|x) = \frac{P(x|c) P(c)} {P(x)} \] 于是,可以定义贝叶斯分类准则为: \[ 若 \ P(c_1 | x, y) > P(c_2 | x, y), \ 那么属于类别 \ C_1 \]

\[ 若 \ P(c_1 | x, y) < P(c_2 | x, y), \ 那么属于类别 \ C_2 \]

使用贝叶斯准则,可以通过已知的三个概率值来计算未知的概率值。

6.1.2 从词向量计算概率

​ 朴素贝叶斯分类器通常有两种实现方式:一种基于贝努利模型实现,一种基于多项式模型实现。在附件中代码4是多项式模型,它考虑词在文档中的出现次数,本节主要讨论贝叶斯多项式模型的实现,对应代码4。

​ 由于这里的特征是词向量,于是重写贝叶斯准则,将之前的x、y 替换为w。粗体w表示这是一个向量,即它由多个数值组成,长度N为词典长度。在词袋模型中,数值个数与词典中的词个数相同,贝叶斯准则公式如下: \[ P(c_i | w) = \frac{P(w|c_i) P(c_i)} {P(w)} \] ​ 本文将使用上述公式,对每个类别计算该值,然后比较这两个概率值的大小。首先通过类别i(垃圾邮件或正常邮件)中样本数除以总的样本数来计算概率 \(P(c_i)\),接下里计算 \(P(w|c_i)\) ,这里使用朴素贝叶斯假设,若将w展开为一个个独立特征,那么就可以将上述概率写作 \(P(w_0, w_1, w_2, ... w_N | c_i)\) ,这里假设所有词都互相独立,该假设也称作条件独立性假设,它意味着可以使用 如下公式计算上述概率: \[ P(w|c_i) = P(w_0|c_i) P(w_1|c_i) P(w_2|c_i) ... P(w_N|c_i) \] 如上,这样就极大的简化了计算过程。

朴素贝叶斯分类具体步骤如下:

  1. 设D是词向量集合,每个词向量用一个N维向量 \(w = \{ w_0, w_1, w_2, ... , w_N \}\) 表示。

  2. 假定有m个类 \(c_i = \{ c_1, c_2, ... , c_m \}\),给定词向量w,分类法将预测w属于最高后验概率的类,即,朴素贝叶斯分类法预测w属于类\(c_i\),当且仅当 \[ P(c_i|w)>P(c_j|w) , \ \ \ 1≤j≤m, j≠i \] 其中,\(P(c_i|w)\) 最大的类 \(c_i\) 称为最大后验概率。

  3. 做条件独立性假设,于是将公式简化 \[ P(w|c_i) = \prod_{k=1}^N{w_k|c_i} \]

  4. 训练:利用公式,对每个词向量每个类别分别计算条件概率,得出 \(P_{0v}, P_{1v}, P_{spam}\) ,分类器训练完成。

  5. 应用:利用贝叶斯分类准则,对预测词向量分别计算 \(P_0, P_1\) ,选择最大概率对应的分类作为目标预测结果。

6.1.3 训练分类器并评估

​ 在给出的数据集中已经完成训练集与测试集的切割,于是下面在训练集上训练分类器,测试集上评估分类器。在训练集上训练,得到条件概率如图7。

图7 训练结果 条件概率

​ 由图7,第一行向量为 \(P_0\) ,长度为2987(词典中词个数),分别代表0分类(正常邮件)条件下样本特征(邮件正文)出现对应词汇的条件概率,第二行为 \(P_1\),长度为2987(词典中词个数),分别代表1分类(垃圾邮件)条件下样本特征(邮件正文)出现对应词汇的条件概率,第三行为 \(P_{spam}\) ,即垃圾邮件占比。至此,分类器训练完成。

​ 使用分类器预测测试集上样本,分类结果正确率如图8。由图可看出,邮件分类正确率可达到92%,只有少数邮件分类错误,效果较好。

图8 测试集分类正确率饼图

​ 对分类错误的词向量转换为原词汇数组,并计算频数,使用 matplotlib,wordcloud绘制词云如图9。从分类错误的词云图可以看出,分类错误的邮件正文词汇多为中性词,此类词汇不易判别,但又经常出现于两个类别,说明算法还有很大的优化空间,可以将这部分词加入停用词。

图9 测试集分类错误 词云图

6.2 Logistic回归

6.2.1 Logistic回归 原理

参考文献

[1] 许建明, 杨磊, 黄同成. 基于贝叶斯方法的邮件分类技术研究[J]. 科学技术与工程, 2008(07):235-238.

[2] 徐治国. 基于朴素贝叶斯的垃圾邮件分类系统的设计[J]. 盐城工学院学报(自然科学版), 2008(02):47-50.

[3] 惠孛, 吴跃. 基于不完全朴素贝叶斯分类模型的垃圾邮件分类模型[J]. 计算机应用, 2009(03):285-286+289.

[4] 曾志中, 雷友珣. 基于贝叶斯算法的垃圾邮件过滤[J]. 2009.

[5] 李少猷. 基于贝叶斯理论的数据挖掘方法在电子邮件分类中的应用研究[D]. 上海交通大学.

[6] 涂堃. 贝叶斯数据挖掘算法在反垃圾邮件中的研究[D]. 南昌大学, 2009.


Q&A

补充

参考

感谢帮助!