• GloVe 教程之实战入门+python gensim 词向量


    前几天看论文,忽然看到了一个跟word2vec并列的词向量工具,这么厉害?还能跟word2vec相提并论?

    果断需要试试。

    GloVe 

    它来自斯坦福的一篇论文,GloVe全称应该是  Global  Vectors for Word Representation

    官网在此  http://nlp.stanford.edu/projects/glove/

    大概长这样,上面还有训练好的模型可以下载


    下面开始动手。

    官方的代码的GitHub在此 :  https://github.com/stanfordnlp/GloVe


    可以看到,这是个c的版本,并且跑在linux下。

    毕竟最爱的是python,首先想,有没有python版本的,GitHub上其实还真搜到了一个,不过看了一下,应该是哪个小伙伴自己写的,试了一下,发现一百句话的语料它的速度就已经慢得不能忍受了。我们是要面对至少几百M几个G的语料,显然这个是不能接受的。所以就不放链接了。

    那就只能用C的代码训练,然后再用python来处理结果。让人欣喜的是,GloVe训练的结果,是可以用gensim里面word2vec的load直接加载并且使用的,那就简单了。

    首先,找到一个linux系统的机器,把上面GitHub上的代码down下来。

    进入glove目录下,首先先参考README.txt,里面主要介绍这个程序包含了四部分子程序,按步骤分别是vocab_count、cooccur、shuffle、glove:

    1.vocab_count:用于计算原文本的单词统计(生成vocab.txt,每一行为:单词  词频)

    2.cooccur:用于统计词与词的共现,目测类似与word2vec的窗口内的任意两个词(生成的是cooccurrence.bin,二进制文件,呵呵)

    3. shuffle:对于2中的共现结果重新整理(一看到shuffle瞬间想到Hadoop,生成的也是二进制文件cooccurrence.shuf.bin)

    4.glove:glove算法的训练模型,会运用到之前生成的相关文件(1&3),最终会输出vectors.txt和vectors.bin(前者直接可以打开,下文主要针对它做研究,后者还是二进制文件)

    上面已经介绍了这个程序的执行流程,下面就具体训练出这个vectors.txt。

    首先二话不说,直接makefile,

    make

    就会多出来一个build文件夹

    然后再执行sh demo.sh就行了:

    sh demo.sh

    其中,可以再demo.sh里面,设置训练语料路径(默认是从网上下载一个语料,把这段删了,改成自己的语料路径就行了),还可以设置迭代次数,向量的维度等等,自己随便折腾就行了

    经历漫长的等待之后(取决于你的语料有多大,当然了,中文的话,记得分词)

    现在,得到了vectors.txt,这就是训练出来的词向量的结果。下面,我们看看怎么用python来加载并使用它。

    首先,默认已经装好python+gensim了,并且已经会用word2vec了。

    其实,只需要在vectors.txt这个文件的最开头,加上两个数,第一个数指明一共有多少个向量,第二个数指明每个向量有多少维,就能直接用word2vec的load函数加载了

    假设你已经加上这两个数了,那么直接

    # Demo: Loads the newly created glove_model.txt into gensim API.
    model=gensim.models.Word2Vec.load_word2vec_format(' vectors.txt',binary=False) #GloVe Model

    就行了,剩下的操作就跟word2vec一样了

    下面附上 这一段的完整代码(包括把 vectors.txt改成能load的格式,和加载模型)

    def load(filename):

    # Input: GloVe Model File
    # More models can be downloaded from http://nlp.stanford.edu/projects/glove/
    # glove_file="glove.840B.300d.txt"
    glove_file = filename

    dimensions = 300

    num_lines = getFileLineNums(filename)
    # num_lines = check_num_lines_in_glove(glove_file)
    # dims = int(dimensions[:-1])
    dims = 300

    print num_lines
    #
    # # Output: Gensim Model text format.
    gensim_file='glove_model.txt'
    gensim_first_line = "{} {}".format(num_lines, dims)
    #
    # # Prepends the line.
    if platform == "linux" or platform == "linux2":
    prepend_line(glove_file, gensim_file, gensim_first_line)
    else:
    prepend_slow(glove_file, gensim_file, gensim_first_line)

    # Demo: Loads the newly created glove_model.txt into gensim API.
    model=gensim.models.Word2Vec.load_word2vec_format(gensim_file,binary=False) #GloVe Model

    model_name = filename[5:-4]

    model.save('model\' + model_name)

    return model

    def getFileLineNums(filename):
    f = open(filename,'r')
    count = 0

    for line in f:

    count += 1
    return count

    def prepend_line(infile, outfile, line):
    """
    Function use to prepend lines using bash utilities in Linux.
    (source: http://stackoverflow.com/a/10850588/610569)
    """
    with open(infile, 'r') as old:
    with open(outfile, 'w') as new:
    new.write(str(line) + " ")
    shutil.copyfileobj(old, new)

    def prepend_slow(infile, outfile, line):
    """
    Slower way to prepend the line by re-creating the inputfile.
    """
    with open(infile, 'r') as fin:
    with open(outfile, 'w') as fout:
    fout.write(line + " ")
    for line in fin:
    fout.write(line)

    这是一段加载模型之后使用的例子,当然了,这个就跟word2vec一样了

    def load_model_and_use(model_name):
    model = gensim.models.Word2Vec.load('model/'+model_name)
    print len(model.vocab)
    word_list = [u'发烧',u'流感']

    for word in word_list:
    print word,'--'
    for i in model.most_similar(word, topn=10):
    print i[0],i[1]
    print ''

    结果如下

    83078
    发烧 --
    瘟疠 0.561131298542
    多无发 0.438511788845
    感冒 0.423784643412
    寒战 0.41094905138
    发冷 0.400202810764
    肌肉酸痛 0.394035518169
    畏寒 0.391746163368
    头痛 0.390283048153
    恶寒 0.387357711792
    石岐 0.385719358921


    流感 --
    芭比 0.693880617619
    嗜血 0.660785496235
    H1N1 0.543790698051
    肺炎 0.520848989487
    流行性感冒 0.517322063446
    副流感 0.51515519619
    甲型 0.495822429657
    肺炎球菌 0.491611480713
    H10N8 0.490446418524
    H3N2 0.486712753773


    这个是经典的那个 man - king, women -? 的例子

    for i in w2v_model.most_similar(positive=['肺炎', '肺'], negative=['胃炎']):
    print i[0],i[1]

    肺部 0.662135243416
    肺门区 0.556283473969
    通气 0.548550665379
    肺泡 0.529182732105
    肺气肿 0.525536477566
    慢阻 0.512038588524
    胸片 0.503533244133
    萎陷 0.502206265926
    肺透明膜病 0.498196214437
    肺段 0.492621898651

    可见,效果不太好,可能是语料太少的原因。

    关于word2vec模型的格式的探究,可见:
    http://blog.csdn.net/sscssz/article/details/51921392 

  • 相关阅读:
    leetcode 62. Unique Paths
    leetcode 345. Reverse Vowels of a String
    leetcode 344. Reverse String
    Centos7.4 kafka集群安装与kafka-eagle1.3.9的安装
    yarn调度器 FairScheduler 与 CapacityScheduler
    Hive性能优化
    HBase笔记
    Zookeeper笔记
    Hadoop组件详解(随缘摸虾)
    ubuntu18.04.2 hadoop3.1.2+zookeeper3.5.5高可用完全分布式集群搭建
  • 原文地址:https://www.cnblogs.com/wszme/p/14845879.html
Copyright © 2020-2023  润新知