BayesianOptimization
BayesianOptimization copied to clipboard
How to treat the problem with related parameters?
The problem I am dealing with has 3 parameters, however, there is a constrained relation between x and y. For example, x+y should always be equal to 4. (x+y=4).
What can I do to make the BO give me the suggestions that satisfy the limits of x+y=4?
Hi @UCASAlbert,
this particular problem can be solved by re-parameterizing your the original target and using a surrogate function, as outlined here.
In your specific case it could look something like this:
surrogate = lambda x, z: original_target_function(x=x, y=4-x, z=z)
# NB: your current bounds don't agree with your equality constraint
pbounds = {'x': (2, 4), 'z':(3,5)}
and then proceed as usual. Let me know if this helps.
Hi @UCASAlbert,
this particular problem can be solved by re-parameterizing your the original target and using a surrogate function, as outlined here.
In your specific case it could look something like this:
surrogate = lambda x, z: original_target_function(x=x, y=4-x, z=z) # NB: your current bounds don't agree with your equality constraint pbounds = {'x': (2, 4), 'z':(3,5)}
and then proceed as usual. Let me know if this helps.
thanks for your suggestion, but the function is unknown in my task, which means "surrogate = lambda x, z: original_target_function(x=x, y=4-x, z=z)" perhaps won't work.
Even if the function is unknown, your equality constraint reduces the degrees of freedom so your problem is dependent on 2 parameters instead of 3. If the relation imposed by the constraint is simple enough (as in your example) then it should be restatable in a form using fewer parameters quite easily. To adapt your example, maybe something like this makes sense:
pbounds = {'x': (2, 4), 'z': (3,5)}
optimizer = BayesianOptimization(
f=None,
pbounds=pbounds,
verbose=2,
random_state=1
)
utility = UtilityFunction(kind="ucb", kappa=2.5, xi=0.05)
next_point_to_probe = optimizer.suggest(utility)
# 4 = x + y => y = 4 - x
next_point_to_probe['y'] = 4 - next_point_to_probe['x']
Out:
{'x': 2.8340440094051482, 'z': 4.440648986884316, 'y': 1.1659559905948518}
If this still doesn't work for your case, please provide a minimal, reproducible example (i.e. as described here) because I think I might be misunderstanding something about your problem.
thanks a lot for your comment. this seems really a feasible solution. thank you very much.
@bwheelz36 this can be closed I think.