標籤:

使用 Fisher Vector 得到文本向量

Klein B, Lev G, Sadeh G, et al. Associating neural word embeddings with deep image representations using fisher vectors[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2015: 4437-4446.

如何使用 Fisher Vector 得到文本向量編碼?

  1. 對 word2vec 詞向量矩陣做獨立成分分析,使得詞向量的每個維度都是相對獨立的,得到新的詞向量模型。

  2. 對於一個句子,使用新的詞向量模型對句子中的每個單詞分別進行向量編碼。

  3. 使用混合模型進行建模,然後使用 EM 演算法求得模型的參數 —— 均值和標準差。

  4. 對混合模型的參數求梯度,然後做歸一化得到 Fisher Vector。

  5. 對 Fisher Vector 作 PCA 降維,得到最終的文本向量編碼。

整個流程的示意圖如圖1.1所示,後面我們會分小結重點介紹流程中的1、2、3步。

1. 獨立成分分析 (ICA)

對 word2vec 詞向量矩陣做獨立成分分析,使得詞向量的每個維度都是相對獨立的,得到 word2vec_fca 模型。這裡的 word2vec 模型使用的是在 Google News 上訓練的詞向量模型。

  • 為什麼要讓詞向量的每個維度都是相對獨立的呢?這是因為混合模型假設輸入的每個維度都是獨立同分布的,這時候總概率可以表示成每個維度概率的乘積,大大地減少了計算量。

  • ICA 相比 PCA 的優點在於:適用於非高斯分布的數據集、能夠得到獨立同分布的特徵表示。ICA 的經典問題是雞尾酒會問題 —— 在酒會上多個人同時說話,怎麼區分出每個人分別說了什麼?

ICA 部分的處理代碼如下:

from gensim.models.word2vec import Word2VecwvModel = Word2Vec.load(static/word2vec-chi/word2vec_news.model)from sklearn.decomposition import FastICA, PCA# word2vec_test包含300000個單詞,每個單詞使用300維向量進行編碼# 這裡需要注意的是,辭彙表的大小(#samples)不能小於詞向量的維度(#features)#word2vec_test = np.random.randn(300000, 300)fca = FastICA(n_components=300, max_iter=100000)word2vec_new = fca.fit_transform(wvModel.wv.syn0)wvModel.wv.syn0 = word2vec_newwvModel.save(static/word2vec-chi/word2vec_fca.model)

n_components 是 ICA 處理後的維度,fit_transform(arr) 中 arr.shape 為 (辭彙表大小,詞向量維度)

論文中提到 "We found that peforming ICA without reducing the dimensionality of the 300D word2vec vectors helps performance",在作主成分分析的時候,不對詞向量降維,效果會比較好。得到的新詞向量模型的使用方法和原來的一樣。

ICA 部分的參考資料如下:

  • 獨立成分分析 (ICA):獨立成分分析Independent component analysis(ICA) 有一個 Python 實例對 ICA 進行講解

  • ICA 和 PCA 的區別在哪裡? 獨立成分分析 ( ICA ) 與主成分分析 ( PCA ) 的區別在哪裡?

2. 混合模型建模

得到新詞向量模型 word2vec_fca 後,對句子中的每個單詞分別進行向量編碼,然後使用一個混合模型進行建模,使用 EM 演算法求得模型的參數均值和標準差。混合模型建模能夠將長度不定的輸入轉換成一個固定長度的參數向量。

大部分文章介紹 Fisher Vector 混合模型的優點時都是與詞袋模型 (BOW) 進行比較。

  • 使用詞袋模型對 raw features 做一些預處理,然後使用 K-means 硬聚類方法,最後將聚類中心點作為特徵表示。硬聚類方法的缺點是:比如有一個點不屬於任何一個聚類中心,但是 K-means 仍然會把它強行劃分到一個聚類中心去。

  • 高斯混合模型是一個軟聚類方法,每個點 x_i 屬於第 k 個聚類中心的可能性是一個概率值。同時混合高斯模型相比於高斯模型,具有更強的表達能力。

混合模型建模部分的處理代碼如下:

from sklearn.mixture import GaussianMixturefor k, temp_1 in enumerate(sens): print processing: %d / %d %(k, len(sens)) #print temp_1.numpy().shape # 第一個值是句子包含的單詞數,第二個值是詞向量的維度 #n_components表示要使用多少個高斯模型,其值不能大於句子包含的單詞數! gm = GaussianMixture(n_components=len(temp_1), covariance_type=diag, max_iter=20, random_state=0) G = gm.fit(temp_1.numpy()) #print G.weights_.shape # (n_components, ) #print G.means_.shape # (n_components, 詞向量的維度) #print G.covariances_.shape # (n_components, 詞向量的維度)

G.weights_ 表示的是混合模型中的每個模型的權重。G.means_ 和 G.covariances_ 分別表示混合模型中每個模型的均值和標準差。有時候並不需要對 G.weights_ 求偏導,因此參數向量的大小為 2 X n_components X 詞向量的維度。論文中使用30個高斯模型,但是在我實際處理的時候,有些句子包含的單詞數小於30,導致代碼報錯,目前還沒有找到解決辦法。

混合模型建模部分的參考資料如下:

  • 一顆中二的哨牙博客 —— 高斯混合模型

3. 對參數向量求導並歸一化

梯度描述了當前樣本參數應當改變的方向,更有利於模型的學習。對 GMM 的權重、均值、標準差求偏導後,需要進行歸一化操作。由於是在概率空間中,與歐式空間的歸一化不同,需要引入 Fisher matrix 進行歸一化。

Fisher Vector 部分的參考資料如下:

  • 一顆中二的哨牙 —— Fisher Vector(2)

  • Fisher Vector 通俗學習:Fisher Vector 通俗學習

  • GMM 求導的兩篇文章:hal.inria.fr/hal-008304、Documentation > C API

  • Fisher Vector 的實現參考:github.com/KarcyLee/Fisgist.github.com/danonea

推薦閱讀:

機器學習總結-Logistic 回歸
集智漫畫:如何教女朋友人工智慧(一)
線性回歸和邏輯回歸代碼部分(五)
強化學習——環境庫OpenAI Gym

TAG:機器學習 |