我正在使用支持向量机对不平衡类进行二进制分类(即我的训练集中的正负标签的比例为~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
不接受任何其他关键字参数(X
和y
)。我尝试了上述的不同变体,但未能弄清楚如何传递不应该针对例程优化的其他参数。
据我所知,我不能使用scikit-learn的网格搜索,因为我想优化m
参数,这不是“内在的”。到估算器。有人可以指点我的解决方案或其他python包进行gridsearch吗?
答案 0 :(得分:3)
在回答实际问题之前的一些评论:
gamma
才能获得良好的结果。仅调整错误分类处罚(C
和weights
)是不够的。optunity.maximize
,optunity.minimize
和optunity.optimize
,而不是您使用的解算器专用方法。虽然两者都提供类似的功能,但API功能可能更容易使用。m
和w
有些多余。如果您要优化班级权重,则不必平衡班级。我会停止优化课程余额(您必须在其中进行过度采样=更改数据)。您为optimize
指定的函数必须是目标函数,这意味着此函数的唯一参数必须是您要优化的超参数。有关此问题的更多信息,请参阅Optunity's paper。在您的具体示例中,这意味着参数应为c
,m
和w
。
要修复X
和y
,您可以使用任何标准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_fixed
和y_fixed
,并根据需要生成一个只有参数超参数的函数。然后你可以做这样的事情(假设你已经构建了求解器等):
svm_acc_with_fixed_data = fix_data(X, y)
best_pars, _ = s.optimize(svm_acc_with_fixed_data)