机器学习入门之《统计学习方法》笔记——朴素贝叶斯法

  朴素贝叶斯(naive Bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。


目录

    • 朴素贝叶斯法
    • 参数估计
      • 极大似然估计
      • 学习与分类算法
        • 算法 朴素贝叶斯算法
      • 贝叶斯估计
    • 小结
    • 参考文章


朴素贝叶斯法

  设输入空间 XRn X ⊆ R n n n 维向量的集合,输出空间为类标记集合 Y={c1,c2,...,cK} Y = { c 1 , c 2 , . . . , c K } ,输入特征向量 xX x ∈ X ,输出类标记为 yY y ∈ Y P(X,Y) P ( X , Y ) X X Y Y 的联合概率分布,数据集

T={(x1,y1),(x2,y2),...,(xn,yn)} T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) }

P(X,Y) P ( X , Y ) 独立同分布产生。

  朴素贝叶斯法就是通过训练集来学习联合概率分布 P(X,Y) P ( X , Y ) .具体就是从先验概率分布和条件概率分布入手,俩概率相乘即可得联合概率。

  称之为朴素是因为将条件概率的估计简化了,对条件概率分布作了条件独立性假设,这也是朴素贝叶斯法的基石,假设如下

P(X=x|Y=ck)=P(X(1)=x(1),...,X(n)=x(n)|Y=ck) P ( X = x | Y = c k ) = P ( X ( 1 ) = x ( 1 ) , . . . , X ( n ) = x ( n ) | Y = c k )

k=1,2,...,K k = 1 , 2 , . . . , K

  这个公式在之前的假设条件下等价于

j=inP(X(j)=x(j)|Y=ck) ∏ j = i n P ( X ( j ) = x ( j ) | Y = c k )

  对于给定的输入向量 x x ,通过学习到的模型计算后验概率分布 P(Y=Ck|X=x) P ( Y = C k | X = x ) ,后验分布中最大的类作为 x x 的输出结果,根据贝叶斯定理可知后验概率为

P(Y=ck|X=x)=P(X=x|Y=ck)P(Y=ck)kP(X=x|Y=ck)P(Y=ck) P ( Y = c k | X = x ) = P ( X = x | Y = c k ) P ( Y = c k ) ∑ k P ( X = x | Y = c k ) P ( Y = c k )

  其中 kP(X=x|Y=ck)P(Y=ck)P(X=x) ∑ k P ( X = x | Y = c k ) P ( Y = c k ) ⇔ P ( X = x )

  所有 ck c k P(X=x) P ( X = x ) 都是相同的,这样我们可以把输出结果化简成

y=argmaxckP(Y=ck)jP(X(j)=x(j)|Y=ck) y = a r g max c k P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) | Y = c k )

  这样,就了解了朴素贝叶斯法的基本原理了,下面要介绍的是参数估计。

参数估计

极大似然估计

  我们已经知道对于给定的输入向量 x x ,其输出结果可以表示为

y=argmaxckP(Y=ck)jP(X(j)=x(j)|Y=ck) y = a r g max c k P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) | Y = c k )

  可以使用极大似然估计法来估计相应的概率。先验概率 P(Y=ck) P ( Y = c k ) 的极大似然估计是

P(Y=ck)=i=1NI(yi=ck)N,k=1,2,...,K P ( Y = c k ) = ∑ i = 1 N I ( y i = c k ) N , k = 1 , 2 , . . . , K

   设第 j j 个特征 x(j) x ( j ) 可能的取值的集合为 {aj1,aj2,...,ajsj} { a j 1 , a j 2 , . . . , a j s j } ,条件概率 P(X(j)=ajl|Y=ck) P ( X ( j ) = a j l | Y = c k ) 的极大似然估计是

P(X(j)=ajl,Y=ck)=i=1NI(x(j)i=ajl,yi=ck)i=1NI(yi=ck) P ( X ( j ) = a j l , Y = c k ) = ∑ i = 1 N I ( x i ( j ) = a j l , y i = c k ) ∑ i = 1 N I ( y i = c k )

