Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

本文的主要目的是引導讀者更加深入的學習數據挖掘和分析技術的同時進一步熟悉Python數據分析的基本流程以及對加深對Python編程的掌握。

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

貝葉斯理論介紹

在概率和統計學領域,貝葉斯理論基於對某一事件證據的認識,來預測該時間事件的發生概率。比如,如果癌症和年齡相關,在考慮年齡影響的條件下,預測癌症的概率的準確率就會高於不考慮年齡的準確率。貝葉斯理論的表達公式如下所示:

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

A、B為事件,並且P(B)≠0

P(A)和P(B)為獨立觀察事件A、B發生的概率

P(A|B),條件概率,即是在B事件發生的情況下,A事件發生的概率

P(B|A),條件概率,即是在A事件發生的情況下,B事件發生的概率

假設藥品測試的靈敏度為99%,準確率為99%。意思就是如果使用了藥品,那麼99%的可能性,會測試結果會顯陽性;如果沒有用藥,那有99%的可能性測試結果顯陰性。現在隨機抽出一個人,測試結果顯陽性,試問用藥的可能性有多大。

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

這個結果與直覺有較大的出入,計算結果表明隨機抽出一個人進行用藥測試,即使結果呈陽性,沒有用藥的可能性也要大於用藥的可能性。

在機器學習領域,樸素貝葉斯分類器是基於貝葉斯理論並假設各特徵相互獨立的分類方法。樸素貝葉斯模型構建分類器的基本方法是:使用特徵向量來表示某個,並賦給這些實體代表其類別的標籤。所有的樸素貝葉斯分類器都假設某個特徵的值與另一個特徵的值是相互獨立的。比如,一種水果,形狀為圓形、直徑在5cm左右且顏色為紅色被分類為蘋果。貝葉斯在進行分類的時候,在判別這種水果為蘋果時,只考慮這幾種特徵獨自對分類概率的影響,而不去考慮形、顏色、直徑這些特徵的相關性。貝葉斯分類器可以通過監督式學習的方式非常高效的訓練。。

儘管貝葉斯分類器的假設條件過於簡單,甚至與實際不符。但大多數時候,它都有較好的表現;它有一個較大的優點是,只需要少量的訓練數據,就可以建立起分類所需要的所有參數。

從抽象的角度而言,樸素貝葉斯其實就是條件概率模型:給定一個實體,求解這個實體屬於某一個類別的概率,這個實體用一個長度為n的向量來表示,向量中的每一個元素都表示一個特徵量的值(相互獨立)。

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

使用貝葉斯理論計算上式:

觀察上式

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

對於上式對於某一個實體而言是一個常數,所以某一個實體屬於某一類與的大小無關。使用之前的假設特徵量之間相互獨立以及聯合概率的計算公式:

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

基於介紹的各特徵值相互獨立的概率模型,再加上一個決策規則,就構成了貝葉斯分類器。決策規則比較常用的是選擇最大概率規則來判斷對應的類別,即實體的所屬類別為下式,最大值時,k所對應的類別。

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

下面用一個例子,來說明如何應用貝葉斯分類器,假設現在有1000封郵件,其中200封郵件為垃圾郵件,800封為正常。現在一封郵件的特徵值為(“ 你好”,”中國”)。假設在垃圾郵件裡面出現“你好”的頻數為50,“中國”的頻數為1。在正常郵件裡面出現”你好”的頻數為700,“中國”的頻數為80。分別計算郵件屬於正常郵件和垃圾郵件的概率:

P(垃圾郵件|(“你好”,“中國”))=P(“你好”|垃圾郵件)*P(“中國”|垃圾郵件)=

50/200*1/200=0.125%。

類似的,計算出正常郵件的概率為8.75%。正常郵件的概率大於垃圾郵件的概率,根據最大概率規則判斷這封郵件是正常郵件。

bayes分類器的實現

本節主要介紹如何使用Python來實現貝葉斯分類器,數據集如表所示:

Python實現貝葉斯分類器,純乾貨,看不懂就收藏吧,日後再說

使用文本編輯器,建立一個bayes_classfier.py的文件,寫入下面的代碼。

