【问题标题】:[Word2Vec][gensim] Handling missing words in vocabulary with the parameter min_count[Word2Vec][gensim] 使用参数 min_count 处理词汇表中的缺失词
【发布时间】:2020-03-17 17:05:46
【问题描述】:

有人就这个话题提出了一些类似的问题,但我对到目前为止的回复并不满意;请先原谅我。

我正在使用python库gensim中的函数Word2Vec

我的问题是,只要我将参数min_count 设置为大于一,我就无法在我的语料库的每个单词上运行我的模型。有人会说这是合乎逻辑的,因为我选择忽略只出现一次的单词。但是这个函数的行为很奇怪,因为它给出了一个错误,说单词'blabla'不在词汇表中,而这正是我想要的(我想要这个词词汇表之外)。

我可以想象这不是很清楚,然后在下面找到一个可重现的示例:

import gensim
from gensim.models import Word2Vec

# My corpus
corpus=[["paris","not","great","city"],
       ["praha","better","great","than","paris"],
       ["praha","not","country"]]

# Load a pre-trained model - The orignal one based on google news 
model_google = gensim.models.KeyedVectors.load_word2vec_format(r'GoogleNews-vectors-negative300.bin', binary=True)

# Initializing our model and upgrading it with Google's 
my_model = Word2Vec(size=300, min_count=2)#with min_count=1, everything works fine
my_model.build_vocab(corpus)
total_examples = my_model.corpus_count
my_model.build_vocab([list(model_google.vocab.keys())], update=True)
my_model.intersect_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True, lockf=1.0)
my_model.train(corpus, total_examples=total_examples, epochs=my_model.iter)

# Show examples
print(my_model['paris'][0:10])#works cause 'paris' is present twice
print(my_model['country'][0:10])#does not work cause 'country' appears only once

例如,您可以找到 Google 的模型 there,但您可以随意使用任何模型或干脆不用,这不是我帖子的重点。

如代码注释中所述:在“paris”上运行模型有效,但在“country”上无效。当然,如果我将参数min_count 设置为1,一切正常。

我希望它足够清楚。

谢谢。

【问题讨论】:

  • 尚不清楚您的示例代码遇到了什么错误。 (您之前显示的错误片段,关于一个词 'blabla',与您以后的代码不匹配。)您能否在问题中准确显示您遇到的错误以及完整的错误堆栈?
  • 而且,目前还不清楚您希望发生什么。如果您选择了一个参数来丢弃某些单词,那么在模型中访问这些单词的任何尝试(例如my_model['country']应该引发错误。这是正确的行为。您不应该尝试在模型中查找已知不存在(甚至可能不存在)的单词并期望没有错误。 (您可以事先检查它们是否存在,或者选择捕捉潜在错误并适应缺席。)
  • 另请注意:.intersect_word2vec_format() 方法有些实验性,并且从不扩展词汇表。而且我认为您的.build_vocab(…, update=True)min_count=2 时没有任何明显的效果,因为list(model_google.vocab.keys()) 中的每个新词都出现一次(失败min_count)。更一般地说,像这样添加一堆外部单词,然后只训练你的一小部分,不太可能有用:训练将单词移动到仅与共同训练的单词相比有意义的地方,与导入的单词进行比较 -但未经训练的话可能是荒谬的。
  • @gojomo 非常感谢您的回复。我将尝试逐个回答您的 cmets。 1 - 只需将 'blabla' 替换为 'country' 即可获得错误的核心(要让完整内容运行我分享的可重现示例,我的帖子已经太长,哈哈)。 2-最终目标是将单词转换为向量,所以如果我在包含我的单词的整个 pandas 列上运行模型,那么它会失败,因为有些单词只出现一次,从这个意义上说它是不正确的。 3-我不确定是否理解,它看起来超出了主题,但我想理解

标签: python nlp gensim word2vec word-embedding


【解决方案1】:

如果您要求一个不存在的单词,它应该会引发错误,因为您选择不学习稀有单词的向量,例如您的示例中的'country'。 (而且:这些例子很少的词通常不会得到好的向量,并且保留它们会使剩余词的向量恶化,所以min_count 尽可能大,并且可能比1 大得多,通常是好主意。)

解决方法是执行以下操作之一:

  1. 不要询问不存在的词。首先通过 Python 的 in 运算符进行检查。例如:
if 'country' in my_model:
    print(my_model['country'][0:10])
else: 
    pass  # do nothing, since `min_count=2` means there's no 'country' vector
  1. 抓住错误,回退到你想要发生的任何事情:
try:
    print(my_model['country'][0:10])
except:
    pass  # do nothing, or perhaps print an error, whatever
  1. 更改为使用始终为任何单词返回某些内容的模型,例如 FastText - 它将尝试使用在训练期间学习的子单词为未知单词合成一个向量。 (这可能是垃圾,如果未知词在字符和含义上与已知词高度相似可能会很好,但对于某些用途来说,它总比没有好。)

【讨论】:

  • 非常感谢您的回复。最后,我做了try/except,我很惊讶这没有在函数中本地处理(可能有警告)。关于您的最后一点,您建议我构建自己的向量(使用FastTextWord2Vec,等等)还是将其与使用更大语料库的预训练模型“混合”?为什么?谢谢
  • [](__getitem__())和in(__contains__)的函数处理的,你可以询问是否存在词向量,或者请求一个词的向量。如果您请求一个不存在的单词,则会通过运行raise KeyError() 在支持代码中本地处理 - 请参阅github.com/RaRe-Technologies/gensim/blob/…。唯一的其他选择是返回一个表示“不存在”的标志值,这将需要您(调用者)进行同样多的额外检查/分支代码,才能根据您的需要做正确的事情。
  • 训练你自己的向量,如果可能的话,使用足够数量和种类的文本来展示你的问题领域中的单词用法。从其他地方导入的词向量可能不会强调它们在您的域中存在的词相互关系,并且如您所尝试的那样,导入然后只训练一些词,可能会导致单词继续训练脱离兼容与未调整的导入词对齐。
  • 再次感谢。仅供参考,我尝试了 3 种方法:训练我自己的向量、使用外部模型(著名的 Google 模型)以及我向您展示的模型。最后两种方法得到或多或少相同的结果(我正在做二进制分类),第一种得到非常糟糕的结果(可能是因为语料库很小 - 大约 7k 条推文)
  • 7k 条推文可能只有 140k 字?是的,这对于训练有用的 word2vec 模型来说太小了。但是世界上有超过 7k 条推文,因此找到 700 万或 7000 万条推文(或具有相似语言用法的类似推文的话语)来训练您的词向量应该不是不可能的。
猜你喜欢
  • 1970-01-01
  • 2017-07-19
  • 2016-06-06
  • 2023-03-24
  • 2019-07-07
  • 2021-06-26
  • 1970-01-01
  • 2016-09-08
  • 2022-01-03
相关资源
最近更新 更多