zoukankan      html  css  js  c++  java
  • 利用python中的gensim模块训练和测试word2vec

    word2vec的基础知识介绍参考上一篇博客和列举的参考资料。

    首先利用安装gensim模块,相关依赖如下,注意版本要一致:

        Python >= 2.7 (tested with versions 2.7, 3.5 and 3.6)
        NumPy >= 1.11.3
        SciPy >= 0.18.1
        Six >= 1.5.0
        smart_open >= 1.2.1

    我们利用jieba分词对《射雕英雄传》进行分词,然后训练词向量,最后进行测试

    # -*- coding: utf-8-*-
    import jieba
    from gensim.models import word2vec
    
    #  去掉中英文状态下的逗号、句号
    def clearSen(comment):
        comment = ' '.join(comment).replace('', '').replace('', '').replace('', '').replace('', '')  .replace('', '').replace('', '').replace('', '').replace('', '').replace('', '').replace('', '')  .replace('', '').replace('', '').replace('', '').replace('', '').replace('', '')  .replace('', '') # 去掉标点符号
        return comment
    
    # 用jieba进行分词
    comment = open(u'./corpus/金庸-射雕英雄传txt精校版.txt').read()
    comment = clearSen(comment)
    #jieba.load_userdict('./user_dict/userdict_food.txt')
    comment = ' '.join(jieba.cut(comment))
    #print comment
    
    
    # 分完词后保存到新的txt中
    fo = open("./corpus/afterSeg.txt","w")
    fo.write(comment.encode('utf-8'))
    print("finished!")
    fo.close()
    
    # 用 word2vec 进行训练
    sentences=word2vec.Text8Corpus(u'./corpus/afterSeg.txt')
    # 第一个参数是训练语料,第二个参数是小于该数的单词会被剔除,默认值为5, 第三个参数是神经网络的隐藏层单元数,默认为100
    model=word2vec.Word2Vec(sentences,min_count=3, size=50, window=5, workers=4)
    #------------------------------------------------------------------------
    # Word2vec有很多可以影响训练速度和质量的参数:
    # (1) sg=1是skip-gram算法,对低频词敏感,默认sg=0为CBOW算法,所以此处设置为1。
    # (2) min_count是对词进行过滤,频率小于min-count的单词则会被忽视,默认值为5。
    # (3) size是输出词向量的维数,即神经网络的隐藏层的单元数。值太小会导致词映射因为冲突而影响结果,值太大则会耗内存并使算法计算变慢,大的size需要更多的训练数据, 但是效果会更好,在本文中设置的size值为300维度。
    # (4) window是句子中当前词与目标词之间的最大距离,即为窗口。本文设置窗口移动的大小为5。
    # (5) negative和sample可根据训练结果进行微调,sample表示更高频率的词被随机下采样到所设置的阈值,默认值为1e-3。
    # (6) hs=1表示层级softmax将会被使用,默认hs=0且negative不为0,则负采样将会被选择使用。
    # (7) 最后一个主要的参数控制训练的并行:worker参数只有在安装了Cython后才有效,由于本文没有安装Cython的, 使用的单核。
    #------------------------------------------------------------------------
    
    # 保存模型
    model.save("word2vec.model")
    model.wv.save_word2vec_format("word2vec.model.bin", binary=True)
    
    #测试
    y2=model.similarity(u"郭靖", u"黄蓉") #计算两个词之间的余弦距离
    print u"郭靖", u"黄蓉", 'similarity:',y2
    
    for i in model.most_similar(u"黄蓉"): #计算余弦距离最接近“黄蓉”的10个词
        print i[0],i[1]
        
    for i in model.most_similar(u"郭靖"): #计算余弦距离最接近“郭靖”的10个词
        print i[0],i[1]
    # 训练词向量时传入的两个参数也对训练效果有很大影响,需要根据语料来决定参数的选择,好的词向量对NLP的分类、聚类、相似度判别等任务有重要意义

    加载保存的模型,进行测试:

    >>> from gensim.models import word2vec
    >>> model = word2vec.Word2Vec.load('word2vec.model')
    >>> for e in model.most_similar(u"郭靖"): print e[0], e[1]
    ...
    黄蓉 0.978638648987
    欧阳克 0.95745909214
    欧阳锋 0.954400420189
    梅超风 0.925759136677
    郑重 0.914724588394
    裘千仞 0.907471776009
    众人 0.906147062778
    彭连虎 0.903428137302
    柯镇恶 0.902874648571
    梁子翁 0.893080115318
    >>> for e in model.most_similar(u"黄蓉"): print e[0], e[1]
    ...
    郭靖 0.978638589382
    欧阳锋 0.941402435303
    欧阳克 0.937647461891
    柯镇恶 0.913198530674
    郑重 0.898928642273
    梅超风 0.895552039146
    杨康 0.890073120594
    穆念慈 0.888899266720.887811601162
    裘千仞 0.884677648544
    >>>

    利用这里训练好的模型,查看其训练效果:

    >>> from gensim.models.deprecated.word2vec import Word2Vec
    C:Python27libsite-packagesgensimutils.py:1212: UserWarning: detected Windows; aliasing chunkize to chunkize_serial
      warnings.warn("detected Windows; aliasing chunkize to chunkize_serial")
    >>> model = Word2Vec.load('./model/Word60.model')
    >>> for e in model.most_similar(u"朝阳区"): print e[0], e[1]
    ...
    C:Python27libsite-packagesgensimmatutils.py:737: FutureWarning: Conversion of the second argument of issubdtype from `int` to `np.signedinteger` is deprecated. In future, it will be treated as `np.int32 == np.dtype(int).type`.
      if np.issubdtype(vec.dtype, np.int):
    海淀区 0.953941822052
    丰台区 0.940896630287
    石景山区 0.928724527359
    东城区 0.90411567688
    大兴区 0.887912631035
    西城区 0.885163784027
    崇文区 0.872635483742
    济南市 0.868344843388
    海淀 0.866064548492
    通州区 0.860960006714
    >>>
    >>> for e in model.most_similar(u"郭靖"): print e[0], e[1]
    ...
    黄蓉 0.947447776794
    杨过 0.939437627792
    段誉 0.930292785168
    令狐冲 0.928993582726
    张无忌 0.921128869057
    周伯通 0.918897628784
    黄药师 0.918717026711
    杨康 0.913613200188
    小龙女 0.911328673363
    乔峰 0.908709168434
    >>>
    >>> for e in model.most_similar(u"黄蓉"): print e[0], e[1]
    ...
    郭靖 0.947447776794
    杨过 0.942064762115
    张无忌 0.929110050201
    令狐冲 0.925551056862
    杨康 0.922640800476
    小龙女 0.92034471035
    段誉 0.915760040283
    赵敏 0.914794445038
    黄药师 0.910506725311
    韦小宝 0.909034609795
    >>> model.similarity(u"郭靖", u"黄蓉") #计算两个词之间的余弦距离
    0.9474477

    补充,word2vec是自然语言处理基础知识,实现了词向量表达。在此基础上可以完成分类、推荐等。

    本片文章是通过gensim来完成word2vec,上篇博客中参考资料也有通过TensorFlow实现word2vec。

    还有一些词向量的模型,看到https://www.cnblogs.com/royhoo/p/Advanced-Word-Vector-Representations.html介绍了GloVe,有时间再继续学习。

  • 相关阅读:
    多线程频繁上锁同步还不如用单线程
    1分钟左右随机生成2000万行随机字符串
    语言:抽象,封装,底层,低级
    构建WDK驱动出现fatal error U1087: cannot have : and :: dependents for same target
    Cmake编译成静态库
    VMware虚拟机相关文件问题
    输出流重定向
    How can I let the compiled script depend on something dynamic
    应用服务攻击工具clusterd
    Kali Linux缺少ifconfig命令
  • 原文地址:https://www.cnblogs.com/Micang/p/10274574.html
Copyright © 2011-2022 走看看