文本表示

文本表示

將文本數據表示成計算機能夠運算的數字或向量

離散表示

獨熱編碼(One-hot)

  • 思想:

    將語料庫中所有的詞拉成一個向量,給每個詞一個下標,就得到對應的詞典。每個分詞的文本表示為該分詞的比特位為1,其餘位為0的矩陣表示。

詞袋模型(Bag of Words)

  • 思想:

    把每篇文章看成一袋子詞,並忽略每個詞出現的順序。具體來看:將整段文本表示成一個長向量,每一維代表一個單詞。該維對應的權重代表這個詞在原文章中的重要程度。

  • 例子:

    句1:Jane wants to go to Shenzhen. 句2:Bob wants to go to Shanghai.

    使用兩個例句構造詞袋: [Jane, wants, to, go, Shenzhen, Bob, Shanghai]

    兩個例句就可以用以下兩個向量表示,對應的下標與映射數組的下標相匹配,其值為該詞語出現的次數

    句1:[1,1,2,1,1,0,0] 句2:[0,1,2,1,0,1,1]

詞頻-逆向文件頻率(TF-IDF)

  • 思想:

    字詞的重要性隨着它在文件中出現的次數成正比增加,但同時會隨着它在語料庫中出現的頻率成反比下降。如果某個單詞在一篇文章中出現的頻率TF高,並且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。

  • 公式:

    • \(TF-IDF(t,d)=TF(t,d) × IDF(t)\)
    • \(IDF(t)=log\frac {文章總數} {包含單詞t的文章總數+1}\)
    • \(TF=\frac{單詞t在文檔中出現的次數}{該文檔的總詞量}\)
  • 缺點:

    (1)沒有考慮特徵詞的位置因素對文本的區分度,詞條出現在文檔的不同位置時,對區分度的貢獻大小是不一樣的。

    (2)按照傳統TF-IDF,往往一些生僻詞的IDF(反文檔頻率)會比較高、因此這些生僻詞常會被誤認為是文檔關鍵詞。

    (3)IDF部分只考慮了特徵詞與它出現的文本數之間的關係,而忽略了特徵項在一個類別中不同的類別間的分佈情況。

    (4)對於文檔中出現次數較少的重要人名、地名信息提取效果不佳。

  • 使用:

# 參數為 CounterVectorizer 和 TfidfTransformer 的所有參數
tfidf=TfidfVectorizer(tokenizer=jieba.lcut,stop_words=stopwords,norm='l2',use_idf=True,smooth_idf=True,sublinear_tf=False)
res=tfidf.fit_transform(contents)#直接對文檔進行轉換提取tfidf特徵
res.toarray()#一步就得到了tfidf向量思想:

N-Gram模型(統計語言模型)

  • 統計語言模型:

    是一個基於概率的判別模型。統計語言模型把語言(詞的序列)看作一個隨機事件,並賦予相應的概率來描述其屬於某種語言集合的可能性。給定一個詞彙集合 V,對於一個由 V 中的詞構成的序列S = ⟨w1, · · · , wT ⟩ ∈ Vn,統計語言模型賦予這個序列一個概率P(S),來衡量S 符合自然語言的語法和語義規則的置信度。用一句簡單的話說,統計語言模型就是計算一個句子的概率大小的這種模型。

  • 思想:

    N-Gram是一種基於統計語言模型的算法。它的基本思想是將文本裏面的內容按照位元組進行大小為N的滑動窗口操作,形成了長度是N的位元組片段序列。每一個位元組片段稱為gram,對所有gram的出現頻度進行統計,並且按照事先設定好的閾值進行過濾,形成關鍵gram列表,也就是這個文本的向量特徵空間,列表中的每一種gram就是一個特徵向量維度。把這些生成一個字典,按照詞袋模型的方式進行編碼得到結果。

  • 例子:

    John likes to watch movies. Mary likes too
    John also likes to watch football games.
    

    構造字典:

    {"John likes」: 1, "likes to」: 2, "to watch」: 3, "watch movies」: 4, "Mary likes」: 5, "likes too」: 6, "John also」: 7, "also likes」: 8, 「watch football」: 9, "football games": 10}
    

    此時,第一句的向量表示為:[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],其中第一個1表示John likes在該句中出現了1次,依次類推。

