1. 程式人生 > >Ubuntu下GloVe中文詞向量模型訓練

Ubuntu下GloVe中文詞向量模型訓練

開啟美好的九月

最近在學習textCNN進行文字分類,然後隨機生成向量構建embedding網路的分類效果不是很佳,便考慮訓練Glove詞向量來進行訓練,整個過程還是有遇到一些問題,希望懂的旁友能來指點下~

關於GloVe

GloVe,全稱是Global Vectors for Word Representation,是斯坦福大學提出的一種新的詞矩陣生成的方法,綜合運用詞的全域性統計資訊和區域性統計資訊來生成語言模型和詞的向量化表示。論文提出的方法融合了主流模型的優點:全域性矩陣分解(LSA)和區域性內容視窗(Word2vec),充分利用統計資訊使用詞共現矩陣中頻率非零的元素來訓練模型。
論文連結

http://www.cs.columbia.edu/~blei/seminar/2016_discrete_data/readings/PenningtonSocherManning2014.pdf
官網講解http://nlp.stanford.edu/projects/glove/
PS:官網上有詳細的說明,其中包括已經訓練好的詞向量模型供使用,在這裡我主要使用它的github程式碼訓練自己的語料

詞向量訓練

1.下載

官方的github程式碼:https://github.com/stanfordnlp/GloVe
進入上面的連線並下載整個檔案,如下:
此處輸入圖片的描述
閱讀其中的README檔案可以對其有一定的理解~
由於其中的程式碼是C的版本,所以在執行前務必確保ubuntu下有gcc

!

2.訓練詞向量模型

(1)進入當前的檔案路徑,輸入命令

make

可以看到資料夾中多了一個build的資料夾
(2)修改demo.sh的內容
此處輸入圖片的描述
原始碼中是預設是從網上下載一個語料text8,可以將其刪除,在語料上修改為自己的路徑(這裡需要說明下,中文語料需要先進行分詞以空格進行間隔)
然後有兩個引數需要注意,即向量維度和視窗值
(根據網上的資料顯示vector_size=300和window_size=8時效果最佳)
PS:不過在我的訓練過程中,300維的詞向量在轉換為embedding時檔案大於2G,一直報錯:

ValueError: Cannot create a tensor proto whose content is larger than 2GB.

(請各位大佬來指點下~)
(3)開始訓練,輸入命令

sh demo.sh

如無意外,最後可以得到一個vector.txt的檔案
(4)修改格式
為了能讓gensim呼叫模型,執行以下程式碼即可

import gensim
import shutil
from sys import platform

# 計算行數,就是單詞數
def getFileLineNums(filename):
    f = open(filename, 'r')
    count = 0
    for line in f:
        count += 1
    return count


# Linux或者Windows下開啟詞向量檔案,在開始增加一行
def prepend_line(infile, outfile, line):
    with open(infile, 'r') as old:
        with open(outfile, 'w') as new:
            new.write(str(line) + "\n")
            shutil.copyfileobj(old, new)


def prepend_slow(infile, outfile, line):
    with open(infile, 'r') as fin:
        with open(outfile, 'w') as fout:
            fout.write(line + "\n")
            for line in fin:
                fout.write(line)


def load(filename):
    num_lines = getFileLineNums(filename)
    gensim_file = 'glove_model.txt'
    gensim_first_line = "{} {}".format(num_lines, 200)
    # Prepends the line.
    if platform == "linux" or platform == "linux2":
        prepend_line(filename, gensim_file, gensim_first_line)
    else:
        prepend_slow(filename, gensim_file, gensim_first_line)

    model = gensim.models.KeyedVectors.load_word2vec_format(gensim_file, binary=False)

if __name__ == '__main__':
    load(vec_path)