• 朴素贝叶斯法


    朴素贝叶斯法

    朴素贝叶斯(naive bayes) 法是基于贝叶斯定理和特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布,然后基于此分布,对给定的输入(x)利用贝叶斯定理求其后验概率最大的输出。

    一、朴素贝叶斯法的学习

    1.1 基本方法

    设输入空间(chi subseteq R^n)为n维向量的集合,输出空间维类标记集合(Y = {c_1,c_2,...,c_k})。输入特征向量(x in chi),输出为类标记(y in Y)(p(x,y))(x,y)的联合概率分布。训练的数据集:

    [ T = {(x_1,y_1),(x_2,y_2),...,(x_N,y_n} ]

    (p(x,y)) 独立同分布产生。

    要得到训练数据集的联合概率分布,先得学习以下先验概率和条件概率:

    [egin{align} p(Y=c_k) ,k=1,2,...,K otag \ p(X=x|Y=c_k) = p(x^{(1)},x^{(2)},...,x^{(n)}|c_k) ag{1} end{align} ]

    其中(1)的条件概率分布,不太好算,假设每个(x^{(l)})(a)个数值可供选择,那么计算(1)式就需要考虑(a^n)中情况。为了方便计算,朴素贝叶斯法引入了一个很强的假设,即条件概率分布具备条件独立性。

    [egin{align} p(X=x|Y=c_k) = p(x^{(1)},x^{(2)},...,x^{(n)}|c_k) &= p(x^{(1)}|c_k)p(x^{(2)}|c_k)...p(x^{(K)}|c_k) otag\ &=prod_{l=1}^{K} p(x^{(l)}|c_k) ag{2} end{align} ]

    这个假设也是朴素贝叶斯法名字的由来。这一假设使得算法变得简单,但是也会牺牲一定的分类准确度。

    我们由贝叶斯定理:

    [P(Y=c_k|X=x) = frac{P(X=x|Y=c_k)P(Y=c_k)}{sum_kP(X=x|Y=c_k)P(Y=c_k)} otag ]

    并将(2)式代入可得:

    [P(Y=c_k|X=x) = frac{P(Y=c_k)prod_j P(X^{(j)}=x^{(j)}|Y=c_k)}{sum_k P(Y=c_k) prod_j P(X^{(j)}=x^{(j)}|Y=c_k)} ag{3} ]

    (3)式即为朴素贝叶斯的基本公式,我们取后验概率最大的类别(c_k)。于是朴素贝叶斯分类器可以表示为 :

    [y = f(x) = mathop{argmax}_{c_k}frac{P(Y=c_k)prod_j P(X^{(j)}=x^{(j)}|Y=c_k)}{sum_k P(Y=c_k) prod_j P(X^{(j)}=x^{(j)}|Y=c_k)} ag{4} ]

    因为(4)中的分母对所有类别都是相同的,所以(4)式可转换为如下的式子:

    [y = f(x) = mathop{argmax}_{c_k}prod_j P(X^{(j)}=x^{(j)}|Y=c_k)P(Y=c_k) ag{5} ]

    1.2 后验概率最大化的含义

    朴素贝叶斯法中y=f(x)取得的是后验概率最大的类,为什么呢?其实最大化后验概率就等于期望风险最小化,假设选择0-1损失函数.

    [egin{equation} left{ egin{array}{**lr**} 1, Y ot= f(x) otag\ 0, Y = f(x) otag end{array} ight. end{equation} ]

    其中f(x)就是分类决策函数,这时期望风险函数就为:

    [R_{exp}(f) = E[L(Y,f(x))] otag ]

    取条件期望可得:

    [R_{exp}(f) = sum_{k=1}^K[L(c_k,f(X))]P(c_k|X) otag ]

    我们对上式子进行转化:

    [egin{align} R_{exp}(f) &= mathop{argmin}_{yin Y}sum_{k=1}^K[L(c_k,y)]P(c_k|X=x) otag\ &= mathop{argmin}_{yin Y} sum_{k=1}^KP(y ot=c_k|X=x) otag\ &= mathop{argmin}_{yin Y} sum_{k=1}^K[1-P(y=c_k|X=x)] otag\ &= mathop{argmax}_{yin Y}P(y=c_k|X=x) otag --最大化累加中的每一项 end{align} ]

    这样使得期望风险最小化就得到了后验概率最大化准则:

    [f(x) = mathop{argmax}_{c_k}P(c_k|X=x) otag ]

    二、朴素贝叶斯的参数估计

    2.1 极大似然估计

    根据(5)式我们可以得出使用朴素贝叶斯法我们需要求(P(Y=c_k))(P(X^{(j)}=x^{(j)}|Y=c_k))。我们可以通过极大似然估计的理论样本中得到上述两式的值:

    [P(Y=c_k) = frac{sum_{i=1}^{N} I(y_i=c_k)}{N} ag{6} ]

    [P(X^{(j)} = a_{jl}|Y=c_k) = frac{sum_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)}{sum_{i=1}^NI(y_i=c_k)} otag ]

    [j = 1,2,...,n;l=1,2,...,S_j;k=1,2,...,K otag \ s_j为第j个特征的取值个数 otag ]

    2.2 学习与分类算法

    朴素贝叶斯算法

    输入:训练数据(T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}),其中(x_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(j)}),x_i^{(j)})是第(j)个特征,(x_i^{(j)} = {a_{j1},a_{j2},...,a_{jS_j}},a_{jl})是第j个特征可能取的第(l)个值,(j=1,2,...,n,l=1,2,...,S_j,y_iin{c_1,c_2,...,c_K});实例(x)

    输出:实例x的分类

    (1) 计算先验概率及条件概率

    [P(Y=c_k) = frac{sum_{i=1}^N I(y_i = c_k)}{N} , k=1,2,...,K otag\ P(X^{(j)} = a_{jl}|Y=c_k) = frac{sum_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)}{sum_{i=1}^NI(y_i=c_k)} otag ]

    (2) 对于给定的实例(x=(x^{(1)},x^{P(2)},...,x^{(n)})),计算:

    [P(Y=c_k) prod_j P(X^{(j)}=x^{(j)}|Y=c_k) ]

    (3) 确定实例(x)的类:

    [y = f(x) = mathop{argmax}_{c_k}prod_j P(X^{(j)}=x^{(j)}|Y=c_k)P(Y=c_k) ]

    2.3 贝叶斯估计

    上诉的朴素贝叶斯算法中求(P(X^{(j)}=x^{(j)}|Y=c_k) 以及 P(Y=c_k))采用的极大似然估计法,但此法有一个缺点,就是(P(X^{(j)}=x^{(j)}|Y=c_k) 以及 P(Y=c_k))可能出现为0的情况,这样在最后求极大的式子中存在累积导致整个式子全为0,所以可以将上述的两式改为:

    [egin{align} P(Y=c_k) &= frac{sum_{i=1}^NI(y_i=c_k)+lambda}{N+Klambda} otag\ P(X^{(j)}=a_{jl} | Y=c_k) &= frac{sum_{i=1}^{N}I(x_i^{(j)}=a_{jl},y_i=c_k)+lambda}{sum_{i=1}^{N}I(y_i=c_k)+S_jlambda} otag end{align} ]

    三、代码部分

    3.1 数据

    下表中(X^{(1)},X^{(2)}) 为特征,取值的集合为(A_1={1,2,3},A_2={S,M,L}),确定(x=(2,S)^T)的类标记

    1 2 3 4 5 6 7 8 10 11 12 13 14 15
    (X^{(1)}) 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
    (X^{(2)}) S M M S S S M M L L L M M L L
    (Y) -1 -1 1 1 -1 -1 -1 1 1 1 1 1 1 1 -1
    import numpy as np
    import pandas as pd
    from collections import Counter
    
    # 生成所需的数据
    df = pd.DataFrame({
        'x1': pd.Series([1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]),
        'x2': pd.Series(['S', 'M', 'M', 'S', 'S', 'S', 'M', 'M', 'L', 'L', 'L', 'M', 'M', 'L', 'L']),
        'y': pd.Series([-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1]),
    })
    
    prov = {}
    x = (2, 'S')
    # 使用极大似然估计计算先验概率和条件概率
    c = Counter(df['y'])
    prov[1] = c[1] / df['y'].shape[0]
    prov[-1] = c[-1] / df['y'].shape[0]
    for key in dict(prov):
        # 计算后验概率
        a1 = np.sum(np.sum(df.loc[:, ['x1', 'y']] == [x[0], key], axis=1) == 2) / c[key]
        a2 = np.sum(np.sum(df.loc[:, ['x2', 'y']] == [x[1], key], axis=1) == 2) / c[key]
        prov[key] = prov[key] * a1 * a2
    ans = 0
    val = 0
    for key in dict(prov):
        if prov[key] > val:
            ans = key
            val = prov[key]
    print(ans)
    

    详细项目:github

  • 相关阅读:
    经典排序算法--快速排序
    经典排序算法——希尔排序
    经典排序算法——插入排序
    经典排序算法——选择排序
    经典排序算法——冒泡排序
    java递归求八皇后问题解法
    学习当前流行框架,同时也要自己去造建议的框架
    如何提高服务器并发处理能力
    数据的校验和空指针
    编写程序流程
  • 原文地址:https://www.cnblogs.com/Mrfanl/p/12002939.html
Copyright © 2020-2023  润新知