樸素貝葉斯改進及其應用
1、貝葉斯定理
設是類標號未知的資料樣本,為某種假設,資料樣本屬於某特定的類 C ,對於該分類問題,期望確定,即給定觀測資料樣本,假定成立的概率,稱為後驗概率,或稱條件下的後驗概率。分類就是要確定。
例如,假定資料樣本集由顧客組成,用他們的年齡和收入情況進行分類。假定表示顧客的年齡在31歲到40之間並且中等收入,表示顧客將購買電腦,則反映的是觀察到顧客的年齡在31歲到40之間並且中等收入時,將購買電腦的確定程度。為先驗概率,在無論顧客的年齡和收入情況而購買電腦的概率。後驗概率比先驗概率基於更多的背景知識,而是獨立於的。與之類似,是在條件下,的後驗概率,即已知顧客購買電腦,其年齡在31歲到40歲之間並且中等收入的概率。由於通常情況下
2、樸素的貝葉斯分類器
樸素貝葉斯分類就是假定一個屬性值對給定類的影響獨立於其他屬性的值,該假定稱作類條件獨立,做此假定是為了簡化計算,在此意義下稱為“樸素的”。樸素貝葉斯分類的工作過程如下:
(1)每個資料樣本用一個n維特徵向量表示,分別描述n個屬性樣本的n個度量。
(2)假定m個類。給定一個未知的資料樣本,樸素貝葉斯分類將未知的樣本分配給類,當且僅當
根據貝葉斯定理,最大化即可進行分類,其中令最大的類稱為最大後驗假設。
(3)其中代表屬性集取值為時的聯合概率,為常數,所以最大化時只需使
(4)給定具有許多屬性的資料集,計算即的開銷可能非常大。為降低計算的開銷,可以做類條件獨立的樸素假定。在此情況下有:
(a)如果是離散屬性,,其中是樣本集中屬於型別的樣本個數。是樣本集中於型別且屬性取值為的樣本個數。
(b)若是連續值屬性,常用的處理方法有兩種:一是對其離散化,然後按照離散值處理;另一種是假定這一屬性服從某一分佈。
對未知樣本分類的時候,對每個類,計算。樣本被指派到類當且僅當時,被指派到其最大的類。
二、實驗過程
1、實驗流程
本次實驗採用RSS資料來源採集網站資料,用到了下面兩個資料來源爬資料:
ny = feedparser.parse('http://newyork.craigslist.org/stp/index.rss')
sf = feedparser.parse('http://sfbay.craigslist.org/stp/index.rss')
得到每個網站的文章之後建立列表doclist,並且建立每篇文章相對應的類標籤classlist,再生成一個所有單詞出現的列表vocablist。接下來統計每個單詞出現的次數,次數出現較多的單詞一般是類似於and、the、for之類的並不能給分類帶來幫助的無用單詞,我們把這些高頻詞去掉。我們在doclist中隨機取20個作為測試集,剩餘的作為訓練集,先計算某個類佔的先驗概率pAbusive,再計算每個類每個單詞佔總的這個單詞出現的概率p0Vect,p1Vect,測試的時候把待測試的樣本向量分別乘以p0Vect,p1Vect再每個元素加起來分別加先驗概率取log。算出來哪個概率大就屬於哪個類。
2、改進演算法
我主要做了互資訊特徵選擇,也就是用互資訊選擇所有出現單詞中的一些做特徵。互資訊衡量的是某個特徵詞和類別之間的統計獨立關係。某個特徵詞t 和某個類別ci 傳統的互資訊定義度量兩個物件之間的相互性,在不良資訊過濾問題中用於度量特徵對於主題的區分度。則特徵詞 t 和類別 ci 的互資訊公式定義為:
其中: P( t,ci) 表示訓練集中既包含特徵t 又屬於類別ci 的文件概率,P( t) 表示在整個文字訓練集中包含特徵t 的文件概率,P( ci) 表示在訓練集中屬於類別ci 的文件概率,P( t | ci)表示在類別ci 中包含特徵t 的文件概率。在某個類別ci 中出現的概率高,而在其他類別中出現的概率低的特徵t 將獲得較高的互資訊,也就有可能被選擇為類別ci 的特徵。 在m 個類別的文字訓練集上特徵項t 的互資訊定義為:
互資訊根據特徵與類別共同出現的概率,度量特徵和類別的相關性。 對於某一類別ci 來講,特徵詞t 的互資訊越大,說明該詞與該類的共現概率越大。 下面利用一個簡單的例子對傳統互資訊演算法進行分析,設存在兩類文字c1 ,c2 ,每類中包含5 篇文件,特徵詞集合中有t1 ,t2 ,t3 三個詞,並且在類別c1 ,c2 的分佈情況如表1 所示。
利用式( 2) 計算可得:
我用這樣的計算方法到的每個單詞的互資訊,具體python實現如下:
def chooseN(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs)
MI=zeros(numWords)
pCondition1=ones(numWords)
pCondition0=ones(numWords)
deleteN=[]
for i in range(numWords):
for j in range(numTrainDocs):
if trainCategory[j]==1:
pCondition1[i]=pCondition1[i]+trainMatrix[j][i]
else:
pCondition0[i]=pCondition0[i]+trainMatrix[j][i]
MI[i]=pAbusive*log(pCondition1[i]/(pCondition1[i]+pCondition0[i]))+\
(1-pAbusive)*log(pCondition0[i]/(pCondition1[i]+pCondition0[i]))
if MI[i]>-0.8:
deleteN.append(i)
return deleteN
下圖是在一次計算中得到的MI:
另外去高頻詞的時候發現去掉10個高頻詞的時候效果比較好。下面是實驗資料:
方法(錯誤率) |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
平均錯誤率 |
互資訊去10 |
0 |
0.15 |
0 |
0.05 |
0 |
0.05 |
0.1 |
0.1 |
0.1 |
0.05 |
0.06 |
互資訊 |
0.1 |
0.15 |
0 |
0.1 |
0 |
0.15 |
0.05 |
0 |
0.05 |
0.15 |
0.075 |
去10 |
0.25 |
0.35 |
0.35 |
0.4 |
0.4 |
0.35 |
0.3 |
0.35 |
0.25 |
0.35 |
0.335 |
去30 |
0.35 |
0.4 |
0.45 |
0.4 |
0.5 |
0.3 |
0.35 |
0.45 |
0.3 |
0.45 |
0.395 |
三、實驗小結
這次實驗相對前兩次比較難,首先要理解原來樸素貝葉斯的每個步驟的程式碼,對於改進還要看文獻,改進的互資訊又很難具體下手寫程式碼,最後找見一篇中文的“文字分類中互資訊特徵選擇方法的研究與演算法改進”的論文按照論文當中的方法才用程式碼實現,不過很奇怪的是計算到互資訊之後用互資訊小的做特徵詞反而得到了很好的效果,這和傳統的方法是相反的,而且對於實驗的兩個RSS源資料每天測試的結果不太一樣,有可能是網站新聞有變動之類的