天天看點

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

文本分類與SVM

分類: 資料挖掘 2012-11-18 20:45  19063人閱讀  評論(14)  收藏  舉報

目錄(?)[+]

之前做過一些文本挖掘的項目,比如網頁分類、微網誌情感分析、使用者評論挖掘,也曾經将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)。

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

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

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

1.2.2 特征選擇

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

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

1.      http://www.blogjava.net/zhenandaci/archive/2009/04/19/266388.html 特征選擇與特征權重計算的差別

2.      http://www.blogjava.net/zhenandaci/archive/2009/03/24/261701.html  特征選擇方法之資訊增益

3.      http://www.blogjava.net/zhenandaci/archive/2008/08/31/225966.html  特征選擇算法之開方檢驗

1.2.3 特征抽取

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

1.3 計算特征權重

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

首先給一張流程圖:

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

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

流程:

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

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

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

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

1.4   模型訓練與預測

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

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

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

資料與程式

1.      http://nlp.stanford.edu/IR-book/html/htmledition/naive-bayes-text-classification-1.html介紹NaïveBayes方法如何應用在文本分類上

2.     http://blog.163.com/[email protected]/blog/static/17123217720113115027394/ 詳細分析了Mahout中如何實作NaïveBayes

3.      http://www.csie.ntu.edu.tw/~cjlin/libsvm/  Libsvm是用來進行SVM訓練與預測的開源工具。下載下傳下來就可以直接用,作者的文檔寫的很詳細。

4.      http://www.blogjava.net/zhenandaci/category/31868.htmlSVM的八股介紹,講解的還是通俗易懂的

5.      http://blog.pluskid.org/?page_id=683 介紹支援向量機的

6.      https://code.google.com/p/tmsvm/  Tmsvm是我之前寫的利用svm進行文本分類的程式,涉及到文本分類的所有流程。

1.5 進一步閱讀:

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

1.      http://www.blogjava.net/zhenandaci/category/31868.html?Show=All 這裡有一個文本分類的入門系列,介紹的還是比較詳細的。

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的全局因子,把這個值放在詞典中,然後在計算特征權重的時候直接調用。

具體的流程圖如下:

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

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

在Classification中哪種特征權重的計算方式最好??tf*idf ?在文獻中最常用的是tf*idf,但是其效果并一定好。曾經有人也在這上面做了一些工作,比如新加坡國立大學的Man Lan曾在ACM和AAAI上發表過文章來闡述這個問題。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模型的訓練等都可以一步完成。示意圖見下面

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

圖 2.4‑1 TMSVM模型訓練流程

模型預測過程:

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

圖 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     Libs與liblinear的多分類政策

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中選擇值最大多對應的類别作為最終的預測類标簽。

    重複樣本對SVM模型的影響

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

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

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

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

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

圖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是無限大的,而且很難估計其真正的分布,即無法對其随機取樣。

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

圖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的。一般情況下,這種情況可以用門檻值來控制。

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

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

2.10  SVM解決樣本傾斜的問題

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

文本分類與SVM 文本分類與SVM1 基礎知識2 若幹問題的讨論

圖2.10‑1樣本傾斜示例

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

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

2.11  其他

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

繼續閱讀