高斯朴素贝叶斯

TIME : 2018-05-17

sklearn.naive_bayes.GaussianNB


当特征是连续变量的时候,运用多项式模型就会导致很多P(xi|yk)=0P(xi|yk)=0(不做平滑的情况下),此时即使做平滑,所得到的条件概率也难以描述真实情况。所以处理连续的特征变量,应该采用高斯模型
公式:

image

参数:

GaussianNB(priors=None)

  • priors:默认None
属性:
  • priors:获取各个类标记对应的先验概率
  • class_prior_:同priors一样,都是获取各个类标记对应的先验概率,区别在于priors属性返回列表,class_prior_返回的是数组
  • class_count_:获取各类标记对应的训练样本数
  • theta_:获取各个类标记在各个特征上的均值
  • sigma_:获取各个类标记在各个特征上的方差
    [含义解释见下]
方法:
  • get_params(deep=True):返回priors与其参数值组成字典
  • set_params(**params):设置估计器priors参数
  • fit(X, y, sample_weight=None)*:训练样本,X表示特征向量,y类标记,sample_weight表各样本权重数组
  • partial_fit(X, y, classes=None, sample_weight=None):增量式训练,当训练数据集数据量非常大,不能一次性全部载入内存时,可以将数据集划分若干份,重复调用partial_fit在线学习模型参数,在第一次调用partial_fit函数时,必须制定classes参数,在随后的调用可以忽略
  • predict(X):直接输出测试集预测的类标记
  • predict_proba(X):输出测试样本在各个类标记预测概率值
  • predict_log_proba(X):输出测试样本在各个类标记上预测概率值对应对数值
  • score(X, y, sample_weight=None):返回测试样本映射到指定类标记上的得分(准确率)

例子:


西瓜书P152 : 密度 / 含糖 例子

#第一列是密度,第二列是含糖,两个属性
exam = [[0.697, 0.460],
     [0.774, 0.376],
     [0.634, 0.264],
     [0.608, 0.318],
     [0.556, 0.215],
     [0.403, 0.237],
     [0.481, 0.149],
     [0.437, 0.211],#8个为好瓜

     [0.666, 0.091],
     [0.243, 0.267],
     [0.245, 0.057],
     [0.343, 0.099],
     [0.639, 0.161],
     [0.657, 0.198],
     [0.360, 0.370],
     [0.593, 0.042],
     [0.719, 0.103]]#9个坏瓜

classes=[1, 1, 1, 1, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 0, 0]#类别:1为好瓜,0为坏瓜

.

x = np.array(exam)
y = np.array(classes)
clf = GaussianNB()
clf.fit(x, y)

#选取第一列作为例子
lsa = [[0.697], [0.774], [0.634],
       [0.608], [0.556], [0.403],
       [0.481], [0.437], [0.666],
       [0.243], [0.245], [0.343],
       [0.639], [0.657], [0.36],
       [0.593], [0.719]]

属性说明:


属性 theta_:均值
公式:样本均值公式 (1/n)*Σ(Xi)

print(clf.theta_)

>>output:
[[0.49611111 0.15422222]
 [0.57375    0.27875   ]]

#以第一列密度为例
#μ(密度,好瓜)
theta=(1/8)
(0.697+0.774+0.634+0.608+
0.556+0.403+0.481+0.437)

>>output: 0.5737500000000001 #和书中相同=0.574

属性 sigma_:方差
公式 : (1/n)*Σ(Xi-μ)^2
注意不是样本方差公式,所以为1/n
而西瓜书上是用的样本方差公式所以改为(1/(n-1))

print(clf.sigma_)

>>output:
[[0.03370254 0.01032862]
 [0.01460844 0.00891244]]

#以第一列密度为例
#σ^2
sigma=(1/8) * 
[ (0.697-μ)^2+(0.774-μ)^2+(0.634-μ)^2+(0.608-μ)^2+
  (0.556-μ)^2+(0.403-μ)^2+(0.481-μ)^2+(0.437-μ)^2  ] 

>>output: 0.014608437499999998 # 和书中相同,=0.129^2

属性 class_count_
属性 priors
属性 class_prior_