離散表示的問題

  • 無法衡量詞向量之間的關係。
  • 詞表的維度隨着語料庫的增長而膨脹。
  • n-gram詞序列隨語料庫增長呈指數型膨脹,更加快。
  • 離散數據來表示文本會帶來數據稀疏問題,導致丟失了信息,與我們生活中理解的信息是不一樣的。

分佈式表示

主要思想是用周圍的詞表示該詞

共現矩陣(Cocurrence matrix)

  • 思想:

    「共現」,即共同出現,如一句話中共同出現,或一篇文章中共同出現。這裡給共同出現的距離一個規範——窗口,如果窗口寬度是2,那就是在當前詞的前後各2個詞的範圍內共同出現。可以想像,其實是一個總長為5的窗口依次掃過所有文本,同時出現在其中的詞就說它們共現。

  • 例子:

    image-20210117155944299

神經網絡語言模型(NNLM)

  • 思想:

    • NNLM是從語言模型出發(即計算概率角度),構建神經網絡針對目標函數對模型進行最優化,訓練的起點是使用神經網絡去搭建語言模型實現詞的預測任務,並且在優化過程後模型的副產品就是詞向量。

    • 進行神經網絡模型的訓練時,目標是進行詞的概率預測,就是在詞環境下,預測下一個該是什麼詞,目標函數如下式, 通過對網絡訓練一定程度後,最後的模型參數就可當成詞向量使用。

    • 最後關心的並不是輸出層的預測概率,而是通過BP+SGD得到的中間產物:最優投影矩陣C,將其作為文本表示矩陣。

  • 概率函數:\(f(w_{t},w_{t-1},…,w_{t-n+2}, w_{t-n+1})=p(w_{t} | {w_{1}}^{t-1})\)

  • 目標函數:img

    • 約束條件:image-20210118145038303
  • 訓練過程就是學習θ的最大似然, 其中R(θ) 是正則項。

  • 模型結構:

img

  • 模型分為兩部分:特徵映射和計算條件概率分佈

    • 特徵映射:對應結構圖中最底部的紫色虛線Matrix C

      • 目的是進行特徵降維,結果是將字典V中的單詞onehot特徵表示投影轉換到稠密詞向量表示,作為NNLM的輸入。

      img

    • 計算條件概率分佈:經過神經網絡的輸入層隱藏層後,經softmax做歸一化計算概率得到輸出層

      image-20210118145156054

  • 神經網絡結構

img

image-20210118145332072

直連矩陣W可以加快模型訓練速度,但對效果提升不大。直連可以合併詞向量不經過隱含層,直接右乘直連矩陣 W 得到 \(v \times 1\) 維輸出後與前述的 \(v \times 1\) 維輸出向相加,得到一個最終的 \(v \times 1\) 維輸出向量。

  • 模型訓練

image-20210118145411203

  • 流程梳理

image-20210118150555438

