One-class-only folds 通过 GridSearchCV 测试

One-class-only folds tested through GridSearchCV

在作为 SVC 包装器的自定义估算器上使用 GridSearchCV 时,出现错误: "ValueError: The number of classes has to be greater than one; got 1 class"

自定义估算器用于将 gridsearch 参数添加到估算器并且似乎工作正常。

使用调试器,我发现确实,一个 class-only train set 被提供给了我的估计器,所以出现了 2 种可能性:

因为我从 SVC.fit 调用中得到一个错误,而且 SVC 似乎不应该接收一个 class-only 集,我认为这是第二个选项。但是我查看了 GridSearchCV 实现,但我没有找到它检查是否有一个 class-only 折叠或为什么它会失败的任何地方...

我在交叉验证中使用了网格搜索来进行嵌套交叉验证:

gs = GridSearchCV(clf.gs_clf.get_gs_clf(), parameter_grid, cv=n_inner_splits, iid=False)
gs.fit(*clf.get_train_set(X, y, train_index))

正如您在问题中已经提到的,问题在于交叉验证拆分不包括第二个 class 数据。这可能是由于您的数据存在不平衡 class 问题,当执行分层 n_inner_splits 折叠时,这个欠样本 class 被遗漏了。

要克服这个问题,您可以尝试以下方法之一:

1- 根据欠采样 class 数据的百分比和您拥有的实例数减少 n_inner_splits

2- 除了将整数传递给 gridsearch 的 cv 参数外,您还可以进行自我拆分并传递给它一个可迭代的生成(训练、测试)数据,您可以确保 2 classes 总是被代表。

3- Generate/acquire 采样不足 class 的更多数据。

查看 cv 参数文档以了解其他解决此问题的方法here

我发现了真正的问题,GridsearchCV 的文档为参数 cv 指定:

# For integer/None inputs, if the estimator is a classifier and ``y`` is
# either binary or multiclass, `StratifiedKFold` is used. In all
# other cases, `KFold` is used.

而且 StratifiedKFold 不可能只有一个 class 个子集。

所以解决方案是让我的自定义估算器继承自 sklearn.base.ClassifierMixin