如何使用 SelectKBest 选择的特征训练模型?
Posted
技术标签:
【中文标题】如何使用 SelectKBest 选择的特征训练模型?【英文标题】:How to train model with features selected by SelectKBest? 【发布时间】:2020-07-30 03:35:16 【问题描述】:我在 Sklearn 的 Pipeline()
类中使用 SelectKBest()
将特征数量从 30 个减少到 5 个最佳特征。当我拟合分类器时,我会得到与特征选择不同的测试结果。但是我在我的代码中发现了一个错误,它似乎不会在运行时导致实际错误。
当我致电predict()
时,我意识到它仍然被赋予所有 30 个特征作为输入,就好像没有进行特征选择一样。尽管我只对模型进行了 5 个最佳特征的训练。如果只对 5 个最佳特征进行训练,是否给 SVM 提供 30 个特征来预测一个类会崩溃?
在我的train_model(df)
函数中,我的代码如下所示:
def train_model(df):
x,y = balance_dataset(df)
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)
feature_selection = SelectKBest()
pipe = Pipeline([('sc', preprocessing.MinMaxScaler()),
('feature_selection', feature_selection),
('SVM', svm.SVC(decision_function_shape = 'ovr', kernel = 'poly'))])
candidate_parameters = ['SVM__C': [0.01, 0.1, 1], 'SVM__gamma': [0.01, 0.1, 1], 'feature_selection__k': [5]]
clf = GridSearchCV(estimator = pipe, param_grid = candidate_parameters, cv = 5, n_jobs = -1)
clf.fit(X_train, y_train )
return clf
但是,当我致电 trade()
时会发生这种情况:
def trade(df):
clf = train_model(df)
for index, row in trading_set.iterrows():
features = row[:-3] #features is now an array of 30 features, even though model is only trained on 5
if trade_balance > 0:
trades[index] = trade_balance
if clf.predict(features) == 1: #So this should crash and give an input Shape error, but it doesn't
#Rest of code unneccesary#
所以我的问题是,我怎么知道模型真的只接受了 5 个最佳特征的训练?
【问题讨论】:
【参考方案1】:您的代码是正确的,它没有理由向您抛出任何错误。你混淆了管道对象和模型本身,模型本身只是管道的一个块。
在您的示例中,管道采用 30 个特征,对其进行缩放,选择 5 个最佳特征,然后在这 5 个最佳特征上训练 SVM。因此,您的 SVM 已经接受了 5 个最佳特征的训练,但您仍然需要将所有 30 个特征传递到您的管道,因为您的管道希望数据以与训练期间相同的格式输入。
【讨论】:
哇,现在更有意义了。感谢您为我解决这个问题,因为我真的很困惑它是如何工作的。我现在可以问一下,我在管道中概述的阶段是否以正确的顺序完成?由于我使用随机上采样平衡了数据集,然后我缩放并选择最佳特征并使用 CV 进行 GridSearch。我只关心数据泄漏 并确保阶段的顺序流程正确。还是这最终归结为“没有免费的午餐定理”? 你的管道对我来说很有意义。而且我在您的设置中看不到任何数据泄漏:) 即使我的balance_dataset()
方法从整个训练集中随机上采样数据?所以重复数据可以分布在 cv 过程中的折叠之间?
确实,你说的上采样是对的,我没注意。您实际上有两种解决方案来避免这种情况:欠采样(但如果不平衡很严重,这可能会导致大量数据丢失)或在管道本身中添加数据重采样(请参阅imbalanced-learn.readthedocs.io/en/stable/generated/…)
好的,谢谢您的帮助!我会将您的答案标记为最佳答案!以上是关于如何使用 SelectKBest 选择的特征训练模型?的主要内容,如果未能解决你的问题,请参考以下文章
scikit-learn:在管道中使用 SelectKBest 时获取选定的功能
sklearn.feature_selection.SelectKBest 特征评分模块中的负数问题
SelectKBest with chi2 给出 ValueError: could not convert string to float