由于后面几篇要讲解Word2Vec怎么用,因此笔者先训练好了一个Word2Vec模型。为了节约读者的时间,并且保证读者可以复现后面的结果,笔者决定把这个训练好的模型分享出来,用Gensim训练的。单纯的词向量并不大,但第一篇已经说了,我们要用到完整的Word2Vec模型,因此我将完整的模型分享出来了,包含四个文件,所以文件相对大一些。

提醒读者的是,如果你想获取完整的Word2Vec模型,又不想改源代码,那么Python的Gensim库应该是你唯一的选择,据我所知,其他版本的Word2Vec最后都是只提供词向量给我们,没有完整的模型

对于做知识挖掘来说,显然用知识库语料(如百科语料)训练的Word2Vec效果会更好。但百科语料我还在爬取中,爬完了我再训练一个模型,到时再分享。

模型概况 #

这个模型的大概情况如下:
$$\begin{array}{c|c}
\hline
\text{训练语料} & \text{微信公众号的文章,多领域,属于中文平衡语料}\\
\hline
\text{语料数量} & \text{800万篇,总词数达到650亿}\\
\hline
\text{模型词数} & \text{共352196词,基本是中文词,包含常见英文词}\\
\hline
\text{模型结构} & \text{Skip-Gram + Huffman Softmax}\\
\hline
\text{向量维度} & \text{256维}\\
\hline
\text{分词工具} & \text{结巴分词,加入了有50万词条的词典,关闭了新词发现}\\
\hline
\text{训练工具} & \text{Gensim的Word2Vec,服务器训练了7天}\\
\hline
\text{其他情况} & \text{窗口大小为10,最小词频是64,迭代了10次}\\
\hline
\end{array}$$

需要特别说明的是:公众号文章属于比较“现代”的文章,反映了近来的网络热点内容,覆盖面也比较广,因此文章相对来说还是比较典型的。对于分词,我用的是结巴分词,并且关闭了新词发现,这是宁可分少一些,也要分准一些。当然,自带的词典是不够的,笔者自己还整理了50万词条,词条来源有两部分:1、网络收集的词典合并;2、在公众号文章上做新词发现,人工筛选后加入到词典中。因此,分词的结果还算靠谱,而且包含了比较多的流行词,可用性较高。

训练代码 #

大家可以参考着改写,要注意,这里引入hashlib.md5是为了对文章进行去重(本来1000万篇文章,去重后得到800万),而这个步骤不是必要的。

#! -*- coding:utf-8 -*-

import gensim, logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

import pymongo
import hashlib

db = pymongo.MongoClient('172.16.0.101').weixin.text_articles_words
md5 = lambda s: hashlib.md5(s).hexdigest()
class sentences:
    def __iter__(self):
        texts_set = set()
        for a in db.find(no_cursor_timeout=True):
            if md5(a['text'].encode('utf-8')) in texts_set:
                continue
            else:
                texts_set.add(md5(a['text'].encode('utf-8')))
                yield a['words']
        print u'最终计算了%s篇文章'%len(texts_set)

word2vec = gensim.models.word2vec.Word2Vec(sentences(), size=256, window=10, min_count=64, sg=1, hs=1, iter=10, workers=25)
word2vec.save('word2vec_wx')

下载链接 #

链接: https://pan.baidu.com/s/1htC495U 密码: 4ff8

包含文件:word2vec_wx, word2vec_wx.syn1neg.npy, word2vec_wx.syn1.npy, word2vec_wx.wv.syn0.npy,4个文件都是Gensim加载模型所必需的。具体每个文件的含义我也没弄清楚,word2vec_wx大概是模型声明,word2vec_wx.wv.syn0.npy应该就是我们所说的词向量表,word2vec_wx.syn1.npy是隐层到输出层的参数(Huffman树的参数),word2vec_wx.syn1neg.npy就不大清楚了~

如果你只关心词向量,也可以下载C版本的格式(跟C版本Word2Vec兼容,只包含词向量):
链接: https://pan.baidu.com/s/1nv3ANLB 密码: dgfw

一些演示 #

主要随便演示一下该模型找近义词的结果。欢迎大家提出改进建议。

>>> import gensim
>>> model = gensim.models.Word2Vec.load('word2vec_wx')

>>> pd.Series(model.most_similar(u'微信'))
0 (QQ, 0.752506196499)
1 (订阅号, 0.714340209961)
2 (QQ号, 0.695577561855)
3 (扫一扫, 0.695488214493)
4 (微信公众号, 0.694692015648)
5 (私聊, 0.681655049324)
6 (微信公众平台, 0.674170553684)
7 (私信, 0.65382117033)
8 (微信平台, 0.65175652504)
9 (官方, 0.643620729446)

>>> pd.Series(model.most_similar(u'公众号'))
0 (订阅号, 0.782696723938)
1 (微信公众号, 0.760639667511)
2 (微信公众账号, 0.73489522934)
3 (公众平台, 0.716173946857)
4 (扫一扫, 0.697836577892)
5 (微信公众平台, 0.696847081184)
6 (置顶, 0.666775584221)
7 (公共账号, 0.665741920471)
8 (微信平台, 0.661035299301)
9 (菜单栏, 0.65234708786)

