I am using DEAP to do symbolic regression on a table of data, i.e. finding a function that best fits the data. Unfortunately, I can't find a way of getting the result in human-readable format. For instance, if I do
best_ind = tools.selBest(pop, 1)[0]
print("Best individual is %s" % (best_ind))
my output is likely to look something like
Best individual is add(mul(add(x, 2), div(y, add(x, y))), 1)
but that is difficult for a human to interpret. Is there a way to print the result in a way that looks more like
(x+2)*(y/(x+y))+1
You can start with using sympy.simplify
import sympy
expr = "Add(x, 2)"
sympy.simplify(expr) # x + 2
However, sympy wants add, mul etc capitalized. Also You need to translate Div(a, b)
to Mul(a, 1/b)
.
You can do this by changing the primitive.format
method like so:
def convert_inverse_prim(prim, args):
"""
Convert inverse prims according to:
[Dd]iv(a,b) -> Mul[a, 1/b]
[Ss]ub(a,b) -> Add[a, -b]
We achieve this by overwriting the corresponding format method of the sub and div prim.
"""
prim = copy.copy(prim)
prim.name = re.sub(r'([A-Z])', lambda pat: pat.group(1).lower(), prim.name) # lower all capital letters
converter = {
'sub': lambda *args_: "Add({}, Mul(-1,{}))".format(*args_),
'div': lambda *args_: "Mul({}, Pow({}, -1))".format(*args_)
}
prim_formatter = converter.get(prim.name, prim.format)
return prim_formatter(*args)
This code is taken from glyph.