开启美好的九月
最近在学习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)