AI基础:朴素贝叶斯与垃圾邮件分类

来,继续回顾基础算法

文章目录

  • 背景&贝叶斯原理
  • 贝叶斯分类器
  • 朴素贝叶斯分类器
  • 西瓜数据集下的朴素贝叶斯示例
  • 朴素贝叶斯分类的优缺点
  • 朴素贝叶斯关键问题
  • 朴素贝叶斯企业中的应用案例
  • 基于朴素贝叶斯的垃圾邮件分类

背景&贝叶斯原理

  • 朴素贝叶斯基于的原理是贝叶斯原理。

  • 贝叶斯原理:通过相关概率已知的情况下利用误判损失来选择最优的类别分类。

  • 贝叶斯原理是英国数学家托马斯·贝叶斯提出的。贝叶斯是个很神奇的人,他的经历类似梵高。生前没有得到重视,死后,他写的一篇关于归纳推理的论文被朋友翻了出来,并发表了。这一发表不要紧,结果这篇论文的思想直接影响了接下来两个多世纪的统计学,是科学史上著名的论文之一。

  • 贝叶斯为了解决一个叫“逆向概率”问题写了一篇文章,尝试解答在没有太多可靠证据的情况下,怎样做出更符合数学逻辑的推测。

  • 什么是“逆向概率”呢?先说正向概率,正向概率的问题很容易理解,比如我们已经知道袋子里面有 N 个球,不是黑球就是白球,其中 M 个是黑球,那么把手伸进去摸一个球,就能知道摸出黑球的概率是多少。但这种情况往往是上帝视角,即了解了事情的全貌再做判断

  • 逆向概率:**如果我们事先不知道袋子里面黑球和白球的比例,而是通过我们摸出来的球的颜色,能判断出袋子里面黑白球的比例么?**贝叶斯原理与其他统计学推断方法截然不同,它是建立在主观判断的基础上:在我们不了解所有客观事实的情况下,同样可以先估计一个值,然后根据实际结果不断进行修正。

  • 关于贝叶斯原理,又不得不熟悉这几个概念:条件概率,先验概率,后验概率,我这边文章有解释:AI基础:先验概率、后验概率

贝叶斯分类器

贝叶斯公式先上
P ( B ∣ A )    =    P ( A ∣ B ) P ( B ) P ( A ) P ( 类别 ∣ 特征 )    =    P ( 特征 ∣ 类别 ) P ( 类别 ) P ( 特征 ) P\left( B|A \right) \,\,=\,\,\frac{P\left( A|B \right) P\left( B \right)}{P\left( A \right)} \\ P\left( \text{类别}|\text{特征} \right) \,\,=\,\,\frac{P\left( \text{特征}|\text{类别} \right) P\left( \text{类别} \right)}{P\left( \text{特征} \right)} P(BA)=P(A)P(AB)P(B)P(类别特征)=P(特征)P(特征类别)P(类别)

我们最终的目的是求在当前特征下样本所属类别,化作条件概率公式就是P(类别|特征1,特征2,特征n)。当然就是求这一组特征{特征1,特征2,特征n}下每个类别的条件概率,哪个概率大,那就属于哪个类别。

贝叶斯分类器是基于贝叶斯原理理论的实践。

假设有N种可能的分类标记,记为={1,2,…,},那对于样本,它属于哪一类呢?

计算步骤如下:

step 1. 算出样本 属于第i个类的概率,即(|);

step 2. 通过比较所有的(|),得到样本所属的最佳类别,最佳类别就是(|)值最大时所属的类。

将类别和样本代入到贝叶斯公式中,得到:
P ( c i ∣ x ) = P ( x ∣ c i ) P ( c i ) P ( x ) . P(c_i|\boldsymbol{x})=\frac{P(\boldsymbol{x}|c_i)P(c_i)}{P(\boldsymbol{x})}. P(cix)=P(x)P(xci)P(ci).
​ 其中,是特征集合,()为先验概率,(|)为条件概率,()是用于归一化的证据因子(这个概念不明白先不管,先往后看)。对于()可以通过训练样本中类别为的样本所占的比例进行估计;此外,由于只需要找出最大的(|),因此我们并不需要计算()。

朴素贝叶斯分类器

