主要参考:https://www.jianshu.com/p/52ee8c5739b6(Gensim Word2vec 使用指南)
https://rare-technologies.com/word2vec-tutorial/ (Word2vec Tutorial)
作为自己复习使用。
Gensim
Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。
它支持包括TF-IDF,LSA,LDA,和word2vec在内的多种主题模型算法,
支持流式训练,并提供了诸如相似度计算,信息检索等一些常用任务的API接口
word2vec
参考:
https://zhuanlan.zhihu.com/p/22477976
一句理解 word2vec
一句话,word2vec就是用一个一层的神经网络(CBOW的本质)把one-hot形式的词向量映射为分布式形式的词向量,为了加快训练速度,用了Hierarchical softmax,negative sampling 等trick。
概念
文本表示/词向量
- 1-of-N的one-hot方式
- 分布式词向量(distributed word representation)
分布式词向量是一个固定大小的实数向量,事前确定它的大小比如N=300维或者N=1000维,每个元素都是一个实数,实数的具体值是词库里面每个词通过不同的贡献得来的,所以叫分布式的。而word2vec就是一种学习这个分布式词向量的算法。
分布式词向量并不是word2vec的作者发明的,他只是提出了一种更快更好的方式来训练也就是:连续词袋模型Continous Bag of Words Model(CBOW)和Skip-Gram Model
代码
输入
Gensim Word2vec 使用一个句子序列作为其输入,每个句子包含一个单词列表。
sentences = [['first', 'sentence'], ['second', 'sentence']]
# train word2vec on the two sentences
model = gensim.models.Word2Vec(sentences, min_count=1)
用 Python 内置的 list 类型作为输入很方便,但当输入内容较多时,会占用很大的内存空间。Gemsim 的输入只要求序列化的句子,而不需要将所有输入都存储在内存中。简单来说,可以输入一个句子,处理它,删除它,再载入另外一个句子。
class MySentences(object):def __init__(self, dirname):self.dirname = dirnamedef __iter__(self):for fname in os.listdir(self.dirname):for line in open(os.path.join(self.dirname, fname)):yield line.split()sentences = MySentences('/some/directory') # a memory-friendly iterator
model = gensim.models.Word2Vec(sentences)
主要参数:
- min_count
修剪内部字典树的,合理的范围是0 - 100
- size
神经网络 NN 层单元数,它也对应了训练算法的自由程度。
更大的 size 值需要更多的训练数据,但也同时可以得到更准确的模型。合理的取值范围是几十到几百。
- workers
训练并行粒度,用来加速训练。
输出(内存)
在内部,Word2vec 模型的参数以矩阵形式存储(NumPy 数组),数组的大小为 vocabulary 乘以 size 的浮点数 (4 bytes)。
三个如上的矩阵被存储在内存中(将其简化为两个或一个的工作进行中)。如果输入中存在 100,000 个互异的词,神经网络规模 size 设为200,则该模型大致需要内存
100,000 * 200 * 3 * 4 bytes = ~229MB。
模型储存和载入
model.save('/tmp/mymodel')
new_model = gensim.models.Word2Vec.load('/tmp/mymodel')
应用
相似度查询:
model.most_similar(positive=['woman', 'king'], negative=['man'], topn=1)
[('queen', 0.50882536)]
model.doesnt_match("breakfast cereal dinner lunch";.split())
'cereal'
model.similarity('woman', 'man')
0.73723527
可以这样查询词向量:
model['computer'] # raw NumPy vector of a word
array([-0.00449447, -0.00310097, 0.02421786, ...], dtype=float32)
-----------------——————————
主要类:KeyedVectors
主要模块:model.wv
model.wv.vocab
model.wv.syn0
model.wv.index2word
model.wv.vectors
小结:
输入:装有单词列表/序列的列表
(输入的是包含单词列表的句子序列,返回的是一个固定维度的每一个单词的词向量。)
输出:大小为**互异词的数量 * size(神经网络规模)**的numpy数组