svm.SVC()的超参数在GridSearchCV()中探索的一个好的取值范围是什么?

23

我遇到了一个问题,我的svm.SVC()的超参数范围太大了,以至于GridSearchCV()永远无法完成!一个想法是改用RandomizedSearchCV()。但是,我的数据集相对较大,500次迭代需要大约1小时时间!

我的问题是,在GridSearchCV(或RandomizedSearchCV)中,如何设置好超参数的值域范围,以便停止浪费资源?

换句话说,如何确定是否例如C值超过100是有意义的,步长为1既不大也不小?非常感谢任何帮助。这是我目前正在使用的设置:

parameters = {
    'C':            np.arange( 1, 100+1, 1 ).tolist(),
    'kernel':       ['linear', 'rbf'],                   # precomputed,'poly', 'sigmoid'
    'degree':       np.arange( 0, 100+0, 1 ).tolist(),
    'gamma':        np.arange( 0.0, 10.0+0.0, 0.1 ).tolist(),
    'coef0':        np.arange( 0.0, 10.0+0.0, 0.1 ).tolist(),
    'shrinking':    [True],
    'probability':  [False],
    'tol':          np.arange( 0.001, 0.01+0.001, 0.001 ).tolist(),
    'cache_size':   [2000],
    'class_weight': [None],
    'verbose':      [False],
    'max_iter':     [-1],
    'random_state': [None],
    }

model = grid_search.RandomizedSearchCV( n_iter              = 500,
                                        estimator           = svm.SVC(),
                                        param_distributions = parameters,
                                        n_jobs              = 4,
                                        iid                 = True,
                                        refit               = True,
                                        cv                  = 5,
                                        verbose             = 1,
                                        pre_dispatch        = '2*n_jobs'
                                        )         # scoring = 'accuracy'
model.fit( train_X, train_Y )
print( model.best_estimator_ )
print( model.best_score_ )
print( model.best_params_ )
2个回答

20

哪种内核最适合取决于您的数据。样本数量和维数以及您拥有的数据类型是什么都很重要。

为了使范围可比较,您需要对数据进行规范化,通常使用StandardScaler,它可以将数据归零并具有单位方差,这是一个好主意。

如果您的数据是非负的,则可以尝试使用MinMaxScaler。

对于kernel="gamma",我通常会这样做:

{'C': np.logspace(-3, 2, 6), 'gamma': np.logspace(-3, 2, 6)}

这是基于无基础的,但在过去的几年里一直为我服务得很好。 我强烈反对使用非对数网格,甚至更不建议使用离散参数的随机搜索。 随机搜索的主要优点之一是您实际上可以使用连续分布搜索连续参数 [请参阅文档]


你是在暗示混合连续和离散参数在随机搜索中不明智吗?为什么会这样,当单个算法的参数混合时,你通常如何搜索这些参数? - B_Miner
你也可以在这里查看我演讲的中间部分:https://www.youtube.com/watch?v=0wUF_Ov8b0A - Andreas Mueller
3
如果您的数据是非负的,可以尝试使用MinMaxScaler。这个细节对我的数据产生了很大的影响,不仅适用于SVM,还适用于Lasso和RFE特征选择。非常有帮助,谢谢! - nischi
3
Andreas,您能否提供一个建议,将离散集 'gamma': np.logspace(-3, 2, 6) 重写为连续的?scipy.expon在sklearn示例中经常使用,但振幅不够大,并且scipy没有本地对数均匀生成器。那么,您最喜欢用随机数发生器编写 'gamma': np.logspace(-3, 2, 6) 的方式是什么,让我们跳过重新发明轮子的步骤? :-) - Anatoly Alekseev

9

要搜索超参数,了解每个超参数的作用总是更好的选择...

C : float, optional (default=1.0)
    Penalty parameter C of the error term.

你应该尝试按数量级变化(0、0.1、1、10、100),然后再在数量级之间缩小搜索范围,但我认为这并不能太大程度上改善你的模型。
degree : int, optional (default=3)
   Degree of the polynomial kernel function (‘poly’). Ignored by all other kernels.

在这里,你应该改变网格搜索的方式,因为正如文档所示,degree仅用于多项式内核,因此当使用“rbf”内核时,你将浪费时间查找每个degree。另一个要点是,使用太多degree只会使数据过度拟合。在这里使用类似(1,2,3,4,5)的东西。

对于coef0也是同样的情况,因为它仅与'poly'内核一起使用。

tol : float, optional (default=1e-3)
   Tolerance for stopping criterion.

我不会碰那个,你的数值范围并没有什么意义。
我对伽马参数不是很熟悉。
因此,请使用这种表示方式代替你的(http://scikit-learn.org/stable/modules/grid_search.html#exhaustive-grid-search):
param_grid = [
 {'C': [1, 10, 100, 1000], 'kernel': ['linear']},
 {'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
]

尝试理解每个参数的含义:

http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf

http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接