文本分析
文本分析指從文本中抽取出的特征來量化來表示文本信息,并在此基礎(chǔ)上對其進(jìn)行基于數(shù)學(xué)模型的處理。它是文本挖掘、信息檢索的一個(gè)基本問題。
在“大數(shù)據(jù)”盛行的今天,對于非結(jié)構(gòu)化信息的處理已經(jīng)成了許多工作的必選項(xiàng),而自然語言書寫的文本,就是最典型的一種非結(jié)構(gòu)化信息。
文本分析已經(jīng)從學(xué)院派象牙塔中的研究課題逐步滲入到各個(gè)應(yīng)用領(lǐng)域。對于正在做或者有志于做數(shù)據(jù)分析的人,掌握基本的文本分析知識(shí)和技法,已經(jīng)成為必要。
向量空間模型
針對文本的具體操作很多,最典型的就是分類和聚類。引入機(jī)器學(xué)習(xí)的辦法,讓程序自己“學(xué)會(huì)”如何去區(qū)分不同類型的文本,是當(dāng)前業(yè)界通行的辦法。
而如此做的前提,是要把一個(gè)個(gè)自然語言文檔(Document),轉(zhuǎn)換為一個(gè)個(gè)可以用來進(jìn)行數(shù)學(xué)運(yùn)算的向量(Vector)。
當(dāng)你用某種機(jī)器學(xué)習(xí)算法對某些文本進(jìn)行分析的時(shí)候,你首先需要一個(gè)訓(xùn)練集(Training Set)。
假設(shè)這個(gè)訓(xùn)練集中包含N個(gè)文檔,你要把這N個(gè)文檔轉(zhuǎn)換成N個(gè)與之一一對應(yīng)的向量。再假設(shè)每個(gè)向量包含M維。
那么最終,當(dāng)全部轉(zhuǎn)換完之后,你把所有N個(gè)M維向量放在一起,就構(gòu)成了一個(gè)NxM的矩陣(Matrix)。
這個(gè)矩陣就是你的訓(xùn)練集所構(gòu)建的向量空間模型(Vector Space Model,VSM)。
之后的算法,就是運(yùn)行在這個(gè)NxM的矩陣之上的。
構(gòu)建向量空間模型
N是文檔數(shù),那么M是什麼數(shù)呢?M是你的全部訓(xùn)練集文本(所有N個(gè)文檔)中包含的Term數(shù)。
這個(gè)Term可以是字,也可以是詞,還可以是若干連續(xù)出現(xiàn)的字的組合,具體是什么,可以由你自己來確定。
在此,我們介紹一種最簡單,最方便,效果總體而言還不錯(cuò)的,確定Term的方法:基于n-gram的文本特征提取方法。
基于n-gram的文檔特征提取
n-gram中的n和文檔個(gè)數(shù)的N無關(guān)(此處特別用大小寫來區(qū)分他們),這個(gè)n是一個(gè)由你確定的值,它指的是最長Term中包含的漢字的個(gè)數(shù)。
一般情況下,我們選n=2就好了。當(dāng)n==2時(shí)的n-gram又叫做bigram。n==1時(shí)叫unigram,n==3時(shí)叫trigram。
假設(shè)我們的N個(gè)文檔中有一個(gè)是下面這個(gè)樣子(為簡單起見,假設(shè)整個(gè)文檔就一句話):
張繼科在比賽中露出了碎花內(nèi)褲。
那么我們首先把這個(gè)文檔切分成unigram:
{張,繼,科,在,比,賽,中,露,出,了,碎,花,內(nèi),褲}
然后再將其切分成bigram:
{張繼,繼科,科在,在比,比賽,賽中,中露,露出,出了,了碎,碎花,花內(nèi),內(nèi)褲}
注意到bigram是怎么切分的沒有?對了,就是取長度為2的窗口,從頭到尾連續(xù)切分文檔,每次后移長度為1。
上面切分出來的這些字段,我們將其稱為Term。我們將unigram和bigram的所有Term合并起來,就是基于bigram的全部Term,總共27個(gè):
{張,繼,科,在,比,賽,中,露,出,了,碎,花,內(nèi),褲,張繼,繼科,科在,在比,比賽,賽中,中露,露出,出了,了碎,碎花,花內(nèi),內(nèi)褲}。
這是一個(gè)文檔,所有文檔,都按如此方法切分成若干的Term。
NOTE:如果是基于trigram的,則取全部unigram,bigram和trigram的Term的集合。
針對Term計(jì)算TF-IDF
N個(gè)文檔,設(shè)其中第i個(gè)文檔的Term為ci個(gè)(i 取值區(qū)間為[1, N])。那么這N個(gè)文檔分別有:c1,c2...cn個(gè)Term。
這些Term中肯定有些是重復(fù)的。我們對所有這些Term做一個(gè)去重操作,最后得出的uni-Term的個(gè)數(shù)就是M。
換言之,在這N個(gè)文檔中,基于bigram抽取的文本特征共有M個(gè)。
那么針對具體的一個(gè)文檔,我們就可以構(gòu)建一個(gè)M維的向量,其中每一維對應(yīng)這M個(gè)Term中的一個(gè)。
每一個(gè)維度的值,都是一個(gè)實(shí)數(shù)(一般在計(jì)算機(jī)處理中是float或者double類型)。
這個(gè)實(shí)數(shù)值,通常的情況下,取這一維度所對應(yīng)Term在全部訓(xùn)練文檔中的TF-IDF(請自行百度TF-IDF)。
VSM成型
假設(shè)我們一共處理了1萬個(gè)文檔(N == 10000),總共得出了2萬個(gè)Term (M == 20000)。
上面那個(gè)例子,“張繼科比賽中露出了碎花內(nèi)褲” 這一文檔共包含27個(gè)Term。對應(yīng)這個(gè)文檔的向量就會(huì)是一個(gè)2萬維的向量,其中27個(gè)維度有大于零的值,其他維度的值都是0——很稀疏啊!
最后這1萬個(gè)文檔就組成了一個(gè)10000 x 20000的矩陣。
縮減VSM
如果在一個(gè)10000 x 20000的矩陣?yán)铮總€(gè)Vector都只有20多個(gè)維度有非零值,那它也太稀疏了。這樣稀疏的矩陣恐怕也不會(huì)有太好的運(yùn)算效果。
而且,一些區(qū)分度過大的Term(例如某一個(gè)Term僅僅只在一個(gè)或者極少的文檔中出現(xiàn)),在經(jīng)過運(yùn)算之后往往會(huì)擁有過大的權(quán)重,導(dǎo)致之后只要一個(gè)文檔包含這個(gè)Term就會(huì)被歸到某一個(gè)類。這種情況顯然是我們要避免的。
因此,我們最好先對所有的Term做一個(gè)過濾。此處講兩個(gè)特別簡單和常見的Term篩選方法:
1. 設(shè)定DF(DocumentFrequency)的下限
設(shè)定一個(gè)Threshold (e.g. DF_Threshold = 2),若一個(gè)Term的DF小于該Threshold,則將該Term棄之不用。
2. 當(dāng)對文本進(jìn)行分類運(yùn)算時(shí),可以根據(jù)每個(gè)Term的信息熵對其進(jìn)行篩選
一個(gè)Term的信息熵(Entroy)表現(xiàn)了該Term在不同類別中的分布情況。
一般而言,一個(gè)Term的Entropy越大,則說明它在各個(gè)類中均勻出現(xiàn)的概率越大,因此區(qū)分度就越小;反之,Entroy越小也就說明該Term的類別區(qū)分度越大。
我們當(dāng)然要選用Entroy盡量小的Term。具體選用多少,可以自己定義一個(gè)Threshold。
Entropy_Threshold可以是一個(gè)數(shù)字(例如8000),也可以是一個(gè)百分比(例如40%)。
計(jì)算了所有Term的Entropy之后,按Entropy從小到大排序,選取不大于
Entropy_Threshold的前若干個(gè),作為最終構(gòu)建VSM的Term。
假設(shè)所有的訓(xùn)練樣本一共被分為K類,則Entropy的計(jì)算方法如下(設(shè)tx表示某個(gè)具體的Term):
Entropy(tx) = Sigma[i] ((-P(ci) *log(P(ci)))) -- i取值范圍為[1,K]
其中,P(ci) 表示tx在第i個(gè)列別中的出現(xiàn)概率,具體計(jì)算方法采用softmax算法,如下:
P(ci)= exp(y(ci)) /Sigmaj -- j取值范圍為[1,K]
其中y(ci) 為tx在類別j中出現(xiàn)的次數(shù)。
來看一個(gè)簡單的例子,假設(shè)我們的樣本空間一共被分為5個(gè)類別,則C == 5。
假設(shè)tx在5個(gè)列別中出現(xiàn)的次數(shù)依次為{1,3,0,0,4}。則:
p(c1) = exp(1) / (exp(1) + exp(3) +exp(0) + exp(0) + exp(4))
p(c2) = exp(3) / (exp(1) + exp(3) + exp(0) + exp(0) + exp(4))
p(c3)= exp(0) / (exp(1) + exp(3) + exp(0)+ exp(0) + exp(4))
p(c4)= exp(0) / (exp(1) + exp(3) + exp(0)+ exp(0) + exp(4))
p(c5)= exp(4) / (exp(1) + exp(3) + exp(0) +exp(0) + exp(4))
entroy(tx) = -p(c1)log(p(c1)) -p(c2)log(p(c2)) -p(c3)log(p(c3))-p(c4)log(p(c4)) -p(c5)*log(p(c5))
就這樣計(jì)算!
經(jīng)過篩選,M個(gè)Term縮減為M' 個(gè),我們NxM' 矩陣變得更加精煉有效了。現(xiàn)在,把它扔給算法庫去做訓(xùn)練吧!
基于VSM的運(yùn)算
如果要做聚類,則我們將這個(gè)矩陣作為輸入傳給某個(gè)算法,例如:KMeansClustering,我們設(shè)K = 5。
該算法經(jīng)過運(yùn)算之后,會(huì)給每一個(gè)向量賦一個(gè)[0,4]區(qū)間內(nèi)的值,這個(gè)值就表示了該向量對應(yīng)文檔最終被聚類的結(jié)果。
如果要做分類操作,則需要對訓(xùn)練集中的文檔進(jìn)行人工標(biāo)注,給每一個(gè)文檔標(biāo)注一個(gè)指定的類別。
然后,除了將文檔本身轉(zhuǎn)化成一個(gè)向量之外,還需要將這個(gè)類別轉(zhuǎn)化成一個(gè)數(shù)值,一般直接將類名排序,然后把排序的index作為類別數(shù)值即可。
然后同樣是把這個(gè)VSM輸入給一個(gè)具體算法,例如:基于Logistic Regression的Multiclassification。經(jīng)過運(yùn)算后,會(huì)得到一個(gè)專門的分類模型。
我們再將一個(gè)新的,不屬于訓(xùn)練集的文檔根據(jù)上面的VSM進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換成一個(gè)向量。把這個(gè)向量輸入給分類模型,分類模型會(huì)根據(jù)每一個(gè)預(yù)定的類,給出一個(gè)該向量被分到該類的可能性數(shù)值,可能性取值區(qū)間(0, 1)。
這幾類中可能性最高的那個(gè),就是分類模型預(yù)測的這個(gè)文檔的最終分類。