【问题标题】:DEAP genetic program - crossover failed (incomplete tree)DEAP 遗传程序 - 交叉失败(不完整的树)
【发布时间】:2020-03-29 18:14:29
【问题描述】:

我使用 deep 进行基因编程。我个人是表达式树。我添加了一些带有 arity 1 和 2 的自定义运算符。

pset = gp.PrimitiveSet("MAIN", 7)
pset.addPrimitive(operator.add, 2)
pset.addPrimitive(operator.sub, 2)
pset.addPrimitive(operator.mul, 2)
pset.addPrimitive(cop.delay10, 1)
pset.addPrimitive(cop.arg_max, 1)
pset.addPrimitive(cop.arg_min, 1)
pset.addPrimitive(cop.rank, 1)
pset.addPrimitive(cop.ma_n, 1)
pset.addPrimitive(cop.std_n, 1)
pset.addPrimitive(cop.max_diff, 1)
pset.addPrimitive(cop.min_diff, 1)
pset.addPrimitive(cop.factor_cov, 2)
pset.addPrimitive(cop.factor_corr, 2)

pset.renameArguments(ARG0="open")
pset.renameArguments(ARG1="high")
pset.renameArguments(ARG2="low")
pset.renameArguments(ARG3="close")
pset.renameArguments(ARG4="volume")
pset.renameArguments(ARG5="turn")
pset.renameArguments(ARG6="re_turn")

# Creators
creator.create("FitnessMax", base.Fitness, weights=(1.0,)) 
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMax)

# Create Individuals
toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=2, max_=5)  
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)

# Create initial population
N_POP = 4 
toolbox.register('population', tools.initRepeat, list, toolbox.individual)
toolbox.register("compile", gp.compile, pset=pset)

def evaluate_fit():
... # the part I customize my fitness score calculation function

toolbox.register("evaluate", evaluate_fit, stock_map=stock_dict, mkt=mkt_value, daily_return=wap_return)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("mate", tools.cxOnePoint)
toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)

toolbox.decorate("mate", gp.staticLimit(key=operator.attrgetter("height"), max_value=17))
toolbox.decorate("mutate", gp.staticLimit(key=operator.attrgetter("height"), max_value=17))

pop = toolbox.population(n=N_POP)
hof = tools.HallOfFame(2)

pop = algorithms.eaSimple(pop, toolbox, 0.5, 0.1, 2,
                          halloffame=hof, verbose=False)

我的大部分参数设置与官方示例非常相似:https://github.com/DEAP/deap/blob/454b4f65a9c944ea2c90b38a75d384cddf524220/examples/gp/symbreg.py 我使用相同的交叉方法:csOnePoint,我的程序的所有其他设置与此示例相同。 我认为我的程序和这个例子之间唯一的不同是自定义的操作符和评估方法。但我不知道为什么我做交叉步骤时总是出错,我有这个错误:

ValueError: Invalid slice assignment : PrimitiveTree 中不允许插入不完整的子树。考虑到基元的数量,当某些节点无法映射到树中的任何位置时,树被定义为不完整的。例如,如果 sub 的元数为 2,则树 [sub, 4, 5, 6] 是不完整的,因为它会产生一个孤立节点(即 6)。

我理解这可能意味着交叉后的树不满足数量要求,但我不知道为什么会出现这个问题。当我尝试 symberg.py 示例时,我没有遇到这个问题。

【问题讨论】:

    标签: python genetic-algorithm genetic-programming deap


    【解决方案1】:

    遇到同样的问题,可悲的是随着深入研究而变得更加困惑。

    当我从 here 复制引发错误的代码时:

    for node in val[1:]:
        total += node.arity - 1
    if total != 0:
        raise ValueError("Invalid slice assignation : insertion of"
            " an incomplete subtree is not allowed in PrimitiveTree."
            " A tree is defined as incomplete when some nodes cannot"
            " be mapped to any position in the tree, considering the"
            " primitives' arity. For instance, the tree [sub, 4, 5,"
            " 6] is incomplete if the arity of sub is 2, because it"
            " would produce an orphan node (the 6).")
    

    并且只是在树上单独运行以进行交叉,两棵树的arity分数均为0。

    【讨论】:

    • 这并不能真正回答问题。如果您有其他问题,可以点击 提问。您也可以add a bounty 引起更多关注这个问题。 - From Review
    • 啊,抱歉并不是 100% 确定流程,只是想节省一些时间调查它的人。如果不是这个地方可以删除
    【解决方案2】:

    你正在使用 tools.cxOnePoint,你应该使用 gp.cxOnePoint

    【讨论】:

    • @TheMaker 如果您查看问题中的 mate 函数,他正在使用工具中的 cxOnePoint 函数。这没有考虑到基因编程,所以它失败了。要修复它,您只需将上述代码中的toolbox.register("mate", tools.cxOnePoint) 替换为toolbox.register("mate", gp.cxOnePoint)
    • 好的,你可以在答案中包含这个解释,不是吗?
    猜你喜欢
    • 2015-10-24
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2023-01-09
    • 2018-05-02
    相关资源
    最近更新 更多