利用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.88889926672 怔 0.887811601162 裘千仞 0.884677648544 >>>
利用这里训练好的模型,查看其训练效果:
>>> from gensim.models.deprecated.word2vec import Word2Vec C:\Python27\lib\site-packages\gensim\utils.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:\Python27\lib\site-packages\gensim\matutils.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,有时间再继续学习。