TIME : 2018-05-17
sklearn.naive_bayes.GaussianNB
当特征是连续变量的时候,运用多项式模型就会导致很多P(xi|yk)=0P(xi|yk)=0(不做平滑的情况下),此时即使做平滑,所得到的条件概率也难以描述真实情况。所以处理连续的特征变量,应该采用高斯模型
公式:
参数:
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后,带入概率密度公式,求条件概率密度:
条件概率密度公式:
#以第一列密度为例
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
参考书籍:<<机器学习>>周志华