假设样本包含个属性,即={1,2,…,},于是对于上述计算公式有
P ( x ∣ c i ) = P ( x 1 , x 2 , . . . , x d ∣ c i ) P\left( \boldsymbol{x}|c_i \right) =P\left( x_1,x_2,...,x_d|c_i \right) P(xci)=P(x1,x2,...,xdci)
这个联合概率(等号后面那一坨)难以从有限的训练样本中直接估计得到。于是,朴素贝叶斯(Naive Bayesian,简称NB)采用了“属性条件独立性假设”:对已知类别,假设所有属性相互独立。于是有:
P ( x 1 , x 2 , ⋯   , x d ∣ c i ) = ∏ j = 1 d P ( x j ∣ c i ) P(x_1,x_2,\cdots,x_d|c_i)=\prod_{j=1}^d P(x_j|c_i) P(x1,x2,,xdci)=j=1dP(xjci)
这样的话,我们就可以很容易地推出相应的判定准则了:
h n b ( x ) = arg ⁡ max ⁡ c i ∈ Y P ( c i ) ∏ j = 1 d P ( x j ∣ c i ) h_{nb}(\boldsymbol{x})=\mathop{\arg \max}_{c_i\in Y} P(c_i)\prod_{j=1}^dP(x_j|c_i) hnb(x)=argmaxciYP(ci)j=1dP(xjci)

多说一句,为啥要假设所有属性相互独立:

  • x是特征集合,有d个特征,例如有P(好人|身高,体重,脾气),其中每个特征又有多个取值比如身高有高、矮俩取值,体重有重、轻,脾气有好、坏,那么这样联合概率就是会有d个层次维度的计算,这例子就是会有 2 * 2 * 2.。。个维度的计算,并且现实生活中往往不止这么少维度和特征取值数量,会让计算机无法计算,所以这里就需要假设特征相互独立。例如:P(好人|身高) * P(好人|体重) * P(好人|脾气)
  • 第二点,假如我们没有假设特征之间相互独立,那么我们统计的时候,就需要在整个特征空间中去找,比如统计p(好人|身高,体重,脾气),我们就需要符合身高、体重、脾气对应取值的条件组下是好人的数据,这样的话,由于数据的稀疏性,很容易统计到0的情况。这样也是不合适的

条件概率 (|)的求解

如果是标签属性,那么我们可以通过计数的方法估计(|):
P ( x j ∣ c i ) = P ( x j , c i ) P ( c i ) ≈ # ( x j , c i ) # ( c i ) 其 中 , # ( x j , c i ) 表 示 在 训 练 样 本 中 x j 与 c i 共 同 出 现 的 次 数 。 如 果 x j 是 数 值 属 性 , 通 常 我 们 假 设 类 别 中 c i 的 所 有 样 本 第 j 个 属 性 的 值 服 从 正 态 分 布 。 我 们 首 先 估 计 这 个 分 布 的 均 值 μ 和 方 差 σ , 然 后 计 算 x j 在 这 个 分 布 中 的 概 率 密 度 P ( x j ∣ c i ) 。 P(x_j|c_i)=\frac{P(x_j,c_i)}{P(c_i)}\approx\frac{\#(x_j,c_i)}{\#(c_i)} \\ 其中,\#(x_j,c_i)表示在训练样本中x_j与c_i共同出现的次数。 \\ 如果x_j是数值属性,通常我们假设类别中c_i的所有样本第j个属性的值服从正态分布。 \\ 我们首先估计这个分布的均值μ和方差σ,然后计算x_j在这个分布中的概率密度P(x_j|c_i)。 P(xjci)=P(ci)P(xj,ci)#(ci)#(xj,ci)#(xj,ci)xjcixjcijμσxjP(xjci)

西瓜数据集下的朴素贝叶斯示例

使用经典的西瓜训练集如下:

编号 色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
1 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.460
2 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376
3 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264
4 青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318
5 浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215
6 青绿 稍蜷 浊响 清晰 稍凹 软粘 0.403 0.237
7 乌黑 稍蜷 浊响 稍糊 稍凹 软粘 0.481 0.149
8 乌黑 稍蜷 浊响 清晰 稍凹 硬滑 0.437 0.211
9 乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑 0.666 0.091
10 青绿 硬挺 清脆 清晰 平坦 软粘 0.243 0.267
11 浅白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057
12 浅白 蜷缩 浊响 模糊 平坦 软粘 0.343 0.099
13 青绿 稍蜷 浊响 稍糊 凹陷 硬滑 0.639 0.161
14 浅白 稍蜷 沉闷 稍糊 凹陷 硬滑 0.657 0.198
15 乌黑 稍蜷 浊响 清晰 稍凹 软粘 0.360 0.370
16 浅白 蜷缩 浊响 模糊 平坦 硬滑 0.593 0.042
17 青绿 蜷缩 沉闷 稍糊 稍凹 硬滑 0.719 0.103