Word2Vec

  • CBOW

    • 獲得中間詞兩邊的的上下文,然後用周圍的詞去預測中間的詞,把中間詞當做y,把窗口中的其它詞當做x輸入,x輸入是經過one-hot編碼過的,然後通過一個隱層進行求和操作,最後通過激活函數softmax,可以計算出每個單詞的生成概率,接下來的任務就是訓練神經網絡的權重,使得語料庫中所有單詞的整體生成概率最大化,而求得的權重矩陣就是文本表示詞向量的結果。
    • 與NNLM的聯繫:
      • 移除前向反饋神經網絡中非線性的hidden layer,直接將中間層的Embedding layer與輸出層的softmax layer連接;
      • 忽略上下文環境的序列信息:輸入的所有詞向量均匯總到同一個Embedding layer;
      • 將Future words納入上下文環境
    • 模型結構

    img

    • 流程梳理

    image-20210118164239883

  • Skip-Gram

    • 通過當前詞來預測窗口中上下文詞出現的概率模型,把當前詞當做x,把窗口中其它詞當做y,依然是通過一個隱層接一個Softmax激活函數來預測其它詞的概率。
    • Skip-gram模型的本質是計算輸入word的input vector與目標word的output vector之間的餘弦相似度,並進行softmax歸一化。我們要學習的模型參數正是這兩類詞向量。
  • 優化tricks

    • 層次Softmax

      • 本質是把 N 分類問題變成 log(N)次二分類
      • hierarchical softmax 使用一顆二叉樹表示詞彙表中的單詞,每個單詞都作為二叉樹的葉子節點。對於一個大小為V的詞彙表,其對應的二叉樹包含V-1非葉子節點。假如每個非葉子節點向左轉標記為1,向右轉標記為0,那麼每個單詞都具有唯一的從根節點到達該葉子節點的由{0 1}組成的代號(實際上為哈夫曼編碼,為哈夫曼樹,是帶權路徑長度最短的樹,哈夫曼樹保證了詞頻高的單詞的路徑短,詞頻相對低的單詞的路徑長,這種編碼方式很大程度減少了計算量)。
      • 使用Huffman Tree來編碼輸出層的詞典,相當於平鋪到各個葉子節點上,瞬間把維度降低到了樹的深度,可以看如下圖所示。這課Tree把出現頻率高的詞放到靠近根節點的葉子節點處,每一次只要做二分類計算,計算路徑上所有非葉子節點詞向量的貢獻即可。
      • img
      • image-20210118165233683
    • 負例採樣(Negative Sampling)

      • 在正確單詞以外的負樣本中進行採樣,最終目的是為了減少負樣本的數量,達到減少計算量效果。將詞典中的每一個詞對應一條線段,所有詞組成了[0,1]間的剖分,如下圖所示,然後每次隨機生成一個[1, M-1]間的整數,看落在哪個詞對應的剖分上就選擇哪個詞,最後會得到一個負樣本集合。

      • 如果 vocabulary 大小為10000時, 當輸入樣本 ( “fox”, “quick”) 到神經網絡時, 「 fox」 經過 one-hot 編碼,在輸出層我們期望對應 「quick」 單詞的那個神經元結點輸出 1,其餘 9999 個都應該輸出 0。在這裡,這9999個我們期望輸出為0的神經元結點所對應的單詞我們為 negative word. negative sampling 的想法也很直接 ,將隨機選擇一小部分的 negative words,比如選 10個 negative words 來更新對應的權重參數。

        假設原來模型每次運行都需要300×10,000(其實沒有減少數量,但是運行過程中,減少了需要載入的數量。) 現在只要300×(1+10)減少了好多。

      • 選擇negative samples:常出現的高頻詞有更大的概率被選為負例。直接基於詞頻的權重分佈獲得概率分佈進行抽樣

      image-20210118170045700

Glove

GloVe的全稱叫Global Vectors for Word Representation,它是一個基於全局詞頻統計(count-based & overall statistics)的詞表徵(word representation)工具,它可以把一個單詞表達成一個由實數組成的向量,這些向量捕捉到了單詞之間一些語義特性,比如相似性(similarity)、類比性(analogy)等。我們通過對向量的運算,比如歐幾里得距離或者cosine相似度,可以計算出兩個單詞之間的語義相似性。

實現步驟

  • 構建共現矩陣

    根據語料庫(corpus)構建一個共現矩陣(Co-ocurrence Matrix)X,矩陣中的每一個元素 Xij 代表單詞 i 和上下文單詞 j 在特定大小的上下文窗口(context window)內共同出現的次數。一般而言,這個次數的最小單位是1,但是GloVe不這麼認為:它根據兩個單詞在上下文窗口的距離 d,提出了一個衰減函數(decreasing weighting):decay=1/d 用於計算權重,也就是說距離越遠的兩個單詞所佔總計數(total count)的權重越小

  • 構建詞向量和共現矩陣之間的近似關係

    • \(w_{i}^{T}\tilde{w_{j}} + b_i + \tilde{b_j} = \log(X_{ij}) \tag{1}\)
    • 其中,\(w_{i}^{T}\)\(\tilde{w_{j}}\)是我們最終要求解的詞向量;\(b_i\)\(\tilde b_j\)分別是兩個詞向量的bias term。
  • 構建損失函數

    \(J = \sum_{i,j=1}^{V} f(X_{ij})(w_{i}^{T}\tilde{w_{j}} + b_i + \tilde{b_j} – \log(X_{ij}) )^2 \tag{2}\)

