1

在作为 SVC 包装器的自定义估计器上使用 GridSearchCV 时,我收到错误消息:“ValueError: The number of classes have to be greater than one; got 1 class”

自定义估算器用于将网格搜索参数添加到估算器中,并且似乎工作正常。

使用调试器,我发现确实给我的估计器提供了一个只有一类的训练集,所以出现了两种可能性:

  • 估计器应该处理仅一类集

  • GridSearchCV 不应该只给出一个类集

当我从 SVC.fit 调用中得到一个错误,并且 SVC 似乎不应该接收仅一类集合时,我认为这是第二个选项。但是,我查看了 GridSearchCV 实现,但没有找到任何地方可以检查是否存在仅一类折叠或为什么会失败...

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

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))

4

2 回答 2

2

我发现了真正的问题,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,只有一类子集是不可能的。

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

于 2019-04-17T12:47:27.870 回答
2

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

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

1-n_inner_splits根据采样不足的类数据的百分比和您拥有的实例数减少。

2-而不是将整数传递给网格搜索的 cv 参数,您可以进行自我拆分并将其传递给可迭代的产生(训练、测试)数据,您将确保始终表示 2 个类。

3- 在采样类下为此生成/获取更多数据。

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

于 2019-04-17T12:08:41.790 回答