Python Optunity:如何将附加参数传递给优化例程
Python Optunity: how to pass additional arguments to optimization routines
背景
我正在使用支持向量机对不平衡 classes 进行二进制 class 化(即我的训练集中正负标签的比例约为 100)。我想优化以下参数:m(我从训练数据中采样的正标签与负标签的比率)、w(class 权重)和 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 是二进制 class化标签,svm_acc
returns 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
不接受任何额外的关键字参数(X
和 y
)。我已经尝试了上述的不同变体,但无法弄清楚如何将不应优化的附加参数传递给例程。
据我所知,我不能使用 scikit-learn 的 gridsearch,因为我想优化 m
参数,这不是估计器的 'intrinsic'。谁能指出解决方案或其他 python 进行网格搜索的软件包?
回答实际问题前的几点评论:
- 使用 RBF 内核时,您确实需要调整
gamma
才能获得好的结果。仅调整 misclass 化惩罚(C
和 weights
)是不够的。
- main API functions 是
optunity.maximize
、optunity.minimize
和 optunity.optimize
,而不是您正在使用的特定于求解器的方法。虽然两者都提供相似的功能,但 API 函数可能更易于使用。
- 对于真正的调整任务,我强烈建议使用默认的粒子群优化器而不是网格搜索。您将在更少的函数评估(= 时间)中获得更好的结果。
- 使用 Optunity 的交叉验证工具而不是 scikit-learn 的工具可能更容易。不过,这完全是可选的。您可以找到有关此 here.
的更多信息
- 超参数
m
和 w
有点多余。如果您要优化 class 权重,则不必平衡 classes。我会停止优化 class 平衡(为此你必须在 - 或过采样 = 改变你的数据)。
解决方案
您为 optimize
指定的函数必须是 objective 函数,这意味着此函数的唯一参数必须是您要优化的超参数。有关这方面的更多信息,请参阅 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)
背景
我正在使用支持向量机对不平衡 classes 进行二进制 class 化(即我的训练集中正负标签的比例约为 100)。我想优化以下参数:m(我从训练数据中采样的正标签与负标签的比率)、w(class 权重)和 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 是二进制 class化标签,svm_acc
returns 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
不接受任何额外的关键字参数(X
和 y
)。我已经尝试了上述的不同变体,但无法弄清楚如何将不应优化的附加参数传递给例程。
据我所知,我不能使用 scikit-learn 的 gridsearch,因为我想优化 m
参数,这不是估计器的 'intrinsic'。谁能指出解决方案或其他 python 进行网格搜索的软件包?
回答实际问题前的几点评论:
- 使用 RBF 内核时,您确实需要调整
gamma
才能获得好的结果。仅调整 misclass 化惩罚(C
和weights
)是不够的。 - main API functions 是
optunity.maximize
、optunity.minimize
和optunity.optimize
,而不是您正在使用的特定于求解器的方法。虽然两者都提供相似的功能,但 API 函数可能更易于使用。 - 对于真正的调整任务,我强烈建议使用默认的粒子群优化器而不是网格搜索。您将在更少的函数评估(= 时间)中获得更好的结果。
- 使用 Optunity 的交叉验证工具而不是 scikit-learn 的工具可能更容易。不过,这完全是可选的。您可以找到有关此 here. 的更多信息
- 超参数
m
和w
有点多余。如果您要优化 class 权重,则不必平衡 classes。我会停止优化 class 平衡(为此你必须在 - 或过采样 = 改变你的数据)。
解决方案
您为 optimize
指定的函数必须是 objective 函数,这意味着此函数的唯一参数必须是您要优化的超参数。有关这方面的更多信息,请参阅 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)