在整个x_data上还是仅在train_data上对Keras fit_to_text更好?

The*_*odo 8 python tokenize keras

我有一个带有文本列的数据框。我将它们分成x_trainx_test

我的问题是,最好Tokenizer.fit_on_text()在整个x数据集上使用Keras的功能x_train

像这样:

tokenizer = Tokenizer()
tokenizer.fit_on_texts(x_data)
Run Code Online (Sandbox Code Playgroud)

要么

tokenizer.fit_on_texts(x_train)        # <- fixed typo
tokenizer.texts_to_sequences(x_train)
Run Code Online (Sandbox Code Playgroud)

有关系吗?我也必须x_test稍后再进行标记化,所以我可以只使用相同的标记化器吗?

Dan*_*ler 6

尽管此问题中的信息很好,但确实需要注意一些更重要的事情:

必须在训练和测试数据中使用相同的标记器

否则,每个数据集将有不同的标记。每个令牌生成器都有一个内部字典,该字典由创建fit_on_texts

不能保证训练和测试数据的相同单词和频率相同,因此每个数据集都会创建不同的字典,并且测试数据的所有结果都是错误的。

这也意味着您不能先fit_on_texts训练,然后fit_on_texts再训练:这将更改内部词典。

可能适合整个数据。但是,为“未知”字词(oov_token=True)保留令牌可能是一个更好的主意,在这种情况下,当您使用模型从未见过的字词查找新的测试数据时(这也需要用此令牌替换训练数据中的稀有字词) 。


用未知词测试令牌生成器:

以下测试表明,oov_token未设置时,令牌生成器将完全忽略未知单词。这可能不是一个好主意。未知词可能是句子中的关键词,而仅仅忽略它们可能比知道那里有未知词更糟糕。

import numpy as np
from keras.layers import *
from keras.models import Model
from keras.preprocessing.text import Tokenizer

training = ['hey you there', 'how are you', 'i am fine thanks', 'hello there']
test = ['he is fine', 'i am fine too']

tokenizer = Tokenizer()
tokenizer.fit_on_texts(training)

print(tokenizer.texts_to_sequences(training))
print(tokenizer.texts_to_sequences(test))
Run Code Online (Sandbox Code Playgroud)

输出:

[[3, 1, 2], [4, 5, 1], [6, 7, 8, 9], [10, 2]]
[[8], [6, 7, 8]]
Run Code Online (Sandbox Code Playgroud)

现在,这表明令牌生成器会将索引1赋予所有未知单词:

tokenizer2 = Tokenizer(oov_token = True)
tokenizer2.fit_on_texts(training)
print(tokenizer2.texts_to_sequences(training))
print(tokenizer2.texts_to_sequences(test))
Run Code Online (Sandbox Code Playgroud)

输出:

[[4, 2, 3], [5, 6, 2], [7, 8, 9, 10], [11, 3]]
[[1, 1, 9], [7, 8, 9, 1]]
Run Code Online (Sandbox Code Playgroud)

但是在训练数据中也将一组稀有词也替换为1可能很有趣,因此您的模型具有如何处理未知词的概念。

  • @xicocaio将数据集分为训练和测试的主要思想是以一种过时的方式评估模型,以应对未来未知的情况。就是说,如果您将令牌生成器适合整个数据集,那么您将在某种程度上偏向模型。为了对模型进行良好的评估,您必须考虑UNK令牌。因此,与任何其他类型的“功能提取”一样,最佳做法是仅适用于培训并适用于所有人。 (3认同)