当我使用sklearn进行交叉验证时,我对特征矩阵的大小感到困惑。这是我的代码:
'''Cross-Validation'''
skf = cross_validation.StratifiedKFold(data_label, n_folds=10, shuffle=True, random_state=None)
'''For each fold, Do the classification'''
for train_index, test_index in skf:
train_data = np.array(data_content[train_index])
train_label = np.array(data_label[train_index])
test_data = np.array(data_content[test_index])
test_label = np.array(data_label[test_index])
'''Create feature matrix'''
cont_vect = CountVectorizer(analyzer='word')
train_data_matrix = cont_vect.fit_transform(train_data)
test_data_matrix = cont_vect.transform(test_data)............the classification
在10次交叉验证的每个循环中。如果由训练数据集创建的特征文档metrix(这里是单词包)与测试特征 - 文档metrix不同,该怎么办?例如,单词' happy'是测试数据集中的一项功能,但不在训练数据集中。我不确定我的代码是否正确,因为我在这里使用了:
cont_vect.fit_transform
创建训练特征矩阵,并使用
cont_vect.transform
创建测试特征矩阵,代码正在运行,但我不知道为什么,比如fit_transform和transform之间的区别是什么?我假设测试矩阵是基于训练矩阵创建的。
如果这是真的,另一个问题是,每个循环的特征尺寸是否相同?因为,当使用10倍CV时,无论训练数据集来自原始数据集的哪个部分,训练+测试(原始数据集)都是相同的,因此每个循环的特征矩阵的大小应相等。但是当我检查结果时,特征的大小是不同的,相似但不相等。我不知道为什么会发生这种情况?感谢。
答案 0 :(得分:2)
这是一个非常好的问题! ML领域的许多年轻研究人员忘记了这个问题。
让我们从最后开始
fit_transform和transform之间有什么区别?
scikit-learn中的变形金刚是能够将一种数据转换为另一种数据的类,而且他们通常通过分析数据来学习如何这样做。
.fit(X)
让模型从X
.transform(X)
要求模型使用经过培训的模型转换X
.fit_transform(X)
只是调用.fit(X)
后跟.transform(X)
的简短形式,仅此而已。由于这是转换我们正在学习的数据的常用做法,因此这种快捷方式在基于sklearn的代码中得到了广泛的应用; 如果训练数据集创建的feature-document metrix(这里是单词包)与test feature-document metrix不同,该怎么办?例如,单词' happy'是测试数据集中的一项功能,但不在训练数据集中
它做了最合理的事情 - 忽略在训练阶段没有看到的对象。对于您的特定情况,当您在训练数据上调用fit
(在fit_transform
内)时,您的变换器(矢量化器)会构建内部词汇 - 在训练期间看到的一组单词。这些是它识别的唯一单词。当您在新文本上调用transform
时,不会忽略变换器词汇表中的单词(因为它对它们一无所知,显然会将分类器混淆在其上)。如果在测试集转换中没有来自词汇表的某些单词怎么办?这些值只是获得0
值(或其他默认含义"现在没有这样的对象")。
我不确定我的代码是否正确,因为我在这里使用了:
cont_vect.fit_transform
创建训练特征矩阵,并使用
cont_vect.transform
是,您的代码非常精细,这正是您应该做的。
总结一下。
如果训练数据集创建的feature-document metrix(这里是单词包)与测试功能 - 文档metrix不同,该怎么办。
矩阵始终相同,因为它在调用fit
后确定了尺寸(维度数),并且跟随transform
调用从不影响内部词汇表(大小是矩阵的大小。)