應(yīng)用樸素貝葉斯分類器對文本簡單分類

樸素貝葉斯分類器

一媚狰,生成詞向量(詞集模型)
第一型檀,假設(shè)這里有兩個(gè)參數(shù)vocabList, inputSet憎妙。vocabList代表著包含很多無重復(fù)的詞甚纲,詞量足夠大口锭,inputSet代表著我們預(yù)轉(zhuǎn)換的詞列表。
第二介杆,創(chuàng)建一個(gè)與vocabList列表等長的全0列表returnVec鹃操,用于保存我們后面inputSet里中詞是否存在vocabList的標(biāo)記。如果存在春哨,則在對應(yīng)為置為1荆隘;如果不存在,這里簡單處理直接忽略悲靴。因此盡量使vocabList里的詞足夠多臭胜。遍歷inputSet詞列表,針對每一個(gè)元素檢測是否出現(xiàn)在vocabList列表中癞尚,存在,則在與vocabList同一索引處的returnVec列表中置位置上中置1乱陡,代完成詞向量標(biāo)記處理浇揩。
第三,返回returnVec列表即可憨颠。

def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print "the %s word not in vocabList" % word
    return returnVec

這是詞集模型胳徽,即將詞的出現(xiàn)與否作為統(tǒng)計(jì)度量,如果一個(gè)詞多次出現(xiàn)與出現(xiàn)一次是一樣的爽彤;而詞袋养盗,還包含了詞出現(xiàn)的次數(shù)。在程序中只需修改為returnVec[vocabList.index(word)] += 1
二适篙,計(jì)算樸素貝葉斯先驗(yàn)概率
第一往核,

貝葉斯概率.png

如果在貝葉斯定理中涉及多個(gè)屬性,我們需要假設(shè)這些屬性間中相互獨(dú)立的嚷节,也即一個(gè)屬性的出現(xiàn)與否不受其他屬性的影響聂儒,雖然假設(shè)是不一定成立的,但這也正是樸素二字的體現(xiàn)硫痰。相比硬規(guī)則而言衩婚,這已經(jīng)使樸素貝葉斯分類器具有相當(dāng)好的結(jié)果了。
圖貝葉斯公式
很容易由訓(xùn)練集求得P(X1|Ci)效斑、P(X2|Ci)非春、P(X3|Ci)...P(Xn|Ci)概率。
X k表示元組X在屬性A k的值。對于每個(gè)屬性需要考查屬性值是分類屬性還是連續(xù)值屬性奇昙。
(1)如果是分類屬性护侮,則P(X1|Ci)的值由屬性值為X1的元組的屬于Ci類別的元組與所有屬于Ci的元組相比求得。
(2)如果是連續(xù)值敬矩,數(shù)個(gè)P(X1|Ci)概行、P(X2|Ci)、P(X3|Ci)...P(Xn|Ci)的概率值乘積也不難求弧岳,通常假定Xi服從均值為u凳忙,標(biāo)準(zhǔn)差為sigma的高斯分布
貝葉斯公式
樸素貝葉斯計(jì)算公式.png

Xk服從服從均值為u,標(biāo)準(zhǔn)差為sigma的高斯分布

高斯計(jì)算公式.png

也即我們只需求出Ci類訓(xùn)練元組A k的均值及標(biāo)準(zhǔn)差即可禽炬。
第二涧卵,這里做的是樸素貝葉斯分類屬性的應(yīng)用,兩個(gè)類別腹尖,1代表著垃圾郵件柳恐,0代表正常郵件。
(1)計(jì)算訓(xùn)練文檔條數(shù)热幔,該訓(xùn)練文檔由詞向量組成乐设。
(2)分別計(jì)算屬于各個(gè)分類的詞出現(xiàn)次數(shù)和該分類下總詞數(shù)。
需要計(jì)算多個(gè)概率的乘積以推測具有某些屬性的詞應(yīng)歸屬于哪個(gè)類別下绎巨,如分類為1具有X1近尚,X2,X3,Xn屬性值的概率:
P(X1|C=1)* P(X2|C=1)*P(X3|C=1)...P(Xn|C=1)场勤,如果其中一個(gè)概率為0戈锻,那么最終概率結(jié)果便成0了,正反例概率同時(shí)為0的概率很大和媳,也就意味著分類無效格遭。為降低概率為0影響,我們在開始為每個(gè)詞出現(xiàn)次數(shù)設(shè)置為1留瞳,文檔數(shù)為2拒迅。同時(shí),為避免多個(gè)float小數(shù)相乘結(jié)果下溢問題撼港,使用numpy模塊的log函數(shù)坪它,注意在下面程序中,我使用python自帶的log函數(shù)運(yùn)算失敗帝牡,該用numpy才算成功往毡。
(3)計(jì)算訓(xùn)練文檔的垃圾率,因?yàn)橄蛄吭?代表著垃圾靶溜,故垃圾文檔率為P(C1)开瞭。

