在python中,有没有一种简单的方法可以在没有交叉验证的情况下进行网格搜索



scikit中有一个非常有用的类GridSearchCV来学习网格搜索和交叉验证,但我不想做交叉验证。我想在没有交叉验证的情况下进行网格搜索,并使用整个数据进行训练。更具体地说,我需要在网格搜索过程中用"oob分数"来评估RandomForestClassifier制作的模型。有简单的方法吗?还是我自己上课?

这些点是

  • 我想用简单的方法进行网格搜索
  • 我不想做交叉验证
  • 我需要使用全部数据进行训练。(不想将训练数据和测试数据分开)
  • 我需要在网格搜索过程中使用oob分数进行评估

我真的建议不要使用OOB来评估模型,但知道如何在GridSearchCV()之外运行网格搜索是很有用的(我经常这样做,这样我就可以保存最佳网格中的CV预测,以便于模型堆叠)。我认为最简单的方法是通过ParameterGrid()创建参数网格,然后循环遍历每组参数。例如,假设您有一个名为"grid"的网格dict和名为"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

请参阅此链接:https://stackoverflow.com/a/44682305/2202107

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

一种方法是使用ParameterGrid生成所需参数的迭代器并在其上循环

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

  • 使用文档中的arg cv,并为其提供一个生成器,该生成器生成一个具有所有索引的元组(这样训练和测试就相同了)
  • 更改scoring参数以使用随机林中给出的oob

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

  1. 创建一个sklearn.model_selection.PredefinedSplit()。它接受一个名为test_fold的参数,该参数是一个列表,大小与输入数据相同。在列表中,将属于训练集的所有样本设置为-1,将其他样本设置为0
  2. 创建一个GridSearchCV对象,cv="创建的预定义拆分对象"

然后,GridSearchCV将只生成1个列验证拆分,该拆分在test_fold中定义。

使用ParameterGrid的并行化解决方案

from sklearn.model_selection import ParameterGrid
from joblib import Parallel, delayed
param_grid = {'a': [1, 2], 'b': [True, False]}
param_candidates = ParameterGrid(param_grid)
print(f'{len(param_candidates)} candidates')
def fit_model(params):
    model = estimator.set_params(**params)
    model.fit(X_train, y_train)
    score = model.score(X_val, y_val)
    return [params, score]
results = Parallel(n_jobs=-1, verbose=10)(delayed(fit_model)(params) for params in param_candidates)
print(max(results, key=lambda x: x[1]))

相关内容

  • 没有找到相关文章

最新更新