当前位置: 代码迷 >> 综合 >> 初识 gensim 之 word2vec
  详细解决方案

初识 gensim 之 word2vec

热度:80   发布时间:2023-12-15 06:05:45.0

主要参考: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数组

  相关解决方案