【问题标题】:Gensim: Loss of Words/Tokens while TrainingGensim:训练时丢失单词/令牌
【发布时间】:2017-07-11 03:51:19
【问题描述】:

我有一个由存储在 sentences.txt 的 Wikimedia Dump 文件构建的语料库 我有一句话说'नीरजः हाँ माता जी! स्कूल ख़त्म होते सीधा घर आऊँगा'

现在,当我尝试提取词向量时,总会有一个或两个词在训练时遗漏(尽管包含在要训练的列表中)并且我得到了 KeyError。 有没有什么办法可以提高训练,使它不会经常漏词?

这是它确实发生的证据。 tok.wordtokenize 是一个词分词器。 sent.drawlist()sents.drawlist() 从存储在 sentences.txt 中的语料库中返回句子列表。


>>> sentence = 'नीरजः हाँ माता जी! स्कूल ख़त्म होते सीधा घर आऊँगा'
>>> sentence = tok.wordtokenize(sentence) #tok.wordtokenize() is simply a word tokenizer.
>>> sentences = sent.drawlist()
>>> sentences = [tok.wordtokenize(i) for i in sentences]
>>> sentences2 = sents.drawlist()
>>> sentences2 = [tok.wordtokenize(i) for i in sentences2]
>>> sentences = sentences2 + sentences + sentence
>>> "नीरजः" in sentences #proof that the word is present inside sentences
True
>>> sentences[0:10] #list of tokenized sentences.
[['विश्व', 'भर', 'में', 'करोड़ों', 'टीवी', 'दर्शकों', 'की', 'उत्सुकता', 'भरी', 'निगाह', 'के', 'बीच', 'मिस', 'ऑस्ट्रेलिया', 'जेनिफर', 'हॉकिंस', 'को', 'मिस', 'यूनिवर्स-२००४', 'का', 'ताज', 'पहनाया', 'गया'], ['करीब', 'दो', 'घंटे', 'चले', 'कार्यक्रम', 'में', 'विभिन्न', 'देशों', 'की', '८०', 'सुंदरियों', 'के', 'बीच', '२०', 'वर्षीय', 'हॉकिंस', 'को', 'सर्वश्रेष्ठ', 'आंका', 'गया'], ['मिस', 'अमेरिका', 'शैंडी', 'फिनेजी', 'को', 'प्रथम', 'उप', 'विजेता', 'और', 'मिस', 'प्यूरेटो', 'रिको', 'अल्बा', 'रेइज', 'द्वितीय', 'उप', 'विजेता', 'चुनी', 'गई'], ['भारत', 'की', 'तनुश्री', 'दत्ता', 'अंतिम', '१०', 'प्रतिभागियों', 'में', 'ही', 'स्थान', 'बना', 'पाई'], ['हॉकिंस', 'ने', 'कहा', 'कि', 'जीत', 'के', 'बारे', 'में', 'उसने', 'सपने', 'में', 'भी', 'नहीं', 'सोचा', 'था'], ['सौंदर्य', 'की', 'यह', 'शीर्ष', 'प्रतियोगिता', 'क्विटो', 'के', 'कन्वेंशन', 'सेंटर', 'में', 'मंगलवार', 'देर', 'रात', 'शुरू', 'हुई'], ['करीब', '७५००', 'विशिष्ट', 'दर्शकों', 'की', 'मौजूदगी', 'में', 'विश्व', 'की', 'सर्वश्रेष्ठ', 'सुंदरी', 'के', 'चयन', 'की', 'कवायद', 'शुरू', 'हुई'], ['हर', 'चरण', 'के', 'बाद', 'लोगों', 'की', 'सांसे', 'थमने', 'लगतीं'], ['टीवी', 'पर', 'लुत्फ', 'उठा', 'रहे', 'दर्शक', 'अपने', 'देश', 'व', 'क्षेत्र', 'की', 'सुंदरी', 'की', 'प्रतियोगिता', 'में', 'स्थिति', 'के', 'बारे', 'में', 'व्यग्र', 'रहे'], ['फाइनल', 'में', 'पहुंचने', 'वाली', 'पांच', 'प्रतिभागियों', 'में', 'मिस', 'पेराग्वे', 'यानिना', 'गोंजालेज', 'और', 'मिस', 'त्रिनिदाद', 'व', 'टोबैगो', 'डेनियल', 'जोंस', 'भी', 'शामिल', 'थीं']]
>>> model = gensim.models.Word2Vec(sentences, size =10,  min_count=1) 
>>> pred = []
>>> for word in sentence:
...         pred.append(model.wv[word].tolist())
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/home/djokester/anaconda3/lib/python3.5/site-packages/gensim/models/keyedvectors.py", line 574, in __getitem__
    return self.word_vec(words)
  File "/home/djokester/anaconda3/lib/python3.5/site-packages/gensim/models/keyedvectors.py", line 273, in word_vec
    raise KeyError("word '%s' not in vocabulary" % word)