def trainNB0(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    p0Num = ones(numWords)
    p1Num = ones(numWords)  # p1Num 為單詞出現(xiàn)次數(shù)數(shù)組
    p0Denom = 2.0
    p1Denom = 2.0  # p1Denom為數(shù)據(jù)集中總詞數(shù)
    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 = log(p1Num / p1Denom)
    p0Vect = log(p0Num / p0Denom)
    return p0Vect, p1Vect, pAbusive

三懒震, 樸素貝葉斯分類器各類別先驗(yàn)概率
在前面我們?yōu)楸苊舛鄠€(gè)小數(shù)值相乘結(jié)果下溢問題,使用了log函數(shù)相加便得出正反例概率相對值大小嗤详。
P(C|W) = P(W|C) * P(C) / P(W)
在計(jì)算正反例(這里僅僅有兩個(gè)分類)后驗(yàn)概率是个扰,由于分母P(W)代表著在所有文檔中該屬性組合出現(xiàn)的概率,它是相等的葱色,所以递宅,我們可以僅僅比較分子大小便可以得出具有某些特征的文檔屬于哪個(gè)類別。

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    # 不在預(yù)保留的詞匯表中的詞語默認(rèn)都是好詞
    # vec2Classify 用來確定測試單詞是否存在苍狰。
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + log(1 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

有一點(diǎn)需要注意的是办龄,sum(vec2Classify * p1Vec) + log(pClass1)表示貝葉斯定理的分子部分。
vec2Classify在詞集模型中表示該屬性是否在訓(xùn)練數(shù)據(jù)集中出現(xiàn)淋昭,如果出現(xiàn)俐填,該屬性的概率值為p1Vec或p0Vec數(shù)組所對應(yīng)位置處的值。最后比較兩個(gè)概率大小翔忽,返回大者英融。
而在詞袋模型中,vec2Classify具有體現(xiàn)該屬性出現(xiàn)的次數(shù)能力歇式,在計(jì)算概率過程中驶悟,它相當(dāng)于為該屬性附上權(quán)重。
四材失,對樸素貝葉斯分類器的分類的測試

def testingNB():
    listOfPosts, listClasses = loadDataSet()
    myVocabList = createVocabList(listOfPosts)
    trainMat = []
    for postinDoc in listOfPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
    testEntry = ['love', 'my', 'dalmation']
    thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
    print testEntry,"classified is:", classifyNB(thisDoc, p0V, p1V, pAb)
    testEntry =['beijing', 'HongKong']
    thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
    print testEntry, "classified is:", classifyNB(thisDoc, p0V, p1V, pAb)

因?yàn)樵谟?xùn)練數(shù)據(jù)集沒有['beijing', 'HongKong']撩银,同時(shí)對訓(xùn)練集中不存在的詞的處理默認(rèn)是非垃圾的,故在這里可以看到['beijing', 'HongKong']也被分到正常類別當(dāng)中豺憔。
五 拓展技巧
(1),留存交叉驗(yàn)證
是指從數(shù)據(jù)集中隨機(jī)選擇一部分?jǐn)?shù)據(jù)作為訓(xùn)練集够庙,而余下的數(shù)據(jù)部分作為測試集恭应,對減弱數(shù)據(jù)過擬合的有重要作用。
Python代碼實(shí)現(xiàn):
思想很簡單耘眨,創(chuàng)建一個(gè)與數(shù)據(jù)集具有同樣長度的trainingIndexSet用來保存訓(xùn)練集索引昼榛,之后從該索引列表中移除測試數(shù)據(jù)集的索引,并保存在一個(gè)新的索引中剔难。在模型訓(xùn)練過程中胆屿,通過索引加載所需數(shù)據(jù)集,同樣測試也是偶宫,由于沒有對分類類標(biāo)進(jìn)行操作非迹,因此,不管是在訓(xùn)練集的屬性還是測試集的屬性所對應(yīng)的分類類號都還是一一對應(yīng)的纯趋。
從10個(gè)數(shù)據(jù)集中隨機(jī)抽出3個(gè)作為測試集憎兽。