对下面的测试例“测1”进行 分类:

编号 色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
测1 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.460

首先,估计类先验概率(),有
P ( 好 瓜 = 是 ) = 8 17 = 0.471 P ( 好 瓜 = 否 ) = 9 17 = 0.529 P(好瓜=是)=\frac{8}{17}=0.471 \\ P(好瓜=否)=\frac{9}{17}=0.529 P(=)=178=0.471P(=)=179=0.529
然后,为每个属性估计条件概率(这里,对于连续属性,假定它们服从正态分布)
P 青 绿 ∣ 是 = P ( 色 泽 = 青 绿 ∣ 好 瓜 = 是 ) = 3 8 = 0.375 P_{青绿|是}=P(色泽=青绿|好瓜=是)=\frac{3}{8}=0.375 P绿=P=绿==83=0.375

P 青 绿 ∣ 否 = P ( 色 泽 = 青 绿 ∣ 好 瓜 = 否 ) = 3 9 ≈ 0.333 P_{青绿|否}=P(色泽=青绿|好瓜=否)=\frac{3}{9}\approx0.333 P绿=P=绿==930.333

P 蜷 缩 ∣ 是 = P ( 根 蒂 = 蜷 缩 ∣ 好 瓜 = 是 ) = 5 8 = 0.625 P_{蜷缩|是}=P(根蒂=蜷缩|好瓜=是)=\frac{5}{8}=0.625 P=P===85=0.625

P 蜷 缩 ∣ 否 = P ( 根 蒂 = 蜷 缩 ∣ 好 瓜 = 否 ) = 3 9 = 0.333 P_{蜷缩|否}=P(根蒂=蜷缩|好瓜=否)=\frac{3}{9}=0.333 P=P===93=0.333

P 浊 响 ∣ 是 = P ( 敲 声 = 浊 响 ∣ 好 瓜 = 是 ) = 6 8 = 0.750 P_{浊响|是}=P(敲声=浊响|好瓜=是)=\frac{6}{8}=0.750 P=P===86=0.750

P 浊 响 ∣ 否 = P ( 敲 声 = 浊 响 ∣ 好 瓜 = 否 ) = 4 9 ≈ 0.444 P_{浊响|否}=P(敲声=浊响|好瓜=否)=\frac{4}{9}\approx 0.444 P=P===940.444

P 清 晰 ∣ 是 = P ( 纹 理 = 清 晰 ∣ 好 瓜 = 是 ) = 7 8 = 0.875 P_{清晰|是}=P(纹理=清晰|好瓜=是)=\frac{7}{8}= 0.875 P=P===87=0.875

P 清 晰 ∣ 否 = P ( 纹 理 = 清 晰 ∣ 好 瓜 = 否 ) = 2 9 ≈ 0.222 P_{清晰|否}=P(纹理=清晰|好瓜=否)=\frac{2}{9}\approx 0.222 P=P===920.222

P 凹 陷 ∣ 是 = P ( 脐 部 = 凹 陷 ∣ 好 瓜 = 是 ) = 6 8 = 0.750 P_{凹陷|是}=P(脐部=凹陷|好瓜=是)=\frac{6}{8}= 0.750 P=P===86=0.750

P 凹 陷 ∣ 否 = P ( 脐 部 = 凹 陷 ∣ 好 瓜 = 否 ) = 2 9 ≈ 0.222 P_{凹陷|否}=P(脐部=凹陷|好瓜=否)=\frac{2}{9} \approx 0.222 P=P===920.222

P 硬 滑 ∣ 是 = P ( 触 感 = 硬 滑 ∣ 好 瓜 = 是 ) = 6 8 = 0.750 P_{硬滑|是}=P(触感=硬滑|好瓜=是)=\frac{6}{8}= 0.750 P=P===86=0.750

P 硬 滑 ∣ 否 = P ( 触 感 = 硬 滑 ∣ 好 瓜 = 否 ) = 6 9 ≈ 0.667 P_{硬滑|否}=P(触感=硬滑|好瓜=否)=\frac{6}{9} \approx 0.667 P=P===960.667