#bayes分類器源代碼datasets={'banana':{'long':400,'not_long':100, 'sweet':350,'not_sweet':150, 'yellow':450,'not_yellow':50}, 'orange':{'long':0,'not_long':300, 'sweet':150,'not_sweet':150, 'yellow':300,'not_yellow':0}, 'other_fruit':{'long':100,'not_long':100, 'sweet':150,'not_sweet':50, 'yellow':50,'not_yellow':150},}def count_total(data): '''計算各種水果的總數 return {'bananas':500 ...}''' count={} total=0 for fruit in data: #因為各種水果要麼甜要麼不甜 #所有可以使用'sweet'和‘not’ sweet 這兩種特徵的水果數目統計出各種水果的總數 count[fruit]=data[fruit]['sweet'] count[fruit]+=data[fruit]['not_sweet'] total=+count[fruit] return count,totaldef cal_base_rates(data): '''計算各種水果的先驗概率(priori probabilities) return {'banana':0.5...}''' categories,total=count_total(data) base_rates={} for label in categories: priori_prob=categories[label]/total base_rates[label]=priori_prob return base_ratesdef likelihood_prob(data): '''計算各個特徵值在已知水果下的概率(likelihood probabilities) {'banana':{'long:0.8'...}...}''' count,_=count_total(data) likelihood={} for fruit in data: #創建一個新字典,臨時存儲各個特徵的概率 attr_prob={} for attr in datasets[fruit]: #計算各個特徵在已知某種水果下的概率 attr_prob[attr]=data[fruit][attr]/count[fruit] #把某種水果的各個特徵的概率放入到likelihood這個字典中 likelihood[fruit]=attr_prob return likelihooddef evidence_prob(data): '''雖然各個證據(特徵)的概率的概率對分類結果沒有影響 主要目的是說明一些基本的概念 return {'long':'50%'}''' #水果的所有特徵 attrs=list(data['banana'].keys()) count,total=count_total(data) evidence_prob={} #計算各種特徵的概率 for attr in attrs: attr_total=0 for fruit in data: attr_total+=data[fruit][attr] evidence_prob[attr]=attr_total/total return evidence_probclass naive_bayes_classifier: #初始化貝葉斯分類器 def __init__(self,data=datasets): self._data=datasets self._labels=[key for key in self._data.keys()] self._priori_prob=cal_base_rates(self._data) self._likelihood_prob=likelihood_prob(self._data) self._evidence_prob=evidence_prob(self._data)def get_label(self,length,sweetness,color): #獲取某一組特徵值的類別 self._attrs=[length,sweetness,color] res={} for label in self._labels: prob=self._priori_prob[label] for attr in self._attrs: prob*=self._likelihood_prob[label][attr]/self._evidence_prob[attr] res[label]=prob return res

下面使用一些未知類別的數據集,來測試貝葉斯分類器的預測能力。

注意:測試數據集,一定要隨機選取,否則不能準確反映bayes分類器的預測能力。

這裡使用Python的random模塊下的randint來隨機生成(0,1) 之間的整數,然後再使用這些隨機數生成相應的特徵值。使用文本編輯器,建立一個generate_attires.py的文件,寫入下面的代碼。

import randomdef random_attr(pair): #生成0或1的隨機數 return pair[random.randint(0,1)]def gen_attrs(): #特徵值的取值集合 sets=[('long','not long'),('sweet','not sweet'),('yellow','not yellow')] test_datasets=[] for i in range(20): #使用map函數來生成一組特徵值 test_datasets.append(list(map(random_attr,sets))) return test_datasets 

隨機生成的20組特徵值如下,

['long', 'sweet', 'yellow']['not_long', 'not_sweet', 'not_yellow']['long', 'sweet', 'yellow']['not_long', 'sweet', 'yellow']['long', 'sweet', 'not_yellow']['not_long', 'sweet', 'not_yellow']['not_long', 'sweet', 'not_yellow']['not_long', 'not_sweet', 'not_yellow']['long', 'not_sweet', 'yellow']['not_long', 'not_sweet', 'yellow']['long', 'not_sweet', 'yellow']['not_long', 'not_sweet', 'not_yellow']['not_long', 'sweet', 'not_yellow']['long', 'not_sweet', 'not_yellow']['not_long', 'sweet', 'not_yellow']['not_long', 'not_sweet', 'yellow']['long', 'not_sweet', 'not_yellow']['not_long', 'not_sweet', 'yellow']['not_long', 'sweet', 'yellow']['long', 'sweet', 'not_yellow']