print(clf.class_count_) # 获取各类标记对应的训练样本数 
#>>output: [9. 8.]

print(clf.priors) # 获取各个类标记对应的先验概率
#>>output: None

print(clf.class_prior_)#同priors一样,都是获取各个类标记对应的先验概率,区别在于priors属性返回列表,class_prior_返回的是数组
#>>output:{'priors': None}

方法说明:


方法 predict_proba(X)
输出测试样本在各个类标记预测概率值

在属性中计算出μ和σ^2后,带入概率密度公式,求条件概率密度:
条件概率密度公式:

image

#以第一列密度为例
import math

test=0.697#测试数据
prob=1.0/(  np.sqrt(2*np.pi)*np.sqrt(sigma)  ) *  \
    np.exp(  math.pow((test-theta),2)  /  (-2*sigma) )
print(prob)

>>output:1.9624922010858186 #为什么不是书中的1.959?因为书中的sigma是/7 这里是/8
#所以将上面的sigma/8就能得到书中结果


#接下来讲解clf.predict_proba(0.697)计算过程
#实质就是后验概率所占的比例:  
P后验概率(好瓜)/ ( P后验概率(好瓜)+P后验概率(坏瓜) )
———————————————————————————————————————————————
在上面计算出两个 条件概率 密度:
好瓜的概率密度P(a)=1.96249220
坏瓜的概率密度P(b)=1.19415497
分别乘以先验概率密度:P(ci)
好瓜P(c=1)=8/17
坏瓜P(c=0)=9/17
得到后验概率的中间值(没有P(x),因为后面求比例会消去)
p(好瓜)=p(a)*P(c=1)=0.92352574
p(坏瓜)=p(b)*P(c=0)=0.63219969

最后计算后验概率(好瓜)比例:
p(预测=好瓜)=p(好瓜)/( p(好瓜)+p(坏瓜) )
=0.92352574/(0.92352574+0.63219969)=0.59363029

最后计算后验概率(坏瓜)比例:
p(预测=坏瓜)=p(坏瓜)/( p(好瓜)+p(坏瓜) )
=0.63219969/(0.92352574+0.63219969)=0.40636971
———————————————————————————————————————————————
#实际结果
clf.predict_proba(0.697)

>>output:[[0.40636971 0.59363029]]
#与上面计算一致

方法 :
fit(X, y, sample_weight=None)
priors
get_params(deep=True)
set_params(**params)
predict(X)
predict_proba(X)

#fit中权值说明
#独立代码,可直接运行
from sklearn.naive_bayes import GaussianNB  
x = np.array([[-1, -1], [-2, -2], [-3, -3],[-4,-4],[-5,-5], [1, 1], [2, 2], [3, 3]])  
y = np.array([1, 1, 1, 1, 1, 2, 2, 2])  
clf = GaussianNB() 
clf.fit(x,y,np.array([0.05,0.05,0.1,0.1,0.1,0.2,0.2,0.2]))  

#对于不平衡样本,类标记1在特征1均值及方差计算过程:
#即每个样本值乘以对应的权值,分母也一样
#μ= ((-1*0.05)+(-2*0.05)+(-3*0.1)+(-4*0.1+(-5*0.1)))/(0.05+0.05+0.1+0.1+0.1)=-3.375
#σ^2=((-1+3.375)**2*0.05 +(-2+3.375)**2*0.05+(-3+3.375)**2*0.1+(-4+3.375)**2*0.1+ \
#(-5+3.375)**2*0.1)/(0.05+0.05+0.1+0.1+0.1)=1.73437501

x = np.array(exam)
y = np.array(classes)
clf = GaussianNB(priors=[9/17.0,8/17.0])
clf.fit(x,y,np.array([1/17,1/17,1/17,1/17,1/17,1/17,1/17,1/17, 
1/17,1/17,1/17,1/17,1/17,1/17,1/17,1/17,1/17]))      #设置样本的权重相同且为1/17  

print(clf.priors)                #priors默认为None
#>>output:[0.5294117647058824, 0.47058823529411764] 