ρ 密 度 : 0.697 ∣ 是 = ρ ( 密 度 = 0.697 ∣ 好 瓜 = 是 ) = 1 2 π × 0.129 e x p ( − ( 0.697 − 0.574 ) 2 2 × 0.12 9 2 ) ≈ 1.959 \begin{aligned} \rho_{密度:0.697|是}&=\rho(密度=0.697|好瓜=是)\\&=\frac{1}{\sqrt{2 \pi}\times0.129}exp\left( -\frac{(0.697-0.574)^2}{2\times0.129^2}\right) \approx 1.959 \end{aligned} ρ0.697=ρ=0.697==2π ×0.1291exp(2×0.1292(0.6970.574)2)1.959

ρ 密 度 : 0.697 ∣ 否 = ρ ( 密 度 = 0.697 ∣ 好 瓜 = 否 ) = 1 2 π × 0.195 e x p ( − ( 0.697 − 0.496 ) 2 2 × 0.19 5 2 ) ≈ 1.203 \begin{aligned} \rho_{密度:0.697|否}&=\rho(密度=0.697|好瓜=否)\\&=\frac{1}{\sqrt{2 \pi}\times0.195}exp\left( -\frac{(0.697-0.496)^2}{2\times0.195^2}\right) \approx 1.203 \end{aligned} ρ0.697=ρ=0.697==2π ×0.1951exp(2×0.1952(0.6970.496)2)1.203

ρ 含 糖 : 0.460 ∣ 是 = ρ ( 密 度 = 0.460 ∣ 好 瓜 = 是 ) = 1 2 π × 0.101 e x p ( − ( 0.460 − 0.279 ) 2 2 × 0.10 1 2 ) ≈ 0.788 \begin{aligned} \rho_{含糖:0.460|是}&=\rho(密度=0.460|好瓜=是)\\&=\frac{1}{\sqrt{2 \pi}\times0.101}exp\left( -\frac{(0.460-0.279)^2}{2\times0.101^2}\right) \approx 0.788 \end{aligned} ρ0.460=ρ=0.460==2π ×0.1011exp(2×0.1012(0.4600.279)2)0.788

ρ 含 糖 : 0.460 ∣ 否 = ρ ( 密 度 = 0.460 ∣ 好 瓜 = 是 ) = 1 2 π × 0.108 e x p ( − ( 0.460 − 0.154 ) 2 2 × 0.10 8 2 ) ≈ 0.066 \begin{aligned} \rho_{含糖:0.460|否}&=\rho(密度=0.460|好瓜=是)\\&=\frac{1}{\sqrt{2 \pi}\times0.108}exp\left( -\frac{(0.460-0.154)^2}{2\times0.108^2}\right) \approx 0.066 \end{aligned} ρ0.460=ρ=0.460==2π ×0.1081exp(2×0.1082(0.4600.154)2)0.066

于是有
P ( 好 瓜 = 是 ) × P 青 绿 ∣ 是 × P 蜷 缩 ∣ 是 × P 浊 响 ∣ 是 × P 清 晰 ∣ 是 × P 凹 陷 ∣ 是 × P 硬 滑 ∣ 是 × p 密 度 : 0.697 ∣ 是 × p 含 糖 : 0.460 ∣ 是 ≈ 0.063 P ( 好 瓜 = 否 ) × P 青 绿 ∣ 否 × P 蜷 缩 ∣ 否 × P 浊 响 ∣ 否 × P 清 晰 ∣ 否 × P 凹 陷 ∣ 否 × P 硬 滑 ∣ 否 × p 密 度 : 0.697 ∣ 否 × p 含 糖 : 0.460 ∣ 否 ≈ 6.80 × 1 0 − 5 P(好瓜=是)\times P_{青绿|是} \times P_{蜷缩|是} \times P_{浊响|是} \times P_{清晰|是} \times P_{凹陷|是} \\ \times P_{硬滑|是} \times p_{密度:0.697|是} \times p_{含糖:0.460|是} \approx 0.063 \\ \\ P(好瓜=否)\times P_{青绿|否} \times P_{蜷缩|否} \times P_{浊响|否} \times P_{清晰|否} \times P_{凹陷|否} \\ \times P_{硬滑|否} \times p_{密度:0.697|否} \times p_{含糖:0.460|否} \approx 6.80\times 10^{-5} P(=)×P绿×P×P×P×P×P×p0.697×p0.4600.063P(=)×P绿×P×P×P×P×P×p0.697×p0.4606.80×105

