Geppy is a Python extension to DEAP for gene expression programming. It evolves readable mathematical functions rather than approximating a function with a trained neural network, replacing gradient-based learning with evolutionary search. section 12.1 section 12.7
A Geppy individual contains genes joined into chromosomes and compiled into executable functions. A primitive set supplies inputs, arithmetic operators, protected division, and randomly generated constants; mutation and crossover then explore candidate expressions. section 12.1
A practical Geppy workflow is:
- Define the target function or environment inputs. section 12.1 section 12.2
- Create the primitive set, gene length, chromosome structure, and linker. section 12.1
- Compile each individual, calculate fitness, and register Geppy operators in the DEAP toolbox. section 12.1
- Evolve a population with elitism, inspect the hall of fame, simplify the best expression, and optionally export its expression tree. section 12.1
Evolving a linear equation
For the target f(x1) = 6x1 + 22, a primitive set with addition, subtraction, multiplication, protected division, and random constants evolves a function whose simplified result is 6*x1 + 22. Fitness uses mean absolute error between predicted and target values. section 12.1
Controlling continuous environments
Geppy can evolve equations for Pendulum-v0 and MountainCarContinuous-v0. The compiled equation receives the environment state, produces an action, clamps it to the permitted range, and earns fitness from accumulated rewards across simulation runs. section 12.2
Listing 12.2 EDL_12_1_GEPPY.ipynb: Adding expression operators
import operator
pset = gep.PrimitiveSet('Main', input_names=['x1']) #1
pset.add_function(operator.add, 2) #2
pset.add_function(operator.sub, 2) #2
pset.add_function(operator.mul, 2) #2
pset.add_function(protected_div, 2) #3
pset.add_ephemeral_terminal(name='enc', gen=lambda:
random.randint(-10, 10)) #4
Inspect the primitive-set definition that supplies inputs, arithmetic functions, protected division, and ephemeral constants. section 12.1
Listing 12.4 EDL_12_1_GEPPY.ipynb: Registering custom operators
toolbox.register('mut_uniform', gep.mutate_uniform,
pset=pset, ind_pb=0.05, pb=1) #1
toolbox.register('mut_invert', gep.invert, pb=0.1) #1
toolbox.register('mut_is_transpose', gep.is_transpose, #1
pb=0.1) #1
toolbox.register('mut_ris_transpose', #1
gep.ris_transpose, pb=0.1) #1
toolbox.register('mut_gene_transpose', #1
gep.gene_transpose, pb=0.1) #1
toolbox.register('cx_1p', gep.crossover_one_point, #2
pb=0.4) #2
toolbox.register('cx_2p', gep.crossover_two_point, #2
pb=0.2)
toolbox.register('cx_gene', gep.crossover_gene, pb=0.1) #2
toolbox.register('mut_ephemeral', gep.mutate_
uniform_ephemeral, ind_pb='1p') #3
toolbox.pbs['mut_ephemeral'] = 1 #3
Inspect the registered mutation and crossover operators used to explore expression structures. section 12.1