KeyError: "word 'नीरजः' not in vocabulary"

如您所见,我在标记化句子列表中检查单词“नीरजः”。它出现在我输入 Word2Vec 训练器的列表中,但在训练后它不在词汇表中。

【问题讨论】:

    标签: python gensim word2vec


    【解决方案1】:

    它不应该“错过”标记化语料库中包含的单词,并且至少出现 min_count 次。因此,如果您收到KeyError,您可以确信在训练期间从未提供过相关的词标记。

    在您要重现的示例代码中,仔细查看:

    sentence = "Jack and Jill went up the Hill"
    sentence = [word_tokenize(i) for i in sentence]
    

    i in sentence 将是字符串的每个字符。您未显示的 word_tokenize() 函数不太可能对单个字符 ['J', 'a', 'c', 'k', ' ', ...] 做任何有用的事情 - 可能只是将它们作为字母列表留下。然后 +-将其附加到您的其他 sentences 使 sentences 长 30 个项目,而不是您期望的单个额外标记化示例。

    我怀疑您的真正问题不同但相关:标记化和组合有问题。因此,请分别检查每个步骤的预期结果和嵌套类型。 (每一步使用唯一变量,如sentences_tokenizedsentence_tokenized,而不是像sentencessentence 这样的重用变量,可以帮助调试。)

    按照您的建议更新:您最新代码的问题是您+-append 所在的行仍然错误;它将每个单词附加到句子中,就好像它是自己的新句子一样。查看每一步的结果——在可变的内容和长度中——应该有助于清楚这一点。此外,我再次建议在调试时不要在多个步骤中重用变量。 "नीरजः" in sentences #proof that the word is present inside sentences 这行实际上是在证明句子是错误的;那个单词不应该是sentences 中的一个项目,而应该是它的最后一个标记列表sentences[-1]

    【讨论】:

    • 请检查我的问题的编辑。在训练时确实会发生一些单词在词汇表中遗漏的情况。这是一个接近 770 万字的庞大语料库。
    • 您仍然在错误地处理新句子。您的代码是一堆未显示的函数(如word_tokenize()wordtokenize())和未显示的变量(如sents)。如果 Word2Vec 中存在错误,您可以使用单个文本复制它,而不会出现所有这些未显示的变量/函数的复杂性。
    • 为什么我不能使用自己的函数进行标记化?最初我使用了 NLTK 的 word_tokenizer,后来我使用了我自己的函数。这是一个标记器。而已!它工作得很好。如果您愿意,我可以显示一些发送,但我认为您并不急于回答这个问题。你要做的就是把责任推到我身上。当我说在大型语料库上训练时它会丢失,你只是拒绝相信我!
    • 我再次编辑了这个问题。 wordtokenizer() 只是一个标记器> 我在训练之前给你一个句子的预览。根据 word2vec 模型的要求,它是一个标记化句子的列表。查看更新后的代码库。
    • 此外,突出显示意外行为的真正来源(在这种情况下是您的代码)不是“推卸责任”,它只是正常的调试和回答。 Word2Vec 没有“遗漏”任何单词——您没有以正确的格式提供这些单词。没关系,掌握 Python 结构/可迭代对象的嵌套以及新类的 API 需要一段时间。但是我的原始答案已经在您的代码中找到了确切的 2 行错误 - sentence = [word_tokenize(i) for i in sentence] & 然后是 +-appending。但是,对原始“遗漏”理论的过于强烈的依恋使您无法专注于这两条线。
    猜你喜欢
    • 2018-11-11
    • 2019-10-27
    • 1970-01-01
    • 2022-01-03
    • 2019-03-02
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    相关资源
    最近更新 更多