由于0.063>6.80×10−5,因此,朴素贝叶斯分类器将测试样本“测1”判别为“好瓜”。

朴素贝叶斯分类的优缺点

  • 优点:
    1.时空开销都非常小
    2.训练预测的时间开销
  • 缺点:
    简化的假设,不太贴合实际,因为独立性假设往往不成立。在属性个数多的时候或者属性之间相关性较大的时候分类效果不好

在属性相关性较小时,朴素贝叶斯性能最为良好。故有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

朴素贝叶斯关键问题

  • 对大样本适配性更好
  • 特征连续值怎么用?分桶离散化、正态分布-高斯分布的概率估计(这也是为啥上述例子对于【密度】连续特征值要假设符合正态分布来获得他的概率估计)
  • 概率估计:极大似然估计、频率估计
  • 概率的拉普拉斯平滑:防止0概率的连乘效应

拉普拉斯平滑和极大似然估计后续单独出文章聊聊

朴素贝叶斯企业中的应用案例

  • 推荐系统中

    基于用户标签的资源推荐
    P(资源|标签) = P(标签|资源)* P(资源)/P(标签)

  • NLP

    文本分类最快最简单的版本
    例如:
    1>反作弊:广告识别/水军识别
    2>拼写检查
    3>新闻分类
    4>情感分析

基于朴素贝叶斯的垃圾邮件分类

import os
import pandas as pd
import jieba
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import BernoulliNB

# 分词
def word_segment(line, stopwords_list):
    word_list = []
    for word in jieba.cut(line):
        if word.isalpha() and word not in stopwords_list:
            word_list.append(word)
    return " ".join(word_list)

# 特征转换-文本特征提取(将中文或英文单词 进行编码为 0101这样的特征数据,这样算法才能进行计算)
def feature_transform(texts):
    # 会将文本中的词语转换为词频矩阵
    transformer = CountVectorizer()
    # 转换成word-count的dataframe
    word_cnt_df = pd.DataFrame(transformer.fit_transform(texts).toarray())
    # 将word-count的dataframe 按列求和 得到每个词整体词频
    word_cnt_freq = pd.DataFrame(word_cnt_df.apply(sum, axis=0))
    # 筛选出词频 > 5的词特征列
    word_keep = [word_cnt_freq.index[i] for i in range(word_cnt_freq.shape[0]) if word_cnt_freq.iloc[i, 0] > 5]
    # 得到最终特征集合
    features = word_cnt_df[word_keep]
    return features

# 加载数据 并 划分数据集为测试和训练数据集
def load_data_and_split_dataset(base_path):
    # 读取邮件数据、停止词
    email_file_name = os.path.join(base_path, "chinesespam.xlsx")
    stopword_file_name = os.path.join(base_path, "stopwords.txt")
    stopwords_list = [i.strip() for i in open(stopword_file_name, 'r', encoding='utf8').readlines()]
    email_df = pd.read_excel(email_file_name, sheet_name=0)
    email_df['text'] = email_df.text.apply(lambda x: word_segment(x, stopwords_list))
    # 提取文本特征
    features = feature_transform(email_df['text'])
    # 提取文本标签(垃圾邮件还是正常邮件)
    labels = email_df['type']
    # 划分训练数据集、测试数据集
    x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=1)
    return x_train, x_test, y_train, y_test

# 模型训练
def model_training(x_train, y_train):
    model = BernoulliNB()
    model.fit(x_train, y_train)
    return model

# 测试模型
base_path = "./raw_data"
x_train, x_test, y_train, y_test = load_data(base_path)
model = model_training(x_train, y_train)
print(model.score(x_test, y_test))

输出:注意:以上是在jupyter notebook上测试编码流程

Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\bangsun\AppData\Local\Temp\jieba.cache
Loading model cost 0.843 seconds.
Prefix dict has been built successfully.

0.9

chinesespam.xlsx、stopwords.txt 文件若没有的话,可以私聊我或评论找我

以上,若有表述不到位的地方,及时指出,谢谢

你可能感兴趣的:(AI基础,朴素贝叶斯,贝叶斯算法,贝叶斯原理,垃圾邮件分类,分类算法)