- 簽證留學(xué) |
- 筆譯 |
- 口譯
- 求職 |
- 日/韓語 |
- 德語
3. 測(cè)試算法:根據(jù)現(xiàn)實(shí)情況修改分類器
利用貝葉斯分類器對(duì)文檔進(jìn)行分類時(shí),要計(jì)算多個(gè)概率的乘積以獲得文檔屬于某個(gè)類別的概率,即計(jì)算p(w0|1)p(w1|1)p(w2|1)。如果其中一個(gè)概率值為0,那么最后的乘積也為0。為降低這種影響,可以將所有詞的出現(xiàn)數(shù)初始化為1,并將分母初始化為2。
在文本編輯器中打開bayes.py文件,并將trainNB0 () 的第4行和第5行修改為:
poNum = ones (numWords); plNum = ones (numMords)
p0Denom = 2.0; p1Denom ? 2.0
另一個(gè)遇到的問題是下溢出,這是由于太多很小的數(shù)相乘造成的。當(dāng)計(jì)算乘積p(w0|ci)p(w1lci)p(w2|ci)..p(wN|ci)時(shí),由于大部分因子都非常小,所以程序會(huì)下溢出或者得到不正確的答案。(讀者可以用Python嘗試相乘許多很小的數(shù),最后四舍五人后會(huì)得到0。)一種解決辦法是對(duì)乘積取自然對(duì)數(shù)。在代數(shù)中有l(wèi)n(a*b)=ln(a)+ln(b),于是通過求對(duì)數(shù)可以避免下溢出或者浮點(diǎn)數(shù)舍人導(dǎo)致的錯(cuò)誤。同時(shí),采用自然對(duì)數(shù)進(jìn)行處理不會(huì)有任何損失。圖1-1給出函數(shù)f(x)與ln(f(x))的曲線。檢查這兩條曲線,就會(huì)發(fā)現(xiàn)它們?cè)谙嗤瑓^(qū)域內(nèi)同時(shí)增加或者減少,并且在相同點(diǎn)上取到極值。它們的取值雖然不同,但不影響最終結(jié)果。通過修改return前的兩行代碼,將上述做法用到分類器中:
圖1-1函數(shù)f(x)與ln(f(x))會(huì)一塊增大。這表明想求函數(shù)的最大值時(shí),可以使用該函數(shù)的自然對(duì)數(shù)來替換原函數(shù)進(jìn)行求解
現(xiàn)在已經(jīng)準(zhǔn)備好構(gòu)建完整的分類器了。當(dāng)使用NumPy向量處理功能時(shí),這一切變得十分簡單。打開文本編輯器,將下面的代碼添加到bayes.py中:
程序清單1-3樸素貝葉斯分類函數(shù)
程序清單1-3的代碼有4個(gè)輸入:要分類的向量vec2Classify以及使用函數(shù)trainNB0 ()計(jì)算得到的三個(gè)概率。使用NumPy的數(shù)組來計(jì)算兩個(gè)向量相乘的結(jié)果①。這里的相乘是指對(duì)應(yīng)元素相乘,即先將兩個(gè)向量中的第1個(gè)元素相乘,然后將第2個(gè)元素相乘,以此類推。接下來將詞匯表中所有詞的對(duì)應(yīng)值相加,然后將該值加到類別的對(duì)數(shù)概率上。最后,比較類別的概率返回大概率對(duì)應(yīng)的類別標(biāo)簽。這一切不是很難,對(duì)吧?
代碼的第二個(gè)函數(shù)是一個(gè)便利函數(shù)(convenience function),該函數(shù)封裝所有操作,以節(jié)省輸入代碼的時(shí)間。
下面來看看實(shí)際結(jié)果。將程序清單1-3中的代碼添加之后,在Python提示符下輸入:
>>> reload(bayes)
>>>bayes.testingNB()
['love', 'my','dalmation'] classified as: 0
['stupid', 'garbage'] classified as: 1
對(duì)文本做一些修改,看看分類器會(huì)輸出什么結(jié)果。這個(gè)例子非常簡單,但是它展示了樸素貝葉斯分類器的工作原理。接下來,我們會(huì)對(duì)代碼做些修改,使分類器工作得更好。
4. 準(zhǔn)備數(shù)據(jù):文檔詞袋模型
目前為止,我們將每個(gè)詞的出現(xiàn)與否作為一個(gè)特征,這可以被描述為詞集模型(set-of-words model)。如果一個(gè)詞在文檔中出現(xiàn)不止一次,這可能意味著包含該詞是否出現(xiàn)在文檔中所不能表達(dá)的某種信息,這種方法被稱為詞袋模型(bag-of-words model)。在詞袋中,每個(gè)單詞可以出現(xiàn)多次,而在詞集中,每個(gè)詞只能出現(xiàn)一次。為適應(yīng)詞袋模型,需要對(duì)函數(shù)setofwords2vec ()稍加修改,修改后的函數(shù)稱為bagofwords2Vec()。
下面的程序清單給出了基于詞袋模型的樸素貝葉斯代碼。它與函數(shù)setofWords2Vec()幾乎完全相同,唯一不同的是每當(dāng)遇到一個(gè)單詞時(shí),它會(huì)增加詞向量中的對(duì)應(yīng)值,而不只是將對(duì)應(yīng)的數(shù)值設(shè)為1。
程序清單1-4樸素貝葉斯詞袋模型
def bagOfWords2VecMN(vocabList, inputSet):
returnVec = [0]*len (vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
return returnVec
現(xiàn)在分類器已經(jīng)構(gòu)建好了,下面我們將利用該分類器來過濾垃圾郵件。
責(zé)任編輯:admin