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

使用DEAP库运行遗传编程代码时出现语法无效错误的求助

问题描述

导入必要模块、定义算子、创建Fitness与Individual后,编写了如下评估函数与toolbox注册代码:

# Define the fitness function for evaluating candidate kernels
def evaluate_kernel(individual):
    # Compile the kernel expression as a callable function
    kernel_func = gp.compile(individual, pset)
    # Train an SVM with the kernel function and compute its accuracy on the validation set
    svm = SVC(kernel=kernel_func)
    svm.fit(X_train, y_train)
    accuracy = svm.score(X_val, y_val)
    return accuracy,
toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=3)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("evaluate", evaluate_kernel)
toolbox.register("mate", gp.cxOnePoint)
toolbox.register("mutate", gp.mutUniform, pset=pset)
toolbox.register("select", tools.selTournament, tournsize=3)

# Define main function
def main():
    import numpy
    pop = toolbox.population(n=50)
    hof = tools.HallOfFame(1)
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", numpy.mean)
    stats.register("min", numpy.min)
    stats.register("max", numpy.max)

    pop, logbook = algorithms.eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=10, stats=stats, halloffame=hof, verbose=True)

    return pop, logbook, hof

# Calling main function
if __name__ == "__main__":
    pop, log, hof = main()
    print("Best individual is: %s\nwith fitness: %s" % (hof[0], hof[0].fitness))
    print(pop)

运行时出现如下语法错误:

File "/usr/local/lib/python3.9/dist-packages/IPython/core/interactiveshell.py", line 3553, in run_code
  exec(code_obj, self.user_global_ns, self.user_ns)

  File "<ipython-input-26-9a5248fbca23>", line 2, in <cell line: 1>
    pop=main()

1 frames
  File "/usr/local/lib/python3.9/dist-packages/deap/algorithms.py", line 151, in eaSimple
    for ind, fit in zip(invalid_ind, fitnesses):

  File "<ipython-input-21-421003e68116>", line 4, in evaluate_kernel
    kernel_func = gp.compile(individual, pset)

  File "/usr/local/lib/python3.9/dist-packages/deap/gp.py", line 480, in compile
    return eval(code, pset.context, {})

  File "<string>", line 1
    lambda ARG0: [<deap.gp.Primitive object at 0x7ffa7a7cb540>, <deap.gp.Primitive object at 0x7ffa7a7cb900>, <deap.gp.Terminal object at 0x7ffa7b3aaa00>, <deap.gp.Terminal object at 0x7ffa7b3aaa00>]
                  ^
SyntaxError: invalid syntax
解决方案

这个错误的核心原因是你的Primitive(基元)没有正确定义可解析的字符串表示,导致gp.compile生成了无效的Python代码——从错误信息看,编译后的代码直接输出了Primitive对象的内存表示,而非合法的函数表达式。

要修复这个问题,需检查并修正pset(PrimitiveSet)的定义,确保所有基元都具备合法的字符串标识:

  1. 规范Primitive的定义
    所有自定义Primitive必须指定一个可被Python解析的名称,示例如下:

    # 错误示例:未指定合法名称
    pset.addPrimitive(my_custom_kernel, 2)
    # 正确示例:指定名称为合法Python标识符
    pset.addPrimitive(my_custom_kernel, 2, name="custom_kernel")
    

    这里的name参数会作为函数名出现在编译后的代码中,必须是有效的变量/函数名(不能包含空格、特殊字符)。

  2. 确保Terminal(终端)的合法性
    若使用自定义Terminal,同样要保证其字符串表示是合法的Python语法(如常数、变量名):

    # 添加常数终端,指定合法名称
    pset.addTerminal(1.0, name="C1")
    # 重命名默认输入变量,提升可读性
    pset.renameArguments(ARG0="x", ARG1="y")
    
  3. 验证pset的正确性
    在编译前可先打印个体的字符串表示,确认其为合法Python表达式:

    ind = toolbox.individual()
    print(str(ind))  # 正常输出应为类似"custom_kernel(x, C1)"的合法表达式
    

    若输出包含<deap.gp.Primitive object...>这类内容,说明Primitive的定义存在问题,必须修正。

  4. 额外注意SVM Kernel的要求
    SVM的自定义kernel函数需接收两个样本矩阵(形状为(n_samples1, n_features)和(n_samples2, n_features)),并返回一个(n_samples1, n_samples2)的核矩阵。确保Primitive组合后的函数符合该要求,否则即使编译通过,后续SVM训练仍会报错。

完整的pset定义示例:

from deap import gp
import numpy as np

# 创建PrimitiveSet,指定输入变量数量
pset = gp.PrimitiveSet("MAIN", 2)
# 重命名默认输入变量
pset.renameArguments(ARG0="x", ARG1="y")

# 定义基础核函数
def linear_kernel(x, y):
    return x @ y.T

def rbf_kernel(x, y):
    return np.exp(-0.1 * np.linalg.norm(x - y, axis=1)**2)

# 添加Primitive并指定合法名称
pset.addPrimitive(linear_kernel, 2, name="linear")
pset.addPrimitive(rbf_kernel, 2, name="rbf")
# 添加常数终端
pset.addTerminal(0.1, name="gamma")

按上述方式定义后,gp.compile生成的代码会是合法的lambda表达式,不会再出现语法错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 10:55:20