在cips2016出來之前,筆者也總結多類似詞向量的內容,自然語言處理︱簡述四大類文本分析中的“詞向量”(文本詞特徵提取)事實證明,筆者當時所寫的基本跟CIPS2016一章中總結的類似,當然由於入門較晚沒有CIPS2016裏面說法權威,於是把CIPS2016中的內容,做一個摘錄。
CIPS2016 中文信息處理報告《第五章 語言表示與深度學習研究進展、現狀及趨勢》第三節 技術方法和研究現狀中有一些關於語言表示模型劃分的內容P33-P35,其中:
語言表示方法大體上可以從兩個維度進行區分。一個維度是按不同粒度進行劃分,語言具有一定的層次結構,語言表示可以分爲字、詞、句子、篇章等不同粒度的表示。另一個維度是按表示形式進行劃分,可以分爲離散表示和連續表示兩類。離散表示是將語言看成離散的符號,而將語言表示爲連續空間中的一個點,包括分佈式表示和分散式表示。
CIPS2016 中文信息處理報告下載鏈接:http://cips-upload.bj.bcebos.com/cips2016.pdf
.
.
一、離散的方法## 標題 ##表示
1、詞向量
- 一個詞可以表示爲One-Hot 向量(一維爲1 其餘維爲0
的向量),也叫局部表示。離散表示的缺點是詞與詞之間沒有距離的概念,這和事實不符。 - 一種改進的方法是基於聚類的詞表示。其中一個經典的方法是Brown 聚類算法,該算法是一種層次化的聚類算法。在得到層次化結構的詞類簇之後,我們可以用根節點到詞之間的路徑來表示該詞。
2、句向量
有了詞的表示之後,我們可以進一步得到句子或篇章的表示。句子或篇章的離散表示通常採用詞袋模型、N 元模型等。
.
.
.
二、連續表示—分佈式表示
這樣就可以通過共現矩陣的方式來進行詞的表示,這類方法也叫分佈式表示(Distributional Representations)
1、詞向量
潛在語義分析模型(Latent Semantic Analysis, LSA)、潛在狄利克雷分配模型(Latent Dirichlet Allocation,LDA)、隨機索引(random indexing)等。
2、句向量
句子的表示方式對應於共現矩陣,另一列,在LDA中句子-詞語矩陣中就是很好地句子表示方式。
.
.
.
★三、連續表示——分散式表示
另一種連續表示是分散式表示(Distributed Representations),即將語言表示爲稠密、低維、連續的向量
1、詞向量
研究者最早發現學習得到詞嵌入之間存在類比關係。比如apple−apples ≈ car−cars, man−woman ≈ king – queen 等。這些方法都可以直接在大規模無標註語料上進行訓練。詞嵌入的質量也非常依賴於上下文窗口大小的選擇。通常大的上下文窗口學到的詞嵌入更反映主題信息,而小的上下文窗口學到的詞嵌入更反映詞的功能和上下文語義信息。
2、句向量
句子編碼主要研究如何有效地從詞嵌入通過不同方式的組合得到句子表示。其中,比較有代表性的方法有四種。
- (1)神經詞袋模型
簡單對文本序列中每個詞嵌入進行平均/加總,作爲整個序列的表示。
這種方法的缺點是丟失了詞序信息。對於長文本,神經詞袋模型比較有效。但是對於短文本,神經詞袋模型很難捕獲語義組合信息。
- (2)遞歸神經網絡(Recursive Neural Network)
按照一個給定的外部拓撲結構(比如成分句法樹),不斷遞歸得到整個序列的表示。遞歸神經網絡的一個缺點是需要給定一個拓撲結構來確定詞和詞之間的依賴關係,因此限制其使用範圍。
- (3)循環神經網絡(Recurrent Neural Network)
將文本序列看作時間序列,不斷更新,最後得到整個序列的表示。
- (4)卷積神經網絡(Convolutional Neural Network)
通過多個卷積層和子採樣層,最終得到一個固定長度的向量。
在上述四種基本方法的基礎上,很多研究者綜合這些方法的優點,結合具體的任務,已經提出了一些更復雜的組合模型,例如雙向循環神經網絡(Bi-directional Recurrent Neural Network)、長短時記憶模型(Long-Short Term Memory)等。
同時根據上面的內容,句向量的表徵在RNN、CNN之間,到底哪個更好呢? 有一篇文章在這點上講得比較清楚,會在下面的延伸三:《NLP 模型到底選 RNN 還是 CNN?》提到。
3、篇章表示
如果處理的對象是比句子更長的文本序列(比如篇章),爲了降低模型複雜度,一般採用層次化的方法,先得到句子編碼,然後以句子編碼爲輸入,進一步得到篇章的表示。具體的層次化可以採用以下幾種方法:
- (1)層次化的卷積神經網絡
即用卷積神經網絡對每個句子進行建模,然後以句子爲單位再進行一次卷積和池化操作,得到篇章表示。
- (2)層次化的循環神經網絡
即用循環神經網絡對每個句子進行建模,然後再用一個循環神經網絡建模以句子爲單位的序列,得到篇章表示。
- (3)混合模型
先用循環神經網絡對每個句子進行建模,然後以句子爲單位再進行一次卷積和池化操作,得到篇章表示。在上述模型中,循環神經網絡因爲非常適合處理文本序列,因此被廣泛應用在很多自然語言處理任務上。
.
.
.
四、總結
基於深度學習的方法在自然語言處理中取得了很大的進展,因此,分散式表示也成爲語言表示中最熱門的方法,不但可以在特定的任務中端到端地學習字、詞、句子、篇章的分散式表示,也可以通過大規模未標註文本自動學習。
分散式表示可以非常方便地應用在下游的各種自然語言處理任務上,並且可以端到端地學習,給研究者帶來了很大的便利。但是分散式表示對以下幾種情況還不能很好地處理,需要進一步解決。
- 語言中出現所有符號是否都需要使用統一的表示模型?比如,無意義的符號、變量、數字等。
- 新詞以及低頻詞的表示學習方法。目前的表示學習方法很難對這些詞進行很好的建模,而這些詞都是極具信息量的,不能簡單忽略。
- 篇章的語言表示。目前對篇章級別的文本進行建模方法比較簡單,不足以表示篇章中的複雜語義。
- 語言表示的基礎數據結構。除了目前的基於向量的數據結構之外是否有更好的表示結構,比如矩陣、隊列、棧等。
.
.
延伸一:句向量的表示方式
參考blog:Sentence Embedding/Nishant Nikhil
在實際應用方面,可以參考google在2014發表的內容,對實際應用非常有幫助:Distributed Representations of Sentences and Documents
該博客較多是對分散表示詞向量進行一定的總結與歸納。
1、詞向量簡單相加/平均(類似神經詞袋模型)
對詞向量的相加/平均,但是譬如以下的兩句話質心是一致的:
You are going there to teach not play.
You are going there to play not teach
這樣的方式,再來求句子距離,其實是在求句子的質心距離(centroid distance)。
另外一種改良版本,用Word Movers’ Distance
相近詞之間求距離,然後把這樣的相近距離相加。
參考paper1:From Word Embeddings To Document Distances
參考paper2:Using Centroids of Word Embeddings and Word Mover’s Distance for Biomedical Document Retrieval in Question Answering
.
.
2、深度學習方面
以上的方法並沒有關照到句子的序列信息。
1、CNN
用CNN來句子表示(paper:Convolutional Neural Networks for Sentence Classification),操作流程是:
padding句子讓其長度一致 -> 使用詞表示技術成爲方陣 -> 使用CNN -> 使用Max-overtime pooling -> 全連接層 -> 獲得句向量。
2、GRU
Dynamic Memory Networks for Visual and Textual Question Answering
通過GRU進行編碼,生成上下文向量+更新記憶。
當然還有用雙向GRUs(Efficient Summarization With Read-Again And Copy Mechanism)
.
.
3、fasttext表示
可見NLP︱高級詞向量表達(二)——FastText(簡述、學習筆記)
.
.
延伸二:句向量表達:Sentence 2 vec
跟眼神一中詞向量簡單相加減類似,是通過PCA/SVD的加權得到了句向量,同時作者在實驗過程中,發現這一表徵方式,可以跟LSTM表徵的效果媲美。
github地址:https://github.com/peter3125/sentence2vec
paper地址:《A SIMPLE BUT TOUGH-TO-BEAT BASELINE FOR SENTENCE EMBEDDINGS》
# test
embedding_size = 4 # dimension of the word embedding
w1 = Word('Peter', [0.1, 0.2, 0.3, 0.4])
w2 = Word('was', [0.2, 0.1, 0.3, 0.4])
w3 = Word('here', [0.1, 0.4, 0.1, 0.4])
sentence1 = Sentence([w1, w2, w3])
sentence2 = Sentence([w2, w3, w1])
sentence3 = Sentence([w3, w1, w2])
# calculate and display the result
print(sentence_to_vec([sentence1, sentence2, sentence3], embedding_size))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
.
延伸三:NLP 模型到底選 RNN 還是 CNN?
本文來源於文章《AI技術講座精選:NLP 模型到底選 RNN 還是 CNN?》,不過實質上並沒有得出非常建設性的答案。
paper地址:https://arxiv.org/pdf/1702.01923.pdf
CNN 是分層架構,RNN 是連續結構。一般靠常規直覺來判斷:
- 傾向於爲分類類型的任務選擇 CNN,例如情感分類,因爲情感通常是由一些關鍵詞來決定的;
- 對於順序建模任務,我們會選擇 RNN,例如語言建模任務,要求在瞭解上下文的基礎上靈活建模。
在實踐中,得到的結論:
- CNN 和 RNN 爲文本分類任務提供補充信息。至於哪個架構的執行效果更好一點,取決於對整個序列的語義理解的重要程度。
- 目前來看,RNN 在文本級別的情感分類表現得很好(Tang et al., 2015),對於LSTM,封閉的 CNN
在語言建模任務上同比 LSTM 更勝一籌 - RNN 表現較好並且在大範圍內的任務中都較爲穩健。除了以下種情況:當前的任務本質上是一項在一些情感探測和問答匹配設置中識別關鍵詞的任務。
- 隱藏層尺寸hidden size和批尺寸batch size會使 DNN 的性能變得非常不穩定,波動較大,從實踐來看這兩個參數對結果的影響非常大。
.
延伸四:對詞向量干預,可以提高效率
paper:All-but-the-Top: Simple and Effective Postprocessing for Word Representations
本文來源於paperweekly,《本週值得讀(2017.02.06-2017.02.10)》
本文提出了一種對已有的詞向量進行預處理的方法,用來對學習到的詞向量降噪。基於詞向量自身的幾何結構 — 均值非零以及各項不同性,本文提出了一個反直觀的處理方法:從所有的詞向量中移除均值,以及移除部分導致各項不同性的方向。雖然這種處理方式忽略了詞向量中的部分信息,但是它可以使多種通過不同方式訓練出來的詞向量加強詞向量中包含的語義信息。經過預處理之後的詞向量在一系列intrinsic衡量方式上(similarity, analogy, concept categorization)得到了一致性地提高。同時,我們通過了不同的應用上進行了測試,試驗結果表明該預處理已經在諸多neural network中有所體現,進一步證實了對詞向量進行預處理的重要性。
.
延伸五:NLP+Skip-Thoughts-Vectors︱基於TensorFlow的帶語義特徵的句向量編碼方式
本篇轉載於新智元,題爲《TensorFlow 自動句子語義編碼,谷歌開源機器學習模型
Skip-Thoughts》
筆者覺得是高層次的
github地址:https://github.com/tensorflow/models/tree/master/skip_thoughts
Skip-Thoughts 模型概要
Skip-Thoughts 模型是一個句子編碼器。它學習將輸入的句子編碼成固定維度的向量表示,這些向量表示能夠對許多任務有用,例如檢測釋義,或對產品評論進行積極或消極的分類等等。有關模型架構和更多示例應用的詳細信息,可以參閱Ryan Kiros 等人的 NIPS 論文 Skip-Thought Vectors。
一個訓練好的 Skip-Thoughts 模型會在嵌入的向量空間中對相互臨近的相似句子進行編碼。以下示例展示了對電影評論數據集中的一些句子的餘弦相似性的最近鄰域。
我們描述了一種通用、分佈式句子編碼器的無監督學習方法。使用從書籍中提取的連續文本,我們訓練了一個編碼器-解碼器模型,試圖重建編碼段落周圍的句子。語義和語法屬性一致的句子因此被映射到相似的向量表示。我們接着引入一個簡單的詞彙擴展方法來編碼不再訓練預料內的單詞,令詞彙量擴展到一百萬詞。同時建立word2vec到skip-thoughts向量之間的映射關係。
在訓練模型後,我們用線性模型在8個任務上提取和評估我們的向量,包括:語義相關性,釋義檢測,圖像句子排序,問題類型歸類,以及4個基準情緒和主觀性數據集。最終的結果是一個非專門設計的編碼器,能夠生成高度通用性的句子表示,在實踐中表現良好。
Skip-Thought 模型是 NIPS 2015論文 Skip-Thought Vectors 中描述的模型的一個 TensorFlow 實現,學習對句子的語義屬性進行編碼。
引用:Ryan Kiros, Yukun Zhu, Ruslan Salakhutdinov, Richard S. Zemel, Antonio Torralba, Raquel Urtasun, Sanja Fidler. Skip-Thought Vectors. In NIPS, 2015.
論文下載地址:https://papers.nips.cc/paper/5950-skip-thought-vectors.pdf
編碼句子示例
該示例的句子來自電影評論數據集(Movie Review Data)。
ipython # Launch iPython.
In [0]:
# Imports.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import os.path
import scipy.spatial.distance as sd
from skip_thoughts import configuration
from skip_thoughts import combined_encoder
In [1]:
# Set paths to the model.
VOCAB_FILE = "/path/to/vocab.txt"
EMBEDDING_MATRIX_FILE = "/path/to/embeddings.npy"
CHECKPOINT_PATH = "/path/to/model.ckpt-9999"
# The following directory should contain files rt-polarity.neg and
# rt-polarity.pos.
MR_DATA_DIR = "/dir/containing/mr/data"
In [2]:
# Set up the encoder. Here we are using a single unidirectional model.
# To use a bidirectional model as well, call load_encoder() again with
# configuration.ModelConfig(bidirectional_encoder=True) and paths to the
# bidirectional model's files. The encoder will use the concatenation of
# all loaded models.
encoder = combined_encoder.CombinedEncoder()
encoder.load_encoder(configuration.ModelConfig(),
vocabulary_file=VOCAB_FILE,
embedding_matrix_file=EMBEDDING_MATRIX_FILE,
checkpoint_path=CHECKPOINT_PATH)
In [3]:
# Load the movie review dataset.
data = []
with open(os.path.join(MR_DATA_DIR, 'rt-polarity.neg'), 'rb') as f:
data.extend([line.decode('latin-1').strip() for line in f])
with open(os.path.join(MR_DATA_DIR, 'rt-polarity.pos'), 'rb') as f:
data.extend([line.decode('latin-1').strip() for line in f])
In [4]:
# Generate Skip-Thought Vectors for each sentence in the dataset.
encodings = encoder.encode(data)
In [5]:
# Define a helper function to generate nearest neighbors.
def get_nn(ind, num=10):
encoding = encodings[ind]
scores = sd.cdist([encoding], encodings, "cosine")[0]
sorted_ids = np.argsort(scores)
print("Sentence:")
print("", data[ind])
print("\nNearest neighbors:")
for i in range(1, num + 1):
print(" %d. %s (%.3f)" %
(i, data[sorted_ids[i]], scores[sorted_ids[i]]))
In [6]:
# Compute nearest neighbors of the first sentence in the dataset.
get_nn(0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
輸出:
Sentence:
simplistic , silly and tedious .
Nearest neighbors:
1. trite , banal , cliched , mostly inoffensive . (0.247)
2. banal and predictable . (0.253)
3. witless , pointless , tasteless and idiotic . (0.272)
4. loud , silly , stupid and pointless . (0.295)
5. grating and tedious . (0.299)
6. idiotic and ugly . (0.330)
7. black-and-white and unrealistic . (0.335)
8. hopelessly inane , humorless and under-inspired . (0.335)
9. shallow , noisy and pretentious . (0.340)
10. . . . unlikable , uninteresting , unfunny , and completely , utterly inept . (0.346)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
延伸六:Doc2Vec的情感分析以及相似性
Tutorial for Sentiment Analysis using Doc2Vec in gensim (or “getting 87% accuracy in sentiment analysis in under 100 lines of code”)
github:https://github.com/linanqiu/word2vec-sentiments
也可以用doc2vec來做相似性分析,其他辦法有:
第一種方法,使用docsim;第二種辦法,使用doc2vec;第三種方式:使用LSH。
博客裏面也有code
詳細可見:用docsim/doc2vec/LSH比較兩個文檔之間的相似度
.
延伸七:能夠表徵相似的:基於CNN的短文本表達模型及相似度計算的全新優化模型
來源:LSF-SCNN:一種基於CNN的短文本表達模型及相似度計算的全新優化模型
LSF-SCNN,即基於詞彙語義特徵的跳躍卷積模型 (Lexical Semantic Feature based Skip Convolution neural network ),基於卷積神經網絡模型引入三種優化策略:詞彙語義特徵 (Lexical Semantic Feature, LSF)、跳躍卷積 (Skip Convolution, SC)和K-Max均值採樣 (K-Max Average Pooling, KMA) ,分別在詞彙粒度、短語粒度、句子粒度上抽取更加豐富的語義特徵,從而更好的在向量空間構建短文本語義表達模型,並廣泛的適用於問答系統 (question answering)、釋義識別 (paraphrase identification) 和文本蘊含 (textual entailment)等計算成對兒出現的短文本的相似度的任務中。
LSF特徵怎樣計算得到?
問題和答案中的每一個單詞都會有一個LSF特徵,具體來說是一個[0,t]上的整數值。LSF的計算過程可通過下面一個例子說明,當我們想要求解問題中general一詞的LSF特徵時,第一步我們需要計算general與答案中每一個詞的餘弦相似度並選取其中的最大值,因此chief被選取出來。第二步,餘弦相似度值的最大值0.79將通過一個映射函數映射爲一個[0,t]區間的整數,當我們假定t=10,最終計算得到general的LSF特徵爲3。這是合理的,general和chief一定程度上是近義詞。
.
延伸八:473個模型試驗告訴你文本分類中的最好編碼方式
論文地址:https://arxiv.org/pdf/1708.02657.pdf
來源機器之心:學界 473個模型試驗告訴你文本分類中的最好編碼方式
本論文實證研究了在文本分類模型中漢語、日語、韓語(CJK)和英語的不同編碼方式。該研究討論了不同層面的編碼,包括 UTF-8 bytes、字符級和詞彙級。對於所有的編碼層面,我們都提供了線性模型、fastText (Joulin et al., 2016) 和卷積網絡之間的對比。對於卷積網絡,我們使用字符字形(character glyph)圖像、one-hot(或 one-of-n)編碼和嵌入方法比較了不同的編碼機制。總的來說,該實驗涉及 473 個模型,並使用了四種語言(漢語、英語、日語和韓語)的 14 個大規模文本分類數據集。該研究所得出來的一些結論:基於 UTF-8 字節層面的 one-hot 編碼在卷積網絡中始終生成優秀結果;詞層面的 N 元線性模型即使不能完美地分詞,它也有強大的性能;fastText 使用字符層面的 N 元模型進行編碼取得了最好的性能,但當特徵太多時容易過擬合。
通過比較以上表格中的誤差率,作者得出以下結論:
- 1、fastText模型對中、日、韓文本(CJK語言文本)在character級編碼的處理結果更好;而對英語文本則在word級編碼的處理結果更好;
- 2、對於fastText和線性模型,CJK語言的word級編碼在沒有完美分割的情況下效果相當;
- 3、卷積網絡的最佳編碼機制是byte級獨熱編碼(byte-level one-hot encoding)。
這表明卷積網絡能夠從低級別的表示中理解文本,並提供了一致的和統一的方式來處理多種語言。 - 4、fastText相比於卷積網絡更傾向於過擬合,而相比於線形模型也並沒有表現出更多的表示能力(representation
capacity)。
當然,儘管作者在此列了473種模型進行對比,但仍不是全部。例如深度學習模型本文只用了卷積網絡模型,但其實還有別的一些有意思的模型,例如週期性網絡(recurrent networks)等。作者似乎計劃在之後會對週期性網絡進行研究,同時還會改進卷積網絡模型,看會有什麼樣的效果。