Keras fit_to_text 是在整个 x_data 上更好还是仅在 train_data 上更好?
Is it better to Keras fit_to_text on the entire x_data or just the train_data?
我有一个包含文本列的数据框。我把它们分成 x_train
和 x_test
.
我的问题是在整个 x
数据集上做 Keras 的 Tokenizer.fit_on_text()
还是只做 x_train
更好?
像这样:
tokenizer = Tokenizer()
tokenizer.fit_on_texts(x_data)
或
tokenizer.fit_on_texts(x_train) # <- fixed typo
tokenizer.texts_to_sequences(x_train)
重要吗?我也必须稍后对 x_test
进行分词,所以我可以只使用相同的分词器吗?
虽然中的信息很好,但确实还有更重要的事情需要注意:
You MUST use the same tokenizer in training and test data
否则,每个数据集会有不同的标记。每个分词器都有一个使用 fit_on_texts
.
创建的内部字典
不能保证训练数据和测试数据具有相同频率的相同单词,因此每个数据集都会创建不同的词典,并且测试数据的所有结果都是错误的。
这也意味着您不能 fit_on_texts
,训练然后再次 fit_on_texts
:这将更改内部字典。
可以拟合整个数据。但是,为“未知”词 (oov_token=True
) 保留一个标记可能是一个更好的主意,因为当您发现新的测试数据包含您的模型从未见过的词时(这需要您替换训练数据中的稀有词)也有这个令牌)。
正如@Fernando H 提到的,最好只使用训练数据来拟合分词器(尽管如此,即使在训练数据中你也必须保留一个 oov 标记(模型必须学习如何处理 oov) .
正在用未知词测试分词器:
以下测试表明,当未设置 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))
输出:
[[3, 1, 2], [4, 5, 1], [6, 7, 8, 9], [10, 2]]
[[8], [6, 7, 8]]
现在,这表明分词器会将索引 1 赋予所有未知词:
tokenizer2 = Tokenizer(oov_token = True)
tokenizer2.fit_on_texts(training)
print(tokenizer2.texts_to_sequences(training))
print(tokenizer2.texts_to_sequences(test))
输出:
[[4, 2, 3], [5, 6, 2], [7, 8, 9, 10], [11, 3]]
[[1, 1, 9], [7, 8, 9, 1]]
但是将训练数据中的一组稀有词也替换为 1 可能会很有趣,这样您的模型就有了如何处理未知词的概念。
我有一个包含文本列的数据框。我把它们分成 x_train
和 x_test
.
我的问题是在整个 x
数据集上做 Keras 的 Tokenizer.fit_on_text()
还是只做 x_train
更好?
像这样:
tokenizer = Tokenizer()
tokenizer.fit_on_texts(x_data)
或
tokenizer.fit_on_texts(x_train) # <- fixed typo
tokenizer.texts_to_sequences(x_train)
重要吗?我也必须稍后对 x_test
进行分词,所以我可以只使用相同的分词器吗?
虽然
You MUST use the same tokenizer in training and test data
否则,每个数据集会有不同的标记。每个分词器都有一个使用 fit_on_texts
.
不能保证训练数据和测试数据具有相同频率的相同单词,因此每个数据集都会创建不同的词典,并且测试数据的所有结果都是错误的。
这也意味着您不能 fit_on_texts
,训练然后再次 fit_on_texts
:这将更改内部字典。
可以拟合整个数据。但是,为“未知”词 (oov_token=True
) 保留一个标记可能是一个更好的主意,因为当您发现新的测试数据包含您的模型从未见过的词时(这需要您替换训练数据中的稀有词)也有这个令牌)。
正如@Fernando H 提到的,最好只使用训练数据来拟合分词器(尽管如此,即使在训练数据中你也必须保留一个 oov 标记(模型必须学习如何处理 oov) .
正在用未知词测试分词器:
以下测试表明,当未设置 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))
输出:
[[3, 1, 2], [4, 5, 1], [6, 7, 8, 9], [10, 2]]
[[8], [6, 7, 8]]
现在,这表明分词器会将索引 1 赋予所有未知词:
tokenizer2 = Tokenizer(oov_token = True)
tokenizer2.fit_on_texts(training)
print(tokenizer2.texts_to_sequences(training))
print(tokenizer2.texts_to_sequences(test))
输出:
[[4, 2, 3], [5, 6, 2], [7, 8, 9, 10], [11, 3]]
[[1, 1, 9], [7, 8, 9, 1]]
但是将训练数据中的一组稀有词也替换为 1 可能会很有趣,这样您的模型就有了如何处理未知词的概念。