zoukankan      html  css  js  c++  java
  • 机器学习——朴素贝叶斯法

    1 前言

      朴素贝叶斯算法,牵扯到一个概念是判别式和生成式。

    • 判别式:就是直接学习出特征输出 $Y$ 和特征 $X$ 之间的关系,如决策函数 $Y=f(X)$,或者从概率论的角度,求出条件分布 $P(Y|X)$。代表算法有决策树、KNN、逻辑回归、支持向量机、随机条件场CRF等
    • 生成式:就是直接找出特征输出 $Y$ 和特征 $X$ 的联合分布 $P(X,Y)$,然后用 $P(Y|X)=frac{P(X,Y)}{P(X)}$ 得出。代表算法有朴素贝叶斯、隐式马尔可夫链等。

    2 朴素贝叶斯原理

      朴素贝叶斯算法基于贝叶斯定理和特征条件独立假设。

    • 贝叶斯定理
    • 特征条件独立:特征条件独立假设 $X$ 的 $n$ 个特征在类确定的条件下都是条件独立的。大大简化了计算过程,但是因为这个假设太过严格,所以会相应牺牲一定的准确率。这也是为什么称呼为朴素的原因。

    3 朴素贝叶斯算法

    • 输入:训练集为 $m$ 个样本 $n$ 个维度 $T={(x_1,y_1),(x_2,y_2),...,(x_m,y_m)}$,共有 $K$ 个特征输出类别,分别为 $yin{{c_1,c_2,...,c_K}}$。
    • 输出:实例 $x(test)$ 的分类。
    • 算法流程如下:

      1.首先计算 $Y$ 的 $K$ 个先验概率
        $P(Y=c_k)$
      2.然后计算条件概率分布:
        $P(X=x|Y=c_k)=P(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)}|Y=c_k)$
         由于上式的参数是指数级别,无法计算。所以根据特征条件独立假设,可以化简为下式。
        $P(X=x|Y=c_k)=prod_{j=1}^nP(X^{(j)}=x^{(j)}|Y=c_k)$
      3.根据贝叶斯原理,计算后验概率:

        $P(Y=c_k|X=x)=frac{P(X=x|Y=c_k)P(Y=c_k)}{sum limits _kP(X=x|Y=c_k)P(Y=c_k)}$

       其中$sum limits _kP(X=x|Y=c_k)P(Y=c_k)Leftrightarrow P(X=x)$
       带入 $P(X=x|Y=c_k)=prod limits _{j=1}^nP(X^{(j)}=x^{(j)}|Y=c_k)$ 得到

        $P(Y=c_k|X=x)=frac{prod limits_{j=1}^nP(X^{(j)}=x^{(j)}|Y=c_k)P(Y=c_k)}{sum limits _kprod limits_{j=1}^nP(X^{(j)}=x^{(j)}|Y=c_k)P(Y=c_k)}$

       由于所有$c_k$的$P(X=x)$都是相同的,这样我们可以把输出结果化简成,上式再变为如下:
        $P(Y=c_k|X=x)=prod limits_{j=1}^nP(X^{(j)}=x^{(j)}|Y=c_k)P(Y=c_k)$
      4.计算 $X(test)$ 的类别
        $y_{(test)}=arg   underset{c_k}{max} prod limits_{j=1}^nP(X^{(j)}=x_{(test)}^{(j)}|Y=c_k)P(Y=c_k)$
         从上面的计算可以看出,没有复杂的求导和矩阵运算,因此效率很高。

    4 极大似然估计

      从上节知道对于给定的输入向量 $x$,其输出结果可以表示为
        $y = arg max limits_{c_k} P(Y=c_k) prod_jP(X^{(j)}=x^{(j)}|Y=c_k)$
      可以使用极大似然估计法来估计相应的概率。
      先求先验概率$P(Y=c_k)$

        $P(Y=c_k)=frac{sum limits_{i=1}^NI(y_i=c_k)} {N}, k=1,2,...,K$

      设第 $j$ 个特征 $x^{(j)}$ 可能的取值的集合为 $left { a_{j1} ,a_{j2} ,...,a_{js_j} ight }$ ,条件概率 $P(X^{(j)}=a_{jl}|Y=c_k)$ 的极大似然估计是

        $P(X^{(j)}=a_{jl},Y=c_k)=frac{sum limits_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)} {sum limits_{i=1}^NI(y_i=c_k)}$

      其中 $j=1,2,...,n; l=1,2,...,S_j;k=1,2,...,K$

    5 朴素贝叶斯法学习与分类算法

    • 输入: 训练数据 $T ={ (x_1,y_1),(x_2,y_2),...,(x_n,y_n) }$ , 其中 $x_i = (x_i^{(1)},x_i^{(2)},...,x_i^{(n)} )^T$ ,$x_i^{(j)}in { a_{j1} ,a_{j2} ,...,a_{js_j}}$,$j=1,2,...,n$,$l=1,2,...,S_j$,$y_i in{ c_1,c_2,...,c_K }$;实例 $x$ ;
    • 输出: 实例 $x$ 的分类。
    • 算法流程如下

      1:计算先验概率及条件概率
        $P(Y=c_k)=frac{sum limits_{i=1}^NI(y_i=c_k)} {N}, k=1,2,...,K$

        $P(X^{(j)}=a_{jl},Y=c_k)=frac{sum limits_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)} {sum limits_{i=1}^NI(y_i=c_k)}$
         其中$j=1,2,...,n; l=1,2,...,S_j;k=1,2,...,K$
      2:对于给定的实例$x = (x^{(1)},x^{(2)},...,x^{(n)} )^T$,计算

        $P(Y=c_k) prod_jP(X^{(j)}=x^{(j)}|Y=c_k),k=1,2,...,K$
      3:确定实例 $x$ 的类
        $y = arg max limits_{c_k} P(Y=c_k) prod_jP(X^{(j)}=x^{(j)}|Y=c_k)$

    6 朴素贝叶斯例子

      试由下表的训练数据学习一个朴素贝叶斯分类器并确定 $x=(2,S)^T$ 的类标记,表中 $X^{(1)},X^{(2)}$为特征, $Y$ 为类标记。


      代码如下:

      
    import numpy as np
    
    #构造NB分类器
    def Train(X_train, Y_train, feature):
        global class_num,label
        class_num = 2           #分类数目
        label = [1, -1]         #分类标签
        feature_len = 3         #特征长度
        #构造3×2的列表
        feature = [[1, 'S'],    
                   [2, 'M'],
                   [3, 'L']]
    
        prior_prob = np.zeros(class_num)                         # 初始化先验概率
        con_prob = np.zeros((class_num,feature_len,2))   # 初始化条件概率
    
        positive_count = 0     #统计正类
        negative_count = 0     #统计负类
        for i in range(len(Y_train)):
            if Y_train[i] == 1:
                positive_count += 1
            else:
                negative_count += 1
        prior_prob[0] = positive_count / len(Y_train)    #求得正类的先验概率
        prior_prob[1] = negative_count / len(Y_train)    #求得负类的先验概率
    
        '''
        con_prob是一个2*3*2的三维列表,第一维是类别分类,第二维和第三维是一个3*2的特征分类
        '''
        #分为两个类别
        for i in range(class_num):
            #对特征按行遍历
            for j in range(feature_len):
                #遍历数据集,并依次做判断
                for k in range(len(Y_train)): 
                    if Y_train[k] == label[i]: #相同类别
                        if X_train[k][0] == feature[j][0]:
                            con_prob[i][j][0] += 1
                        if X_train[k][1] == feature[j][1]:
                            con_prob[i][j][1] += 1
    
        class_label_num = [positive_count, negative_count]  #存放各类型的数目
        for i in range(class_num):
            for j in range(feature_len):
                con_prob[i][j][0] = con_prob[i][j][0] / class_label_num[i]  #求得i类j行第一个特征的条件概率 
                con_prob[i][j][1] = con_prob[i][j][1] / class_label_num[i]  #求得i类j行第二个特征的条件概率
    
        return prior_prob,con_prob
    
    #给定数据进行分类
    def Predict(testset, prior_prob, con_prob, feature):
        result = np.zeros(len(label))
        for i in range(class_num):
            for j in range(len(feature)):
                if feature[j][0] == testset[0]:
                    conA = con_prob[i][j][0]
                if feature[j][1] == testset[1]:
                    conB = con_prob[i][j][1]
            result[i] = conA * conB * prior_prob[i]
    
        result = np.vstack([result,label])
    
        return result
    
    
    def main():
        X_train = [[1, 'S'], [1, 'M'], [1, 'M'], [1, 'S'],  [1, 'S'],
                   [2, 'S'], [2, 'M'], [2, 'M'], [2, 'L'],  [2, 'L'],
                   [3, 'L'], [3, 'M'], [3, 'M'], [3, 'L'],  [3, 'L']]
        Y_train = [-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1]   
    
        #构造3×2的列表
        feature = [[1, 'S'],    
                   [2, 'M'],
                   [3, 'L']]
    
        testset = [2, 'S']
    
        prior_prob, con_prob= Train(X_train, Y_train, feature)
    
        result = Predict(testset, prior_prob, con_prob, feature)
        print('The result:',result)
    
    main()
     
    View Code

    7 朴素贝叶斯算法小结

      朴素贝叶斯算法的主要原理基本已经做了总结,这里对朴素贝叶斯的优缺点做一个总结。

    朴素贝叶斯的主要优点

    1. 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。
    2. 对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。
    3. 对缺失数据不太敏感,算法也比较简单,常用于文本分类。

    朴素贝叶斯的主要缺点

    1. 朴素贝叶斯模型的特征条件独立假设在实际应用中往往是不成立的。
    2. 如果样本数据分布不能很好的代表样本空间分布,那先验概率容易测不准。
    3. 对输入数据的表达形式很敏感。

    参考文献

    1:朴素贝叶斯算法(Naive Bayes)
    2:机器学习入门之《统计学习方法》笔记——朴素贝叶斯法

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/14879028.html

  • 相关阅读:
    记录。短信网关.
    TP 笔记~
    FUCK IE FLASH(inline hook)
    API HOOK(MessageBoxA)
    inline hook MessageBox(2)
    c#线程中使用 dataset
    匈牙利算法解决二分图最大匹配
    C#:Array类的排序
    C#:属性
    C#:结构
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/14879028.html
Copyright © 2011-2022 走看看