Python Optunity:如何将其他参数传递给优化例程

时间:2015-06-22 21:42:08

标签: python optimization scikit-learn

背景

我正在使用支持向量机对不平衡类进行二进制分类(即我的训练集中的正负标签的比例为~100)。我想优化以下参数:m(我从训练数据中采样的正负标签的比例),w(类权重)和SVM参数C.

问题

我想通过gridsearch优化这些参数,并按如下方式定义了得分函数:

def svm_acc(X, y, m, w, c):
  X, y = balanceClasses(X, y, m)
  clf = svm.SVC(kernel='rbf', C=c, class_weight = {1: w})
  scores = cross_validation.cross_val_score(clf, X, y, 5)
  return( scores.mean() )

其中X是特征矩阵,y是二进制分类标签,svm_acc返回5倍交叉验证的平均准确度。我在选择中尝试了以下方法:

import optunity as opt
s = opt.solvers.GridSearch(mult=[1,10], w=[1,10], c=[1,10])
best_pars, _ = s.optimize(svm_acc, X=X, y=y)

但是我收到了这个错误:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: optimize() got an unexpected keyword argument 'X'

我从文档中收集optimize不接受任何其他关键字参数(Xy)。我尝试了上述的不同变体,但未能弄清楚如何传递不应该针对例程优化的其他参数。

据我所知,我不能使用scikit-learn的网格搜索,因为我想优化m参数,这不是“内在的”。到估算器。有人可以指点我的解决方案或其他python包进行gridsearch吗?

1 个答案:

答案 0 :(得分:3)

在回答实际问题之前的一些评论:

  1. 使用RBF内核时,您必须调整gamma才能获得良好的结果。仅调整错误分类处罚(Cweights)是不够的。
  2. main API functionsoptunity.maximizeoptunity.minimizeoptunity.optimize,而不是您使用的解算器专用方法。虽然两者都提供类似的功能,但API功能可能更容易使用。
  3. 对于实际调整任务,我强烈建议在网格搜索中使用默认粒子群优化器。在更少的函数评估(=时间)中,您将获得更好的结果。
  4. 使用Optunity的交叉验证设施可能更容易,而不是scikit-learn。但这完全是可选的。您可以找到有关此here
  5. 的更多信息
  6. 超参数mw有些多余。如果您要优化班级权重,则不必平衡班级。我会停止优化课程余额(您必须在其中进行过度采样=更改数据)。
  7. 解决方案

    您为optimize指定的函数必须是目标函数,这意味着此函数的唯一参数必须是您要优化的超参数。有关此问题的更多信息,请参阅Optunity's paper。在您的具体示例中,这意味着参数应为cmw

    要修复Xy,您可以使用任何标准Python方法,例如functools.partial或闭包。在我看来,闭包是最干净的方法:

    def fix_data(X_fixed, y_fixed):
        def svm_acc(m, w, c):
            X, y = balanceClasses(X_fixed, y_fixed, m)
            clf = svm.SVC(kernel='rbf', C=c, class_weight = {1: w})
            scores = cross_validation.cross_val_score(clf, X, y, 5)
            return( scores.mean() )
    
        return svm_acc
    

    函数fix_data修复了某个数据集X_fixedy_fixed,并根据需要生成一个只有参数超参数的函数。然后你可以做这样的事情(假设你已经构建了求解器等):

    svm_acc_with_fixed_data = fix_data(X, y)
    best_pars, _ = s.optimize(svm_acc_with_fixed_data)