在火车测试拆分之前或之后处理

processing before or after train test split

我正在使用这篇优秀的文章来学习机器学习。

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 class 之前对其进行标记化,我可以节省几行代码。

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)

我只是想确认我的方法是正确的,我不希望脚本后面出现任何意外。

这两种方法在实践中都有效。但是在训练集上拟合分词器并将其应用于训练集和测试集比在整个数据集上拟合更好。事实上,使用第一种方法,您是在模拟这样一个事实,即模型未见过的词会在部署模型后的某个时刻出现。因此,您的模型评估将更接近生产环境中发生的情况。

补充一下 Simons post,我想说在拆分之前甚至禁止标记化。

该算法将使用分词器的数据进行学习,这仅用于测试算法。这是火车和测试集之间的主要方法。

同意@desertnaut 的评论,该问题更适合“Cross Validated”,你会在那里得到更好的回应。不过我还是想说一下。

TL;DR: Don't do it, it's generally not a good idea to cross contaminate your training and test set. It's not statistically correct to do so.

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

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