拆分训练和测试数据之前还是之后进行数据处理?

6
我正在使用这篇优秀的文章学习机器学习。
链接:https://stackabuse.com/python-for-nlp-multi-label-text-classification-with-keras/ 在拆分数据后,作者对X和y数据进行了标记化处理。
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.20, random_state=42
)

tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(X_train)

X_train = tokenizer.texts_to_sequences(X_train)
X_test = tokenizer.texts_to_sequences(X_test)

vocab_size = len(tokenizer.word_index) + 1

maxlen = 200

X_train = pad_sequences(X_train, padding="post", maxlen=maxlen)
X_test = pad_sequences(X_test, padding="post", maxlen=maxlen)

如果在使用train_test_split类之前对其进行标记化,就可以省下几行代码。
tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(X)

X_t = tokenizer.texts_to_sequences(X)
vocab_size = len(tokenizer.word_index) + 1
maxlen = 200

X = pad_sequences(X_t, padding="post", maxlen=maxlen)

我只是想确认我的方法是正确的,而且我不希望在脚本后面遇到任何意外情况。


2
这不是一个编程问题,因此在这里可能属于离题讨论;更适合在交叉验证上讨论。 - desertnaut
ML预处理的简单黄金法则是在整个模型拟合管道过程中将测试数据视为不可用。请参见此处的讨论(尽管上下文略有不同)。 - desertnaut
3个回答

10

两种方法都可以实现。但在训练集上对分词器进行训练,然后将其应用于训练集和测试集要比在整个数据集上进行训练更好。实际上,通过第一种方法,您正在模仿模型中未见过的单词将在部署模型后的某个时候出现的情况。因此,您的模型评估将更接近于在生产环境中发生的情况。


7

同意@desertnaut的评论,认为这个问题更适合于 "Cross Validated",在那里你会得到更好的回答。但我还是想说一句话。

简而言之:不要这样做,将训练集和测试集交叉污染通常不是一个好主意。这样做在统计上是不正确的。

Tokenizer.fit_to_texts(dictionary)对单词进行索引,即它构建了从任何单词序列到数字(向量表示)的翻译,因此,如果它仅使用训练数据,训练集和测试集之间的词汇差异可能不是零集,即某些测试集中的单词不存在于Tokenizer对象建立的单词索引器中。这可能导致一些测试集生成不同的向量,如果您只在训练集上进行了tokenizer的训练

由于学习问题中的测试集应该是隐藏的,在训练模型的任何过程中使用它都是统计上不正确的。


4

补充一下Simon的帖子,我认为在分割之前进行标记化处理甚至是被禁止的。

算法会通过来自标记化程序的数据进行学习,这严格限定于测试算法。这是训练集和测试集之间的主要差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接