6. 朴素贝叶斯算法实现垃圾分类实战详解

1 介绍

分类预测中,以概率论作为基础的算法较少,而朴素贝叶斯便是其中一种,它实现简单、预测分类的效率还很高,因此使用频率也很高。

由于它基于概率论,因此这里首先来了解一下概率论的基础。

如果事件A发送的概率表示为P(A)P(A),事件B发生的概率为P(B)P(B),那么事件A、B同时发生的概率我们就可以表示为P(AB)P(AB)

在该基础之上,如果我想要求当事件B发生之后A发生的概率为多少,就被称为条件概率,其计算公式为:P(AB)=P(AB)P(B)P(A \mid B)=\frac{P(AB)}{P(B)}

有了B事件发生之后A事件发生的概率公式,那么如果求P(BA)P(B|A)呢?也就是在A事件发生之后的B事件发生的概率?

这便是贝叶斯定理,其推导过程如下:

P(BA)=P(AB)P(A)P(B \mid A)=\frac{P(AB)}{P(A)}

P(AB)=P(AB)×P(B)P(AB)=P(A\mid B)\times P(B)

结合上面两个式子得到完整的贝叶斯定理:

P(BA)=P(AB)P(A)=P(AB)×P(B)P(A)P(B \mid A) = \frac{P(AB)}{P(A)}=\frac{P(A \mid B)\times P(B)}{P(A)}

其中P(A)P(A)P(B)P(B) 这种已知的概率,称为先验概率,它是通过过往经验和分析得到的概率,比如抛硬币我们会认为其概率就是0.5。

当事件发生之后求的反向概率,则被称为后验概率,比如上式中的P(BA)P(B \mid A) 就是通过P(A)P(A)P(B)P(B)先验概率求出来的反向条件概率。

而朴素贝叶斯的原理就是将贝叶斯原理与条件独立结合而成的算法:

P(类别 \mid 特征) = \frac{P(特征 \mid 类别)\times P(类别)}{P(特征)}

相当于就是将A换为了特征、B换为了类别。

那么我们现在就可以通过这个公式求出当特征概率已知的情况下,它类别概率是什么,这不正好满足我们分类的需求嘛!

其中右边类别的概率、特征的概率、特征在类别下的概率都是已知的。

朴素贝叶斯中的朴素,含义就是假设预测的各个属性之间相互独立、每个属性独立的对分类结果产生影响。

比如判断一朵花的类型有叶长、花瓣数量两个特征,那么前面我们预测的方式都是结合这两者一起来预测花朵的类型,而在朴素贝叶斯中,就认为这两个特征是独立的影响类别判断、而不会将其结合在一起判断。

这样做使得其变得简单而简洁,但自然的,在某些情况下就会牺牲一定的分类准确度。

2 朴素贝叶斯算法实现

有了上面的基础,下面我们就可以来介绍朴素贝叶斯算法的python代码实现逻辑了。

流程如下:

  1. 假设X=\left\{x_1,x_2, \dots ,x_n\right\}为训练数据,而xix_i是训练数据的特征值。
  2. 假设Y=\left\{y_1,y_2,\dots,y_m \right\}为类别集合
  3. 计算每种类别在特征值条件下的概率:P(y_1\mid x),P(y_2\mid x),\dots,P(y_m\mid x)
  4. 寻找P(y_1\mid x),P(y_2\mid x),\dots,P(y_m\mid x)中最大的概率P(ykx)P(y_k\mid x),则x就属于类别yky_k

而根据前面朴素贝叶斯算法原理,这里比较所有的P(yix)P(y_i\mid x)大小,实际上比较的是P(类别_i \mid 特征),由于根据上面的转换公式,它等于:\frac{P(特征 \mid 类别)\times P(类别)}{P(特征)}

所有的P(特征)分母值都相同,所以相当于就是比较分子P(特征 \mid 类别)\times P(类别)的乘积大小。

那么如何计算得到这两个值呢?这就需要用到极大似然估计法贝叶斯估计法了。

为了更加直观的看到效果,这里先给出一组测试数据:

def gen_data():
    # 生成示例数据
    data = {
        "x": ["g", "g", "r", "r", "b", "g", "g", "r", "b", "b", "g","r", "g", "r", "b"],
        "y": ["m", "s", "l", "s", "m", "s", "m", "s", "m", "l", "l", "s", "m", "m", "l"],
        "labels": ["A", "A", "A", "A","A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B"],
    }
    return data

这里的测试数据中,x、y为两个特征值,也就是X={x,y}X=\{x,y\}。labels则是一个类别,也就是Y={labels}Y=\{labels\}

2.1 极大似然估计

所谓极大似然估计,就是根据过往经验,推断出最有可能造成某个结果的参数值。

比如A箱子里面有999个白球、一个黑球,B箱子里面有999个黑球、一个白球。

那么当我说我抽出了要给白球时,你自然而然的就会认为我是从A箱子里面抽出来的,因为A箱子里面抽出白球的概率实在是太大了。

回到这里,我们求P(类别)时,可以认为它的概率就是它在训练数据中所有类别的占比,比如这里训练数据中的labels为其中一个类别,由于数据总共有15条,其中A占8条,B占7条,那么就能求出各自的概率分别为815\frac{8}{15}715\frac{7}{15}

此时对应的python代码为:

def get_P_labels(labels):
    labels = list(labels)  # 转换为 list 类型
    P_label = {}  # 设置空字典用于存入 label 的概率
    for label in labels:
        # 统计 label 标签在标签集中出现的次数再除以总长度
        P_label[label] = labels.count(label) / float(
            len(labels)
作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux