1. 程式人生 > >利用SVM 實現文字分類的例項

利用SVM 實現文字分類的例項

原文來自:http://blog.csdn.net/zhzhl202/article/details/8197109

之前做過一些文字挖掘的專案,比如網頁分類、微博情感分析、使用者評論挖掘,也曾經將libsvm進行包裝,寫了一個文字分類的開軟軟體Tmsvm。所以這裡將之前做過一些關於文字分類的東西整理總結一下。

1 基礎知識

1. 1 樣本整理

文字分類屬於有監督的學習,所以需要整理樣本。根據業務需求,確定樣本標籤與數目,其中樣本標籤多為整數。在svm中其中如果為二分類,樣本標籤一般會設定為-1和1,而在樸素貝葉斯方法中,一般為0和1,但不是固定的,標籤的設定和演算法本身的性質有關的。
如下面的整理的樣本,1為正類,-1為反類(為了能便於展示,這裡使用了一些即時聊天工具中的文字,裡面的一些對話都是YY,並非真實的)。

表 1.1‑1 一個訓練樣本的例子

標籤

樣本

1

如要購買商品的請加我qq61517891聯絡我購買!

1

聯絡qq1121107282  

1

你好需要訂購請加扣扣

-1

索尼愛立信手機的體驗是一個月嗎

-1

不好意思這個價錢最便宜了

-1

3件的那個他是高價在賣     

1.2 特徵選擇

文字分類中最著名的特徵提取方法就是向量空間模型(VSM),即將樣本轉換為向量的形式。為了能實現這種轉換,需要做兩個工作:確定特徵集和提取特徵。

1.2.1 確定特徵集

特徵集其實就是詞典,而且還需要給每個詞設定一個編號。

一般可以將所有樣本的詞都提取出來作為詞典,而詞典的編號可以隨意設定,預設情況下,所有詞的權重都是等同的。如何從樣本中提取出一個個意義的詞呢?最常用的方法就是使用分詞工具,比如“如要購買商品的請加我qq61517891聯絡我購買!”,可以分成“如^要^購買^商品^的^請^加^我^qq61517891^聯絡^我^購買^!”,其中“^”是用來分割詞的。現在比較常見的分詞工具有ICTCLAS(C++),Iksegment(Java)。

下圖是一個典型的生成詞典的流程圖。


圖 1.1‑1 從樣本中提取詞典流程圖

1.2.2 特徵選擇

根據不同的業務,文字分類中詞典的規模在萬級到千萬級甚至億級。而這麼大的維度可能會帶來維度災難,因此就要想辦法從大量的特徵中選擇一些有代表性的特徵而又不影響分類的效果(而根據文獻中的結果,特徵選擇可以在一定程度上提高分類的效果)。特徵選擇就是從特徵集中選擇一些代表性的詞。而如何衡量詞的代表性呢?一般的計算方法有詞頻、卡方公式、資訊增益等。當前文獻中一致認為比較好的方法是卡方公式。

下面幾個連結是幾篇寫的比較詳細介紹如何進行特徵選擇的文章

1.2.3 特徵抽取

另外一種解決維度災難的思路就是特徵抽取。同樣是降維,相比特徵選擇,特徵抽取採用了一種高階的方法來進行。Topic Modeling是原理就是將利用對映將高緯度空間對映到低緯空間,從而達到降維的目的。具體可以見2.1特徵抽取部分

1.3 計算特徵權重

給定一個樣本,如何轉換成向量呢?

首先給一張流程圖:


圖 1.1‑2 計算特徵權重的流程

流程:

1)首先,對樣本進行分詞,提取出所有的詞。

2)根據已經生成的詞典,如果詞典中的詞出現,就在相應對應的位置填入該詞的詞頻。

3)對生成的向量進行歸一化

上面的所示的方法是比較簡單的一種,其中特徵權重採用的為詞頻來表示,現在比較常用的特徵權重的計算方式為TF*IDF,TF*RF。詳見2.3 特徵權重

1.4   模型訓練與預測

當把文字轉換成向量的形式後,大部分的工作其實已經做完了。後面所要做的就是利用演算法進行訓練和預測了。

現在文字分類的演算法很多,常見的有Naïve Bayes,SVM,KNN,Logistic迴歸等。其中SVM據文獻中說是在工業界和學術界通吃的,不過據我瞭解現在公司裡用SVM來做分類的不多 = =,而Logistic迴歸則是比較常用的,因為相對來說簡單,而且可以並行化訓練。最重要是簡單可依賴

而至於這些演算法具體是什麼我這裡也不再累述了,因為網路上介紹相關的演算法的文獻很多,而且源程式也很多。可以直接下來下來使用。

資料與程式

1.5 進一步閱讀:

文字分類的技術已經被研究了很多年,所以相關的資料也是非常多,可以進一步閱讀下面的一些資料

2.      《文字挖掘中若干關鍵問題研究》,這本書很薄,但是寫的很深入,對文字挖掘的一些重點問題進行了討論

2 若干問題的討論

2.1 特徵選擇

特徵選擇是就是依據某種權重計算公式從詞典中選擇一些有代表性的詞。常用的特徵選擇的方法有很多種,Chi、Mutual Information、Information Gain。另外TF、IDF也可以作為特徵選擇的一種方法。在這個問題上很多人做了大量的實驗,Chi方法是效果最好的一種,所以本系統(指的是TMSVM)中採用了這種方法。關於特徵選擇無論是Wikipedia還是Paper中都有很細緻的講解。

2.2 特徵抽取

特徵抽取和特徵選擇都是為了降維。特徵選擇的方法是從詞典中選出一些有代表性的詞,而特徵抽取是利用對映將高緯度空間對映到低緯空間,從而達到降維的目的。最常見的特徵抽取的方法是Latent Semantic Analysis(潛在語義分析),其中LSA也被稱作Topic Modeling,比較常用的Topic Modeling的方法有LSA、PLSA、LDA。之前使用的方法LSA。

假設原來的詞-文件矩陣為,即有m個term,n篇文件。表示第j篇文件的向量。,經過SVD分解後,選擇前k個特徵值後。再去重組文件的特徵向量,,這樣新的文件特徵向量就由原來的m維降至k維。而一個新的文件即可通過,對映到U空間上。其實還有另外一種方法,就是,但是在實驗中發現,前一種對映效果會更好一點。另外wikipedia上對LSA也有很詳細的闡述

本系統將LSA用來Classification上的方法是一種叫做local relevancy weighted LSI的方法。其主要步驟為

*             模型訓練

①             訓練初始分類器C0

②             對訓練樣本預測,生成初始分值

③             文件特徵向量變換

④             設定閾值,選擇top n文件作為區域性LSA區域

⑤             對區域性詞/文件 矩陣做SVD分解。得到U、S、V矩陣

⑥             將其他的訓練樣本對映到U空間中

⑦             對所有經過變換後的訓練樣本進行訓練,得到LSA分類器

*             模型預測

①             利用C0預測得到其初始分值

②             文件特徵向量變換

③             對映到U空間

④             利用LSA模型進行預測得分

2.3 特徵權重計算

文件特徵向量的特徵權重計算的一般公式為,即第i個term在第j篇文件向量中的權重。其中Local(i,j)被稱為區域性因子,與term在文件中出現的次數有關。global(i)又稱為term的全域性因子,與在整個訓練集中term出現有關。通常我們熟悉的公式都可以轉化為這一個通用的表示式。如最常用的tf形式,tf*idf形式。因此我們就可以在構造詞典的時候就計算term的全域性因子,把這個值放在詞典中,然後在計算特徵權重的時候直接呼叫。

具體的流程圖如下:


圖 2.3‑1 特徵權重的計算流程

在Classification中哪種特徵權重的計算方式最好??tf*idf ?在文獻中最常用的是tf*idf,但是其效果並一定好。曾經有人也在這上面做了一些工作,比如新加坡國立大學的Man Lan曾在ACMAAAI上發表過文章來闡述這個問題。Zhi-Hong Deng也對各種feature weight的方法做了系統的比較,最終的結論是tf*idf並不是最佳的,而最簡單的tf表現不錯,一些具有區分性的方法比如tf*chi等效果差強人意。

後來Man Lan在09年發表了一篇論文,對term weighting方法做了一個綜合細緻的闡述,並對其提出的tf*rf方法做了各方面的論證。

2.4 TSVM的模型訓練和預測流程

訓練過程:對文字自動做SVM模型的訓練。包括Libsvm、Liblinear包的選擇,分詞,詞典生成,特徵選擇,SVM引數的選優,SVM模型的訓練等都可以一步完成。示意圖見下面


圖 2.4‑1 TMSVM模型訓練流程

模型預測過程


圖 2.4‑2 多個模型同時預測流程

模型結果:

