Hope is a dangerous thing, but I have it.


【实验分析】GloVe的使用

之前使用的是Word2Vec和一个现成的训练好的词向量,后来补充了一些实验,发现即使都是300维的word embedding,使用word2vec的效果也没有现成的实验结果好。后来看到很多文章用的GloVe的词向量,觉得可以用一下。

理论依据

GloVe是论文Glove: Global vectors for word representation中间提出来的,在写这篇博客的时候我还没看这篇文章,所以这部分过几天看完补上。

实验使用

GloVe的话pycharm安装是不成功的,无论是glove,还是glove-python,网上一些说法是它只支持mac和Linux系统,windows不适用。我也找了一些方法,github上好像也有改写的python版本,最后折腾了一圈还是选择官方给的代码:https://github.com/stanfordnlp/GloVe。至于我用的是windows系统,还懒了一下没有装双系统,但是突然想到实验室的服务器是linux的呀,所以也是在服务器上跑的,而且由于数据量不大,也很快就有结果了。

语料库生成

这里我要训练的语料库还是REN这个数据集,就大概是1000多条博客。事先我先使用一个python脚本把所有文件都读进来,分词,去标点(未去停用词),然后保存到一个corpus.txt文件中。具体代码如下:

import os
import re
import pickle
import data_helper
import numpy as np

if __name__ == "__main__":
    stopwords = data_helper.stopwordslist("./data/stopwords.txt")  # 去掉停用词

    # 标签
    labelpath = "./data/REN/label.txt"
    lfile = open(labelpath, 'r', encoding='UTF-8')
    labels = lfile.read().split('\n')
    lfile.close()

    labels = labels[0:1487]
    labels = [la.split() for la in labels]
    labels = [la[1:] for la in labels]
    labels = [[int(np.floor(float(l) * 100)) for l in la] for la in labels]

    # 文本
    textpath = "./data/REN/data.txt"
    tfile = open(textpath, 'r', encoding='UTF-8')
    texts = tfile.read().split('<d>')
    tfile.close()

    texts=texts[1:]
    texts = [re.sub(r"<doc_[0-9]*>", "", text) for text in texts]
    texts = [re.sub(r"\n", "", text) for text in texts]
    texts = [re.sub(r"( )+", "", text) for text in texts]

    totaltexts=data_helper.remove_words(texts, [], 1)

    f = open('./data/REN/corpus.txt', 'w', encoding='UTF-8')
    totaltexts=[' '.join(totaltext) for totaltext in totaltexts]
    totaltexts=' '.join(totaltexts)
    f.write(totaltexts)
    f.close()

GloVe语料库训练

这里我主要参照了博客:https://www.cnblogs.com/echo-cheng/p/8561171.html
   就是先将预处理后的语料库corpus.txt放到GloVe-master文件夹下,然后修改demo.sh文件,注释掉从网上下载的那一段,并修改下面的语料库地址。

# make
# if [ ! -e text8 ]; then
#   if hash wget 2>/dev/null; then
#     wget http://mattmahoney.net/dc/text8.zip
#   else
#     curl -O http://mattmahoney.net/dc/text8.zip
#   fi
#   unzip text8.zip
#   rm text8.zip
# fi

CORPUS=corpus.txt
VOCAB_FILE=vocab.txt
COOCCURRENCE_FILE=cooccurrence.bin
COOCCURRENCE_SHUF_FILE=cooccurrence.shuf.bin
BUILDDIR=build
SAVE_FILE=vectors
VERBOSE=2
MEMORY=4.0
VOCAB_MIN_COUNT=2
VECTOR_SIZE=300
MAX_ITER=15
WINDOW_SIZE=15
BINARY=2
NUM_THREADS=8
X_MAX=10

然后将文件传到服务器上面,运行命令。

make
bash demo.sh

GloVe词向量使用

得到的vector.txt文件就是词向量,打开文件,在开头加入一行:vacob_size vector_size。这个在运行输出中可以看到,然后这个文件就可以用gensim自带的word2vec的函数读取,具体如下:

def GloVe_embedding(modelpath):
    embeddingmodel = word2vec.Word2VecKeyedVectors.load_word2vec_format(modelpath, binary=False)

    wordsize = embeddingmodel.vector_size
    worddict = corpora.dictionary.Dictionary()
    worddict.doc2bow(embeddingmodel.wv.vocab.keys(), allow_update=True)
    wordindex = {v: k for k, v in worddict.items()}  # 词语的索引,从0开始编号
    wordvectordict = {word: embeddingmodel[word] for word in wordindex.keys()}  # 词语的词向量
    if '' not in wordindex.keys():
        wordindex[''] = len(wordindex.keys())
        wordvectordict[''] = np.zeros(wordsize)
    return wordindex, wordvectordict