>>> pd.Series(model.most_similar(u'牛逼'))
0 (牛掰, 0.701575636864)
1 (厉害, 0.619165301323)
2 (靠谱, 0.588266670704)
3 (苦逼, 0.586573541164)
4 (吹牛逼, 0.569260418415)
5 (了不起, 0.565731525421)
6 (牛叉, 0.563843131065)
7 (绝逼, 0.549570798874)
8 (说真的, 0.549259066582)
9 (两把刷子, 0.545115828514)

>>> pd.Series(model.most_similar(u'广州'))
0 (东莞, 0.840889930725)
1 (深圳, 0.799216389656)
2 (佛山, 0.786817133427)
3 (惠州, 0.779960036278)
4 (珠海, 0.73523247242)
5 (厦门, 0.72509008646)
6 (武汉, 0.724122405052)
7 (汕头, 0.719602584839)
8 (增城, 0.713532209396)
9 (上海, 0.710560560226)

>>> pd.Series(model.most_similar(u'朱元璋'))
0 (朱棣, 0.857951819897)
1 (燕王, 0.853199958801)
2 (朝廷, 0.847517609596)
3 (明太祖朱元璋, 0.837111353874)
4 (赵匡胤, 0.835654854774)
5 (称帝, 0.835589051247)
6 (起兵, 0.833530187607)
7 (明太祖, 0.829249799252)
8 (太祖, 0.826784193516)
9 (丞相, 0.826457977295)

>>> pd.Series(model.most_similar(u'微积分'))
0 (线性代数, 0.808522999287)
1 (数学分析, 0.791161835194)
2 (高等数学, 0.786414265633)
3 (数学, 0.758676528931)
4 (概率论, 0.747221827507)
5 (高等代数, 0.737897276878)
6 (解析几何, 0.730488717556)
7 (复变函数, 0.715447306633)
8 (微分方程, 0.71503329277)
9 (微积分学, 0.704192101955)

>>> pd.Series(model.most_similar(u'apple'))
0 (banana, 0.79927945137)
1 (pineapple, 0.789698243141)
2 (pen, 0.779583632946)
3 (orange, 0.769554674625)
4 (sweet, 0.721074819565)
5 (fruit, 0.71402490139)
6 (pie, 0.711439430714)
7 (watermelon, 0.700904607773)
8 (apples, 0.697601020336)
9 (juice, 0.694036960602)

>>> pd.Series(model.most_similar(u'企鹅'))
0 (海豹, 0.665253281593)
1 (帝企鹅, 0.645192623138)
2 (北极熊, 0.619929730892)
3 (大象, 0.618502140045)
4 (鲸鱼, 0.606555819511)
5 (猫, 0.591019570827)
6 (蜥蜴, 0.584576964378)
7 (蓝鲸, 0.572826981544)
8 (海豚, 0.566122889519)
9 (猩猩, 0.563284397125)

>>> pd.Series(model.most_similar(u'足球'))
0 (篮球, 0.842746257782)
1 (足球运动, 0.819511592388)
2 (青训, 0.793446540833)
3 (排球, 0.774085760117)
4 (乒乓球, 0.760577201843)
5 (足球赛事, 0.758624792099)
6 (棒垒球, 0.750351667404)
7 (篮球运动, 0.746055066586)
8 (足球队, 0.74296438694)
9 (网球, 0.742858171463)

>>> pd.Series(model.most_similar(u'爸爸'))
0 (妈妈, 0.779690504074)
1 (儿子, 0.752222895622)
2 (奶奶, 0.70418381691)
3 (妈, 0.693783283234)
4 (爷爷, 0.683066487312)
5 (父亲, 0.673043072224)
6 (女儿, 0.670304119587)
7 (爸妈, 0.669358253479)
8 (爸, 0.663688421249)
9 (外婆, 0.652905225754)

>>> pd.Series(model.most_similar(u'淘宝'))
0 (淘, 0.770935535431)
1 (店铺, 0.739198565483)
2 (手机端, 0.728774428368)
3 (天猫店, 0.725838780403)
4 (口令, 0.721312999725)
5 (登录淘宝, 0.717839717865)
6 (淘宝店, 0.71473968029)
7 (淘宝搜, 0.697688698769)
8 (天猫, 0.690212249756)
9 (网店, 0.6820114851)

转载到请包括本文地址:https://kexue.fm/archives/4304

更详细的转载事宜请参考:《科学空间FAQ》

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

如果您需要引用本文,请参考:

苏剑林. (Apr. 03, 2017). 《【不可思议的Word2Vec】 2.训练好的模型 》[Blog post]. Retrieved from https://kexue.fm/archives/4304

@online{kexuefm-4304,
        title={【不可思议的Word2Vec】 2.训练好的模型},
        author={苏剑林},
        year={2017},
        month={Apr},
        url={\url{https://kexue.fm/archives/4304}},
}