樸素貝葉斯公式來歷
?
Na?veBayes算法,又叫樸素貝葉斯算法。
??樸素:特征條件獨立;
??貝葉斯:基于貝葉斯定理。屬于監(jiān)督學(xué)習(xí)的生成模型,實現(xiàn)簡單,沒有迭代,并有堅實的數(shù)學(xué)理論(即貝葉斯定理)作為支撐。在大量樣本下會有較好的表現(xiàn),不適用于輸入向量的特征條件有關(guān)聯(lián)的場景。
??樸素貝葉斯(Naive Bayesian)是基于貝葉斯定理和特征條件獨立假設(shè)的分類方法,它 通過特征計算分類的概率,選取概率大的情況,是基于概率論的一種機器學(xué)習(xí)分類(監(jiān)督學(xué)習(xí))方法,被廣泛應(yīng)用于情感分類領(lǐng)域的分類器。
樸素貝葉斯算法是應(yīng)用最為廣泛的分類算法之一,在垃圾郵件分類等場景展露出了非常優(yōu)秀的性能。
在介紹樸素貝葉斯公式前,先介紹一下條件概率公式。條件概率表示在B已經(jīng)發(fā)生的條件下,A發(fā)生概率。
樸素貝葉斯公式就是條件概率的變形。
假設(shè)已有數(shù)據(jù)為
其中x為屬性值,y為分類結(jié)果,共有n個已有數(shù)據(jù)。每個x有多種屬性,以第一組數(shù)據(jù)為例,上標(biāo)表示第幾個屬性值,x的具體表示如下?
假設(shè)y的可取值為(c1,c2,…,ck)
則貝葉斯公式表示為
由公式可以看出,貝葉斯公式就是條件概率的公式。貝葉斯公式的解釋很簡單:在已有數(shù)據(jù)的基礎(chǔ)上,出現(xiàn)了一個新數(shù)據(jù),只有X=(a1,a2,…,am),來預(yù)測y的取值。貝葉斯公式就是求在目前X發(fā)生的情況下,y取不同值的概率大小進行排序,取最大概率的y值。
其中X有多個屬性,樸素貝葉斯假設(shè)各個屬性之間是獨立的,因此
因此樸素貝葉斯公式可以寫成
此公式的含義就是在目前已知歷史數(shù)據(jù)數(shù)據(jù)的前提下,出現(xiàn)了一個新的X,求在X已經(jīng)發(fā)生的條件下,y取不同值的概率,然后取使得條件概率最大的y作為預(yù)測結(jié)果。也就是說尋找y的取值Cn,使得上式最大。
舉例:在夏季,某公園男性穿涼鞋的概率為 1/2 ,女性穿涼鞋的概率為?2/3 ,并且該公園中男女比例通常為?2:1 ,問題:若你在公園中隨機遇到一個穿涼鞋的人,請問他的性別為男性或女性的概率分別為多少?
分析:
在例子中,根據(jù)男女比例2:1,可得 P(Y=ymen)=2/3,P(Y=ywomen)=1/3
在例子中:男性穿涼鞋的概率為?1/2,也就是說“是男性的前提下,穿涼鞋的概率是?1/2,此概率為條件概率,即?P(X=x1|Y=ymen)=1/2。同理“女性穿涼鞋的概率為?2/3” 為條件概率?P(X=x1|Y=ywomen)=2/3。
則P(X=x1)=(1/2*2+2/3*1)/3=5/9
則可得
?同理
?則為男性的概率為3/5 為女性的概率為2/5.
垃圾郵件分類實現(xiàn)
步驟:
收集數(shù)據(jù):提供文本文件。
準(zhǔn)備數(shù)據(jù):將文本文件解析成詞條向量。
分析數(shù)據(jù):檢查詞條確保解析的正確性。
訓(xùn)練算法:計算不同的獨立特征的條件概率。
測試算法:計算錯誤率。
使用算法:構(gòu)建一個完整的程序?qū)σ唤M文檔進行分類
訓(xùn)練集的準(zhǔn)備與處理
準(zhǔn)備兩個文件夾分別存入垃圾郵件及正常郵件兩種郵件當(dāng)作訓(xùn)練集。
?準(zhǔn)備數(shù)據(jù):從文本中構(gòu)建詞向量
def loadDataSet():
postingList=[['my','dog','has','flea','problems','help','please'],
['maybe','not','take','him','to','dog','park','stupid'],
['my','dalmatian','is','so','cute','I','love','him'],
['stop','posting','stupid','worthless','garbage'],
['mr','licks','ate','my','steak','how','to','stop','him'],
['quit','buying','worthless','dog','food','stupid']]
classVec=[0,1,0,1,0,1] #1代表侮辱性文字,0代表正常言論(對應(yīng)6個文檔)
return postingList,classVec
def createVocabList(dataSet):
vocabSet=set()
for document in dataSet:
vocabSet=vocabSet|set(document) #兩個集合的并集
return list(vocabSet)
def setOfWords2Vec(vocabList,inputSet):
returnVec=[0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]=1
else:
print("the word:%s is not in my vocabulary!"%word)
return returnVec
訓(xùn)練算法:從詞向量計算概率
import numpy as np
def trainNB0(trainMatrix,trainCategory):
numTrainDocs=len(trainMatrix)
numWords=len(trainMatrix[0])
pABusive=sum(trainCategory)/float(numTrainDocs)
# p0Num=np.zeros(numWords)
# p1Num=np.zeros(numWords)
# p0Denom=0.0
# p1Denom=0.0
p0Num=np.ones(numWords)
p1Num=np.ones(numWords)
p0Denom=2.0
p1Denom=2.0
for i in range(numTrainDocs):
if trainCategory[i]==1:
p1Num+=trainMatrix[i]
p1Denom+=sum(trainMatrix[i])
else:
p0Num+=trainMatrix[i]
p0Denom+=sum(trainMatrix[i])
# p1Vect=p1Num/p1Denom
# p0Vect=p0Num/p0Denom
p1Vect=np.log(p1Num/p1Denom)
p0Vect=np.log(p0Num/p0Denom)
return p0Vect,p1Vect,pABusive
?貝葉斯分類函數(shù)
#貝葉斯分類函數(shù)
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
p1=sum(vec2Classify*p1Vec)+np.log(pClass1)
p0=sum(vec2Classify*p0Vec)+np.log(1-pClass1)
if p1>p0:
return 1
else:
return 0
def NBtesting():
listOPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listOPosts)
trainMat=[]
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=trainNB0(np.array(trainMat),np.array(listClasses))
testEntry=['love','my','dalmation']
thidDoc=np.array(setOfWords2Vec(myVocabList,testEntry))
print(testEntry,'classified as:',classifyNB(thidDoc,p0V,p1V,pAb))
testEntry=['stupid','garbage']
thisDoc=np.array(setOfWords2Vec(myVocabList,testEntry))
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
文檔詞袋模型?
#樸素貝葉斯詞袋模型
def bagOfWords2Vec(vocabList,inputSet):
returnVec=[0*len(vocabList)]
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]+=1
return returnVec
切分文本?
mySent='This book is the best book on python or M.L. I have ever laid eyes upon.'
print(mySent.split())
import re
mySent='This book is the best book on python or M.L. I have ever laid eyes upon.'
regEX=re.compile('\\W+')
listOfTokens=regEX.split(mySent)
print(listOfTokens)
import re
mySent='This book is the best book on python or M.L. I have ever laid eyes upon.'
regEX=re.compile('\\W+')
listOfTokens=regEX.split(mySent)
print([tok for tok in listOfTokens if len(tok)>0])
print([tok.lower() for tok in listOfTokens if len(tok)>0])
使用樸素貝葉斯進行交叉驗證
def textParse(bigString):
import re
listOfTokens = re.split(r'\W*', bigString)
return [tok.lower() for tok in listOfTokens if len(tok) > 2]
import random
def spamTest():
docList = []
classList = []
fullText = []
for i in range(1, 26): # 遍歷25個txt文件
wordList = textParse(open('C:/Users/Administrator/Desktop/email/spam/%d.txt' % i).read()) # 讀取每個垃圾郵件,并字符串轉(zhuǎn)換成字符串列表
docList.append(wordList)
fullText.append(wordList)
classList.append(1) # 標(biāo)記垃圾郵件,1表示垃圾文件
wordList = textParse(open('C:/Users/Administrator/Desktop/email/ham/%d.txt' % i).read()) # 讀取每個非垃圾郵件,并字符串轉(zhuǎn)換成字符串列表
docList.append(wordList)
fullText.append(wordList)
classList.append(0) # 標(biāo)記正常郵件,0表示正常文件
vocabList = createVocabList(docList) # 創(chuàng)建詞匯表,不重復(fù)
trainingSet = list(range(50))
testSet = [] # 創(chuàng)建存儲訓(xùn)練集的索引值的列表和測試集的索引值的列表
for i in range(10): # 從50個郵件中,隨機挑選出40個作為訓(xùn)練集,10個做測試集
randIndex = int(random.uniform(0, len(trainingSet))) # 隨機選取索索引值
testSet.append(trainingSet[randIndex]) # 添加測試集的索引值
del (trainingSet[randIndex]) # 在訓(xùn)練集列表中刪除添加到測試集的索引值
trainMat = []
trainClasses = [] # 創(chuàng)建訓(xùn)練集矩陣和訓(xùn)練集類別標(biāo)簽系向量
for docIndex in trainingSet: # 遍歷訓(xùn)練集
trainMat.append(setOfWords2Vec(vocabList, docList[docIndex])) # 將生成的詞集模型添加到訓(xùn)練矩陣中
trainClasses.append(classList[docIndex]) # 將類別添加到訓(xùn)練集類別標(biāo)簽系向量中
p0V, p1V, pSpam = trainNB0(np.array(trainMat), np.array(trainClasses)) # 訓(xùn)練樸素貝葉斯模型
errorCount = 0 # 錯誤分類計數(shù)
for docIndex in testSet: # 遍歷測試集
wordVector = setOfWords2Vec(vocabList, docList[docIndex]) # 測試集的詞集模型
if classifyNB(np.array(wordVector), p0V, p1V, pSpam) != classList[docIndex]: # 如果分類錯誤
errorCount += 1 # 錯誤計數(shù)加1
# print("分類錯誤的測試集:",docList[docIndex])
print('錯誤率:%.2f%%' % (float(errorCount) / len(testSet) * 100))
spamTest()
測試結(jié)果: (隨機獲取10個訓(xùn)練集里的文本當(dāng)做測試集)
?
?
由結(jié)果可知錯誤率平均為0.6 我認(rèn)為錯誤率這么大的原因是因為我的訓(xùn)練集樣本不夠豐富而且訓(xùn)練集樣本中很多文檔的內(nèi)容相似,如果有夠好的訓(xùn)練集的話訓(xùn)練結(jié)果應(yīng)該會更好。
總結(jié)
樸素貝葉斯優(yōu)缺點:
優(yōu)點:在數(shù)據(jù)較少的情況下仍然有效,可以處理多類別問題
缺點:對于輸入數(shù)據(jù)的準(zhǔn)備方式較為敏感,由于樸素貝葉斯的“特征條件獨立”特點,所以會帶來一些準(zhǔn)確率上的損失
?文章來源:http://www.zghlxwxcb.cn/news/detail-493766.html
代碼參考機器學(xué)習(xí)實戰(zhàn)課本文章來源地址http://www.zghlxwxcb.cn/news/detail-493766.html
到了這里,關(guān)于樸素貝葉斯算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!