【问题标题】:Is there a quicker way of running GridsearchCV有没有更快的运行 GridsearchCV 的方法
【发布时间】:2016-06-09 21:41:23
【问题描述】:

我正在优化 sklearn 中 SVC 的一些参数,这里最大的问题是必须等待 30 分钟才能尝试任何其他参数范围。更糟糕的是,我想在同一范围内尝试更多的 c 和 gamma 值(这样我可以创建更平滑的曲面图),但我知道这将花费越来越长的时间......当我今天运行它时我将 cache_size 从 200 更改为 600(并不真正知道它的作用),看看它是否有所作为。时间减少了大约一分钟。

这是我可以帮忙的吗?还是我只需要处理很长时间?

clf = svm.SVC(kernel="rbf" , probability = True, cache_size = 600)

gamma_range = [1e-7,1e-6,1e-5,1e-4,1e-3,1e-2,1e-1,1e0,1e1]
c_range = [1e-3,1e-2,1e-1,1e0,1e1,1e2,1e3,1e4,1e5]
param_grid = dict(gamma = gamma_range, C = c_range)

grid = GridSearchCV(clf, param_grid, cv= 10, scoring="accuracy")
%time grid.fit(X_norm, y)

返回:

Wall time: 32min 59s

GridSearchCV(cv=10, error_score='raise',
   estimator=SVC(C=1.0, cache_size=600, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
kernel='rbf', max_iter=-1, probability=True, random_state=None,
shrinking=True, tol=0.001, verbose=False),
   fit_params={}, iid=True, loss_func=None, n_jobs=1,
   param_grid={'C': [0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0], 'gamma': [1e-07, 1e-06, 1e-05, 0.0001, 0.001, 0.01, 0.1, 1.0, 10.0]},
   pre_dispatch='2*n_jobs', refit=True, score_func=None,
   scoring='accuracy', verbose=0)

【问题讨论】:

    标签: python time scikit-learn svc grid-search


    【解决方案1】:

    一些事情:

    1. 10 倍 CV 是多余的,会导致您为每个参数组拟合 10 个模型。通过切换到 5 倍或 3 倍 CV(即 GridSearchCV 调用中的 cv=3),您可以立即获得 2-3 倍的加速,而不会对性能估计产生任何有意义的差异。
    2. 在每一轮中尝试更少的参数选项。使用 9x9 组合,您在每次运行中尝试 81 种不同的组合。通常,您会在规模的一端或另一端发现更好的性能,因此可能从一个包含 3-4 个选项的粗网格开始,然后在您开始识别对您的数据更感兴趣的区域时再细化。 3x3 选项意味着与您现在所做的相比,速度提高了 9 倍。
    3. 您可以通过在 GridSearchCV 调用中将 njobs 设置为 2+ 来获得微不足道的加速,这样您就可以一次运行多个模型。根据数据的大小,您可能无法将其增加得太高,并且您不会看到将其增加到超过您正在运行的核心数量的改进,但您可能可以通过这种方式减少一些时间.

    【讨论】:

    • 将 njobs 设置为 -1 将自动为每个核心创建 1 个作业。根据您的型号,内存可能会成为问题,但通常不会!
    【解决方案2】:

    您还可以在 SVC 估计器中设置probability=False,以避免在内部应用昂贵的 Platt 校准。 (如果能够运行 predict_proba 至关重要,请使用 refit=False 执行 GridSearchCv,并在根据模型在测试集上的质量方面选择最佳参数集后,只需在整个训练集上重新训练概率 = True 的最佳估计器。)

    另一个步骤是使用RandomizedSearchCV 而不是GridSearchCV,这将允许您在大致相同的时间达到更好的模型质量(由n_iters 参数控制)。

    如前所述,使用n_jobs=-1

    【讨论】:

      【解决方案3】:

      除了其他答案(例如不使用 10 倍 CV 并且每轮使用更少的参数选项)之外,还有其他方法可以加快模型速度。

      并行化您的代码

      Randy 提到可以使用 n_jobs 来并行化您的 taining(这取决于您计算机上的内核数量)。与下面代码的唯一区别是它使用n_jobs = -1,它会自动为每个核心创建 1 个作业。因此,如果您有 4 个核心,它将尝试利用所有 4 个核心。下面的代码在 8 核计算机上运行。在我的电脑上使用n_jobs = -1 需要 18.3 秒,而没有使用 n_jobs = -1 则需要 2 分 17 秒。

      import numpy as np
      from sklearn import svm
      from sklearn import datasets
      from sklearn.model_selection import GridSearchCV
      rng = np.random.RandomState(0)
      X, y = datasets.make_classification(n_samples=1000, random_state=rng)
      
      
      clf = svm.SVC(kernel="rbf" , probability = True, cache_size = 600)
      
      gamma_range = [1e-7,1e-6,1e-5,1e-4,1e-3,1e-2,1e-1,1e0,1e1]
      c_range = [1e-3,1e-2,1e-1,1e0,1e1,1e2,1e3,1e4,1e5]
      param_grid = dict(gamma = gamma_range, C = c_range)
      
      grid = GridSearchCV(clf, param_grid, cv= 10, scoring="accuracy", n_jobs = -1)
      %time grid.fit(X, y)
      

      请注意,如果您有权访问集群,则可以使用 Dask or Ray 分发您的培训。

      不同的超参数优化技术

      您的代码使用GridSearchCV,这是对估算器的指定参数值的详尽搜索。 Scikit-Learn 还有RandomizedSearchCV,它从具有指定分布的参数空间中对给定数量的候选者进行采样。对下面的代码示例使用随机搜索需要 3.35 秒。

      import numpy as np
      
      from sklearn import svm
      from sklearn import datasets
      from sklearn.model_selection import RandomizedSearchCV
      
      rng = np.random.RandomState(0)
      X, y = datasets.make_classification(n_samples=1000, random_state=rng)
      
      
      clf = svm.SVC(kernel="rbf" , probability = True, cache_size = 600)
      
      gamma_range = [1e-7,1e-6,1e-5,1e-4,1e-3,1e-2,1e-1,1e0,1e1]
      c_range = [1e-3,1e-2,1e-1,1e0,1e1,1e2,1e3,1e4,1e5]
      param_grid = dict(gamma = gamma_range, C = c_range)
      
      grid = RandomizedSearchCV(clf, param_grid, cv= 10, scoring="accuracy", n_jobs = -1)
      %time grid.fit(X, y)
      

      图片来自documentation

      最近(scikit-learn 0.24.1 January 2021),scikit-learn 添加了实验性超参数搜索估计器,将网格搜索减半(HalvingGridSearchCV)和随机搜索减半(HalvingRandomSearch)。这些技术可用于使用连续减半来搜索参数空间。上图显示在第一次迭代中使用少量资源评估所有超参数候选者,并在每次后续迭代中选择更有希望的候选者并给予更多资源。您可以通过升级您的 scikit-learn (pip install --upgrade scikit-learn )

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-04
        • 1970-01-01
        • 1970-01-01
        • 2018-12-12
        • 2016-02-06
        • 2011-03-22
        • 1970-01-01
        相关资源
        最近更新 更多