You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DEAP eaSimple运行报错:嵌套括号过多SyntaxError

错误信息

出现SyntaxError: too many nested parentheses错误。

报错堆栈:

File /home/tilen/genetic_programming/.venv/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3577 in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)

  Cell In[4],   line 80
    pop, log = eaSimple(pop, toolbox, 0.5, 0.2, 100000, stats=stats, halloffame=hof, verbose=True)

  File /home/tilen/genetic_programming/.venv/lib/python3.10/site-packages/deap/algorithms.py:173 in eaSimple
    for ind, fit in zip(invalid_ind, fitnesses):

  Cell In[4],   line 52
    func = toolbox.compile(expr=individual)

File /home/tilen/genetic_programming/.venv/lib/python3.10/site-packages/deap/gp.py:494 in compile
    return eval(code, pset.context, {})

  File <string>:1
    lambda Lag1,Lag2,Lag3: multiply(protectedSqrt(multiply(Lag3, Lag2)), sin(sin(subtract(subtract(subtract(sin(subtract(multiply(sin(sin( 
相关代码
## Preprocessing:
def preprocessing(df):
    df['Return'] = df['close'].pct_change().fillna(0)
    df['Lag1'] = df['Return'].shift(1).fillna(0)
    df['Lag2'] = df['Return'].shift(2).fillna(0)
    df['Lag3'] = df['Return'].shift(3).fillna(0)

    df['Target'] = df['Return'].shift(-1).fillna(0)
    
    X = df[features]
    y = df['Target']
    
    return df, X, y

features = ['Lag1', 'Lag2', 'Lag3']
btc_data, X, y = preprocessing(df)

#print(btc_data)
print(X)
print(y)

## gp
def protectedDiv(left, right):
    if right == 0:
        return 1
    try:
        return np.divide(left, right + 2.226e-308)
    except ZeroDivisionError:
        return 1
    
def protectedLog(x):
    if x <= 0:
        return 1
    return np.log(x)

def protectedSqrt(x):
    if x < 0:
        return 0
    return np.sqrt(x)

def protectedExp(x):
    if x > np.log(np.finfo(np.float32).max):
        return np.finfo(np.float32).max
    return np.exp(x)

gp.staticLimit(operator.attrgetter('height'), 50)
pset = gp.PrimitiveSet("MAIN", len(features))
pset.addPrimitive(np.add, 2)
pset.addPrimitive(np.subtract, 2)
pset.addPrimitive(np.multiply, 2)
pset.addPrimitive(protectedDiv, 2)
pset.addPrimitive(np.sin, 1) 
pset.addPrimitive(np.cos, 1)  
#pset.addPrimitive(np.tan, 1)
pset.addPrimitive(np.negative, 1)
pset.addPrimitive(protectedLog, 1)
pset.addPrimitive(protectedExp, 1)
pset.addPrimitive(protectedSqrt, 1)

pset.addEphemeralConstant("rand101", partial(random.uniform, -1, 1))
pset.renameArguments(ARG0='Lag1', ARG1='Lag2', ARG2='Lag3')

if 'FitnessMin' in creator.__dict__:
    del creator.FitnessMin
if 'Individual' in creator.__dict__:
    del creator.Individual
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMin)

def evalSymbReg(individual, X, y):
    func = toolbox.compile(expr=individual)
    predictions = np.array([func(*x) for x in X], dtype=np.float128)
    return mean_squared_error(y, predictions),

toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("compile", gp.compile, pset=pset)
toolbox.register("evaluate", evalSymbReg, X=X.values, y=y.values)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("mate", gp.cxOnePoint)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr, pset=pset)
toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

toolbox.register("map", map)

pop = toolbox.population(n=100)
hof = tools.HallOfFame(1)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", np.mean)
stats.register("std", np.std)
stats.register("min", np.min)
stats.register("max", np.max)

pop, log = eaSimple(pop, toolbox, 0.5, 0.2, 100, stats=stats, halloffame=hof, verbose=True)

print(hof[0])
问题与解决方法

已通过gp.staticLimit(operator.attrgetter('height'), 50)限制遗传编程树高,推测Python嵌套括号阈值约为90,但仍触发报错,可尝试以下解决思路:

  • 进一步降低树高限制:将树高从50下调至30甚至更低,比如修改gp.staticLimit(operator.attrgetter('height'), 20),减少嵌套函数层数,避开Python语法解析上限。
  • 替换编译方式:放弃DEAP默认的gp.compile生成lambda的方式,直接遍历PrimitiveTree递归求值,彻底避免嵌套括号问题。示例代码:
    def eval_individual(individual, args):
        stack = []
        for node in individual:
            if isinstance(node, gp.Primitive):
                node_args = [stack.pop() for _ in range(node.arity)]
                stack.append(node(*node_args))
            elif isinstance(node, gp.Terminal):
                stack.append(node.value)
        return stack[0]
    
    def evalSymbReg(individual, X, y):
        predictions = np.array([eval_individual(individual, x) for x in X], dtype=np.float128)
        return mean_squared_error(y, predictions),
    
  • 限制初始个体复杂度:修改初始树生成参数,将toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)中的max_从2改为1,同时在变异操作中也限制树的增长幅度。
  • 修剪超限个体:在评估前遍历PrimitiveTree计算实际嵌套深度,对超过阈值的个体直接赋予低适应度,或自动修剪到安全层数。

内容的提问来源于stack exchange,提问作者tilen5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:37:06