print(clf.get_params())          #返回priors与其参数值组成字典
#>>output:{'priors': [0.5294117647058824, 0.47058823529411764]}

clf.set_params(priors=None)      #设置估计器priors参数
print(clf.priors)
print(clf.get_params())
#>>output:None
#>>output:{'priors': None}

clf.predict([[-6,-6],[4,5]])     # 直接输出测试集预测的类标记 
#>>output:[1, 2]

clf.predict_log_proba([[-6,-6],[4,5]])     # 输出测试样本在各个类标记预测概率值
#>>output:[[  0.00000000e+00,  -9.06654487e+01],  
#>>output: [ -2.75124782e+01,  -1.12621024e-12]]

clf.score([[-6,-6],[-4,-2],[-3,-4],[4,5]],[1,1,2,2])   # 返回测试样本映射到指定类标记上的得分(准确率)  
#>>output: 0.75 

clf.score([[-6,-6],[-4,-2],[-3,-4],[4,5]],[1,1,2,2],sample_weight=[0.3 ,0.2,0.4,0.1])  
#>>output: 0.59999999999999998

方法 partial_fit(X, y, classes=None, sample_weight=None)
增量式训练,当训练数据集数据量非常大,不能一次性全部载入内存时,可以将数据集划分若干份,重复调用partial_fit在线学习模型参数,在第一次调用partial_fit函数时,必须制定classes参数,在随后的调用可以忽略

#独立代码,可直接运行
from sklearn.naive_bayes import GaussianNB

X = np.array([[-1, -1], [-2, -2], [-3, -3], [-4, -4], [-5, -5], [1, 1], [2, 2], [3, 3]])
y = np.array([1, 1, 1, 1, 1, 2, 2, 2])
clf = GaussianNB()   
clf.partial_fit(X, y, classes=[1, 2], sample_weight=np.array([0.05, 0.05, 0.1, 0.1, 0.1, 0.2, 0.2, 0.2]))

print(clf.theta_)
#>>output: [[-3.375 -3.375] #同上面权值不同下的均值计算

完整测试代码


import numpy as np
from sklearn.naive_bayes import GaussianNB

#密度 / 含糖
exam = [[0.697, 0.460],
        [0.774, 0.376],
        [0.634, 0.264],
        [0.608, 0.318],
        [0.556, 0.215],
        [0.403, 0.237],
        [0.481, 0.149],
        [0.437, 0.211],

        [0.666, 0.091],
        [0.243, 0.267],
        [0.245, 0.057],
        [0.343, 0.099],
        [0.639, 0.161],
        [0.657, 0.198],
        [0.360, 0.370],
        [0.593, 0.042],
        [0.719, 0.103]]
#密度列
lsa = [[0.697], [0.774], [0.634],
       [0.608], [0.556], [0.403],
       [0.481], [0.437], [0.666],
       [0.243], [0.245], [0.343],
       [0.639], [0.657], [0.36],
       [0.593], [0.719]]
#含糖列
lsb = [[0.460], [0.376], [0.264],
       [0.318], [0.215], [0.237],
       [0.149], [0.211],
       [0.091], [0.267], [0.057],
       [0.099], [0.161], [0.198],
       [0.370], [0.042], [0.103]]

#类别:1为好瓜,0为坏瓜
classes=[1, 1, 1, 1, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 0, 0]

x = np.array(exam)
y = np.array(classes)
clf = GaussianNB()
clf.fit(x, y)

print(clf.predict_proba([[0.697,0.460]]))
#>>output:[[0.04164757 0.95835243]]

#密度列测试:
x = np.array(lsa)
clf.fit(x, y)
print(clf.predict_proba([[0.697]]))
#>>output:[[0.40636971 0.59363029]]

print(clf.sigma_)
#>>output:[[0.03370254]
#          [0.01460844]] <=>0.129^2     和书中相同

print(clf.theta_)
#>>output:[[0.49611111]
#          [0.57375   ]]        和书中相同

参考https://blog.csdn.net/kancy110/article/details/72763276
参考https://blog.csdn.net/u012162613/article/details/48323777
参考书籍:<<机器学习>>周志华

你可能感兴趣的:(高斯朴素贝叶斯)