pythondeap

Human-readable output with DEAP


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

Solution

  • 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.