自然语言处理之词移距离Word Mover's Distance
目錄
?
一、從EMD到WMD
二、詞移距離(WMD)
舉例說明
帶監督的詞移距離(Supervised Word Mover’s Distance)
三、word2vec實現詞移距離
四、詞移距離來衡量唐詩詩句的相關性
一、從EMD到WMD
EMD算法簡介,該部分引用自[1]。
Earth Mover’s Distance (EMD),和歐氏距離一樣,他們都是一種距離度量的定義,可以用來測量某分布之間的距離。EMD主要應用在圖像處理和語音信號處理領域。
EMD問題如下圖所示
給定兩個簽名(或者叫分布、特征量集合)P和Q,P為m個特征量Pi和其權重wPi的集合,記作P={(P1,wP1),(P2,wP2),...(Pm,wPm)},如圖左側部分。同樣的,還有一個分布Q,Q=(Q1,wQ1),(Q2,wQ2),...(Qn,wQn),即上圖右側部分。在計算這個這兩個簽名的Earth Mover's Distance(EMD)前,我們要先定義好P、Q中任意取一個特征量(?Pi?and?Qj?)之間的距離(這個距離叫ground distance,兩個簽名之間EMD依賴于簽名中特征量之間的ground distance)。當這兩個特征量是向量時得到的是歐式距離,當這兩個特征量是概率分布時得到的是相對熵(KL距離/Kullback–Leibler divergence)。現在,給定兩個簽名(P和Q),只要計算好每兩個特征量之間的距離,系統就能給出這兩個簽名之間的距離了。
EMD?實際上是線性規劃中運輸問題的最優解。首先,簡要描述下運輸問題。我們假設這個例子是從多個工廠運輸貨物到多個倉庫。在上圖左側,P從在P1?到?Pm代表m座工廠,工廠Pi有重量為wPi的貨物。在上圖右側,Q從Q1到Qn代表n個倉庫,倉庫Qj最大容量為wQj。貨物之間沒有什么區別,都是同一類東西。每個倉庫都希望裝盡可能多的貨物。如何盡可能高效把所有貨物(實際上不一定是所有貨物,部分也OK)從P運送到Q,就是運輸問題的優化目標。在本例中,P、Q都是離散的,那么EMD可以用運輸問題的Hungarian算法來計算它們之間的距離。挖個坑而已,這里不具體討論。
這里定義,貨物從工廠Pi運到倉庫Qj,距離是,運送貨物的重量為。這樣一次運輸需要的工作量為?。顯然,距離越遠、或貨物越重,工作量就越大。(注:運輸可能是多對多的,即一個工廠運輸貨物到多個倉庫,或者一個倉庫接收多個工廠的貨物。)貨物從工廠運到倉庫需要很多次這樣的運輸,經過一些計算和優化,這時我們得到了工作量總和的最小值W。
W =?
距離是事先定義的,所以運輸量fij是式中唯一的變量,對作如下4個約束:
(1)?運輸過程從工廠P到倉庫Q,不能反向。
≥ 0 (1≤i≤m,1≤j≤n)
(2)?從工廠Pi一次次運出去的所有貨物重量的和不可能超過該工廠中所有貨物的總重量wPi
?≤ wPi (1≤i≤m)
(3)?倉庫Qj接收的所有貨物總重量不可能超過其總容量wQj。
≤ wQj (1≤j≤n)
(4)?總運輸量的上限是工廠中貨物總重、倉庫總容量中的最小值。
當倉庫的總容量和工廠貨物總重不一樣時,我們才需要上述第4個限制條件。倉庫總容量比貨物總量大的話就可以全部運輸了,所以這時候呢,運輸量的上限就是貨物總量。但如果貨物總量比倉庫總容量大的話,就不能全部運輸了,這時候,運輸量的上限就是倉庫的總容量啦。方便起見,本例中當倉庫的總容量和工廠貨物總重是一樣的。
運輸問題的具體解答此處省略不討論,假設這個時候我們已經得到了最優解。為了使EMD不會隨著總運輸量的變化而變化,每一次的運輸量還要除以總運輸量,以達到歸一化的目的。(in order to avoid favoring smaller signatures in the case of partial matching.)在后面的具體例子中會對它進行詳細描述。
很自然可以想到,給定兩個簽名,把一個變成另一個所需要的最小工作量,就是EMD對距離的定義,這里的「工作量」要基于用戶對ground distance的定義,即特征量之間的距離的定義。然而,當特征量非常多的時候,由于要做一一匹配,其計算量是非常大的。因此,有人提出了一種將多個特征量組合起來做向量量化編碼(Vector Quantization)后再組成簽名的方法。
EMD算法在自然語言處理領域的應用
通過詞嵌入(Word Embedding),我們可以得到詞語的分布式低維實數向量表示,我們可以計算詞語之間的距離,即我們可以得到dij,因此可以將EMD引入自然語言處理領域。
Matt等人[2]將詞嵌入與EMD相聯系,用來度量文檔距離。提出了WMD(word mover’s distance)算法,以及WCD(word centroid distance)、RWMD(relaxed word mover’s distance)兩種犧牲精度降低復雜度的算法。
如何將一個文檔變為分布P這種形式?
用歸一化的詞袋模型(nBOW,?normalized bag-of-words)表示。其中P1表示詞語,用計算該詞的權重,其中表示詞語i在文檔中出現了次,P1的特征量用該詞語的詞向量表示。一個nBOW文檔向量是比較稀疏的,因為大部分的詞語不會出現在該文檔中,且在生成文檔向量時,去掉的停用詞。用歐式距離計算詞語與詞語之間的距離。
假定數據集中只有兩個文檔,則這兩個文檔生成的歸一化nBOW向量如下圖所示。
轉移量用矩陣T表示,生成的矩陣T如下圖所示
表示詞語i有多少轉移到了詞語j,
綜上,Matt等人提出了WMD算法,WMD是EMD的一個特殊形式。
由于文檔向量是經過歸一化的,與EMD算法相比,WMD沒有
的約束。
WMD算法的復雜度是,其中p表示nBOW模型的長度,即數據集中不同詞語的數目(去處停用詞)。該算法已經有成熟的解決方法,詳情參考[3]
算法的改進
為了降低模型的計算復雜度,Matt等人提出了WCD和RWMD兩個算法,這兩個算法是WMD的兩個不同下限,通過降低精度來降低計算復雜度。
Word centroid distance(WCD)
將作為WCD。其中X是一個的矩陣,d表示詞向量的維度,p表示nBOW模型的長度。d表示一個nBOW文檔向量。如下圖所示
WCD的復雜度度是
Relaxed word moving distance(RWMD)
通過放松限制條件,得到WMD的下限。通過去掉條件2,保留條件1,我們得到
通過去掉條件2,其實是去掉了倉庫容量的限制,我們可以將貨物全部運到離其最近的倉庫,而不需要考慮倉庫的容量。我們在運某個貨物時,往離該貨物最近的倉庫運送,即在轉移詞語i時,我們只向與詞語i距離最近的詞語j轉移。
當我們去掉條件1,保留條件2時,我們得到,與基本相同。去掉條件1,其實是去掉了貨物量的限制,我們可以將貨物源源不斷的運到倉庫中,直到倉庫滿了為止。我們在為填滿某個倉庫選擇運送的貨物時,選擇離該倉庫距離最近的貨物,即在詞語j接收時,我們選擇接收與詞語j距離近詞語i。
我們將作為RWMD。在計算文檔距離時,我們可以事先計算該數據集中,每個詞語之間的相似度,復雜度為,之后計算兩個文檔的時,只需要。
WCD vs. RWMD
RWMD相比WCD更緊,具體的驗證可以參考論文[2]。
讀完論文[2]后,有些問題:對比實驗使用的是歐式距離,歐式距離是否適用于所有的文本表示方式?譬如LDA得到的應該是一個主題概率分布向量,對于概率分布KL距離是否更合適?
?
Reference:
[1]?http://blog.mckelv.in/articles/1474.html
[2] From word embeddings to document distances, Matt J. kusner et al.
[3] Fast and robust earth mover’s distance, Pele et al.
二、詞移距離(WMD)
假如現在有一個任務,是判斷兩段文本之間的相似性,那我們應該怎么做呢?一個很自然的想法是用word2vec對兩段文本的詞向量化,然后再利用歐氏距離或者余弦相似性進行求解。不過這種方法有著致命的缺陷,即無法從文檔整體上來考慮相似性,僅僅是基于詞,這就造成了很大的信息缺失問題,下面要介紹的這種方法可以從文檔整體上來考慮兩個文檔之間的相似性,這種技術稱為詞移距離(WMD)。
究竟什么才是詞移距離呢?這要從Word2Vec講起。Word2Vec將詞映射為一個詞向量,在這個向量空間中,語義相似的詞之間距離會比較小,而詞移距離(WMD)正是基于word2vec的這一特性開發出來的。
正如上面所講到的,Word2Vec得到的詞向量可以反映詞與詞之間的語義差別,那么如果我們希望有一個距離能夠反映文檔和文檔之間的相似度,應該怎么做呢?一個想法是將文檔距離建模成兩個文檔中詞的語義距離的一個組合,比如說對兩個文檔中的任意兩個詞所對應的詞向量求歐氏距離然后再加權求和,大概是這樣的形式:∑i,j=1nTijc(i,j)∑i,j=1nTijc(i,j),其中c(i,j)c(i,j)為i,ji,j兩個詞所對應的詞向量的歐氏距離。
那我們怎樣得到這個加權矩陣TT呢?又或者說這個加權矩陣TT代表什么含義呢?在我看來,這個加權矩陣TT有些類似于HMM中的狀態轉移矩陣,只不過其中的概率轉換為權重了而已。我們再來看下面這個圖:
這里有兩個文檔,去除停用詞后,每篇文檔僅剩下4個詞,我們就是要用這四個詞來比較兩個文檔之間的相似度。在這里,我們假設’Obama’這個詞在文檔1中的的權重為0.5(可以簡單地用詞頻或者TFIDF進行計算),那么由于’Obama’和’president’的相似度很高,那么我們可以給由’Obama’移動到’president’很高的權重,這里假設為0.4,文檔2中其他的詞由于和’Obama’的距離比較遠,所以會分到更小的權重。這里的約束是,由文檔1中的某個詞ii移動到文檔2中的各個詞的權重之和應該與文檔1中的這個詞ii的權重相等,即’Obama’要把自己的權重(0.5)分給文檔2中的各個詞。同樣,文檔2中的某個詞jj所接受到由文檔1中的各個詞所流入的權重之和應該等于詞jj在文檔2中的權重。
為什么要有這樣的操作呢?因為我們可以設想,∑i,j=1nTijc(i,j)∑i,j=1nTijc(i,j)代表的是文檔1要轉換為文檔2所需要付出的總代價。將這種代價求得下界即最小化之后,即可求得所有文檔a中單詞轉移到文檔b中單詞的最短總距離,代表兩個文檔之間的相似度。
舉例說明
形象化的考慮一下,我們有三個文檔,文檔1中每個詞都跟“王者榮耀”緊密相關;文檔2中只有一個詞跟“王者榮耀”密切相關,其余詞都跟“王者榮耀”完全無關;文檔3中有一個詞跟“王者榮耀”密切相關,其他詞都跟“王者榮耀”有點關系但關聯性不大。那么可以想象,WMD(d1,d2)>WMD(d1,d3)WMD(d1,d2)>WMD(d1,d3),因為文檔1中的詞和文檔2中和“王者榮耀”完全無關的詞之間的距離要比文檔1中的詞和文檔3中和“王者榮耀”有點關系但關聯性不大的詞之間的距離要大。
帶監督的詞移距離(Supervised Word Mover’s Distance)
我們理解了WMD距離,那么問題來了,學習這個權重矩陣用來聚類雖好(告訴我們哪些文檔比較相近),但是, 用來分類卻很差,這就要引入監督學習。
為什么? 因為一些文章雖然近義詞很多, 但是表達的不是一個語義和主題. 比如: I love playing football 和 I like playing piano . 雖然看起來句式差不多, 可能會歸為同類, 但是如果打標簽時如果是”運動”和”藝術”兩類, 顯然就不能用WMD直接分類了. 因為, WMD沒有加入 football和”運動”是強相關的信息.
所以, 論文Supervised Word Mover’s Distance給出的解決方案就是在WMD距離中加入可以訓練類別權重的功能:
這里的dd加入了類別權重ww:
單詞間距離也要進行調整(單詞間距離也因為類別不同需要調整距離),加入訓練參數矩陣AA。
詞移距離(Word Mover's Distance)是在詞向量的基礎上發展而來的用來衡量文檔相似性的度量。
本文主要介紹了詞移距離的源碼實現,并給出了使用實例計算文本相似度。
三、word2vec實現詞移距離
安裝gensim?并且有pyemd,詳情見下def wmdistance(self, document1, document2):"""Compute the Word Mover's Distance between two documents. When using thiscode, please consider citing the following papers:.. Ofir Pele and Michael Werman, "A linear time histogram metric for improved SIFT matching"... Ofir Pele and Michael Werman, "Fast and robust earth mover's distances"... Matt Kusner et al. "From Word Embeddings To Document Distances".Note that if one of the documents have no words that exist in theWord2Vec vocab, `float('inf')` (i.e. infinity) will be returned.This method only works if `pyemd` is installed (can be installed via pip, but requires a C compiler).Example:>>> # Train word2vec model.>>> model = Word2Vec(sentences)>>> # Some sentences to test.>>> sentence_obama = 'Obama speaks to the media in Illinois'.lower().split()>>> sentence_president = 'The president greets the press in Chicago'.lower().split()>>> # Remove their stopwords.>>> from nltk.corpus import stopwords>>> stopwords = nltk.corpus.stopwords.words('english')>>> sentence_obama = [w for w in sentence_obama if w not in stopwords]>>> sentence_president = [w for w in sentence_president if w not in stopwords]>>> # Compute WMD.>>> distance = model.wmdistance(sentence_obama, sentence_president)"""if not PYEMD_EXT:raise ImportError("Please install pyemd Python package to compute WMD.")# Remove out-of-vocabulary words.len_pre_oov1 = len(document1)len_pre_oov2 = len(document2)document1 = [token for token in document1 if token in self]document2 = [token for token in document2 if token in self]diff1 = len_pre_oov1 - len(document1)diff2 = len_pre_oov2 - len(document2)if diff1 > 0 or diff2 > 0:logger.info('Removed %d and %d OOV words from document 1 and 2 (respectively).',diff1, diff2)if len(document1) == 0 or len(document2) == 0:logger.info('At least one of the documents had no words that were''in the vocabulary. Aborting (returning inf).')return float('inf')dictionary = Dictionary(documents=[document1, document2])vocab_len = len(dictionary)if vocab_len == 1:# Both documents are composed by a single unique tokenreturn 0.0# Sets for faster look-up.docset1 = set(document1)docset2 = set(document2)# Compute distance matrix.distance_matrix = zeros((vocab_len, vocab_len), dtype=double)for i, t1 in dictionary.items():for j, t2 in dictionary.items():if not t1 in docset1 or not t2 in docset2:continue# Compute Euclidean distance between word vectors.distance_matrix[i, j] = sqrt(np_sum((self[t1] - self[t2])**2))if np_sum(distance_matrix) == 0.0:# `emd` gets stuck if the distance matrix contains only zeros.logger.info('The distance matrix is all zeros. Aborting (returning inf).')return float('inf')def nbow(document):d = zeros(vocab_len, dtype=double)nbow = dictionary.doc2bow(document) # Word frequencies.doc_len = len(document)for idx, freq in nbow:d[idx] = freq / float(doc_len) # Normalized word frequencies.return d# Compute nBOW representation of documents.d1 = nbow(document1)d2 = nbow(document2)# Compute WMD.return emd(d1, d2, distance_matrix)四、詞移距離來衡量唐詩詩句的相關性
詞移距離在gensim中有封裝包,代碼實現如上,本例子直接調用gensim中封裝函數
全唐詩txt鏈接:https://files.cnblogs.com/files/combfish/%E5%85%A8%E5%94%90%E8%AF%97.zip。
步驟:
1. 預處理語料集: 唐詩的斷句分詞,斷句基于標點符號,分詞依靠結巴分詞
2. gensim訓練詞向量模型與wmd相似性模型
3. 查詢
import?jieba from?nltk?import?word_tokenize from?nltk.corpus?import?stopwords from?time?import?time start_nb?=?time() import?loggingprint(20*'*','loading data',40*'*') f=open('全唐詩.txt',encoding='utf-8') lines=f.readlines() corpus=[] documents=[] useless=[',','.','(',')','!','?','\'','\"',':','<','>',',',?'。',?'(',?')',?'!',?'?',?'’',?'“',':','《','》','[',']','【','】'] for?each?in?lines:each=each.replace('\n','')each.replace('-','')each=each.strip()each=each.replace(' ','')if(len(each)>3):if(each[0]!='卷'):documents.append(each)each=list(jieba.cut(each))text=[w?for?w?in?each?if?not?w?in?useless]corpus.append(text)print(len(corpus))print(20*'*','trainning models',40*'*') from?gensim.models?import?Word2Vec model?=?Word2Vec(corpus, workers=3, size=100)# Initialize WmdSimilarity. from?gensim.similarities?import?WmdSimilarity num_best?=?10 instance?=?WmdSimilarity(corpus, model, num_best=10)print(20*'*','testing',40*'*') while?True:sent?=?input('輸入查詢語句: ')sent_w?=?list(jieba.cut(sent))query?=?[w?for?w?in?sent_w?if?not?w?in?useless]sims?=?instance[query]??# A query is simply a "look-up" in the similarity class.# Print the query and the retrieved documents, together with their similarities.print('Query:')print(sent)for?i?in?range(num_best):printprint('sim = %.4f'?%?sims[i][1])print(documents[sims[i][0]])
結果:從結果kan
?
?
?
?
?
?
?
相關參考:
https://www.cnblogs.com/combfish/p/8126857.html
詞移距離的具體介紹http://blog.csdn.net/qrlhl/article/details/78512598
官方例子
https://github.com/RaReTechnologies/gensim/blob/c971411c09773488dbdd899754537c0d1a9fce50/docs/notebooks/WMD_tutorial.ipynb?
如何通過詞向量技術來計算2個文檔的相似度?
Supervised Word Mover’s Distance (可監督的詞移距離) – NIPS 2016論文精選#2
https://blog.csdn.net/qrlhl/article/details/78512598
總結
以上是生活随笔為你收集整理的自然语言处理之词移距离Word Mover's Distance的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hbuilderx 各种项目 开发区别
- 下一篇: 例题:索洛模型——要素支付