模型會返回兩個結果:label和score,其中label即其預測的標籤。而score是該樣本屬於該類的隸屬度,分值越大,代表屬於該類的置信度越大。具體的計算方式則是根據公式,,其中k為所有支援判別類得個數,n為所有類別個數,si 為所有支援判別類的分數。返回score的好處是對與information filtering問題,因為訓練樣本的unbalance和randomly sampling 問題,依據判別的標籤得到的結果準確率較低,因此需要通過閾值控制。

2.5 SVM引數選擇

Libsvm中最重要的兩個引數為C和gamma。C是懲罰係數,即對誤差的寬容度。c越高,說明越不能容忍出現誤差。C過大或過小,泛化能力變差。gamma是選擇RBF函式作為kernel後,該函式自帶的一個引數。隱含地決定了資料對映到新的特徵空間後的分佈,gamma越大,支援向量越少,gamma值越小,支援向量越多。支援向量的個數影響訓練與預測的速度。這個問題Chih-Jen Lin在其主頁上有詳細的介紹。

而Liblinear的C引數也是非常重要的。

因此在系統中會通過5-flods交叉驗證的方法對一定範圍內的C,gamma進行grid 搜尋,關於grid搜尋可以參考論文以及libsvm中tool資料夾中grid.py原始檔。grid搜尋是可以得到全域性最優的引數的。

為了加快SVM引數搜尋的效率,採用兩種粒度的搜尋粗粒度細粒度,兩種搜尋方式的區別就是搜尋步長不同。粗粒度是指搜尋步長較大,為了能在較大的搜尋範圍內找到一個最優解所在的大體區域。細粒度搜索搜尋步長較小,為了能在一個較小範圍內找到一個精確引數。

而對與大樣本的檔案,使用上面的方法仍然會比較耗費時間。為了進一步提高效率,同時在保證得到全域性最優的情況下,先對選擇大樣本的子集進行粗粒度的搜尋,然後得到在得到的最優區間內對全量樣本進行細粒度的搜尋。

2.6 SVM引數選擇的並行化

SVM對訓練過程還是比較久的,尤其是為了能夠找到最合適的引數。自然就想到能不能對SVM的巡檢並行化。我之前做的方法是對引數的選擇並行化,而單個引數的訓練還是放在一個機器上序列進行。我把訓練的方法放在我部落格上,就不再貼上到這裡了。

2.7 Libsvm 與liblinear的多分類策略

libsvm的多分類策略為one-againt-one。總共有k*(k-1)/2個binary classifier,對這k*(k-1)/2個binary classifier的value進行遍歷,如果第i個類和第j個類binary 的classifier的value大於0,則會給第i個類投1票,否則給第j個類投1票。選擇最終獲得投票數最多的類作為最終的類別。

而liblinear的策略為one-against-rest。總共有k個binary classifier。從所有binary classifier中選擇值最大多對應的類別作為最終的預測類標籤。

2.8 重複樣本對SVM模型的影響

重複樣本對於SVM模型有怎樣的影響呢?

我自己做了個實驗,用來看重複樣本的影響。

原有一個訓練樣本共有Positive樣本1000,Negative樣本2000,然後將Positive樣本*2,構造了一個Positive樣本2000,Negative樣本2000的訓練樣本。然後測試一個包含Positive樣本4494 ,Negative樣本24206的樣本。最終的結果如下:


圖2.8‑1重複樣本對結果影響

從結果上來看:在F值上,無重複的樣本會比重複樣本稍高(圖中保留了2位小數,其實差異不超過0.5%)。而正確率上,重複樣本會比無重複樣本稍高。

然後我又把模型放入到一個包含3千萬樣本中去測試,具體的指標無法測算。但是感覺還是重複樣本會好一點。

具體分析:

1、       一個樣本被重複的多次,意義上相當於增加了該樣本的權重。在SVM有一種WeightedInstance。在正常樣本難免會有些誤判,如果同一條樣本同時出現在Positive和Negative類中,包含重複樣本的Positive類就會把Negative類誤判的樣本的影響抵消。而在SVM分類中對這些離群點會用懲罰函式進行控制。

2、       但是如果保留重複樣本,會增加樣本的量,對libsvm來說,分類的複雜度為O(Nsv3),而且如果一個樣本是支援向量,那麼所有重複的樣本也都會被加入到支援向量中去。而且如果要為SVM模型選擇合適的引數的,如果在SVM選擇的是RBF核函式,挑選合適的懲罰cost和RBF的引數gramma,如果在都是在[1,5,0.5]進行挑選,則總共會有9*9=81組引數需要挑選,在每組引數下如果要進行5-flods的交叉驗證,則需要81*5=405次訓練與測試的過程。如果每次訓練與測試花費2分鐘(在樣本達到10萬數量級的時候,libsvm的訓練時間差不多按分鐘計算),則總共需要405*2/60=12.3小時,所以說訓練一個好的SVM模型十分不容易。因此如果去掉重複樣本對訓練效率來說大有裨益。

 2.9 將分類應用與資訊過濾

