NLP中的語言模型及文字特徵提取演算法
本文以基本語言模型為邏輯主線,漫談NLP中兩個核心問題,即文字表示(Text Representation)與文字特徵提取(Feature Engineering)。通過本文你會發現,NLP的一部分經典演算法以及目前的發展都能夠通過文字表示串聯在一起,有個基本的結構脈絡。當然,NLP大牛們正在不斷地探索NLP更多的維度,本文只是一種切入的角度,也僅代表個人觀點,如有任何錯誤還希望大牛們指教。
如果聽過翟成祥老師《Text Mining and Analytics》的童鞋一定對圖1有印象,人們對真實世界的感知被成為感知世界,而人們用語言表達出自己的感知視為文字資料。那麼反過來,NLP,或者更精確地表達為文字挖掘,則是從文字資料出發,來儘可能復原人們的感知世界,從而服務於真實世界的過程。這裡面就包括如圖中所示的模型和演算法,包括:
(1)文字層:NLP文字表示;
(2)文字-感知世界:詞彙相關性分析、主題模型、意見情感分析等;
(3)文字-真實世界:基於文字的預測等。
圖1:NLP與真實世界、感知世界、文字資料之間的關係
顯而易見,文字表示在文字挖掘中有著絕對核心的地位,是其他所有模型建構的基礎。因此,本文就以Language Model為核心,串聯一些NLP當中的經典模型和演算法,當然最終目的並非為搞清楚每個文字挖掘演算法的理論推導應用blabla,而是為了理清文字挖掘的體系結構,最終服務於Real World實際應用中。
圖2:NLP工程中技術框架——From阿里雲棲社群
圖2給出了講NLP應用於實際工程場景中的結構,基礎演算法層面,主要將NLP按照演算法物件分為詞法分析、句法分析、語義分析和文件分析。顯然這些都是NLP技術體系的重要組成部分,也是常規劃分。而本文變換了視角,不從技術角度出發,而以應用為目的,來梳理文字挖掘的基礎模型演算法。
一、語言模型(Language Model, LM) - 我們的主線
A statistical language model is a probability distribution over sequences of words. Given such a sequence, say of length m, it assigns a probability to the whole sequence. Having a way to estimate the relative likelihood of different phrases is useful in many natural language processing applications, especially ones that generate text as an output. Language modeling is used in speech recognition, machine translation, part-of-speech tagging, parsing, handwriting recognition, information retrieval and other applications.
統計語言模型是詞序列的概率分佈,目的是建立一個能夠描述給定詞序列在語言中的出現的概率的分佈。掌握不同句子/片語的概率估計方法在NLP中有很多應用,特別是用來生成文字。語言模型在語音識別、機器翻譯、詞性標註、句法分析、手寫識別、資訊檢索都有廣泛的應用。
- 語言模型的基礎模型為:
P(w1w2...wT)=∏ni=1P(w1)P(w2|w1)P(wi|w1w2...wi−1) (公式1) - 目標函式(基於對數似然):
L=∑w∈Clog(P(w|context(w)) (公式2,其中C為語料,Context(w)為詞w的上下文) - 對於語言裡的每一個字串 S 給出一個概率
二、語言模型的演化和相關模型演算法的出現
為了讓大家對後文有個初步的認識,在這一節中用概念圖的形式整理了語言模型的演化歷史和建構在每種語言模型上的各類演算法。
圖三:基於Language Model的NLP主要模型演算法梳理
三、最基本的語言模型——詞袋模型Bag of Word(BOW)及相關演算法
詞袋模型,顧名思義,把各種詞放在一個文字的袋子裡,即把文字看做是無序的詞的組合。利用統計語言模型來理解,文字中每個詞出現的概率僅與自身有關而無關於上下文。這是對公式1的最極端的簡化。然而,很多常用的文字挖掘演算法和文字統計特徵都建構在此基礎上。
1.TF、IDF等統計特徵–>文字關鍵詞提取
基於BOW的文字統計特徵不勝列舉,這些特徵在文字挖掘領域包括大家熟知的TF,IDF特徵,也包括一些看似平凡瑣碎實則在模型中權重很高的特徵。在討論TF-IDF特徵前,先列舉一些有關詞頻、詞密度及可讀性的統計特徵。如:
(1)Count特徵:詞頻統計、句頻句長統計、標點統計以及一些領域相關詞的統計等。
(2)可讀性特徵:音節數、煙霧指數和閱讀舒適性等
該類特徵可以利用github中的Textstat軟體包進行分析。該軟體提供瞭如下很多函式挖掘文字的統計學特徵。
from textstat.textstat import textstat
if __name__ == '__main__':
test_data = """Playing games has always been thought to be important to the development of well-balanced and creative children; however, what part, if any, they should play in the lives of adults has never been researched that deeply. """
print textstat.flesch_reading_ease(test_data)
print textstat.smog_index(test_data)
print textstat.flesch_kincaid_grade(test_data)
print textstat.coleman_liau_index(test_data)
print textstat.automated_readability_index(test_data)
print textstat.dale_chall_readability_score(test_data)
print textstat.difficult_words(test_data)
print textstat.linsear_write_formula(test_data)
print textstat.gunning_fog(test_data)
print textstat.text_standard(test_data)
迴歸正題,對於BOW模型來說,最經典的模型,沒有之一,無異於TF-IDF(Term Frequency-Inverse Document Frequency)模型。該模型基於詞頻,將文字轉換成向量,而不考慮詞序。假設現在又N篇文件,在其中一篇文件D中,詞彙w的TF、IDF、TF-IDF定義如下:
1.Term Frequency:詞彙w在文件D中的頻數
2.Inverse Document Frequency(IDF): log(總文件數N/包含詞彙w的文件數Nw)
3.TF-IDF = TF*IDF,作為該詞彙在該語料庫中對於該文章的權重,寫成公式如下:
wi,j=tfi,j∗log(N/dfi)
sklearn中有TF-IDF模型的API,可將文字轉換為權重向量,這既可以作為文字關鍵詞提取的基本方法,也可以作為文字相似度度量的根據。例子如下:
In [1]: from sklearn.feature_extraction.text import TfidfVectorizer
In [2]: vec = TfidfVectorizer()
In [3]: corpus = ['This is sample document.', 'another random document.', 'third sample document text']
In [4]: X = vec.fit_transform(corpus)
In [5]: print X #(#doc, #wordFeature) weight
(0, 7) 0.58448290102
(0, 2) 0.58448290102
(0, 4) 0.444514311537
(0, 1) 0.345205016865
(1, 1) 0.385371627466
(1, 0) 0.652490884513
(1, 3) 0.652490884513
(2, 4) 0.444514311537
(2, 1) 0.345205016865
(2, 6) 0.58448290102
(2, 5) 0.58448290102
In [6]: vec.get_feature_names() #wordFeature Order
Out[6]:
[u'another',
u'document',
u'is',
u'random',
u'sample',
u'text',
u'third',
u'this']
2.LSA潛在語義分析–文字稀疏表示–>文字相似度度量、主題模型
瞭解了TF-IDF模型,我們得到了文字的基本向量化表示,即得到了文字的(特徵)向量,向量具有一定語義表達的能力。LSA正是在此基礎上挖掘文字的潛在語義,建構主題模型等。
遍歷語料庫,得到全部文字-單詞的權重矩陣,權重即上文所求TF-IDF值。建立文字-單詞權重矩陣X後,可以通過SVD奇異值矩陣分解的方式將矩陣X轉換為它的低秩逼近矩陣。可以去前k維作為主要特徵,實現資料降維(原矩陣X維度為N*M,M為語料詞彙總數)。推導過程見LDA_Wikipedia對SVD過程的詳解。利用sklearn軟體包中的降維模組,即可完成SVD過程。以上文中corpus = [‘This is sample document.’, ‘another random document.’, ‘third sample document text’]為例展示一下LSA過程的程式碼,如下:
In [17]: svd = TruncatedSVD(2)
In [18]: norm = Normalizer(copy=False)
In [19]: lsa = make_pipeline(svd, norm)
In [20]: X = vec.fit_transform(corpus)
In [21]: X = lsa.fit_transform(X)
In [22]: print svd.explained_variance_ratio_.sum()
0.576009049909 # if svd = TruncatedSVd(3), sum=1.0
In [23]: print svd.explained_variance_ratio_ #每個變數能夠解釋的資訊量(Variance)佔比
[ 0.02791594 0.54809311]
In [24]: print X
[[ 0.93630095 -0.35119871]
[ 0.49995544 0.86605113]
[ 0.93630095 -0.35119871]]
In [25]: print svd.components_ #每個新特徵中,原詞彙權重的係數
[[ 0.23229736 0.51070605 0.31620157 0.23229736 0.4809589 0.31620157 0.31620157 0.31620157]
[ 0.61930819 0.15015437 -0.18253737 0.61930819 -0.27764876 -0.18253737 -0.18253737 -0.18253737]
3.PLSA概率潛在語言分析
圖四:PLSA Plate Notation
在LSA的基礎上,Hofmann引入了概率模型,對LSA進行了豐富。PLSA的文字生成模型在圖四。PLSA模型將這種文字-詞語共現性(co-occurrence)關係看作一種條件獨立多項式分佈的混合
4.LDA隱含狄利克雷分佈
圖五:LDA Plate Notation
在PLSA基礎上,Blei等為PLSA中的兩個多項式分佈引入了先驗。而多項式分佈的共軛分佈為Dirchlet狄利克雷分佈,這就是LDA中Dirchlet的由來。LDA生成模型為三層貝葉斯概率模型,包含詞、主題(隱含)和文件三層結構。包含K個主題的文件D生成過程如下:
1.For 每個主題k, 利用超引數eta抽樣beta_k~Dirichlet(eta), k=1...K
2.For 每篇文件d,利用超引數alpha抽樣theta_d~Dirichlet(alpha), d=1...D
3.For 文件d中的單詞i:
a.從多項式分佈theta_d中抽樣得到單詞i所屬的主題z_di~Multinomial(theta(d))
b.從多項式分佈beta_(z_di)中抽樣得到單詞w_ij~Multinomial(beta_(z_di) )
我們常用Gibbs Samplig吉布斯取樣的方案訓練LDA模型。利用sklearn訓練LDA主題模型的過程如下。
dataset = fetch_20newsgroups(shuffle=True, random_state=1,
remove=('headers', 'footers', 'quotes'))
#Use term count features for LDA
In [13]: tf_vectorizer = CountVectorizer(max_df=0.95, min_df=2,
...: max_features=n_features,
...: stop_words='english')
In [14]: tf = tf_vectorizer.fit_transform(data_samples)
In [15]: lda = LatentDirichletAllocation(n_topics=n_topics, max_iter=5,
...:
...: learning_method='online',
...: learning_offset=50.,
...: random_state=0)
In [16]: lda.fit(tf)
In [17]: #print trained topic model
In [18]: tf_feature_names = tf_vectorizer.get_feature_names()
In [19]: for idx, topic in enumerate(lda.components_):
...: print('Topic #%d' % idx)
...: print(" ".join([tf_feature_names[i] for i in topic.argsort ()[:-11:-1]])) #列印(主題-詞彙)向量
Out[19]:
Topic #0
edu com mail send graphics ftp pub available contact university
Topic #1
don like just know think ve way use right good
Topic #2
christian think atheism faith pittsburgh new bible radio games alt
Topic #3
drive disk windows thanks use card drives hard version pc
Topic #4
hiv health aids disease april medical care research 1993 light
Topic #5
god people does just good don jesus say israel way
Topic #6
55 10 11 18 15 team game 19 period play
Topic #7
car year just cars new engine like bike good oil
Topic #8
people said did just didn know time like went think
Topic #9
key space law government public use encryption earth section security
In [20]: lda.transform(tf)[0] #列印(文章-主題)向量
Out[20]:
array([ 0.00344893, 0.6285982 , 0.00344908, 0.00344877, 0.00344865,
0.34381098, 0.00344842, 0.00344869, 0.00344944, 0.00344884])
Reference
以上是最基本的語言模型Bag-of-word以及在這個大背景下衍生出來的文字統計特徵、語義特徵等。在下一篇中,將繼續瞭解更多的NLP語言模型,並瞭解在其背景下進行的延伸和探索。敬請期待。