TIME : 2018-05-17
sklearn.naive_bayes.GaussianNB
當(dāng)特征是連續(xù)變量的時候,運(yùn)用多項式模型就會導(dǎo)致很多P(xi|yk)=0P(xi|yk)=0(不做平滑的情況下),此時即使做平滑,所得到的條件概率也難以描述真實情況。所以處理連續(xù)的特征變量,應(yīng)該采用高斯模型
公式:

參數(shù):
GaussianNB(priors=None)
- priors:默認(rèn)None
屬性:
- priors:獲取各個類標(biāo)記對應(yīng)的先驗概率
- class_prior_:同priors一樣,都是獲取各個類標(biāo)記對應(yīng)的先驗概率,區(qū)別在于priors屬性返回列表,class_prior_返回的是數(shù)組
- class_count_:獲取各類標(biāo)記對應(yīng)的訓(xùn)練樣本數(shù)
- theta_:獲取各個類標(biāo)記在各個特征上的均值
- sigma_:獲取各個類標(biāo)記在各個特征上的方差
[含義解釋見下]
方法:
- get_params(deep=True):返回priors與其參數(shù)值組成字典
- set_params(**params):設(shè)置估計器priors參數(shù)
- fit(X, y, sample_weight=None)*:訓(xùn)練樣本,X表示特征向量,y類標(biāo)記,sample_weight表各樣本權(quán)重數(shù)組
- partial_fit(X, y, classes=None, sample_weight=None):增量式訓(xùn)練,當(dāng)訓(xùn)練數(shù)據(jù)集數(shù)據(jù)量非常大,不能一次性全部載入內(nèi)存時,可以將數(shù)據(jù)集劃分若干份,重復(fù)調(diào)用partial_fit在線學(xué)習(xí)模型參數(shù),在第一次調(diào)用partial_fit函數(shù)時,必須制定classes參數(shù),在隨后的調(diào)用可以忽略
- predict(X):直接輸出測試集預(yù)測的類標(biāo)記
- predict_proba(X):輸出測試樣本在各個類標(biāo)記預(yù)測概率值
- predict_log_proba(X):輸出測試樣本在各個類標(biāo)記上預(yù)測概率值對應(yīng)對數(shù)值
- score(X, y, sample_weight=None):返回測試樣本映射到指定類標(biāo)記上的得分(準(zhǔn)確率)
例子:
西瓜書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_) # 獲取各類標(biāo)記對應(yīng)的訓(xùn)練樣本數(shù)
#>>output: [9. 8.]
print(clf.priors) # 獲取各個類標(biāo)記對應(yīng)的先驗概率
#>>output: None
print(clf.class_prior_)#同priors一樣,都是獲取各個類標(biāo)記對應(yīng)的先驗概率,區(qū)別在于priors屬性返回列表,class_prior_返回的是數(shù)組
#>>output:{'priors': None}
方法說明:
方法 predict_proba(X)
輸出測試樣本在各個類標(biāo)記預(yù)測概率值
在屬性中計算出μ和σ^2后,帶入概率密度公式,求條件概率密度:
條件概率密度公式:

#以第一列密度為例
import math
test=0.697#測試數(shù)據(jù)
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就能得到書中結(jié)果
#接下來講解clf.predict_proba(0.697)計算過程
#實質(zhì)就是后驗概率所占的比例:
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(預(yù)測=好瓜)=p(好瓜)/( p(好瓜)+p(壞瓜) )
=0.92352574/(0.92352574+0.63219969)=0.59363029
最后計算后驗概率(壞瓜)比例:
p(預(yù)測=壞瓜)=p(壞瓜)/( p(好瓜)+p(壞瓜) )
=0.63219969/(0.92352574+0.63219969)=0.40636971
———————————————————————————————————————————————
#實際結(jié)果
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中權(quán)值說明
#獨(dú)立代碼,可直接運(yùn)行
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]))
#對于不平衡樣本,類標(biāo)記1在特征1均值及方差計算過程:
#即每個樣本值乘以對應(yīng)的權(quán)值,分母也一樣
#μ= ((-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])) #設(shè)置樣本的權(quán)重相同且為1/17
print(clf.priors) #priors默認(rèn)為None
#>>output:[0.5294117647058824, 0.47058823529411764]
print(clf.get_params()) #返回priors與其參數(shù)值組成字典
#>>output:{'priors': [0.5294117647058824, 0.47058823529411764]}
clf.set_params(priors=None) #設(shè)置估計器priors參數(shù)
print(clf.priors)
print(clf.get_params())
#>>output:None
#>>output:{'priors': None}
clf.predict([[-6,-6],[4,5]]) # 直接輸出測試集預(yù)測的類標(biāo)記
#>>output:[1, 2]
clf.predict_log_proba([[-6,-6],[4,5]]) # 輸出測試樣本在各個類標(biāo)記預(yù)測概率值
#>>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]) # 返回測試樣本映射到指定類標(biāo)記上的得分(準(zhǔn)確率)
#>>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)
增量式訓(xùn)練,當(dāng)訓(xùn)練數(shù)據(jù)集數(shù)據(jù)量非常大,不能一次性全部載入內(nèi)存時,可以將數(shù)據(jù)集劃分若干份,重復(fù)調(diào)用partial_fit在線學(xué)習(xí)模型參數(shù),在第一次調(diào)用partial_fit函數(shù)時,必須制定classes參數(shù),在隨后的調(diào)用可以忽略
#獨(dú)立代碼,可直接運(yùn)行
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] #同上面權(quán)值不同下的均值計算
完整測試代碼
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
參考書籍:<<機(jī)器學(xué)習(xí)>>周志華