我想做什么?
我正在尝试在GridSearchCV()
中使用StratifiedKFold()
.
那么,是什么让我感到困惑?
当我们使用 K 折叠交叉验证时,我们只需将 CV 的数量传递GridSearchCV()
如下所示。
grid_search_m = GridSearchCV(rdm_forest_clf, param_grid, cv=5, scoring='f1', return_train_score=True, n_jobs=2)
然后,当我需要使用StratifiedKFold()
时,我认为程序应该保持不变。也就是说,仅设置拆分次数 -StratifiedKFold(n_splits=5)
到cv
.
grid_search_m = GridSearchCV(rdm_forest_clf, param_grid, cv=StratifiedKFold(n_splits=5), scoring='f1', return_train_score=True, n_jobs=2)
但这个答案说
无论使用何种交叉验证策略,所需要的只是 使用函数拆分提供生成器,如建议的那样:
kfolds = StratifiedKFold(5) clf = GridSearchCV(estimator, parameters, scoring=qwk, cv=kfolds.split(xtrain,ytrain)) clf.fit(xtrain, ytrain)
此外,这个问题的答案之一也建议这样做。这意味着,他们建议在使用GridSearchCV()
期间调用split函数:StratifiedKFold(n_splits=5).split(xtrain,ytrain)
。但是,我发现打电话split()
而不打电话给我split()
给我相同的 f1 分数。
因此,我的问题
我不明白为什么我们需要在分层 K 折叠期间调用
split()
函数为 在 K 折叠 CV 期间,我们不需要做这类事情。如果调用
split()
函数,当函数返回训练和测试数据集索引时Split()
GridSearchCV()
将如何工作?也就是说,我想知道GridSearchCV()
将如何使用这些指数?
基本上,GridSearchCV很聪明,可以为该cv参数提供多个选项 - 一个数字,一个拆分索引的迭代器或一个带有拆分函数的对象。你可以在这里查看代码,复制在下面。
cv = 5 if cv is None else cv
if isinstance(cv, numbers.Integral):
if (classifier and (y is not None) and
(type_of_target(y) in ('binary', 'multiclass'))):
return StratifiedKFold(cv)
else:
return KFold(cv)
if not hasattr(cv, 'split') or isinstance(cv, str):
if not isinstance(cv, Iterable) or isinstance(cv, str):
raise ValueError("Expected cv as an integer, cross-validation "
"object (from sklearn.model_selection) "
"or an iterable. Got %s." % cv)
return _CVIterableWrapper(cv)
return cv # New style cv objects are passed without any modification
基本上,如果你不传递任何东西,它使用带有 5 的 KFold。如果它是一个分类问题并且目标是二进制/多类,则自动使用 StratifedKFold 也足够聪明。
如果你传递一个带有split函数的对象,它只是使用它。如果你没有传递其中任何一个,而是传递一个可迭代对象,它会假设它是拆分索引的可迭代对象,并为你包装它。
因此,在您的情况下,假设这是二进制/多类目标的分类问题,则以下所有内容都将给出完全相同的结果/拆分 - 您使用哪一个并不重要!
cv=5
cv=StratifiedKFold(5)
cv=StratifiedKFold(5).split(xtrain,ytrain)