人类可读的DEAP输出

2024-10-03 17:21:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用DEAP对数据表进行符号回归,即找到一个最适合数据的函数。不幸的是,我找不到一种方法来获得人类可读格式的结果。例如,如果我这么做

best_ind = tools.selBest(pop, 1)[0]
print("Best individual is %s" % (best_ind))

我的输出可能看起来像

^{pr2}$

但这对人类来说很难解释。有没有办法把结果打印得更像

(x+2)*(y/(x+y))+1

Tags: 数据方法函数格式符号人类toolspop
2条回答

您可以从使用sympy.simplify开始

import sympy

expr = "Add(x, 2)"
sympy.simplify(expr)  # x + 2

但是,sympy希望add、mul等大写。您还需要将Div(a, b)转换为Mul(a, 1/b)。在

您可以通过如下方式更改primitive.format方法来完成此操作:

^{pr2}$

此代码取自glyph。在

Ohjeahs的答案不能按规定工作。我修改了提供的代码,并在下面提供了它。在

import sympy
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_),
        'protectedDiv': lambda *args_: "Mul({}, Pow({}, -1))".format(*args_),
        'mul': lambda *args_: "Mul({},{})".format(*args_),
        'add': lambda *args_: "Add({},{})".format(*args_)
    }
    prim_formatter = converter.get(prim.name, prim.format)

    return prim_formatter(*args)

def stringify_for_sympy(f):
    """Return the expression in a human readable string.
    """
    string = ""
    stack = []
    for node in f:
        stack.append((node, []))
        while len(stack[-1][1]) == stack[-1][0].arity:
            prim, args = stack.pop()
            string = convert_inverse_prim(prim, args)
            if len(stack) == 0:
                break  # If stack is empty, all nodes should have been seen
            stack[-1][1].append(string)
    return string

sympy.simplify(stringify_for_sympy(best_ind))

相关问题 更多 >