我正在努力弄清楚如何在参数优化方法上设置边界(最小/最大)。 Twiddle是优化算法:https://www.youtube.com/watch?v=2uQ2BSzDvXs。如何确保p(参数)保持在某个域内?下面是我在Python中的Twiddle实现:
def twiddle(objFunction, args, init=0.5, tolerance=0.00001, domain=(0,float("inf"))):
"""Optimize a single parameter given an objective function.
This is a local hill-climbing algorithm. Here is a simple description of it:
https://www.youtube.com/watch?v=2uQ2BSzDvXs
@param args (tuple) Arguments necessary for the objective function.
@param tolerance (float) Number used to determine when optimization has
converged to a sufficiently good score.
@param objFunction(function)Objective Function used to quantify how good a
particular parameter choice is.
@param init (float) Initial value of the parameter.
@param domain (tuple) Domain of parameter values, as (min, max).
@return (dict) Contains:
"parameter" (float) Threshold that returns the largest score from the
Objective function.
"score" (float) The score from the objective function given the
threshold.
"""
pastCalls = {}
x = init
delta = 0.1
bestScore = objFunction(x, args)
pastCalls[x] = bestScore
while delta > tolerance: #and x >= domain[0]+tolerance and x <= domain[1]-tolerance:
x += delta
if x not in pastCalls:
score = objFunction(x, args)
pastCalls[x] = score
score = pastCalls[x]
if score > bestScore:
bestScore = score
delta *= 2
else:
x -= 2*delta
if x not in pastCalls:
score = objFunction(x, args)
pastCalls[x] = score
score = pastCalls[x]
if score > bestScore:
bestScore = score
delta *= 2
else:
x += delta
delta *= 0.5
print "Parameter:", x
print "Best score:", bestScore
print "delta:", delta
print
return {"parameter": x,
"score": bestScore}
E.g。我想将正弦函数作为objFunction
运行,但域名设置为[0,2 * pi]。
答案 0 :(得分:2)
知道了!与@ AlexMartelli的评论类似,该算法需要防止在每次递增/递减到x时越界。为了保持爬山算法的核心功能,步长delta
必须调整到当前位置和外边界之间距离的一半。这样算法仍然倾向于在边界方向上移动,如果最大值在边界处可以到达那里,并且如果需要可以从边界移回。代码如下:
def twiddle(objFunction, args, init=0.5, tolerance=0.00001, domain=(float("-inf"), float("inf"))):
"""Optimize a single parameter given an objective function.
This is a local hill-climbing algorithm. Here is a simple description of it:
https://www.youtube.com/watch?v=2uQ2BSzDvXs
@param args (tuple) Arguments necessary for the objective function.
@param tolerance (float) Number used to determine when optimization has
converged to a sufficiently good score.
@param objFunction(function)Objective Function used to quantify how good a
particular parameter choice is.
@param init (float) Initial value of the parameter.
@param domain (tuple) Domain of parameter values, as (min, max).
@return (dict) Contains:
"parameter" (float) Threshold that returns the largest score from the
Objective function.
"score" (float) The score from the objective function given the
threshold.
"""
pastCalls = {}
x = init
delta = 0.1
bestScore = objFunction(x, args)
pastCalls[x] = bestScore
while delta > tolerance:
# Keep x within bounds
if x+delta > domain[1]:
delta = abs(domain[1] - x) / 2
x += delta
if x not in pastCalls:
score = objFunction(x, args)
pastCalls[x] = score
score = pastCalls[x]
if score > bestScore:
bestScore = score
delta *= 2
else:
# Keep x within bounds
if x-delta < domain[0]:
delta = abs(domain[0] - x) / 2
x -= 2*delta
if x not in pastCalls:
score = objFunction(x, args)
pastCalls[x] = score
score = pastCalls[x]
if score > bestScore:
bestScore = score
delta *= 2
else:
x += delta
delta *= 0.5
print "Parameter:", x
print "Best score:", bestScore
print "Step size:", delta
print
return {"parameter": x,
"score": bestScore}