統計學習方法 樸素貝葉斯 python實現

2021-09-25 13:45:41 字數 4471 閱讀 1229

樸素貝葉斯演算法

首先訓練樸素貝葉斯模型,對應演算法4.1(1),分別計算先驗概率及條件概率,分別存在字典priorp和condp中(初始化函式中定義)。其中,計算乙個向量各元素頻率的操作反覆出現,定義為count函式。

# 初始化函式定義了先驗概率和條件概率字典,並訓練模型

def__init__

(self, data, label)

: self.priorp =

self.condp =

self.train(data, label)

count函式,輸入乙個向量,輸出乙個字典,包含各元素頻率

# 給乙個向量,返回字典,包含不同元素的頻率。可以引用collections中的counter函式來實現

# 這個函式可以改進,懶得弄了

defcount

(self, vec)

: np.array(vec)

keys = np.unique(vec)

p =for key in keys:

n = np.

sum(np.isin(vec, key)+0

)# 加0可以使布林向量變為0-1向量

p[key]

= n/

len(vec)

# 計算頻率

return p

訓練函式,關於condp的儲存下面有詳細說明

def

train

(self, data, label)

: m, n = np.shape(data)

# 計算先驗概率

self.priorp = self.count(label)

print

("priorp:"

, self.priorp)

# 計算條件概率

classes = np.unique(label)

for c in classes:

subset =

[data[i]

for i in

range

(m)if label[i]

== c]

# 取y=ck的子集

for j in

range

(n):

# 遍歷每乙個特徵,分別求條件概率

self.condp[

str(c)

+" "

+str

(j)]

= self.count(

[x[j]

for x in subset]

)print

("condp:"

, self.condp)

對於條件概率condp的儲存,將每個特徵關於y=ck的條件概率都存為乙個字典,再存入字典condp中,key設為 「ck j」 ,其中 ck 為 y 的類別,j 表示第 j 個特徵。訓練例4.1得到的模型如下, condp中的"-1 0"項即表示y=-1條件下,p(x(0)=1)=0.5, p(x(0)=2)=0.333, p(x(0)=3)=0.166. 為了顯示方便,只給出了小數點後3位。

priorp:

condp:

,'-1 1':,

'1 0':,

'1 1'

:}

訓練之後,對給定x進行**,結果儲存在字典prep中

def

predict

(self, x)

: prep =

for c in self.priorp.keys():

prep[c]

= self.priorp[c]

for i, features in

enumerate

(x):

prep[c]

*= self.condp[

str(c)

+" "

+str

(i)]

[features]

print

("probability: "

, prep)

print

("prediction: "

,max

(prep, key=prep.get)

)

結果:

probability:

prediction:

-1

貝葉斯分類

考慮到概率可能為0,在隨機變數各個取值的頻數上賦予乙個正數lamda,lamda為0時即為極大似然估計;lamda取1時稱為拉普拉斯平滑。

先驗概率變為(a)

條件概率變為(b)

在之前的演算法基礎上改進,新增乙個字典變數rangeoffeature來儲存每個特徵的取值個數,定義在初始化函式中。

self.rangeoffeature =

# 儲存每個特徵的取值個數

公式(a)和(b)形式相同,將 k 或sj 作為引數傳入count函式,lamda預設為0:

def

count

(self, vec, classnum, lamda=0)

: keys =

set(vec)

p =for key in keys:

n = np.

sum(np.isin(vec, key)+0

) p[key]

=(n+lamda)/(

len(vec)

+classnum*lamda)

return p

訓練函式變為

def

train

(self, data, label, lamda=0)

: m, n = np.shape(data)

# 計算rangeoffeature

for j in

range

(n):

self.rangeoffeature[j]

=len

(set

([x[j]

for x in data]))

classes =

set(label)

# 計算先驗概率

self.priorp = self.count(label,

len(classes)

, lamda)

print

("priorp:"

, self.priorp)

# 計算條件概率

for c in classes:

subset =

[data[i]

for i in

range

(m)if label[i]

== c]

for j in

range

(n):

self.condp[

str(c)

+" "

+str

(j)]

= self.count(

[x[j]

for x in subset]

, self.rangeoffeature[j]

, lamda)

print

("condp:"

, self.condp)

其他不變,對之前的例項執行

bayes = bayes(dataset, labels,1)

bayes.predict([2

,"s"

])

結果如下:

probability:

prediction:

-1

筆記

for i, value in enumerate(['a', 'b', 'c']):把list變成索引-元素對用enumerate函式,這樣就可以在for迴圈中同時迭代索引和元素本身

[a[j] for a in data]取data第 j 列

np.isin(a,b)判斷a中每個元素是否在b中,返回與a形狀相同的bool陣列

np.unique(a)去重並排序

統計學習方法 樸素貝葉斯法

乙個事件概率依賴於另外乙個事件 已發生 的度量。p b a 的意義是在a發生的情況下b事件發生的概率。這就是條件概率。p ab p a times p b a 代表的意義是,ab事件同時發生的概率等於事件a發生的概率乘以在a發生條件下b事件發生的概率。p b a frac 事件序列發生且彼此相互依賴...

統計學習方法四 樸素貝葉斯

結合之前的部落格 一 什麼是樸素貝葉斯?樸素貝葉斯是基於貝葉斯定理與特徵條件獨立假設的分類方法。對於給定的資料集,首先基於特徵條件獨立假設學習輸入 輸出的聯合概率分布 然後基於此模型,對給定的輸入x,利用貝葉斯定理求出後驗概率最大的輸出y 特徵 1 多分類 2 生成學習方法二 學習與分類 1 條件獨...

統計學習方法四 樸素貝葉斯分類

樸素貝葉斯分類 1,基本概念 2,演算法流程 關鍵點 理解先驗概率,條件概率,最大後驗概率,下面是以極大似然估計的 3,演算法改進 貝葉斯估計 上述用極大似然估計可能會出現所要估計的概率值為0的情況,改進方法 先驗概率貝葉斯估計 k表示類別數,為引數 0時為極大似然估計 1時為拉普拉斯平滑 條件概率...