Keras Tokenizer方法到底能做什么?


74

有时,我们需要执行以下操作:

from keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer(num_words=my_max)

然后,我们总是吟诵此咒语:

tokenizer.fit_on_texts(text) 
sequences = tokenizer.texts_to_sequences(text)

尽管我(或多或少)了解了总的效果,但是无论我做了多少研究(显然包括文档),我都无法弄清楚每个人分别做什么。我想我从来没有见过一个没有另一个。

那么,每个做什么?在任何情况下,您会使用其中一个而不使用另一个吗?如果不是,为什么不将它们简单地组合成如下形式:

sequences = tokenizer.fit_on_texts_to_sequences(text)

很抱歉,如果我缺少明显的内容,但是我对此很陌生。


1
我发现与直觉相反的是,分词器的输出是整数序列,例如单词索引,而不是单个令牌的列表。实际上,它可以采用标记化文本(每种内容的标记列表),并输出整数序列tensorflow.org/api_docs/python/tf/keras/preprocessing/text/…
flow2k

Answers:


117

源代码

  1. fit_on_texts 根据文本列表更新内部词汇。该方法根据词频创建词汇索引。因此,如果给它类似“猫坐在垫子上”的字样。它将创建一个字典,word_index["the"] = 1; word_index["cat"] = 2它是单词->索引字典,因此每个单词都会获得一个唯一的整数值。0保留用于填充。因此,较低的整数表示更频繁的单词(通常前几个是停用词,因为它们出现的次数很多)。
  2. texts_to_sequences 将文本中的每个文本转换为整数序列。因此,它基本上采用了文本中的每个单词,并将其替换为word_index字典中相应的整数值。仅此而已,当然也不会涉及任何魔术。

为什么不合并它们?因为您几乎总是适合一次多次转换为序列。您将适合您的训练语料库,并word_index在训练/评估/测试/预测时使用完全相同的词典将实际文本转换为序列,以将其输入网络。因此,将这些方法分开是有意义的。


1
这样就全部在源代码中了!我想我看起来还不够努力...现在我明白了:适合-一次,顺序-很多!像往常一样生活和学习。谢谢。
Jack Fleeting)

@nuric感谢您的回复。但是,一些注意事项。根据官方文档,“0是保留索引,不会分配给任何单词。” 因此,在您的示例中,第一个单词索引将为1 keras.io/preprocessing/text。另一点是,默认过滤器会删除大部分标点符号,因此,仅当您从过滤器中删除标点符号时,它们才会在词汇表中最为频繁。
Nikita,

1
@Nikita感谢您指出这一点,我更新了答案以解决此问题。
nuric

49

通过示例在上述答案中添加更多内容,有助于更好地理解:

范例1

t  = Tokenizer()
fit_text = "The earth is an awesome place live"
t.fit_on_texts(fit_text)
test_text = "The earth is an great place live"
sequences = t.texts_to_sequences(test_text)

print("sequences : ",sequences,'\n')

print("word_index : ",t.word_index)
#[] specifies : 1. space b/w the words in the test_text    2. letters that have not occured in fit_text

Output :

       sequences :  [[3], [4], [1], [], [1], [2], [8], [3], [4], [], [5], [6], [], [2], [9], [], [], [8], [1], [2], [3], [], [13], [7], [2], [14], [1], [], [7], [5], [15], [1]] 

       word_index :  {'e': 1, 'a': 2, 't': 3, 'h': 4, 'i': 5, 's': 6, 'l': 7, 'r': 8, 'n': 9, 'w': 10, 'o': 11, 'm': 12, 'p': 13, 'c': 14, 'v': 15}

范例2

t  = Tokenizer()
fit_text = ["The earth is an awesome place live"]
t.fit_on_texts(fit_text)

#fit_on_texts fits on sentences when list of sentences is passed to fit_on_texts() function. 
#ie - fit_on_texts( [ sent1, sent2, sent3,....sentN ] )

#Similarly, list of sentences/single sentence in a list must be passed into texts_to_sequences.
test_text1 = "The earth is an great place live"
test_text2 = "The is my program"
sequences = t.texts_to_sequences([test_text1, test_text2])

print('sequences : ',sequences,'\n')

print('word_index : ',t.word_index)
#texts_to_sequences() returns list of list. ie - [ [] ]

Output:

        sequences :  [[1, 2, 3, 4, 6, 7], [1, 3]] 

        word_index :  {'the': 1, 'earth': 2, 'is': 3, 'an': 4, 'awesome': 5, 'place': 6, 'live': 7}

4
例子永远不会说谎!感谢您的出色回答。
Chintan

我有一个训练数据集和一个测试数据集都有两列:索引和已清除的文本。我想知道是否可以在两个数据帧之间执行append(),然后对附加集执行Tokenizer.fit_on_text(),而不是仅对训练对象执行。我想,如果我只想将文本转换成整数向量,其中每个整数代表所有使用的词汇表中的一个单词,那么最好先执行append(),因为当我执行text_to_sequence时,测试集中的向量将包含更多元素()。
Nachengue

9

让我们看看这行代码的作用。

tokenizer.fit_on_texts(文本)

例如,考虑句子“地球是一个很棒的生活场所”

tokenizer.fit_on_texts("The earth is an awesome place live") 适合[[1,2,3,4,5,6,7]]其中3->“ is”,6->“ place”,依此类推。

sequences = tokenizer.texts_to_sequences("The earth is an great place live")

返回[[1,2,3,4,6,7]]。

你看这里发生了什么。单词“ great”最初不适合使用,因此无法识别单词“ great”。意思是,可以在火车数据上单独使用fit_on_text,然后可以使用拟合的词汇索引来表示一组全新的单词序列。这是两个不同的过程。因此,这两行代码。


很好地了解缺失的单词“ great”。但是我们如何处理词汇表中没有的单词呢?
kkgarg
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.