教培參考
教育培訓(xùn)行業(yè)知識(shí)型媒體
發(fā)布時(shí)間: 2025年05月18日 09:36
在開始介紹貝葉斯之前,先簡單介紹下概率的基礎(chǔ)知識(shí)。概率是某一結(jié)果出現(xiàn)的可能性。例如,拋一枚勻質(zhì)硬幣,正面向上的可能性多大?概率值是一個(gè)0-1之間的數(shù)字,用來衡量一個(gè)事件發(fā)生可能性的大小。概率值越接近1,事件發(fā)生的可能性越大,概率值越接近0,事件越不可能發(fā)生。我們?nèi)粘I钪新牭阶疃嗟氖翘鞖忸A(yù)報(bào)中的降水概率。概率的表示方法叫維恩圖。下面我們通過維恩圖來說明貝葉斯公式中常見的幾個(gè)概率。
在維恩圖中:
S:S是樣本空間,是所有可能事件的總和。
?P(A):是樣本空間S中A事件發(fā)生的概率,維恩圖中綠色的部分。
?P(B):是樣本空間S中B事件發(fā)生的概率,維恩圖中藍(lán)色的部分。
?P(A∩B):是樣本空間S中A事件和B事件同時(shí)發(fā)生的概率,也就是A和B相交的區(qū)域。
?P(A|B):是條件概率,是B事件已經(jīng)發(fā)生時(shí)A事件發(fā)生的概率。
貝葉斯算法通過已知的P(A|B),P(A),和P(B)三個(gè)概率計(jì)算P(B|A)發(fā)生的概率。假設(shè)我們現(xiàn)在已知P(A|B),P(A)和P(B)三個(gè)概率,如何計(jì)算P(B|A)呢?通過前面的概率樹及P(A|B)的概率可知,P(B|A)的概率是在事件A發(fā)生的前提下事件B發(fā)生的概率,因此P(B|A)可以表示為事件B與事件A的交集與事件A的比率。
?
在貝葉斯推斷中,每一種概率都有一個(gè)特定的名字:
?P(B)是”先驗(yàn)概率”(Prior probability)。
?P(A)是”先驗(yàn)概率”(Prior probability),也作標(biāo)準(zhǔn)化常量(normalized constant)。
?P(A|B)是已知B發(fā)生后A的條件概率,叫做似然函數(shù)(likelihood)。
?P(B|A)是已知A發(fā)生后B的條件概率,是我們要求的值,叫做后驗(yàn)概率。
?P(A|B)/P(A)是調(diào)整因子,也被稱作標(biāo)準(zhǔn)似然度(standardised likelihood)。
?
解決問題
下面從一個(gè)簡單問題出發(fā),介紹怎么使用樸素貝葉斯解決分類問題。
一天,老師問了個(gè)問題,只根據(jù)頭發(fā)和聲音怎么判斷一位同學(xué)的性別。
為了解決這個(gè)問題,同學(xué)們馬上簡單的統(tǒng)計(jì)了7位同學(xué)的相關(guān)特征,數(shù)據(jù)如下:?
頭發(fā) | 聲音 | 性別 |
長 | 粗 | 男 |
短 | 粗 | 男 |
短 | 粗 | 男 |
長 | 細(xì) | 女 |
短 | 細(xì) | 女 |
短 | 粗 | 女 |
長 | 粗 | 女 |
長 | 粗 | 女 |
這個(gè)問題之前用決策樹做過了,這里我們換一種思路。
要是知道男生和女生頭發(fā)長短的概率以及聲音粗細(xì)的概率,我們就可以計(jì)算出各種情況的概率,然后比較概率大小,來判斷性別。
假設(shè)抽樣樣本足夠大,我們可以近似認(rèn)為可以代表所有數(shù)據(jù),假設(shè)上位7位同學(xué)能代表所有數(shù)據(jù),這里方便計(jì)算~
由這7位同學(xué),我們馬上得出下面表格概率分布。
概率分布?
性別 | 頭發(fā)長 | 聲音粗 |
男 | 1/3 | 1 |
女 | 3/5 | 3/5 |
公式中,事件Bi的概率為P(Bi),事件Bi已發(fā)生條件下事件A的概率為P(A│Bi),事件A發(fā)生條件下事件Bi的概率為P(Bi│A)。
帶入我們的例子中,判斷頭發(fā)長的人性別:
P(男|頭發(fā)長)=P(頭發(fā)長|男)*P(男)/P(頭發(fā)長)
P(女|頭發(fā)長)=P(頭發(fā)長|女)*P(女)/P(頭發(fā)長)
判斷頭發(fā)長、聲音粗的人性別:
P(男|頭發(fā)長聲音粗)=P(頭發(fā)長|男)P(聲音粗|男)*P(男)/P(頭發(fā)長聲音粗)
P(女|頭發(fā)長聲音粗)=P(頭發(fā)長|女)P(聲音粗|女)*P(女)/P(頭發(fā)長聲音粗)
可以看到,比較最后比較概率,只用比較分子即可。也就是前面計(jì)算頭發(fā)長聲音粗的人是男生女生的概率。
?
樸素貝葉斯分類的工作流程?
樸素貝葉斯python實(shí)例?
實(shí)例內(nèi)容?
假設(shè)有兩類數(shù)據(jù)p1(x,y)表示(x,y)屬于類別1,用p2(x,y)表示(x,y)屬于類別2,那么對(duì)于一個(gè)新的數(shù)據(jù)集(x,y),可以根據(jù)一下規(guī)則來判斷他的類別
1.如果p1(x,y)>p2(x,y),則(x,y)屬于類別1
2.如果p2(x,y)>p1(x,y),則(x,y)屬于類別2
也就是說,我們會(huì)選擇具有最高概率的決策,這就是貝葉斯決策理論的核心思想通常,事件A在事件B(發(fā)生)的條件下的概率,與事件B在事件A的條件下的概率是不一樣的;然而,這兩者是有確定的關(guān)系,貝葉斯法則就是這種關(guān)系的陳述。作為一個(gè)規(guī)范的原理,貝葉斯法則對(duì)于所有概率的解釋是有效的;然而,頻率主義者和貝葉斯主義者對(duì)于在應(yīng)用中概率如何被賦值有著不同的看法:頻率主義者根據(jù)隨機(jī)事件發(fā)生的頻率,或者總體樣本里面的個(gè)數(shù)來賦值概率;貝葉斯主義者要根據(jù)未知的命題來賦值概率。一個(gè)結(jié)果就是,貝葉斯主義者有更多的機(jī)會(huì)使用貝葉斯法則。
14個(gè)里面有5個(gè)不買電腦,9個(gè)買電腦。
p(age=youth|buy_computer=yes) = 2/9 =0.222
p(age=youth|buy_computer=no) = 3/5 = 0.6
p(student=yes|buy_computer=yes) = 6/9 =0.667
p(student=yes|buy_computer=no) = 1/5 = 0.2
p(age=senior & student=yes|buy_computer=yes) = 2/3 =0.667
p(age=senior & student=yes|buy_computer=no) = 1/3 = 0.333
Python代碼
class NBClassify(object): def __init__(self,fillNa = 1): self.fillNa = 1 pass def train(self,trainSet): # 計(jì)算每種類別的概率 # 保存所有tag的所有種類,及它們出現(xiàn)的頻次 dictTag = {} for subTuple in trainSet: dictTag[str(subTuple[1])] = 1 if str(subTuple[1]) not in dictTag.keys() else dictTag[str(subTuple[1])] + 1 # 保存每個(gè)tag本身的概率 tagProbablity = {} totalFreq = sum([value for value in dictTag.values()]) for key,value in dictTag.items(): tagProbablity[key] = value / totalFreq # print(tagProbablity) self.tagProbablity = tagProbablity ############################################################################## # 計(jì)算特征的條件概率 # 保存特征屬性基本信息{特征1:{值1:出現(xiàn)5次,值2:出現(xiàn)1次},特征2:{值1:出現(xiàn)1次,值2:出現(xiàn)5次}} dictFeaturesbase = {} for subTuple in trainSet: for key,value in subTuple[0].items(): if key not in dictFeaturesbase.keys(): dictFeaturesbase[key] = {value:1} else: if value not in dictFeaturesbase[key].keys(): dictFeaturesbase[key][value] = 1 else: dictFeaturesbase[key][value] += 1 # dictFeaturesbase = { # '職業(yè)': {'農(nóng)夫': 1,'教師': 2,'建筑工人': 2,'護(hù)士': 1}, # '癥狀': {'打噴嚏': 3,'頭痛': 3} # } dictFeatures = {}.fromkeys([key for key in dictTag]) for key in dictFeatures.keys(): dictFeatures[key] = {}.fromkeys([key for key in dictFeaturesbase]) for key,value in dictFeatures.items(): for subkey in value.keys(): value[subkey] = {}.fromkeys([x for x in dictFeaturesbase[subkey].keys()]) # dictFeatures = { # '感冒 ': {'癥狀': {'打噴嚏': None,'頭痛': None},'職業(yè)': {'護(hù)士': None,'農(nóng)夫': None,'建筑工人': None,'教師': None}}, # '腦震蕩': {'癥狀': {'打噴嚏': None,'頭痛': None},'職業(yè)': {'護(hù)士': None,'農(nóng)夫': None,'建筑工人': None,'教師': None}}, # '過敏 ': {'癥狀': {'打噴嚏': None,'頭痛': None},'職業(yè)': {'護(hù)士': None,'農(nóng)夫': None,'建筑工人': None,'教師': None}} # } # initialise dictFeatures for subTuple in trainSet: for key,value in subTuple[0].items(): dictFeatures[subTuple[1]][key][value] = 1 if dictFeatures[subTuple[1]][key][value] == None else dictFeatures[subTuple[1]][key][value] + 1 # print(dictFeatures) # 將馴良樣本中沒有的項(xiàng)目,由None改為一個(gè)非常小的數(shù)值,表示其概率極小而并非是零 for tag,featuresDict in dictFeatures.items(): for featureName,feturevalueDict in featuresDict.items(): for featureKey,featurevalues in feturevalueDict.items(): if featurevalues == None: feturevalueDict[featureKey] = 1 # 由特征頻率計(jì)算特征的條件概率P(feature|tag) for tag,featuresDict in dictFeatures.items(): for featureName,feturevalueDict in featuresDict.items(): totalCount = sum([x for x in feturevalueDict.values() if x != None]) for featureKey,featurevalues in feturevalueDict.items(): feturevalueDict[featureKey] = featurevalues/totalCount if featurevalues != None else None self.featuresProbablity = dictFeatures ############################################################################## def classify(self,featureDict): resultDict = {} # 計(jì)算每個(gè)tag的條件概率 for key,value in self.tagProbablity.items(): iNumList = [] for f,v in featureDict.items(): if self.featuresProbablity[key][f][v]: iNumList.append(self.featuresProbablity[key][f][v]) conditionPr = 1 for iNum in iNumList: conditionPr *= iNum resultDict[key] = value * conditionPr # 對(duì)比每個(gè)tag的條件概率的大小 resultList = sorted(resultDict.items(),key=lambda x:x[1],reverse=True) return resultList[0][0] if __name__ == '__main__': trainSet = [ ({"癥狀":"打噴嚏","職業(yè)":"護(hù)士"},"感冒 "), ({"癥狀":"打噴嚏","職業(yè)":"農(nóng)夫"},"過敏 "), ({"癥狀":"頭痛","職業(yè)":"建筑工人"},"腦震蕩"), ({"癥狀":"頭痛","職業(yè)":"建筑工人"},"感冒 "), ({"癥狀":"打噴嚏","職業(yè)":"教師"},"感冒 "), ({"癥狀":"頭痛","職業(yè)":"教師"},"腦震蕩"), ] trainSet = [ ({"age":"youth","收入":"高","學(xué)生":"no","信用":"fair"},"不買"), ({"age":"youth","收入":"高","學(xué)生":"no","信用":"excellent"},"不買"), ({"age":"midden_aged","收入":"高","學(xué)生":"no","信用":"fair"},"買"), ({"age":"senior","收入":"中等","學(xué)生":"no","信用":"fair"},"買"), ({"age":"senior","收入":"低","學(xué)生":"yes","信用":"fair"},"買"), ({"age":"senior","收入":"低","學(xué)生":"yes","信用":"excellent"},"不買"), ({"age":"midden_aged","收入":"低","學(xué)生":"yes","信用":"excellent"},"買"), ({"age":"youth","收入":"中等","學(xué)生":"no","信用":"fair"},"不買"), ({"age":"youth","收入":"低","學(xué)生":"yes","信用":"fair"},"買"), ({"age":"senior","收入":"中等","學(xué)生":"yes","信用":"fair"},"買"), ({"age":"youth","收入":"中等","學(xué)生":"yes","信用":"excellent"},"買"), ({"age":"midden_aged","收入":"中等","學(xué)生":"no","信用":"excellent"},"買"), ({"age":"midden_aged","收入":"高","學(xué)生":"yes","信用":"fair"},"買"), ({"age":"senior","收入":"中等","學(xué)生":"no","信用":"excellent"},"不買") ] monitor = NBClassify() # trainSet is something like that [(featureDict,tag),] monitor.train(trainSet) # 打噴嚏的建筑工人 # 請(qǐng)問他患上感冒的概率有多大? # result = monitor.classify({"癥狀":"頭痛","職業(yè)":"教師"}) result = monitor.classify({"age":"midden_aged","收入":"高","學(xué)生":"yes","信用":"excellent"}) print(result) |
?樸素貝葉斯優(yōu)缺點(diǎn)
優(yōu)點(diǎn):在數(shù)據(jù)較少的請(qǐng)胯下仍然有效,可以處理多類別問題;
缺點(diǎn):對(duì)于輸入數(shù)據(jù)的準(zhǔn)備方式較為敏感。
使用數(shù)據(jù)類型:標(biāo)稱型數(shù)據(jù)
微信掃碼關(guān)注公眾號(hào)
獲取更多考試熱門資料