使用 10 折交叉验证时 sklearn 的特征大小

Posted

技术标签:

【中文标题】使用 10 折交叉验证时 sklearn 的特征大小【英文标题】:Feature size for sklearn when using 10 fold Cross Validation 【发布时间】:2016-02-11 14:52:22 【问题描述】:

当我使用 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 折交叉验证的每个循环中。如果训练数据集创建的特征文档矩阵(这里是词袋)与测试特征文档矩阵不同怎么办。例如,单词“happy”是测试数据集中的一个特征,但不是训练数据集中的一个特征。我不确定我的代码是否正确,因为我在这里使用过:

cont_vect.fit_transform

创建训练特征矩阵,并使用

cont_vect.transform

要创建测试特征矩阵,代码可以运行,但我不知道为什么,比如 fit_transform 和 transform 有什么区别?我假设测试矩阵是基于训练矩阵创建的。

如果是真的,另一个问题是,每个循环的特征大小是否应该相同?因为,当使用 10 倍 CV 时,无论训练数据集来自原始数据集的哪一部分,训练+测试(原始数据集)都是相同的,因此每个循环的特征矩阵的大小应该相等。但是当我检查结果时,特征的大小是不同的,相似但不相等。我不知道为什么会发生这种情况?谢谢。

【问题讨论】:

【参考方案1】:

这是一个非常好的问题!机器学习领域的许多年轻研究人员都忘记了这个问题。

让我们从头开始

fit_transform 和 transform 有什么区别?

scikit-learn 中的转换器是能够将一种类型的数据转换为另一种类型的类,而且它们通常通过分析数据来学习如何做到这一点。

.fit(X) 让模型从 X 学习一些参数集 .transform(X) 要求模型使用经过训练的模型转换 X .fit_transform(X) 只是调用.fit(X) 后跟.transform(X) 的缩写形式,仅此而已。由于这是转换我们正在学习的数据的常用做法,因此这种快捷方式真正广泛用于基于 sklearn 的代码中;

如果训练数据集创建的特征文档矩阵(这里是词袋)与测试特征文档矩阵不同怎么办。例如,单词“happy”是测试数据集中的特征,而不是训练数据集中的特征

它做了最合理的事情——它忽略在训练阶段没有看到的对象。对于您的特定情况,当您在训练数据上调用 fit(在 fit_transform 内)时,您的转换器(矢量化器)构建了内部词汇表 - 训练期间看到的一组单词。这些是它唯一能识别的词。当您在新文本上调用 transform 时,不在转换器词汇表中的单词会被简单地忽略(因为它对它们一无所知,显然它会使上面的分类器混淆)。如果词汇表中的某些单词在测试集转换中不存在怎么办?这些值只是获得0 值(或其他默认含义“现在没有这样的对象”)。

我不确定我的代码是否正确,因为我在这里使用过:

 cont_vect.fit_transform

创建训练特征矩阵,并使用

 cont_vect.transform

是的,您的代码非常好,这正是您应该做的。

总结一下。

如果训练数据集创建的特征文档矩阵(这里是词袋)与测试特征文档矩阵不同怎么办。

矩阵始终相同,因为它的大小(维数)在您调用 fit 后就确定了,并且在调用 transform 之后不会影响内部词汇表(哪个大小是矩阵的大小)。

【讨论】:

非常感谢,@lejlot,非常清楚。忽略测试数据集中的新特征绝对是为什么每个循环中特征大小不同的答案。另一件事是,在交叉验证之前或交叉验证之后(如循环中的此处)使用转换创建特征文档矩阵,通常实现哪个?谢谢。 通常你在拟合训练集期间调用fit_transform,所以在CV的每一折内(就像你做的那样),因为它应该在你获得新数据时模拟“真实测试”,从不以前见过(所以你不能“适应”它) 太棒了,谢谢,我明白了,如果在 CV 之前使用,这会使 CV 没用。

以上是关于使用 10 折交叉验证时 sklearn 的特征大小的主要内容,如果未能解决你的问题,请参考以下文章

使用 sklearn 进行交叉验证的高级特征提取

如何在sklearn中计算交叉验证的每个模型中的特征重要性

R语言caret包构建xgboost模型实战:特征工程(连续数据离散化因子化无用特征删除)配置模型参数(随机超参数寻优10折交叉验证)并训练模型

cross_val_score 交叉验证与 K折交叉验证,嗯都是抄来的,自己作个参考

python-sklearn数据拆分与决策树的实现

通过 Sklearn 的 RFECV(带有交叉验证的递归特征消除)选择特定数量的特征