在 python 中是否有无需交叉验证的简单网格搜索方法?

Is there easy way to grid search without cross validation in python?

scikit-learn 中的 class GridSearchCV 绝对有帮助,可以进行网格搜索和交叉验证,但我不想进行交叉验证。我想在没有交叉验证的情况下进行网格搜索,并使用整个数据进行训练。 更具体地说,我需要在网格搜索期间用 "oob score" 评估由 RandomForestClassifier 制作的模型。 有简单的方法吗?还是我自己做一个class?

积分是

我真的建议不要使用 OOB 来评估模型,但了解如何 运行 在 GridSearchCV() 之外进行网格搜索很有用(我经常这样做,这样我可以节省来自最佳网格的 CV 预测,便于模型堆叠)。我认为最简单的方法是通过 ParameterGrid() 创建参数网格,然后循环遍历每组参数。例如假设你有一个名为 "grid" 的网格字典和名为 "rf" 的 RF 模型对象,那么你可以这样做:

for g in ParameterGrid(grid):
    rf.set_params(**g)
    rf.fit(X,y)
    # save if best
    if rf.oob_score_ > best_score:
        best_score = rf.oob_score_
        best_grid = g

print "OOB: %0.5f" % best_score 
print "Grid:", best_grid

一种方法是使用 ParameterGrid 制作所需参数的迭代器并对其进行循环。

您可以做的另一件事是实际配置 GridSearchCV 以执行您想要的操作。我不会推荐这么多,因为它不必要地复杂。
您需要做的是:

  • 使用 docs 中的 arg cv 并给它一个生成器,生成一个包含所有索引的元组(以便训练和测试相同)
  • 更改 scoring arg 以使用随机森林给出的 oob。

看到这个link:

他使用了 sklearn 作者不推荐的 cv=[(slice(None), slice(None))]

虽然这个问题在几年前就已经解决了,但我只是发现如果你坚持使用 GridSearchCV() 而不是其他方法(ParameterGrid() 等)的话,一个更自然的方法:

  1. 创建一个sklearn.model_selection.PredefinedSplit()。它需要一个名为 test_fold 的参数,它是一个列表并且与您的输入数据具有相同的大小。在列表中,您将属于训练集的所有样本设置为 -1,将其他样本设置为 0.
  2. 使用 cv="the created PredefinedSplit object" 创建一个 GridSearchCV 对象。

然后,GridSearchCV 将只生成 1 个训练验证拆分,定义在 test_fold.