【发布时间】:2019-06-02 05:58:29
【问题描述】:
所以我发现 StandardScaler() 可以使我的 RFECV 在我的 GridSearchCV 中,每个嵌套的 3 折交叉验证运行得更快。如果没有 StandardScaler(),我的代码运行了超过 2 天,所以我取消并决定将 StandardScaler 注入到进程中。但现在它已经运行了 4 个多小时,我不确定我是否做得对。这是我的代码:
# Choose Linear SVM as classifier
LSVM = SVC(kernel='linear')
selector = RFECV(LSVM, step=1, cv=3, scoring='f1')
param_grid = [{'estimator__C': [0.001, 0.01, 0.1, 1, 10, 100]}]
clf = make_pipeline(StandardScaler(),
GridSearchCV(selector,
param_grid,
cv=3,
refit=True,
scoring='f1'))
clf.fit(X, Y)
老实说,我认为我没有做对,因为我认为 StandardScaler() 应该放在 GridSearchCV() 函数中,以便规范化每个折叠的数据,而不仅仅是一次(?)。如果我错了或者我的管道不正确以及为什么它仍然运行了很长时间,请纠正我。
我有 8000 行 145 个特征要被 RFECV 修剪,6 个 C 值要被 GridSearchCV 修剪。因此对于每个 C-Value,最佳特征集由 RFECV 确定。
谢谢!
更新:
所以我将 StandardScaler 放在 RFECV 中,如下所示:
clf = SVC(kernel='linear')
kf = KFold(n_splits=3, shuffle=True, random_state=0)
estimators = [('standardize' , StandardScaler()),
('clf', clf)]
class Mypipeline(Pipeline):
@property
def coef_(self):
return self._final_estimator.coef_
@property
def feature_importances_(self):
return self._final_estimator.feature_importances_
pipeline = Mypipeline(estimators)
rfecv = RFECV(estimator=pipeline, cv=kf, scoring='f1', verbose=10)
param_grid = [{'estimator__svc__C': [0.001, 0.01, 0.1, 1, 10, 100]}]
clf = GridSearchCV(rfecv, param_grid, cv=3, scoring='f1', verbose=10)
但它仍然抛出以下错误:
ValueError:估计器管道的参数 C 无效(memory=None, steps=[('standardscaler', StandardScaler(copy=True, with_mean=True, >with_std=True)), ('svc', SVC(C=1.0, cache_size=200, class_weight=None, >coef0=0.0, 决策函数形状='ovr',度数=3,伽玛='自动',内核='线性', max_iter=-1,probability=False,random_state=None,shrinking=True, tol=0.001,详细=假))])。使用 >
estimator.get_params().keys()检查可用参数列表。
【问题讨论】:
-
是的,你是对的。
make_pipeline应该在包含StandardScaler和SVC的RFECV 内。GridSearchCV应该是外部的。但即便如此,你也不能肯定地说代码不会是有限的。这只是线性支持向量机无法收敛到给定数据并且可能运行很长时间的问题。将其与 RFE 和 GridSearch 结合使用,会增加运行时间。 -
好的,但现在它抛出了一个错误(见编辑)。
-
既然你已经改变了结构,你还需要改变参数名称。正确的名称是
estimator__svc__C。但是你会在RFECV上遇到错误。因为它需要管道未暴露的SVC的coef_。见this question -
还有see this了解更多说明
-
这很复杂哇。所以事实证明 StandardScaler() 不会加速这个过程,所以根本不使用它是否有效(不规范化数据(?))。我为 Logistic 回归使用了相同的代码(没有 StandardScaler()),只用了 15 分钟就得出了很好的准确性。现在,我只想训练一个 SVM 进行比较,因此可以安全地假设即使问题是线性问题,LR 很容易解决,但对于线性 SVM 来说仍然很难(?)
标签: scikit-learn svm rfe gridsearchcv