【问题标题】:Python Optunity: how to pass additional arguments to optimization routinesPython Optunity:如何将附加参数传递给优化例程
【发布时间】:2015-06-23 14:48:22
【问题描述】:

背景

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

问题

我想通过网格搜索来优化这些参数,并定义了分数函数如下:

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 折交叉验证的平均准确度。我在 optunity 中尝试了以下方法:

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 包?

【问题讨论】:

    标签: python optimization scikit-learn


    【解决方案1】:

    在回答实际问题之前先说几句:

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

    解决办法

    您为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)
    

    【讨论】:

    • 感谢您的建议和快速回复!
    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    相关资源
    最近更新 更多