alist = [[0, 1, 2, 3, 4],
         [5, 6, 7, 8, 9],
         [10, 11, 12, 13, 14],
         [15, 16, 17, 18, 19],
         [20, 21, 22, 23, 24],
         [25, 26, 27, 28, 29],
         [30, 31, 32, 33, 34],
         [35, 36, 37, 38, 39],
         [40, 41, 42, 43, 44],
         [45, 46, 47, 48, 49]]
classes = [1, 0, 1, 1, 1, 0, 0, 1, 0, 0]

trainingIndexSet = range(len(alist))
testIndexSet = []
for i in range(3):
    index = int(random.uniform(0, len(trainingIndexSet)))
    print 'index: ', index
    testIndexSet.append(trainingIndexSet[index])
    del trainingIndexSet[index]
print testIndexSet
# 在模型訓(xùn)練和測試時(shí)通過`alist[trainingIndexSet[i]]`冷离、`alist[testIndex[i]]`獲取數(shù)據(jù)集

注意uniform函數(shù)按說能夠返回與末端相等的值,但我試驗(yàn)循環(huán)1百萬次沒試出來纯命。
還有一種對分類號操作的實(shí)現(xiàn)西剥,這里不寫了。
六亿汞,總結(jié)
(1)詞集僅僅統(tǒng)計(jì)一個(gè)單詞是否出現(xiàn)瞭空;而詞袋還包含了單詞出現(xiàn)次數(shù)的統(tǒng)計(jì),相當(dāng)在計(jì)算貝葉斯先驗(yàn)概率時(shí)為每個(gè)單詞賦予權(quán)重疗我;TF-IDF是更高級的文本分類應(yīng)用咆畏,它排除了輔助詞對文本分類的影響,如中文中的"的"碍粥,"是"鳖眼,"啊"等詞,這些詞在對正確分類的貢獻(xiàn)小嚼摩、價(jià)值低钦讳,因此給予它很小的權(quán)重,雖然出現(xiàn)次數(shù)很多枕面,這也就是逆文檔率概念愿卒。
(2)貝葉斯先驗(yàn)概率求解過程涉及多個(gè)概率相乘問題,最終結(jié)果可能下溢問題潮秘,故選用log琼开,首選numpy,Python自帶的log函數(shù)可能不合適枕荞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柜候,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子躏精,更是在濱河造成了極大的恐慌渣刷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矗烛,死亡現(xiàn)場離奇詭異辅柴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瞭吃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門碌嘀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人歪架,你說我怎么就攤上這事股冗。” “怎么了牡拇?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵魁瞪,是天一觀的道長穆律。 經(jīng)常有香客問我,道長导俘,這世上最難降的妖魔是什么峦耘? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮旅薄,結(jié)果婚禮上辅髓,老公的妹妹穿的比我還像新娘。我一直安慰自己少梁,他們只是感情好洛口,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凯沪,像睡著了一般第焰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妨马,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天挺举,我揣著相機(jī)與錄音,去河邊找鬼烘跺。 笑死湘纵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的滤淳。 我是一名探鬼主播梧喷,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼脖咐!你這毒婦竟也來了铺敌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤屁擅,失蹤者是張志新(化名)和其女友劉穎适刀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煤蹭,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年取视,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了硝皂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡作谭,死狀恐怖稽物,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情折欠,我是刑警寧澤贝或,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布吼过,位于F島的核電站,受9級特大地震影響咪奖,放射性物質(zhì)發(fā)生泄漏盗忱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一羊赵、第九天 我趴在偏房一處隱蔽的房頂上張望趟佃。 院中可真熱鬧,春花似錦昧捷、人聲如沸闲昭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽序矩。三九已至,卻和暖如春跋破,著一層夾襖步出監(jiān)牢的瞬間簸淀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工幔烛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啃擦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓饿悬,卻偏偏與公主長得像令蛉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子狡恬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容