image-20210118190523016

  • 流程梳理

image-20210118190638818

  • Glove與LSA、word2vec的比較

    LSA(Latent Semantic Analysis)是一種比較早的count-based的詞向量表徵工具,它也是基於co-occurance matrix的,只不過採用了基於奇異值分解(SVD)的矩陣分解技術對大矩陣進行降維,而我們知道SVD的複雜度是很高的,所以它的計算代價比較大。還有一點是它對所有單詞的統計權重都是一致的。而這些缺點在GloVe中被一一克服了。而word2vec最大的缺點則是沒有充分利用所有的語料,所以GloVe其實是把兩者的優點結合了起來。從這篇論文給出的實驗結果來看,GloVe的性能是遠超LSA和word2vec的,但網上也有人說GloVe和word2vec實際表現其實差不多。

文本分類模型

fastText

  • 思想

    • 將整篇文檔的詞及n-gram向量疊加平均得到文檔向量,然後使用文檔向量做softmax多分類。這中間涉及到兩個技巧:字符級n-gram特徵的引入以及分層Softmax分類。疊加詞向量背後的思想就是傳統的詞袋法,即將文檔看成一個由詞構成的集合。
    • 模型的前半部分,即從輸入層輸入到隱含層輸出部分:生成用來表徵文檔的向量。疊加構成這篇文檔的所有詞及n-gram的詞向量,然後取平均。疊加詞向量背後的思想就是傳統的詞袋法,即將文檔看成一個由詞構成的集合。
    • 模型的後半部分,即從隱含層輸出到輸出層輸出部分:是一個softmax線性多類別分類器,分類器的輸入是一個用來表徵當前文檔的向量。
    • 子詞嵌入(subword embedding),使用字符級別的n-grams表示一個單詞。
      • 例子:對於單詞「book」,假設n的取值為3,則它的trigram有:「<bo」, 「boo」, 「ook」, 「ok>」其中,<表示前綴,>表示後綴。於是,我們可以用這些trigram來表示「book」這個單詞。
  • 模型結構:與CBOW相似

    img

  • fastText與CBOW不同點

    • CBOW的輸入是目標單詞的上下文,fastText的輸入是多個單詞及其n-gram特徵,這些特徵用來表示單個文檔;

    • CBOW的輸入單詞被one-hot編碼過,fastText的輸入特徵是被embedding過;

    • CBOW的輸出是目標詞彙,fastText的輸出是文檔對應的類標。

    • 值得注意的是,fastText在輸入時,將單詞的字符級別的n-gram向量作為額外的特徵;在輸出時,fastText採用了分層Softmax,大大降低了模型訓練時間。

  • 分類效果

    • 用單詞的embedding疊加獲得的文檔向量,詞向量的重要特點就是向量的距離可以用來衡量單詞間的語義相似程度。
    • 使用詞embedding而非詞本身作為特徵,這是fastText效果好的一個原因;另一個原因就是字符級n-gram特徵的引入對分類效果會有一些提升 。
  • fastText與Word2Vec的異同

    • 相同點

      • 圖模型結構很像,都是採用embedding向量的形式,得到word的隱向量表達。
      • 都採用很多相似的優化方法,比如使用Hierarchical softmax優化訓練和預測中的打分速度。
    • 不同點

      • 層次softmax:CBOW的葉子節點是詞和詞頻,fasttext葉子節點裏是類標和類標的頻數。

      • image-20210118175159028

      • word2vec的目的是得到詞向量,該詞向量最終是在輸入層得到的,輸出層對應的h-softmax也會生成一系列的向量,但是最終都被拋棄,不會使用。

        fastText則充分利用了h-softmax的分類功能,遍歷分類樹的所有葉節點,找到概率最大的label

  • 代碼實現