我使用 GridSearch CV创建了一个随机森林和梯度提升回归器。对于 Gradient Boosting Regressor,对我来说它需要的时间太长了。但我需要知道哪些是模型的最佳参数。所以我在想是否有没有 CV 的 GridSearch,因为 OOB 分数足以评估模型。我希望我能解释我的意思。
没有简历的 GridSearch
GridSearchCV 是围绕交叉验证构建的,但如果速度是您的主要关注点,您可以使用较少的折叠数获得更好的性能。
从文档:
sklearn.model_selection.GridSearchCV 类(估计器,param_grid,评分=None,n_jobs=None,iid='deprecated',refit=True,cv=None,verbose=0,pre_dispatch='2*n_jobs',error_score=nan,return_train_score =假)
cv:int,交叉验证生成器或可迭代的,可选
确定交叉验证拆分策略。cv 的可能输入是:
None, to use the default 5-fold cross validation, integer, to specify the number of folds in a (Stratified)KFold, CV splitter, An iterable yielding (train, test) splits as arrays of indices.对于整数/无输入,如果估计器是分类器并且 y 是二元或多类,则使用 StratifiedKFold。在所有其他情况下,使用 KFold。
cv默认为 5,因此将其更改为 2 应该会为您提供显着的加速。这将显着削弱交叉验证。
或者,您可以为您的cv. 这将有效地禁用交叉验证并消除它提供的好处。
通过传递一个可调用的参数scoring,它直接使用模型的 oob 分数并完全忽略传递的数据,您应该能够使 GridSearchCV 按您希望的方式运行。cv正如@jnranton 建议的那样,只需为参数传递一个拆分;您甚至可以更进一步,使单个拆分使用训练部分的所有数据,而测试部分甚至不会在上述设置中使用。(sklearn 是否执行检查以防止通过cv=1?)
我还没有机会尝试这个:
def oob_scorer(estimator, X, y):
return estimator.oob_score_
model = GridSearchCV(estimator=RandomForest(...),
param_grid={...},
scoring=oob_scorer,
cv=PredefinedSplit([-1]*TRAIN_SET.shape[0]),
...
)
相关问题:
使用 oob 作为度量的 Scikitlearn 网格搜索随机森林?
RandomForestClassifier OOB 评分方法
我不确定这种方法是否值得。即使使用并行化,自己制作网格循环也不会非常困难。
编辑:是的,没有测试组的 cv-splitter 失败。按分钟计算,但您可以只拆分一个测试点,或者添加一个虚拟测试集,或者......
这是一个工作示例。似乎确实在使用 oob_score,并且测试集只有一个牺牲点:
https ://github.com/bmreiniger/datascience.stackexchange/blob/master/GridSearchNoCV_oob.ipynb
有几种方法可以加快速度:
- 减少 CV 值,如@jncraton 所述
- 减少超参数的搜索空间(只测试几个参数或减少参数的范围)
此外,您可能会考虑通过使用 hyperopt 或 nevergrad 来使用更有效的超参数搜索方式。
或者,只需自己实现一个简单的网格搜索算法。Mueller 和 Guido 的“Python 机器学习简介”一书中包含一个使用以下代码的示例SVC:
# naive grid search implementation
from sklearn.svm import SVC
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)
print("Size of training set: {} size of test set: {}".format( X_train.shape[0], X_test.shape[0]))
best_score = 0
for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
for C in [0.001, 0.01, 0.1, 1, 10, 100]:
# for each combination of parameters, train an SVC
svm = SVC(gamma=gamma, C=C)
svm.fit(X_train, y_train)
# evaluate the SVC on the test set
score = svm.score(X_test, y_test)
# if we got a better score, store the score and parameters
if score > best_score:
best_score = score
best_parameters = {'C': C, 'gamma': gamma}
print("Best score: {:.2f}".format(best_score))
print("Best parameters: {}".format(best_parameters))