operon
operon copied to clipboard
Custom cost function
Hello,
just checking if it is possible to use a custom cost function like
def mycost(expr_str):
cost = myfun(eval(expr_str))
return cost
Thnks
Hi,
Yes, it is possible. With the C++ library, you can construct a UserDefinedEvaluator
with a lambda, see here for an example.
With the python bindings, you need to define a custom function and pass it to the UserDefinedEvaluator
. Consider the operon-bindings.py example. The following changes will work:
diff --git a/example/operon-bindings.py b/example/operon-bindings.py
index 100a4e4..b3f3ce5 100644
--- a/example/operon-bindings.py
+++ b/example/operon-bindings.py
@@ -74,10 +74,14 @@ mutation.Add(mut_replace, 1)
crossover_internal_probability = 0.9 # probability to pick an internal node as a cut point
crossover = Operon.SubtreeCrossover(crossover_internal_probability, maxD, maxL)
+def custom_eval(rng, ind):
+ return [ ind.Genotype.Length ]
+
# define fitness evaluation
interpreter = Operon.Interpreter() # tree interpreter
error_metric = Operon.R2() # use the coefficient of determination as fitness
-evaluator = Operon.Evaluator(problem, interpreter, error_metric, True) # initialize evaluator, use linear scaling = True
+#evaluator = Operon.Evaluator(problem, interpreter, error_metric, True) # initialize evaluator, use linear scaling = True
+evaluator = Operon.UserDefinedEvaluator(problem, custom_eval)
evaluator.Budget = 1000 * 1000 # computational budget
evaluator.LocalOptimizationIterations = 0 # number of local optimization iterations (coefficient tuning using gradient descent)
Note that this will most likely incur a performance cost due to crossing the python/C++ boundary. If the cost function is expensive enough it might not matter.
I hope this answers your question.
EDIT your question seems to be specifically about using operon to evaluate an expression string, yes that's possible, but a bit more involved. you'd have to create by hand the objects involved in evaluation (a dataset, interpreter, problem -- see example above). you can use operon.InfixParser.Parse (see here which takes the string and a dictionary mapping the variable names to variable hashes from the dataset). I will try to provide a full example in the next days.
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.