j=1,2,...,n;l=1,2,...,Sj;k=1,2,...,K j = 1 , 2 , . . . , n ; l = 1 , 2 , . . . , S j ; k = 1 , 2 , . . . , K

学习与分类算法

  下面给出朴素贝叶斯法的学习与分类算法。

算法 (朴素贝叶斯算法)

输入: 训练数据 T={(x1,y1),(x2,y2),...,(xn,yn)} T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) } , 其中 xi=(x(1)i,x(2)i,...,x(n)i)T x i = ( x i ( 1 ) , x i ( 2 ) , . . . , x i ( n ) ) T x(j)i{aj1,aj2,...,ajsj} x i ( j ) ∈ { a j 1 , a j 2 , . . . , a j s j } j=1,2,...,n j = 1 , 2 , . . . , n l=1,2,...,Sj l = 1 , 2 , . . . , S j yi{c1,c2,...,cK} y i ∈ { c 1 , c 2 , . . . , c K } ;实例 x x

输出: 实例 x x 的分类.

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

P(Y=ck)=i=1NI(yi=ck)N,k=1,2,...,K P ( Y = c k ) = ∑ i = 1 N I ( y i = c k ) N , k = 1 , 2 , . . . , K

P(X(j)=ajl,Y=ck)=i=1NI(x(j)i=ajl,yi=ck)i=1NI(yi=ck) P ( X ( j ) = a j l , Y = c k ) = ∑ i = 1 N I ( x i ( j ) = a j l , y i = c k ) ∑ i = 1 N I ( y i = c k )

j=1,2,...,n;l=1,2,...,Sj;k=1,2,...,K j = 1 , 2 , . . . , n ; l = 1 , 2 , . . . , S j ; k = 1 , 2 , . . . , K

(2) 对于给定的实例 x=(x(1),x(2),...,x(n))T x = ( x ( 1 ) , x ( 2 ) , . . . , x ( n ) ) T ,计算

P(Y=ck)jP(X(j)=x(j)|Y=ck),k=1,2,...,K P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) | Y = c k ) , k = 1 , 2 , . . . , K

(3) 确定实例 x x 的类

y=argmaxckP(Y=ck)jP(X(j)=x(j)|Y=ck) y = a r g max c k P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) | Y = c k )

例子:试由下表的训练数据学习一个朴素贝叶斯分类器并确定

x=(2,S)T x = ( 2 , S ) T
的类标记,表中 X(1),X(2) X ( 1 ) , X ( 2 ) 为特征, Y Y 为类标记。

机器学习入门之《统计学习方法》笔记——朴素贝叶斯法_第1张图片

python代码如下:

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()

  得到结果:

The result: [[ 0.02222222  0.06666667]
 [ 1.         -1.        ]]

贝叶斯估计

  极大似然估计的一个可能是会出现所要估计的概率值为0的情况,这时会影响到后验概率的计算结果,解决这一问题的方法是采用贝叶斯估计,具体的只需要在极大似然估计的基础上加多一个参数即可。

Pλ(X(j)=ajl,Y=ck)=i=1NI(x(j)i=ajl,yi=ck)+λi=1NI(yi=ck)+Sjλ,λ0 P λ ( X ( j ) = a j l , Y = c k ) = ∑ i = 1 N I ( x i ( j ) = a j l , y i = c k ) + λ ∑ i = 1 N I ( y i = c k ) + S j λ , λ ≥ 0

  当 λ=0 λ = 0 时就是最大似然估计。常取 λ=1 λ = 1 ,这时称为拉普拉斯平滑(Laplace smoothing)。

小结

  朴素贝叶斯法高效,且易于实现,但是其缺点就是分类的性能不一定很高。

参考文章

  1. 统计学习方法(四)——朴素贝叶斯法
  2. 朴素贝叶斯分类器的应用
  3. 李航统计学习方法——算法3朴素贝叶斯法
  4. 李航《统计学习方法》朴素贝叶斯分类器实现

你可能感兴趣的:(人工智能,机器学习,机器学习笔记)