將樣本數據成功轉化為向量表示之后,計算機才算開始真正意義上的“學習”過程。
再重復一次,所謂樣本,也叫訓練數據,是由人工進行分類處理過的文檔集合,計算機認為這些數據的分類是絕對正確的,可以信賴的(但某些方法也有針對訓練數據可能有錯誤而應對的措施)。接下來的一步便是由計算機來觀察這些訓練數據的特點,來猜測一個可能的分類規則(這個分類規則也可以叫做分類器,在機器學習的理論著作中也叫做一個“假設”,因為畢竟是對真實分類規則的一個猜測),一旦這個分類滿足一些條件,我們就認為這個分類規則大致正確并且足夠好了,便成為訓練階段的最終產品——分類器!再遇到新的,計算機沒有見過的文檔時,便使用這個分類器來判斷新文檔的類別。
舉一個現實中的例子,人們評價一輛車是否是“好車”的時候,可以看作一個分類問題。我們也可以把一輛車的所有特征提取出來轉化為向量形式。在這個問題中詞典向量可以為:
D=(價格,最高時速,外觀得分,性價比,稀有程度)
則一輛保時捷的向量表示就可以寫成
vp=(200萬,320,9.5,3,9)
而一輛豐田花冠則可以寫成
vt=(15萬,220,6.0,8,3)
找不同的人來評價哪輛車算好車,很可能會得出不同的結論。務實的人認為性價比才是評判的指標,他會認為豐田花冠是好車而保時捷不是;喜歡奢華的有錢人可能以稀有程度來評判,得出相反的結論;喜歡綜合考量的人很可能把各項指標都加權考慮之后才下結論。
可見,對同一個分類問題,用同樣的表示形式(同樣的文檔模型),但因為關注數據不同方面的特性而可能得到不同的結論。這種對文檔數據不同方面側重的不同導致了原理和實現方式都不盡相同的多種方法,每種方法也都對文本分類這個問題本身作了一些有利于自身的假設和簡化,這些假設又接下來影響著依據這些方法而得到的分類器最終的表現,可謂環環相連,絲絲入扣,冥冥之中自有天意呀(這都什么詞兒……)。
比較常見,家喻戶曉,常年被評為國家免檢產品(?!)的分類算法有一大堆,什么決策樹,Rocchio,樸素貝葉斯,神經網絡,支持向量機,線性最小平方擬合,kNN,遺傳算法,最大熵,Generalized Instance Set等等等等(這張單子還可以繼續列下去)。在這里只挑幾個最具代表性的算法侃一侃。
Rocchio算法
Rocchio算法應該算是人們思考文本分類問題時最先能想到,也最符合直覺的解決方法。基本的思路是把一個類別里的樣本文檔各項取個平均值(例如把所有“體育”類文檔中詞匯“籃球”出現的次數取個平均值,再把“裁判”取個平均值,依次做下去),可以得到一個新的向量,形象的稱之為“質心”,質心就成了這個類別最具代表性的向量表示。再有新文檔需要判斷的時候,比較新文檔和質心有多么相像(八股點說,判斷他們之間的距離)就可以確定新文檔屬不屬于這個類。稍微改進一點的Rocchio算法不盡考慮屬于這個類別的文檔(稱為正樣本),也考慮不屬于這個類別的文檔數據(稱為負樣本),計算出來的質心盡量靠近正樣本同時盡量遠離負樣本。Rocchio算法做了兩個很致命的假設,使得它的性能出奇的差。一是它認為一個類別的文檔僅僅聚集在一個質心的周圍,實際情況往往不是如此(這樣的數據稱為線性不可分的);二是它假設訓練數據是絕對正確的,因為它沒有任何定量衡量樣本是否含有噪聲的機制,因而也就對錯誤數據毫無抵抗力。
不過Rocchio產生的分類器很直觀,很容易被人類理解,算法也簡單,還是有一定的利用價值的(做漢奸狀),常常被用來做科研中比較不同算法優劣的基線系統(Base Line)。
樸素貝葉斯算法(Naive Bayes)
貝葉斯算法關注的是文檔屬于某類別概率。文檔屬于某個類別的概率等于文檔中每個詞屬于該類別的概率的綜合表達式。而每個詞屬于該類別的概率又在一定程度上可以用這個詞在該類別訓練文檔中出現的次數(詞頻信息)來粗略估計,因而使得整個計算過程成為可行的。使用樸素貝葉斯算法時,在訓練階段的主要任務就是估計這些值。
樸素貝葉斯算法的公式只有一個
其中P(d| Ci)=P(w1|Ci) P(w2|Ci) …P(wi|Ci) P(w1|Ci) …P(wm|Ci) (式1)
P(wi|Ci)就代表詞匯wi屬于類別Ci的概率。
這其中就蘊含著樸素貝葉斯算法最大的兩個缺陷。
首先,P(d| Ci)之所以能展開成(式1)的連乘積形式,就是假設一篇文章中的各個詞之間是彼此獨立的,其中一個詞的出現絲毫不受另一個詞的影響(回憶一下概率論中變量彼此獨立的概念就可以知道),但這顯然不對,即使不是語言學專家的我們也知道,詞語之間有明顯的所謂“共現”關系,在不同主題的文章中,可能共現的次數或頻率有變化,但彼此間絕對談不上獨立。
其二,使用某個詞在某個類別訓練文檔中出現的次數來估計P(wi|Ci)時,只在訓練樣本數量非常多的情況下才比較準確(考慮扔硬幣的問題,得通過大量觀察才能基本得出正反面出現的概率都是二分之一的結論,觀察次數太少時很可能得到錯誤的答案),而需要大量樣本的要求不僅給前期人工分類的工作帶來更高要求(從而成本上升),在后期由計算機處理的時候也對存儲和計算資源提出了更高的要求。
kNN算法則又有所不同,在kNN算法看來,訓練樣本就代表了類別的準確信息(因此此算法產生的分類器也叫做“基于實例”的分類器),而不管樣本是使用什么特征表示的。其基本思想是在給定新文檔后,計算新文檔特征向量和訓練文檔集中各個文檔的向量的相似度,得到K篇與該新文檔距離最近最相似的文檔,根據這K篇文檔所屬的類別判定新文檔所屬的類別(注意這也意味著kNN算法根本沒有真正意義上的“訓練”階段)。這種判斷方法很好的克服了Rocchio算法中無法處理線性不可分問題的缺陷,也很適用于分類標準隨時會產生變化的需求(只要刪除舊訓練文檔,添加新訓練文檔,就改變了分類的準則)。
kNN唯一的也可以說最致命的缺點就是判斷一篇新文檔的類別時,需要把它與現存的所有訓練文檔全都比較一遍,這個計算代價并不是每個系統都能夠承受的(比如我將要構建的一個文本分類系統,上萬個類,每個類即便只有20個訓練樣本,為了判斷一個新文檔的類別,也要做20萬次的向量比較!)。一些基于kNN的改良方法比如Generalized Instance Set就在試圖解決這個問題。
下一節繼續講和訓練階段有關的話題,包括概述已知性能最好的SVM算法。明兒見!(北京人兒,呵呵)
我有個疑問,如果用開方的方法提取的話,不是需要知道某一個特征是否出現在某個類別里么?
但是測試集并不知道這個信息呀。