我在大约 750k 个单词的文本上运行了一个 word2vec 算法(在删除一些停用词之前(。使用我的模型,我开始查看与我选择的特定单词最相似的单词,并且相似性得分(对于model.wv.most_similar方法(都非常接近 1。第十个最接近的分数仍然是 .998,所以我觉得我在单词的相似性之间没有任何显着差异,从而导致无意义的相似单词。
我的模型构造函数是
model = Word2Vec(all_words, size=75, min_count=30, window=10, sg=1)
我认为问题可能在于我如何构建运行神经网络的文本。我存储所有单词如下:
all_sentences = nltk.sent_tokenize(v)
all_words = [nltk.word_tokenize(sent) for sent in all_sentences]
all_words = [[word for word in all_words[0] if word not in nltk.stopwords('English')]]
。其中 v 是在 txt 文件上调用 read(( 的结果。
您是否在将其传递给Word2Vec
之前查看过all_words
,以确保它包含您期望的语料库的大小和种类?(最后一个停用词剥离步骤看起来只会在第一句话上运行,all_words[0]
。
此外,您是否在INFO
级别启用了日志记录,并观察了模型最终词汇量和训练进度指标的输出,以检查这些值是否符合预期?
请注意,删除停用词对于 word2vec 训练并不是绝对必要的。它们的存在并没有太大的伤害,并且由sample
参数控制的默认频繁单词缩减采样已经用于经常忽略非常频繁的单词,如停用词。
(此外,对于小型语料库来说,min_count=30
相当激进。
根据我的知识,我推荐以下内容:
使用sg=0
使用连续词袋模型而不是 skip-gram 模型。CBOW在较小的数据集上更好。skip-gram模型在官方论文中进行了超过10亿字的训练。- 使用
min_count=5
这是他们在论文中使用的那个,他们有10亿。我认为 30 对您的数据来说太多了。 - 不要删除停用词,因为它会更改移动窗口中的相邻词。 例如,
- 使用更多迭代,例如
iter=10
。 - 使用
gensim.utils.simple_preprocess
而不是word_tokenize
,因为在这种情况下标点符号没有帮助。 - 另外,我建议将您的数据集拆分为段落而不是句子,但我不知道这是否适用于您的数据集
执行以下步骤时,您的代码应为:
>>> from gensim.utils import simple_preprocess
>>> all_sentences = nltk.sent_tokenize(v)
>>> all_words = [simple_preprocess(sent) for sent in all_sentences]
>>> # define the model
>>> model = Word2Vec(all_words, size=75, min_count=5, window=10, sg=0, iter=10)