使用貝葉斯分類器來對測試數據集進行分類。使用文本編輯器,建立一個classfication.py的文件,寫入下面的代碼:

import operatorimport bayes import generate_attrsdef main(): #生成測試數據集 test_datasets=generate_attrs.gen_attrs() #建立分類器 classfier=bayes.naive_bayes_classifier() for data in test_datasets: print('特徵值:',end='\t') print(data) print('預測結果:',end='\t') res=classfier.get_label(*data) print(res)print('水果類別:',end='\t')#對後驗概率排序,輸出概率最大的標籤print(sorted(res.items(),key=operator.itemgetter(1),reverse=True)[0][0])#導入該模塊,並自動運行main函數if __name__=='__main__': main()

輸出結果如下:

特徵值: ['long','sweet', 'yellow']預測結果: {'other_fruit':0.006490384615384616, 'banana': 0.08723076923076924, 'orange': 0.0}水果類別: banana特徵值: ['long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.03085714285714286, 'orange': 0.0}水果類別: other_fruit特徵值: ['not_long','sweet', 'not_yellow']預測結果: {'other_fruit':0.07788461538461539, 'banana': 0.009692307692307695, 'orange': 0.0}水果類別: other_fruit特徵值: ['not_long','not_sweet', 'yellow']預測結果: {'other_fruit':0.0040178571428571425, 'banana': 0.01735714285714286, 'orange':0.09642857142857142}水果類別: orange特徵值: ['long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.03085714285714286, 'orange': 0.0}水果類別: other_fruit特徵值: ['not_long','sweet', 'yellow']預測結果: {'other_fruit':0.006490384615384616, 'banana': 0.02180769230769231, 'orange':0.051923076923076926}水果類別: orange特徵值: ['long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.03085714285714286, 'orange': 0.0}水果類別: other_fruit特徵值: ['not_long','not_sweet', 'yellow']預測結果: {'other_fruit':0.0040178571428571425, 'banana': 0.01735714285714286, 'orange':0.09642857142857142}水果類別: orange特徵值: ['long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.03085714285714286, 'orange': 0.0}水果類別: other_fruit特徵值: ['long','not_sweet', 'yellow']預測結果: {'other_fruit':0.0040178571428571425, 'banana': 0.06942857142857144, 'orange': 0.0}水果類別: banana特徵值: ['not_long','not_sweet', 'yellow']預測結果: {'other_fruit':0.0040178571428571425, 'banana': 0.01735714285714286, 'orange':0.09642857142857142}水果類別: orange特徵值: ['long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.03085714285714286, 'orange': 0.0}水果類別: other_fruit特徵值: ['long','sweet', 'yellow']預測結果: {'other_fruit':0.006490384615384616, 'banana': 0.08723076923076924, 'orange': 0.0}水果類別: banana特徵值: ['long','not_sweet', 'yellow']預測結果: {'other_fruit':0.0040178571428571425, 'banana': 0.06942857142857144, 'orange': 0.0}水果類別: banana特徵值: ['not_long','sweet', 'yellow']預測結果: {'other_fruit':0.006490384615384616, 'banana': 0.02180769230769231, 'orange':0.051923076923076926}水果類別: orange特徵值: ['not_long','not_sweet', 'yellow']預測結果: {'other_fruit':0.0040178571428571425, 'banana': 0.01735714285714286, 'orange':0.09642857142857142}水果類別: orange特徵值: ['long','sweet', 'not_yellow']預測結果: {'other_fruit':0.07788461538461539, 'banana': 0.03876923076923078, 'orange': 0.0}水果類別: other_fruit特徵值: ['long','sweet', 'not_yellow']預測結果: {'other_fruit':0.07788461538461539, 'banana': 0.03876923076923078, 'orange': 0.0}水果類別: other_fruit特徵值: ['not_long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.007714285714285715, 'orange': 0.0}水果類別: other_fruit特徵值: ['not_long','not_sweet', 'not_yellow']預測結果: {'other_fruit':0.04821428571428571, 'banana': 0.007714285714285715, 'orange': 0.0}水果類別: other_fruit

本節假設讀者具備基本的概率知識,如果覺得學習有困難,可以去補習一下概率論方面的基礎知識。這裡建議讀者去選擇別的問題實現一個bayes分類器,加深對知識的理解。


分享到:


相關文章: