樸素貝葉斯算法(Naive Bayes)
前兩章學(xué)習(xí)的knn和決策樹(shù)分類都直接給出了答案,但是不能避免一些分類錯(cuò)誤,本章學(xué)習(xí)的方法給出的是一個(gè)最優(yōu)的類別猜測(cè)結(jié)果,并且給出概率估計(jì)值。
-
樸素一詞是因?yàn)檎麄€(gè)過(guò)程都是最原始最簡(jiǎn)單的假設(shè)<特征之間獨(dú)立性假設(shè)>。
是基于貝葉斯定理和特征條件獨(dú)立假設(shè)的分類方法。
- 優(yōu)點(diǎn):數(shù)據(jù)少也可以有效,可以處理多分類問(wèn)題
- 缺點(diǎn):輸入數(shù)據(jù)的準(zhǔn)備方式較為敏感
貝葉斯決策理論:核心就是選擇具有最高概率的決策。樸素貝葉斯就是基于貝葉斯決策理論的一種分類方法。
概率知識(shí)復(fù)習(xí)
- 條件概率
-
P(A|B) = P(A·B)/P(B)
例子
-
例題:
- P(A·B)-->在B桶中抽到白球的概率-->1/7;
- P(B)-->B桶中有3塊石頭的概率-->3/7;
- 根據(jù)公式P(A|B) = (1/7)/(3/7) = 1/3
貝葉斯準(zhǔn)則

