SelectFromModel scikit-learn:训练和测试阶段生成的特征矩阵维度

Posted

技术标签:

【中文标题】SelectFromModel scikit-learn:训练和测试阶段生成的特征矩阵维度【英文标题】:SelectFromModel scikit-learn: Resulting Feature Matrix Dimensions During Training and Testing Stages 【发布时间】:2017-12-10 18:59:28 【问题描述】:

我刚开始在我的数据集上使用特征选择,我遇到了SelectFromModel 模块,它自动将原始的n x m 特征矩阵转换为n x k,其中k << m。但是,k 是先验未知的。

我想知道我应该如何使用它来训练模型,然后使用现有模型来预测新数据。众所周知,训练数据实例和测试数据实例必须用相同维度的特征向量表示。

但是这个维度会依赖于数据,不能用SelectFromModel控制。

我编写了如下代码:

X_train = ... # feature matrix

print("BEFORE FEATURE SELECTION, FEATURE MATRIX shape=".format(X_train.shape))
# output of this line is 24771, 11680

select = SelectFromModel(LogisticRegression(class_weight='balanced',penalty="l1",C=0.01))
X_train = select.fit_transform(X_train, y_train)

print("AFTER FEATURE SELECTION, FEATURE MATRIX shape=".format(M.shape))
# output of this line is 24771, 170

测试时,加载预训练好的模型,新的数据实例需要用相同的特征向量表示:

X_test = ... # feature matrix

# the next line maps test set features to the feature vectors observed on training data, using corresponding vocabularies

X_test=map_test_to_train_featurevectors(X_test, X_train)

print("BEFORE FEATURE SELECTION, FEATURE MATRIX shape=".format(X_test.shape))
# output of this line is 550, 11680, so test instances has same vector dimension as training instances

select = SelectFromModel(LogisticRegression(class_weight='balanced',penalty="l1",C=0.01))
X_test = select.fit_transform(X_test, y_test)

print("AFTER FEATURE SELECTION, FEATURE MATRIX shape=".format(M.shape))
# output of this line is 550, 5, but the pre-trained model will expect 170

best_estimator = util.load_classifier_model(model_file)
prediction_dev = best_estimator.predict_proba(X_test)

最后一行显然会产生如下错误,因为训练和测试时特征选择后得到的特征矩阵是不同的维度:

ValueError: X has 5 features per sample; expecting 169

是不是就不能这样使用 SelectFromModel 了?只能用于训练和评估吗?

【问题讨论】:

【参考方案1】:

您不能以这种方式使用SelectFromModel() 模块。它并没有简单地降低维度复杂性。相比之下,PCA().fit_transform(**data) 会按照您想要的方式工作。 SelectFromModel() 上的文档说明如下:

用于根据重要性权重选择特征的元转换器。

话虽如此,您将所需的模型传递给SelectFromModel() 并将其与输入数据相匹配。完成此操作后,它会根据模型权重的重要性提取最可行的特征。与这种方法相比,PCA() 处理数据的解释方差,并努力尽可能多地保存数据,同时降低数据维度的复杂性。这非常方便,因为您可以手动将解释方差比设置为原始输入数据。

但是,您尝试通过实现LogisticRegression() 的另一个拟合来转换(即减少)测试数据的维度。它将为这个集合计算自己的权重,因为它与训练阶段的集合完全不同。因此,它根据与测试集相关的权重的重要性来选择最重要的特征,而不是训练集


您可能会遇到以下两种方法:

观察select.fit_transform(X_train, y_train)之后使用了哪些170个特征,并创建一个与X_test相同特征的新变量。因此,您将避免指向不同大小的错误。

实现降维方法,如PCA或SVD

希望对你有帮助!

【讨论】:

以上是关于SelectFromModel scikit-learn:训练和测试阶段生成的特征矩阵维度的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 SelectFromModel() 中选择特征的阈值?

ValueError:使用 GridSearchCV 时估计器 SelectFromModel 的参数 C 无效

来自 sklearn 的 SelectFromModel 在随机森林和梯度提升分类器上提供了显着不同的特征

SelectFromModel scikit-learn:训练和测试阶段生成的特征矩阵维度

特征工程之特征选择----嵌入法(Embed)

特征工程(下)