我有一个庞大的语料库,需要花费超过3天的时间来构建词汇表。因此,我真的需要重复使用这些词汇。然而,随着新版本的出现,如下面的代码片段所示,这变得不可能了:
vocab = gensim.models.word2vec.Word2VecVocab(min_count=1, sorted_vocab=True)
vocab.scan_vocab(sentences, progress_per=PROGRESS_PER, trim_rule=None)
vocab.save(VOCAB_FILE_NAME)
#LATER
vocab = gensim.models.word2vec.Word2VecVocab.load(VOCAB_FILE_NAME)
#Word2VecVocab object doesn't keep total_words and corpus_count info
#it is now impossible for me to retrieve these values.
#These values are returned from scan_vocab instead of being saved as fields of the object
#Create an empty model.
model = gensim.models.word2vec.Word2Vec(min_count=MIN_COUNT, max_vocab_size=MAX_VOCAB_SIZE, seed=SEED, sg=SG, workers=WORKERS, size=SIZE)
#prepare the vocabulary. This step is also very confusing.
#I think prepare_vocab should belong to the model object since it actually modifies model's parameters
vocab.prepare_vocab(model.hs, model.negative, model.wv, min_count=MIN_COUNT, keep_raw_vocab=False)
#This part is even messier. There is no way I could have known what to do next without having to go thru the source code.
#model.build_vocab rescans the whole vocabulary again, rendering my first phase useless.
#instead, I have to use model.trainables.prepare_weights to have a workaround.
#Again, what does vocabulary=model.vocabulary do?
model.trainables.prepare_weights(model.hs, model.negative, model.wv, update=False, vocabulary=model.vocabulary)
#Now, most importantly, how do I set total_examples parameter? and why is it named differently?
#model.corpus_count returns zero, because the only way of setting it up is to use build_vocab, which will rescan the vocabulary
#since model.corpus_count is zero now, I get this error:
#File "/home/ahmed/anaconda3/lib/python3.5/site-packages/gensim/models/base_any2vec.py", line 135, in _job_producer
# epoch_progress = 1.0 * pushed_words / total_words
#ZeroDivisionError: float division by zero
#---
#there is no way I can get the total_words info from the vocabulary without scanning it again
model.train(sentences=sentences, total_examples=model.corpus_count, total_words=model.corpus_count, epochs=model.iter)
model.save(MODEL_FILE_NAME)
4条答案
按热度按时间vawmfj5a1#
你好@ahmedahmedov,感谢你的报告,这是一个API的问题(我不知道如何在不破坏向后兼容性的情况下以一种好的方式解决这个问题)。
@manneshiva有什么想法吗?
https://groups.google.com/forum/#!topic/gensim/BqWh3l6C5J0 - 类似的讨论
2o7dmzc52#
感谢回复。
我认为
Vocabulary
类需要修改为具有total_examples
和total_words
作为类字段,而不仅仅是返回这些值。其次,我认为
prepare_vocab
方法不属于Vocabulary
类,因为它修改了Model
类的字段。所以,如果Word2VecModel.prepare_vocab()
以一个Vocabulary
对象作为输入并修改其内部状态,设置Model.wv
以及其他字段,那么会更好。接下来,
model.vocabulary.make_cum_table(model.wv)
也应该成为prepare_vocabulary
方法的一部分。目前,我必须在调用prepare_vocabulary
之后手动执行它。总之,在我谦虚的观点中,API 需要修改以适应模块化的方法。也就是说,应该能够扫描(或构建)词汇表、更新词汇表、根据各种参数(唯一单词的数量、
min_count
、max_vocab_size
等)准备词汇表、创建模型、训练模型以及独立于彼此使用新语料库更新模型。目前,需要解决一些混乱的耦合问题。z31licg03#
CC @manneshiva@janpom -这是否与最近的重构有关?
f0ofjuux4#
我能否在这个项目中实现以下功能 -
最理想的是,我希望它具有以下特点:
原因 -
在我的项目中,我使用了一种图嵌入模型,需要创建一个词汇表,用于首先创建一个由相互关联的单词组成的图。这作为基础,使用比普通word2vec更好的采样策略来获得嵌入。如果我可以直接将词汇表对象传递到Word2Vec模型中,它将占用更少的内存。而不是重新构建它。这个功能将允许用户拥有更多的自由和集成的便利性。
我完全同意@ahmedahmedov的观点。