用樸素貝葉斯進(jìn)行文檔分類
文檔分類是機(jī)器學(xué)習(xí)的一個(gè)重要應(yīng)用??梢杂^察文檔中的詞,將每個(gè)詞的出現(xiàn)或者不出現(xiàn)作為一個(gè)特征,這樣特征數(shù)目就等同于詞匯表的詞數(shù)。
一般步驟:
- 1) 收集數(shù)據(jù)
- 2)準(zhǔn)備數(shù)據(jù)(數(shù)值型、布爾型)
- 3)分析數(shù)據(jù)(特征多,用直方圖效果好)
- 4)訓(xùn)練算法(計(jì)算不同獨(dú)立特征多條件概率)
- 5)測(cè)試算法(計(jì)算錯(cuò)誤率)
- 6)使用算法(一般應(yīng)用于文檔分類,但也無(wú)限制)
通常每個(gè)特征需要N個(gè)樣本,10個(gè)特征需要N^10個(gè)樣本;如果特征相互獨(dú)立,那么樣本數(shù)就變成1000*N
獨(dú)立:一個(gè)特征或者單詞出現(xiàn)與它和其它單詞相鄰沒(méi)有關(guān)系。
* 這個(gè)假設(shè)也是樸素貝葉斯分類中樸素一詞的含義。
* 另一個(gè)假設(shè)是每個(gè)特征都是等重要的,即每個(gè)詞是等權(quán)重的,只考慮詞是否出現(xiàn),不考慮出現(xiàn)次數(shù)。
python進(jìn)行文本分類
準(zhǔn)備數(shù)據(jù):詞向量構(gòu)建
思路在于:
- 構(gòu)建一個(gè)詞表,包含文本的所有詞,長(zhǎng)度是文本中不同詞的數(shù)量
- 對(duì)每一句話進(jìn)行詞向量化
- 構(gòu)建一個(gè)同詞表等長(zhǎng)的0向量
- 判斷每句話中的詞在詞表中是否出現(xiàn),出現(xiàn)在0向量中相應(yīng)位置記為1
def loadDataSet():
'''
postingList: 切詞后的句子
classVec:數(shù)據(jù)集對(duì)應(yīng)的分類標(biāo)簽
'''
postingList = [ ['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', '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代表正常言論
return postingList,classVec
def creatVocabList(dataset):
'''
構(gòu)建詞表
output:詞表
'''
vocabSet = set([])
for doc in dataset:
vocabSet = vocabSet | set(doc) # 通過(guò)對(duì)兩個(gè)集合取并,找出所有非重復(fù)的單詞
return list(vocabSet)
#對(duì)于這個(gè)函數(shù),自己的思路是將所有句子用extend拼接成一個(gè)大list,然后用set來(lái)得到詞表
def Words2Vec(vocabSet, inputSet):
'''
vocabSet:詞表
inputSet:輸入需要向量化的句子
output:輸出文檔向量(0,1)形式
'''
return_vec = [0] * len(vocabSet)
# 創(chuàng)建與詞匯表等長(zhǎng)的列表向量
for word in inputSet:
if word in vocabSet:
return_vec[vocabSet.index(word)] = 1 # 出現(xiàn)的單詞賦1
else: print("the word %s is not in list" % word)
return return_vec
if __name__=='__main__':
dataSet,labels = loadDataSet()
vocabSet = creatVocabList(dataSet)
wordVect = Words2Vec(vocabSet,dataSet[0])
print('the vocabulary list is :'+'\n'+repr(vocabSet)+'\n')
print('word2vect of sentence 2 is : '+'\n'+repr(wordVect))
trainvec = []
for i in range(len(dataSet)):
wordVect = Words2Vec(vocabSet,dataSet[I])
trainvec.append(wordVect)
trainvec
the vocabulary list is :
['to', 'how', 'not', 'dalmation', 'love', 'garbage', 'licks', 'my', 'mr', 'quit', 'so', 'I', 'steak', 'posting', 'food', 'flea', 'take', 'is', 'problems', 'park', 'stupid', 'please', 'him', 'ate', 'help', 'maybe', 'cute', 'worthless', 'has', 'dog', 'stop', 'buying']
word2vect of sentence 2 is :
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0]
訓(xùn)練算法:根據(jù)詞向量計(jì)算概率
目的是:輸入訓(xùn)練樣本和標(biāo)簽,可以得到詞表中每個(gè)詞是某一類別的概率。即計(jì)算P(Ci|wi)的概率。比如在wi這個(gè)詞出現(xiàn)的條件下,它是類別1的概率。后驗(yàn)求條件概率需要用到貝葉斯公式。
樸素貝葉斯分類器就是基于數(shù)據(jù)集D,估計(jì)先驗(yàn)概率P(c),再對(duì)每個(gè)屬性,估計(jì)條件概率P(wi | c).
- 先驗(yàn)概率是屬于某個(gè)類別的樣本集合Dc/樣本總數(shù),是橫向計(jì)算
- 條件概率是在上述樣本空間內(nèi),某個(gè)樣本屬性取值的集合/Dc??v向計(jì)算

W是一個(gè)特征向量,長(zhǎng)度和詞表長(zhǎng)度相同;c是對(duì)應(yīng)的類別;P(W) = ∑P(W|ci)·P(ci)全概率公式得到
import numpy as np
def NaiveBayes0(trainMatrix,trainCategory):
'''
用樸素貝葉斯計(jì)算先驗(yàn)概率P(ci)和條件概率P(w | ci)
trainMatrix:特征向量組成的矩陣
trainCategory:各特征向量對(duì)應(yīng)的分類
'''
numTrain = len(trainMatrix) #訓(xùn)練的文檔個(gè)數(shù)
numWords = len(trainMatrix[0]) #詞表的大小,即特征的大小
p1 = sum(trainCategory)/float(numTrain) #分類1的概率p(y=1),標(biāo)簽中1出現(xiàn)的次數(shù)/總文檔數(shù);p(y=0) = 1-p1
p0Num = np.zeros(numWords); p1Num = np.zeros(numWords) #初始化為0
p0Denom = 0.0; p1Denom = 0.0
#對(duì)每一個(gè)訓(xùn)練文檔
for i in range(numTrain):
#出現(xiàn)侮辱性詞語(yǔ)
if trainCategory[i] == 1:
p1Num += trainMatrix[I]
#c=1條件下,統(tǒng)計(jì)某個(gè)單詞出現(xiàn)的個(gè)數(shù)(因?yàn)槊總€(gè)特征向量都是等長(zhǎng)的,其中每個(gè)詞條位置固定,可以直接相加來(lái)計(jì)算次數(shù)),用于計(jì)算p(wi/c=1)
p1Denom += sum(trainMatrix[I])
#累計(jì)c=1的所有單詞數(shù)量
else:
p0Num += trainMatrix[I]
p0Denom += sum(trainMatrix[I])
p1Vect = p1Num/float(p1Denom) #p(w/c=1)
p0Vect = p0Num/float(p0Denom) #p(w/c=0)
return p0Vect,p1Vect,p1
if __name__ == '__main__':
p0Vect,p1Vect,p1 = NaiveBayes0(trainvec,labels)
print("先驗(yàn)概率 p(c=1) = ",p1) #classVec = [0,1,0,1,0,1] ,so p1=0.5
print("每個(gè)特征的條件概率 p(w | c=1) = ",p1Vect)
print("c=1,the word with the max Probability=(%f), is(%s)"%(np.max(p1Vect),vocabSet[np.argmax(p1Vect)]))
# 對(duì)詞條按概率排序
dt = list(p1Vect)
result = dict(list(zip(vocabSet,dt)))
result_sort = sorted(result.items(),key=lambda x:x[1],reverse=True)[0:5]
print('詞條屬于侮辱性詞語(yǔ)的概率排序:'+repr(result_sort))
先驗(yàn)概率 p(c=1) = 0.5
每個(gè)特征的條件概率 p(w | c=1) = [0.05263158 0. 0.05263158 0. 0. 0.05263158
0. 0. 0. 0.05263158 0. 0.
0. 0.05263158 0.05263158 0. 0.05263158 0.
0. 0.05263158 0.15789474 0. 0.05263158 0.
0. 0.05263158 0. 0.10526316 0. 0.10526316
0.05263158 0.05263158]
c=1,the word with the max Probability=(0.157895), is(stupid)
詞條屬于侮辱性詞語(yǔ)的概率排序:[('stupid', 0.15789473684210525), ('worthless', 0.10526315789473684), ('dog', 0.10526315789473684), ('to', 0.05263157894736842), ('not', 0.05263157894736842)]
這個(gè)結(jié)果表示,在侮辱性的類別中,詞條stupid一詞是出現(xiàn)頻率最高的詞,即這個(gè)詞是侮辱性詞語(yǔ)的概率最大。
- 在計(jì)算多個(gè)概率乘積會(huì)因?yàn)槟硞€(gè)概率值為0,導(dǎo)致乘積也為0,可以初始化所有詞為1,分母初始化為2。
- 小數(shù)相乘會(huì)出現(xiàn)下溢現(xiàn)象,即四舍五入的時(shí)候會(huì)變成0,需要取log
統(tǒng)計(jì)學(xué)習(xí)方法里面提到,原來(lái)的估計(jì)方法是極大似然估計(jì),可以用貝葉斯估計(jì)來(lái)優(yōu)化,具體做法如下圖:
拉普拉斯平滑
def NaiveBayes1(trainMatrix,trainCategory):
numTrain = len(trainMatrix) #訓(xùn)練的文檔個(gè)數(shù)
numWords = len(trainMatrix[0]) #詞匯表的大小,即特征的大小
p1 = sum(trainCategory)/float(numTrain) #分類1的概率p(y=1),這里是二分類,所以,p0=1-p1
p0Num = np.ones(numWords); p1Num = np.ones(numWords) #change to 1 ,一般sigma = 1
p0Denom = 2.0; p1Denom = 2.0 # change to 2.0 因?yàn)橛袃蓚€(gè)類別
for i in range(numTrain):
if trainCategory[i] == 1:
p1Num += trainMatrix[i] #y=1條件下,統(tǒng)計(jì)某個(gè)單詞出現(xiàn)的個(gè)數(shù),用于計(jì)算p(w/y=1)
p1Denom += sum(trainMatrix[i]) #累計(jì)y=1的所有單詞數(shù)量
else:
p0Num += trainMatrix[i] #y=0條件下,統(tǒng)計(jì)某個(gè)單詞出現(xiàn)的個(gè)數(shù),用于計(jì)算p(w/y=0)
p0Denom += sum(trainMatrix[i]) #累計(jì)y=0的所有單詞數(shù)量
p1Vect = np.log(p1Num/float(p1Denom)) #change to log()
p0Vect = np.log(p0Num/float(p0Denom)) #change to log()
return p0Vect,p1Vect,p1
NaiveBayes1(trainvec,labels)
(array([-2.56494936, -2.56494936, -3.25809654, -2.56494936, -2.56494936,
-3.25809654, -2.56494936, -1.87180218, -2.56494936, -3.25809654,
-2.56494936, -2.56494936, -2.56494936, -3.25809654, -3.25809654,
-2.56494936, -3.25809654, -2.56494936, -2.56494936, -3.25809654,
-3.25809654, -2.56494936, -2.15948425, -2.56494936, -2.56494936,
-3.25809654, -2.56494936, -3.25809654, -2.56494936, -2.56494936,
-2.56494936, -3.25809654]),
array([-2.35137526, -3.04452244, -2.35137526, -3.04452244, -3.04452244,
-2.35137526, -3.04452244, -3.04452244, -3.04452244, -2.35137526,
-3.04452244, -3.04452244, -3.04452244, -2.35137526, -2.35137526,
-3.04452244, -2.35137526, -3.04452244, -3.04452244, -2.35137526,
-1.65822808, -3.04452244, -2.35137526, -3.04452244, -3.04452244,
-2.35137526, -3.04452244, -1.94591015, -3.04452244, -1.94591015,
-2.35137526, -2.35137526]),
0.5)
取log自然就是負(fù)值
李航書中關(guān)于樸素貝葉斯分類器在最后部分,分母問(wèn)題上不是很清楚,這篇文章幫助我理解,為什么分母可以約去,只考慮分子部分。
def classify(testVec, p0Vec, p1Vec, pClass1):
'''
樸素貝葉斯分類器-->用于計(jì)算特征的類別
testVec:特征向量(測(cè)試樣本)
p0Vect:P(w | c=0)條件概率
p1Vect:P(w | c =1)條件概率
pClass1:P(c = i)先驗(yàn)概率
output:返回分類的結(jié)果1:侮辱性,0:非侮辱性。
'''
p1 = sum(testVec * p1Vec) + np.log(pClass1) #因?yàn)槭莑og,ln(a*b) = ln(a)+ln(b)所以這里是求和以及+號(hào)操作
#p(c=1/w) = p(w/c=1) * p(c=1)因?yàn)楦鶕?jù)樸素貝葉斯算法公式,分母是P(C = Ci),分母對(duì)于已知的,對(duì)估計(jì)結(jié)果不影響,可以約去;至于乘上testVec,不是很清楚。
p0 = sum(testVec * p0Vec) + np.log(1.0 - pClass1) #p(y=0) = 1 - p(y=1)
if p1 > p0: #選取最大的概率的類
return 1
else:
return 0
p0V,p1V,p1 = NaiveBayes1(trainvec,labels)
test0 = ['love', 'my', 'dalmation']
testVec0 = Words2Vec(vocabSet, test0)
print(test0,'classified as: ',classify(testVec0,p0V,p1V,p1))
test1 = ['stupid', 'garbage']
testVec1 = Words2Vec(vocabSet, test1)
print(test1,'classified as: ',classify(testVec1,p0V,p1V,p1))
['love', 'my', 'dalmation'] classified as: 0
['stupid', 'garbage'] classified as: 1
詞袋模型(bag of words model)
- 對(duì)于每個(gè)詞是否出現(xiàn)---->詞集模型(
set of words model) - 對(duì)于每個(gè)詞可以多次出現(xiàn)--->詞袋模型(
bag of words model)
因此需要對(duì)詞向量模型做一些修改
- 每當(dāng)遇到一個(gè)單詞,模型會(huì)增加詞向量中對(duì)應(yīng)的值,而不是全為1.
idea:
- 構(gòu)建一個(gè)長(zhǎng)度同詞表的0向量
- 對(duì)樣本中每個(gè)詞遍歷:
- 判斷該詞是否在詞表中:
- 在,則在0向量相應(yīng)位置記1
- 判斷該詞是否在詞表中:
def bagOfWordsVec(vocabSet, inputSet):
'''
詞袋模型,需要統(tǒng)計(jì)某個(gè)詞條出現(xiàn)的次數(shù)
vocabSet:詞表
inputSet:一個(gè)樣本;特征向量
output:詞向量
'''
returnVec = [0]*len(vocabSet)
for word in inputSet:
if word in vocabSet:
returnVec[vocabSet.index(word)] += 1 #出現(xiàn)一次,累加一次
return returnVec
test_Vec = bagOfWordsVec(vocabSet,['i','hate','this','stupid','dog'])
print('詞袋模型的詞向量:'+repr(test_Vec))
詞袋模型的詞向量:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
練習(xí)-用樸素貝葉斯分類器過(guò)濾垃圾郵件
步驟依然是:
- 收集數(shù)據(jù)
- 準(zhǔn)備數(shù)據(jù)-->文件文本向量化
- 分析數(shù)據(jù)
- 訓(xùn)練算法-->訓(xùn)練模型
- 測(cè)試算法-->查看文檔分類的錯(cuò)誤率
- 使用算法-->構(gòu)建完整程序,并將分類結(jié)果以及錯(cuò)誤分類情況輸出
數(shù)據(jù)包含已經(jīng)分類的普通郵件和垃圾郵件各25封,需要做的是將數(shù)據(jù)集劃分成訓(xùn)練集和測(cè)試集;將劃分好的數(shù)據(jù)集進(jìn)行詞向量化;將詞向量給分類器進(jìn)行分類;根據(jù)標(biāo)簽集統(tǒng)計(jì)分類錯(cuò)誤率;由于劃分?jǐn)?shù)據(jù)集是隨機(jī)的,需要重復(fù)多次取均值。
idea:
- 劃分?jǐn)?shù)據(jù)集,隨機(jī)采樣-->書上是4:1
- 詞向量化
- 訓(xùn)練
- 計(jì)算錯(cuò)誤率
- 重新劃分?jǐn)?shù)據(jù)集(重復(fù))
準(zhǔn)備數(shù)據(jù)
- 讀取文本數(shù)據(jù),預(yù)處理,只保留文本(需要用到正則表達(dá)式)
import re
def textParse(bigString):
'''
字符串處理函數(shù):保留英文字符和數(shù)字作為詞條,且長(zhǎng)度>2
bigString:輸入的文本文件
output:返回一個(gè)詞列表
'''
listOfTokens = re.split(r'\W*', bigString) #只需要字符和數(shù)字
return [tok.lower() for tok in listOfTokens if len(tok) > 2] #變成小寫,過(guò)濾長(zhǎng)度小于3的字符串
def spamTest():
'''
垃圾郵件分類函數(shù)
'''
docList=[]; classList = []; fullText =[]
#分別是總郵件列表,郵件對(duì)應(yīng)分類標(biāo)簽集合,所有句子組成的文本
for i in list(range(1,26)): #每個(gè)文件夾,有25個(gè)文件
wordList = textParse(open('./email/spam/%d.txt' % i,encoding='ISO-8859-1').read())
docList.append(wordList)
fullText.extend(wordList)
classList.append(1)
wordList = textParse(open('./email/ham/%d.txt' % i,encoding='ISO-8859-1').read())
docList.append(wordList)
fullText.extend(wordList)
classList.append(0)
vocabularyList = creatVocabList(docList)#建總詞表
trainingSet =list( range(50)); testSet=[] #create test set,這里其實(shí)是val set,而且只保存了下標(biāo)
for i in list(range(10)):
randIndex = int(np.random.uniform(0,len(trainingSet)))
testSet.append(trainingSet[randIndex])
del(trainingSet[randIndex]) #隨機(jī)選取10個(gè),并且從train中刪除
'''
抽樣將數(shù)據(jù)集一開(kāi)始合并成同一個(gè)數(shù)組比較好,將分類標(biāo)簽全部加在list[0]位置,或者把數(shù)據(jù)集append方法加在標(biāo)簽集后面便于后續(xù)操作。
抽樣可方法很多,無(wú)非是記住index,然后從數(shù)據(jù)集中選擇,自己選用的是random.sample()函數(shù),從1-50數(shù)組中抽樣得到index_list,然后劃分。
其中用了map(),和filter()方法,可讀性更強(qiáng)。
'''
trainMat=[]; trainClasses = []
for docIndex in trainingSet:#獲得索引
trainMat.append(bagOfWordsVec(vocabularyList, docList[docIndex]))
trainClasses.append(classList[docIndex])
p0V,p1V,pSpam = NaiveBayes1(trainMat,trainClasses) #訓(xùn)練,得到條件概率
errorCount = 0
for docIndex in testSet: #classify the remaining items
wordVector = bagOfWordsVec(vocabularyList, docList[docIndex])
if classify(wordVector,p0V,p1V,pSpam) != classList[docIndex]: #用于test/val
errorCount += 1
#print( "classification error",docList[docIndex])
#print('the error rate is: ',float(errorCount)/len(testSet))
return float(errorCount)/len(testSet)
spamTest()
0.1
留出法
由于隨機(jī)劃分?jǐn)?shù)據(jù)集是隨機(jī)的,單次劃分結(jié)果不夠穩(wěn)定,需要多次重復(fù)取均值
Er = []
for i in range(20):
error = spamTest()
Er.extend([error])
mean_error = sum(Er)/20
print('20次重復(fù)劃分?jǐn)?shù)據(jù)集的平均誤差:%f'%mean_error)
20次重復(fù)劃分?jǐn)?shù)據(jù)集的平均誤差:0.050000
關(guān)于抽樣的一些想法和實(shí)現(xiàn)
- 1.用random.sample()對(duì)數(shù)組抽樣,得到訓(xùn)練集index
- 2.用map(),從未劃分的數(shù)據(jù)集中,按index索引取樣
- 3.用filter(),得到測(cè)試集的index
- 4.同2
def splitDataSet(docList,classList,size):
'''
隨機(jī)抽樣-數(shù)據(jù)集劃分
docList:未劃分的訓(xùn)練集
classList:未劃分的標(biāo)簽集
sample:采樣大小
output:劃分后的訓(xùn)練集、測(cè)試集及其對(duì)應(yīng)的分類標(biāo)簽
'''
import random
#訓(xùn)練集
index_train = random.sample(range(50),size)
trainSet = list(map(lambda x:docList[x],index_train))
classSet_train = list(map(lambda x:classList[x],index_train))
#測(cè)試集
index_test = list(filter(lambda x:x not in index_train,range(50)))
testSet = list(map(lambda x:docList[x],index_test))
classSet_test = list(map(lambda x:classList[x],index_test))
return trainSet,classSet_train,testSet,classSet_test
dtrain,labeltrain,dtest,labeltest = splitDataSet(docList,classList,40)
小結(jié)
關(guān)于樸素貝葉斯算法,核心在于通過(guò)樸素貝葉斯公式和‘樸素’這個(gè)特點(diǎn),即通過(guò)假設(shè)隨機(jī)變量之間兩兩獨(dú)立,從而簡(jiǎn)化了特征之間的關(guān)系,利用先驗(yàn)概率和條件概率,來(lái)估算后驗(yàn)概率,選擇后驗(yàn)概率中的最大概率,來(lái)確定最終的類別。
主要有以下幾個(gè)注意點(diǎn):
-
詞向量化(word2Vector):主要是通過(guò)構(gòu)造詞表,即將切詞后的所有文本組成一個(gè)集合,組成一個(gè)n維的詞向量,每個(gè)詞在相應(yīng)的位置,出現(xiàn)記1,不出現(xiàn)記0。 -
詞集模型(set of words model):就是將詞是否出現(xiàn)作為判斷依據(jù),只考慮是否出現(xiàn),而不考慮出現(xiàn)的次數(shù)。 -
詞袋模型(bag of words model):將詞出現(xiàn)的次數(shù)考慮在內(nèi),來(lái)生成詞向量。 -
樸素的含義:對(duì)條件概率做了獨(dú)立性假設(shè),假設(shè)各特征屬性之間相互獨(dú)立。 - 對(duì)于
后驗(yàn)概率最大化,李航書中解釋是等價(jià)于期望風(fēng)險(xiǎn)最小化,具體可以看推導(dǎo)過(guò)程。 - 由于用樸素貝葉斯法的參數(shù)估計(jì)采用的是
極大似然估計(jì),可能會(huì)出現(xiàn)特征屬性集合為0而導(dǎo)致估計(jì)的概率乘積為0,導(dǎo)致結(jié)果出現(xiàn)偏差,需要用到貝葉斯估計(jì)來(lái)修正,通常在隨機(jī)變量各取值頻數(shù)上加一個(gè)正數(shù)λ,=0是極大似然估計(jì),=1是拉普拉斯平滑,通常分子是λ,分母是Kλ,K表示分類類別數(shù)量。 -
下溢問(wèn)題(太小的數(shù)相乘導(dǎo)致取值近似為0)可以用取對(duì)數(shù)來(lái)解決,要降低錯(cuò)誤率可以通過(guò)去停用詞等方法改進(jìn)。
tips:使用markdown寫文章遇到插入圖片問(wèn)題,Mac 可以使用ipic這個(gè)應(yīng)用,把圖片匿名傳到云端,生成一個(gè)鏈接。即傳即用~
推薦閱讀
- 《統(tǒng)計(jì)學(xué)習(xí)方法》

