我在尝试通过以下代码理解keras中的skipgrams()
函数
from keras.preprocessing.text import *from keras.preprocessing.sequence import skipgramstext = "I love money" #My test sentencetokenizer = Tokenizer()tokenizer.fit_on_texts([text])word2id = tokenizer.word_indexwids = [word2id[w] for w in text_to_word_sequence(text)]pairs, labels = skipgrams(wids, len(word2id),window_size=1)for i in range(len(pairs)): #Visualizing the result print("({:s} , {:s} ) -> {:d}".format( id2word[pairs[i][0]], id2word[pairs[i][1]], labels[i]))
对于句子”I love money”,我期望在keras中定义的窗口大小为1的情况下得到以下(context, word)
对:
([i, money], love)([love], i)([love], money)
根据我对Keras文档的理解,如果(word, 同一窗口内的词)
,它将输出标签1;如果(word, 词汇表中的随机词)
,则输出标签0。
由于我使用的是窗口大小为1,我期望以下对的标签为1:
(love, i)(love, money)(i, love)(money, love)
而以下对的标签应为0
(i, money)(money, i)
然而,代码给我的结果如下
(love , i ) -> 1(love , money ) -> 1(i , love ) -> 1(money , love ) -> 1 (i , i ) -> 0(love , love ) -> 0(love , i ) -> 0(money , love ) -> 0
为什么(love , i )
和(money , love )
对会被标记为0和1?还有(i, money)
和(money, i)
的结果在哪里?
我对标签0的理解是否有误?但似乎我对标签1的理解是正确的。
回答:
这是因为你的词汇量非常小:它是相同的("love", "i", "money")
词。因此,“词汇表中的随机词”总是来自同一句子,而且还来自同一上下文。
作为一个实验,你可以这样做:
text = "I love money" #My test sentencetext2 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " \ "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"tokenizer = Tokenizer()tokenizer.fit_on_texts([text, text2])...
基本上,让分词器知道文本中有更多词。你会看到负样本现在主要是从第二句话生成的,例如:
(i , sit ) -> 0(love , i ) -> 1(love , money ) -> 1(love , ut ) -> 0(love , sit ) -> 0(money , consectetur ) -> 0(money , love ) -> 1(i , love ) -> 1