分類應用與資訊過濾,對最終效果影響最大的是什麼?分類演算法?詞典大小?特徵選擇?模型引數?這些都會影響到最終的過濾效果,但是如果說對過濾效果影響最大的,還是訓練樣本的取樣

現在基於機器學習的分類演算法一般都是基於一個假設:訓練集和測試集的分佈是一致的,這樣在訓練集上訓練出來的分類器應用與測試集時其效果才會比較有效。

但是資訊過濾面對的資料集一般是整個網際網路,而網際網路的資料集一般很難去隨機取樣。如下圖所示:通常來說,資訊過濾或其它面向全網際網路的應用在分類,選擇資料集時,需要包含P(Positive,即使用者感興趣的樣本),N(Negative,即使用者不關心、不敢興趣的樣本)。最理想的情況是:P選擇是使用者感興趣的,而N是全網中除去P,顯而易見N是無限大的,而且很難估計其真正的分佈,即無法對其隨機取樣。


圖2.9‑1樣本分佈

同樣面對整個網際網路的應用時網頁分類,網頁分類應用一般會選擇Yahoo!或者是專門整理網頁分類專門網站的網頁作為初始訓練樣本。

資訊過濾的樣本一般來說,感興趣的樣本是很好隨機取樣的。但是與感興趣相對於的是正常樣本,這個很難去選擇。而正常樣本對全網測試效果是影響非常大的。我曾經做過一個實驗:

首先,有一個包含5萬條樣本的資料集,有2.5萬條Positive樣本,2.5萬條Negative樣本。這裡的Negative樣本是以前用關鍵字的方法找出的不正確的樣本。用4萬條樣本做訓練樣本,用1萬條樣本做測試樣本。訓練出得模型交叉驗證的結果可以達到97%以上。在測試樣本中的測試效果,然後選定閾值為0.9,這是的召回率可以達到93%,正確率為96%。

然後把這個模型放到一個包含3千萬條中去測試,設定閾值為0.9,共找出疑似違規樣本300萬條。對這個實驗來說,召回的樣本實在是太多了,其正確率是很低的。

然後,我又更換了一下正常樣本。從這3千萬樣本中隨機取樣出3萬條樣本,然後經過校驗,將其中Positive的樣本剔除掉。剩下大約2萬7千條樣本放入到訓練樣本重新訓練。

把得到的新模型放到3千萬樣本中測試,同樣設定閾值為0.9,共找出疑似樣本15萬。正確率可以達到70%左右。所以正常樣本的隨機選擇對分類來說同樣至關重要。

舉一個小例子:

下圖左面的圖是用P和N訓練出得模型。右面的圖中有一個未知的類C,根據已知的模型,他應該會被分入到P中,但是實際上他是不屬於P的。一般情況下,這種情況可以用閾值來控制。


圖2.9‑2分類用於資訊過濾

2.10  SVM解決樣本傾斜的問題

所謂資料偏斜(unbalanced),它指的是參與分類的兩個類別(也可以指多個類別)樣本數量差異很大。比如說正類有10,000個樣本,而負類只給了100個,這會引起的問題顯而易見,可以看看下面的圖:


圖2.10‑1樣本傾斜示例

方形的點是負類。H,H1,H2是根據給的樣本算出來的分類面,由於負類的樣本很少很少,所以有一些本來是負類的樣本點沒有提供,比如圖中兩個灰色的方形點,如果這兩個點有提供的話,那算出來的分類面應該是H’,H2’和H1,他們顯然和之前的結果有出入,實際上負類給的樣本點越多,就越容易出現在灰色點附近的點,我們算出的結果也就越接近於真實的分類面。但現在由於偏斜的現象存在,使得數量多的正類可以把分類面向負類的方向“推”,因而影響了結果的準確性。

具體的解決方法還是看我部落格上的文章吧,這裡就不單獨貼出來了。

2.11  其他

文字分類的問題點很多,之前還想再寫寫如何對短文字(比如query)進行分類,利用利用Wikipedia的知識增強文字分類的效果,如何利用未標記樣本來提高分類的效果。現在時間不多,等有時間了再繼續深入的寫吧。