python - 通过随机搜索和递归特征消除将特征缩放添加到嵌套交叉验证
问题描述
我有一个分类任务,想使用重复的嵌套交叉验证来同时执行超参数调整和特征选择。为此,我正在RandomizedSearchCV
使用RFECV
Python 的sklearn
库,正如这个 SO answer中所建议的那样。
但是,我还需要先扩展我的特征并估算一些缺失值。这两个步骤也应该包含在 CV 框架中,以避免训练和测试折叠之间的信息泄漏。我试图创建一个管道来到达那里,但我认为它“破坏”了我的 CV 嵌套(即,彼此分开执行 RFECV 和随机搜索):
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.feature_selection import RFECV
import scipy.stats as stats
from sklearn.utils.fixes import loguniform
from sklearn.preprocessing import StandardScaler
from sklearn.impute import KNNImputer
from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import RandomizedSearchCV
from sklearn.pipeline import Pipeline
# create example data with missings
Xtrain, ytrain = make_classification(n_samples = 500,
n_features = 150,
n_informative = 25,
n_redundant = 125,
random_state = 1897)
c = 10000 # number of missings
Xtrain.ravel()[np.random.choice(Xtrain.size, c, replace = False)] = np.nan # introduce random missings
folds = 5
repeats = 5
rskfold = RepeatedStratifiedKFold(n_splits = folds, n_repeats = repeats, random_state = 1897)
n_iter = 100
scl = StandardScaler()
imp = KNNImputer(n_neighbors = 5, weights = 'uniform')
sgdc = SGDClassifier(loss = 'log', penalty = 'elasticnet', class_weight = 'balanced', random_state = 1897)
sel = RFECV(sgdc, cv = folds)
pipe = Pipeline([('scaler', scl),
('imputer', imp),
('selector', sel),
('clf', sgdc)])
param_rand = {'clf__l1_ratio': stats.uniform(0, 1),
'clf__alpha': loguniform(0.001, 1)}
rskfold_search = RandomizedSearchCV(pipe, param_rand, n_iter = n_iter, cv = rskfold, scoring = 'accuracy', random_state = 1897, verbose = 1, n_jobs = -1)
rskfold_search.fit(Xtrain, ytrain)
有谁知道如何在不丢失我的嵌套的情况下将缩放和插补包含到 CV 框架RandomizedSearchCV
中RFECV
?
非常感谢任何帮助!
解决方案
你没有丢失嵌套的简历。
您在顶层有一个搜索对象;当您调用 时fit
,它会将数据拆分为多个折叠。让我们关注一个这样的火车折叠。您的管道安装在上面,因此您可以缩放和估算,然后RFECV
将其拆分为内部折叠。最后,一个新的估计器被安装在外部训练折叠上,并在外部测试折叠上得分。
这意味着 RFE 可能会有一点泄漏,因为缩放和插补发生在其分裂之前。您可以将它们添加到估算器之前的管道中,并将该管道用作 RFE 估算器。并且由于RFECV
使用发现的最佳特征数量重新调整其估计器并将其公开predict
以此类推,因此您实际上并不需要 ; 的第二个副本sgdc
。仅使用一个副本也会产生超参数调整选择的副作用:
scl = StandardScaler()
imp = KNNImputer(n_neighbors=5, weights='uniform')
sgdc = SGDClassifier(loss='log', penalty='elasticnet', class_weight='balanced', random_state=1897)
base_pipe = Pipeline([
('scaler', scl),
('imputer', imp),
('clf', sgdc),
])
sel = RFECV(base_pipe, cv=folds)
param_rand = {'estimator__clf__l1_ratio': stats.uniform(0, 1),
'estimator__clf__alpha': loguniform(0.001, 1)}
rskfold_search = RandomizedSearchCV(sel, param_rand, n_iter=n_iter, cv=rskfold, scoring='accuracy', random_state=1897, verbose=1, n_jobs=-1)
推荐阅读
- r - 使用线串裁剪多边形
- javascript - 打开应用程序之前角度初始化连接
- mongodb - 如何在本地打开 Mongo Atlas 备份快照?
- mysql - MySQL:使用 LONGTEXT 而不是 MEDIUMTEXT 是否缺乏性能?
- c - 函数中的变量输入类型
- python - 如何获取 Keras 模型所有层的输出?
- python - 如何在python中按字符串中的特定单词对行进行分组
- python - 如何在 python 中调用我网站上的 php 脚本?
- python - 将 hive 表卸载到。使用 Spark 或 pyspark 或 python 的 dat 文件
- python - 矩阵的平均值乘以标量向量