美文网首页
朴素贝叶斯法

朴素贝叶斯法

作者: cccshuang | 来源:发表于2019-01-11 17:12 被阅读0次

    理论

    公式推导

    朴素贝叶斯法是基于贝叶斯定理和特征条件独立假设的分类方法,即对给定的输入 x,预测其类别 y
    此方法的思路是首先由训练数据计算 P(Y)P(X|Y) 的估计,然后得到联合概率分布
    P(X,Y) = P(Y)P(X|Y)
    之后利用贝叶斯定理及学到的联合概率分布计算 X 属于类别 Y 的概率
    P(Y|X) = \frac{P(X,Y)}{P(X)} = \frac{P(Y)P(X|Y)}{\mathop{\sum}_{Y}P(Y)P(X|Y)}
    对于给定的输入 x,通过上式计算 x 属于类别 c_k 的概率 P(Y=c_k|X=x),即
    P(Y=c_k|X=x) = \frac{P(Y=c_k)P(X=x|Y=c_k)}{\mathop{\sum}_{k}P(Y=c_k)P(X=x|Y=c_k)}
    又由朴素贝叶斯法的特征条件独立性假设,有
    \begin{equation}\begin{split} P(X=x|Y=c_k) &=P( X^{(1)}=x^{(1)},\cdots,X^{(n)}=x^{(n)} | Y=c_k )\\\\ &= \prod_{j=1}^{n} P(X^{(j)}=x^{(j)}|Y=c_k) \end{split}\end{equation}
    其中,xn 维向量,x^{(j)}x 的第 j 个特征。故
    P(Y=c_k|X=x) = \frac{P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}{\mathop{\sum}_{k}P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)} , k=1,2,\dots,K
    x 分到后验概率最大的类中,朴素贝叶斯分类器可表示为
    y = f(x) = arg \max_{c_k} \frac{P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}{\mathop{\sum}_{k}P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}
    又因为上式中分母对于所有 c_k 都是相同的,故上式可以简化为
    y = arg \max_{c_k} P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)

    由上式可知,只要由训练数据估计出每一个类别的概率 P(Y=c_k) 和输入的每一个特征值在某一类别下的概率 P(X^{(j)}=x^{(j)}|Y=c_k),便可进行预测。下面介绍进行估计的两种方法。

    参数估计

    极大似然估计

    假设训练数据集为 T = \\{(x_1,y_1),\dots,(x_n,y_n)\\}
    先验概率 P(Y=c_k) 的极大似然估计为
    P(Y=c_k) = \frac{\sum_{i=1}^{N}I(y_i=c_k)}{N}
    设第 j 个特征 x^{(j)} 可能取值的集合为 \\{a_{j1},\dots,a_{jS_j}\\},条件概率 P(X^{(j)}=a_{jl}|Y=c_k) 的极大似然估计为
    P(X^{(j)}=a_{jl}|Y=c_k) = \frac{\sum_{i=1}^{N}I(x_{i}^{(j)}=a_{jl},y_i=c_k)}{\sum_{i=1}^{N}I(y_i=c_k)}
    j=1,2,\dots,n;l=1,2,\dots,S_j;k=1,2,\dots,K
    其中,x_{i}^{j} 是第 i 个样本的第 j 个特征;a_{jl} 是第 j 个特征可能取的第 l 个值; I 为指示函数,满足取 1,否则取 0

    贝叶斯估计

    极大似然估计可能会出现所要估计的概率值为0的情况,在随机变量各个取值的频数上赋予一个正数 \lambda \gt 0,常取 \lambda = 1,称为拉普拉斯平滑。
    P_{\lambda}(Y=c_k) = \frac{\sum_{i=1}^{N}I(y_i=c_k)+{\lambda}}{N+K\lambda}
    P_{\lambda}(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_j\lambda}

    实现

    训练一个朴素贝叶斯分类器并确定 x=(2,S)^T 的类标记 y。表中 X^{(1)}X^{(2)} 为特征,取值集合分别为 A_1 = \\{1,2,3\\}A_2 = \\{S,M,L\\}Y 为类标记,Y \in C =\\{1,-1\\}

    训练数据 train_data.csv

    ID,X1,X2,Y
    1,1,S,-1
    2,1,M,-1
    3,1,M,1
    4,1,S,1
    5,1,S,-1
    6,2,S,-1
    7,2,M,-1
    8,2,M,1
    9,2,L,1
    10,2,L,1
    11,3,L,1
    12,3,M,1
    13,3,M,1
    14,3,L,1
    15,3,L,-1
    

    代码实现 naivebayes.py

     # -*- coding: utf-8 -*-
    import pandas as pd
    
    
    def add2dict(thedict, key_a, key_b, val):
        if key_a in thedict.keys():
            thedict[key_a].update({key_b: val})
        else:
            thedict.update({key_a:{key_b: val}})        
    
    def conditionalProbability(obj, attribute, clazz, lambd):
        C = obj[clazz].value_counts()
        label = C.index
        counts = C.values
    
        CP = dict()
        for i in range(label.size):
            for j in range(attribute.size):
                temp = obj[obj[clazz] == label[i]][attribute[j]] 
                CC = temp.value_counts()
                Sj = obj[attribute[j]].value_counts().index.size
                P = ( CC + lambd) / ( counts[i] + Sj*lambd)
                add2dict(CP,label[i],attribute[j],P) # Using dict to store probabilities
        return CP
    
    def priorProbability(obj, clazz, lambd):
        C = obj[clazz].value_counts()
        N = float(obj.index.size)
        K = float(C.index.size)
        P = ( C + lambd ) / ( N + K*lambd)
        return P
    
    def predicts(x, obj, attribute, clazz,lambd):
        label = obj[clazz].value_counts().index # Types of class
        P = priorProbability(obj,clazz, lambd) # Prior probability
        CP = conditionalProbability(obj, attribute, clazz, lambd) # Conditional probability
        max_p = 0 # Probability of the most likely class
        max_c = '' # The most likely class
        for i in range(label.size):
            cur_max_p = 1
            for j in range(attribute.size):
                cur_max_p *= CP[label[i]][attribute[j]][x[j]]
            cur_max_p *= P[label[i]]
            if cur_max_p > max_p:
                max_c = str(label[i])
                max_p = cur_max_p
        return [max_c,max_p]
    
    df = pd.read_csv('train_data.csv', encoding='utf-8')
    [max_c,max_p] = predicts([2,'S'],df, df.columns.drop('Y').drop('ID'), 'Y', 1)
    print(max_c,max_p)
    

    相关文章

      网友评论

          本文标题:朴素贝叶斯法

          本文链接:https://www.haomeiwen.com/subject/ffaxdqtx.html