当我使用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
为了创建测试特性矩阵,代码正在运行,但我不知道为什么,比如fittransform和transform有什么区别?我认为测试矩阵是基于训练矩阵创建的。
如果这是真的,另一个问题是,每个循环的特征大小是否应该相同?因为,当使用10倍CV时,无论训练数据集来自原始数据集的哪个部分,训练+测试(原始数据集)都是相同的,因此每个循环的特征矩阵大小应该相等。但当我检查结果时,特征的大小是不同的,相似但不相等。我不知道为什么会发生这种事?谢谢
这是一个非常好的问题!ML领域的许多年轻研究人员忘记了这个问题。
所以让我们从的结尾开始
fittransform和transform有什么区别?
scikit学习中的转换器是能够将一种类型的数据转换为另一种类型数据的类,此外,它们通常通过分析数据来学习如何做到这一点。
.fit(X)
使模型从X
学习一些参数.transform(X)
要求模型使用训练后的模型对X
进行变换.fit_transform(X)
只是调用.fit(X)
和.transform(X)
的简短形式,仅此而已。由于这是转换我们正在学习的数据的一种常见做法,因此这种快捷方式在基于sklearn的代码中确实被广泛使用
如果训练数据集创建的特征文档metrix(这里是单词袋)与测试特征文档metrix不同,该怎么办。例如,单词"快乐"在测试数据集中是一个特征,但在训练数据集中不是
它做的是最合理的事情-它忽略在训练阶段没有看到的对象。对于您的特定情况,当您对训练数据调用fit
(在fit_transform
内部)时,您的转换器(矢量器)会构建内部词汇库——训练期间看到的单词集。这些是它唯一能识别的单词。当你在新文本上调用transform
时,不在transformer vocabulary中的单词会被忽略(因为它对它们一无所知,显然这会混淆它上面的分类器)。如果vocalblurary中的一些单词没有出现在测试集转换中,该怎么办?这些值只是得到0
值(或其他默认值,意思是"现在没有这样的对象")。
我不确定我的代码是否正确,因为我在这里使用了:
cont_vect.fit_transform
创建训练特征矩阵,并使用
cont_vect.transform
是,您的代码非常好,这正是您应该做的。
综上所述。
如果训练数据集创建的特征文档metrix(这里是单词袋)与测试特征文档metrix不同,该怎么办。
矩阵始终是相同的,因为它的大小(维度数)是在您调用fit
后确定的,并且随后的transform
调用永远不会影响内部人声(哪个大小就是矩阵的大小)。