HyperOpt-quniform 范围问题

251 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情

在使用 quniform 的时候,可能会出现超出指定范围的值,例如对于 GBDT 设置参数空间为 'learning_rate':hp.quniform('learning_rate',0.05,2.05,0.2),但是仍然会报错 ValueError: learning_rate must be greater than 0 but was 0.0,但我们并没有把 0 设置在范围内。

实际上,Hyperopt 对于 quniform 的处理并不是类似于 range(起始,终止,步长) ,而是另一种处理方式,这里可以查看官方文档

hp.quniform(label, low, high, q) Returns a value like round (uniform (low, high) / q) * q 返回像 round (uniform (low, high) / q) * q 的值

Suitable for a discrete value with respect to which the objective is still somewhat "smooth", but which should be bounded both above and below. 适用于相对取值仍然有点“平滑”,但应有上下限限制的离散值。

进一步,我们需要看一下 uniform 的定义

hp.uniform(label, low, high) Returns a value uniformly between low and high. 返回值介于在 low 和 hight 之间

When optimizing, this variable is constrained to a two-sided interval. 在优化的时候,这个变量被限制在最大值和最小值中间

因此对于上面的报错我们就可以找到原因了。根据给出的公式 round(uniform(low,high)/q)qround (uniform (low, high) / q) * q ,我们代入任意小于 12q\frac{1}{2}q 的的值,该式即为

round(12qϵq)q=round(1/2ϵ)q=0q=0\begin{aligned} &round(\frac{\frac{1}{2}q-\epsilon }{q})*q\\ =&round(1/2-\epsilon )*q\\ =&0*q\\ =&0 \end{aligned}

这里 ϵ\epsilon 是一个很小的正数。

附:HyperOpt个人优化模板

import numpy as np
from hyperopt import hp,fmin,tpe,Trials,partial
from hyperopt.early_stop import no_progress_loss
from sklearn.model_selection import KFold,cross_validate

cv = KFold(shuffle=True,random_state=110)
def hyperopt_objective(params):
    model = 模型(超参数=params['超参数']
				,random_state=110
				,n_jobs=8
			   )
    validation_loss = cross_validate(model,X,y
                                     ,scoring='评估指标'
                                     ,cv=cv
                                     ,n_jobs=8
                                     ,error_score='raise'
                                    )
    return validation_loss['test_score']可能需要处理

param_grid = {看定义写
             }

def param_hyperopt(max_evals=100):
    trials = Trials()
    early_stop_fn = no_progress_loss(30)
    params_best = fmin(hyperopt_objective
                       ,param_grid
                       ,algo=tpe.suggest
                       ,max_evals=max_evals
                       ,verbose=True
                       ,trials=trials
                       ,early_stop_fn=early_stop_fn
                      )
    return params_best, trials

param_best,trials = param_hyperopt(一共采集多少个点)