def mut_shrink(individual: gp.PrimitiveTree, rng: random.Random) -> Tuple[gp.PrimitiveTree]: """Replace node with one of its arguments""" # We don't want to "shrink" the root if len(individual) < 3 or individual.height <= 1: return individual, iprims = [] for i, node in enumerate(individual[1:], 1): if isinstance(node, gp.Primitive) and node.ret in node.args: iprims.append((i, node)) if len(iprims) != 0: index, prim = rng.choice(iprims) arg_idx = rng.choice( [i for i, type_ in enumerate(prim.args) if type_ == prim.ret]) rindex = index + 1 for _ in range(arg_idx + 1): rslice = individual.searchSubtree(rindex) subtree = individual[rslice] rindex += len(subtree) slice_ = individual.searchSubtree(index) individual[slice_] = subtree return individual,
def cx_one_point( ind1: gp.PrimitiveTree, ind2: gp.PrimitiveTree, rng: random.Random) -> Tuple[gp.PrimitiveTree, gp.PrimitiveTree]: if len(ind1) < 2 or len(ind2) < 2: # No crossover on single node tree return ind1, ind2 # List all available primitive types in each individual types1 = collections.defaultdict(list) types2 = collections.defaultdict(list) for idx, node in enumerate(ind1[1:], 1): types1[node.ret].append(idx) for idx, node in enumerate(ind2[1:], 1): types2[node.ret].append(idx) common_types = set(types1.keys()).intersection(set(types2.keys())) if len(common_types) > 0: type_ = rng.choice(list(common_types)) index1 = rng.choice(types1[type_]) index2 = rng.choice(types2[type_]) slice1 = ind1.searchSubtree(index1) slice2 = ind2.searchSubtree(index2) ind1[slice1], ind2[slice2] = ind2[slice2], ind1[slice1] return ind1, ind2
def mut_uniform(individual: gp.PrimitiveTree, expr: Callable, pset: gp.PrimitiveSetTyped, rng: random.Random): """Replace subtree with randomly generated tree""" index = rng.randrange(len(individual)) slice_ = individual.searchSubtree(index) type_ = individual[index].ret individual[slice_] = expr(pset=pset, type_=type_) return individual,
def serialize_me(obj): obj = copy(obj) if hasattr(obj, '_optimized_pipeline') and not isinstance( obj._optimized_pipeline, str): obj._optimized_pipeline = PrimitiveTree( obj._optimized_pipeline).__str__() for a in vars(obj).keys(): if hasattr(obj, a) and not is_serializable(getattr(obj, a)): setattr(obj, a, []) return obj
def __getstate__(self): if hasattr(self, '_optimized_pipeline') and not isinstance( self._optimized_pipeline, str): self._optimized_pipeline = PrimitiveTree( self._optimized_pipeline).__str__() attributes = self.__dict__.copy() # for attr in [a for a in attributes.keys() if not is_serializable(attributes.get(a))]: for attr in attributes.keys(): if attr in self.non_serializable: attributes[attr] = [] return attributes
def from_string_np_terms(string, pset): """Try to convert a string expression into a PrimitiveTree given a PrimitiveSet *pset*. The primitive set needs to contain every primitive present in the expression. :param string: String representation of a Python expression. :param pset: Primitive set from which primitives are selected. :returns: PrimitiveTree populated with the deserialized primitives. """ tokens = re.split("[ \t\n\r\f\v(),]", string) expr = [] ret_types = deque() for token in tokens: if token == '': continue if len(ret_types) != 0: type_ = ret_types.popleft() else: type_ = None if token in pset.mapping: primitive = pset.mapping[token] if type_ is not None and not issubclass(primitive.ret, type_): raise TypeError("Primitive {} return type {} does not " "match the expected one: {}." .format(primitive, primitive.ret, type_)) expr.append(primitive) if isinstance(primitive, Primitive): ret_types.extendleft(reversed(primitive.args)) else: try: token = eval(token) except NameError: raise TypeError("Unable to evaluate terminal: {}.".format(token)) if type_ is None: type_ = type(token) _act_type = type(token) # THE CHANGE. Can cast float to ndarray. if not issubclass(_act_type, type_) and not (_act_type == float and issubclass(type_, np.ndarray)): raise TypeError("Terminal {} type {} does not " "match the expected one: {}." .format(token, type(token), type_)) terminal = Terminal(token, False, type_) expr.append(terminal) # expr.append(class_) return PrimitiveTree(expr)
def __init__(self, content, gene_num): self.gene = [] self.gene_num = gene_num for i in range(self.gene_num): self.gene.append(PrimitiveTree(content()))
def individual_from_string(self, code): return creator.Individual( PrimitiveTree.from_string(code, self.grammar.pset))
def generate_and_evaluate_semantically_distinct_trees(pset, max_depth, predictors): last_trees = [] smaller_trees = [] sem_dictionary = {} for terminal in pset.terminals[pset.ret]: tree = PrimitiveTree([terminal]) tree.semantics = semantics.get_terminal_semantics( terminal, pset.context, predictors) if numpy.isfinite(numpy.sum( tree.semantics)) and tree.semantics.tostring( ) not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = 0 last_trees.append(tree) for depth in range(max_depth): trees = [] for function in pset.primitives[pset.ret]: func = pset.context[function.name] if function.arity == 1: for subtree in last_trees: tree = PrimitiveTree([function] + subtree[:]) tree.semantics = func(subtree.semantics) if numpy.isfinite(numpy.sum( tree.semantics)) and tree.semantics.tostring( ) not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) elif function.arity == 2: for subtree_1 in last_trees: for subtree_2 in last_trees: tree = PrimitiveTree([function] + subtree_1[:] + subtree_2[:]) tree.semantics = func(subtree_1.semantics, subtree_2.semantics) if numpy.isfinite(numpy.sum( tree.semantics)) and tree.semantics.tostring( ) not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) for subtree_2 in smaller_trees: tree = PrimitiveTree([function] + subtree_1[:] + subtree_2[:]) tree.semantics = func(subtree_1.semantics, subtree_2.semantics) if numpy.isfinite(numpy.sum( tree.semantics)) and tree.semantics.tostring( ) not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) tree = PrimitiveTree([function] + subtree_2[:] + subtree_1[:]) tree.semantics = func(subtree_2.semantics, subtree_1.semantics) if numpy.isfinite(numpy.sum( tree.semantics)) and tree.semantics.tostring( ) not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) smaller_trees.extend(last_trees) last_trees = trees return smaller_trees + last_trees
pset.addPrimitive(bool_xor, 2) pset.addPrimitive(bool_not, 1) pset.addTerminal(np.array([True, True, True, True]), name='full') pset.addTerminal(np.array([False, False, False, False]), name='empty') pset.addTerminal(np.array([False, False, True, True]), name='b0011') pset.addTerminal(np.array([True, True, False, False]), name='b1100') pset.addEphemeralConstant("random101", lambda: (np.random.rand(4) > 0.5)) creator.create("FitnessMin", base.Fitness, weights=(-1.0, )) creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMin, pset=pset) toolbox = base.Toolbox() toolbox.register("expr", gp.genFull, pset=pset, min_=2, max_=2) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr) # generate full tree ranging from size 1 to 3 depth expr = genFull(pset, min_=1, max_=3) tree = PrimitiveTree(expr) # print out the tree print(tree) func = gp.compile(tree, pset) ans = func(np.array([True, True, True, True])) print(f'The answer is {mask_to_string(ans)}')
def generate_and_evaluate_semantically_distinct_trees(pset, max_depth, predictors): last_trees = [] smaller_trees = [] sem_dictionary = {} for terminal in pset.terminals[pset.ret]: tree = PrimitiveTree([terminal]) tree.semantics = semantics.get_terminal_semantics(terminal, pset.context, predictors) if numpy.isfinite(numpy.sum(tree.semantics)) and tree.semantics.tostring() not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = 0 last_trees.append(tree) for depth in range(max_depth): trees = [] for function in pset.primitives[pset.ret]: func = pset.context[function.name] if function.arity == 1: for subtree in last_trees: tree = PrimitiveTree([function] + subtree[:]) tree.semantics = func(subtree.semantics) if numpy.isfinite(numpy.sum(tree.semantics)) and tree.semantics.tostring() not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) elif function.arity == 2: for subtree_1 in last_trees: for subtree_2 in last_trees: tree = PrimitiveTree([function] + subtree_1[:] + subtree_2[:]) tree.semantics = func(subtree_1.semantics, subtree_2.semantics) if numpy.isfinite( numpy.sum(tree.semantics)) and tree.semantics.tostring() not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) for subtree_2 in smaller_trees: tree = PrimitiveTree([function] + subtree_1[:] + subtree_2[:]) tree.semantics = func(subtree_1.semantics, subtree_2.semantics) if numpy.isfinite( numpy.sum(tree.semantics)) and tree.semantics.tostring() not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) tree = PrimitiveTree([function] + subtree_2[:] + subtree_1[:]) tree.semantics = func(subtree_2.semantics, subtree_1.semantics) if numpy.isfinite( numpy.sum(tree.semantics)) and tree.semantics.tostring() not in sem_dictionary: sem_dictionary[tree.semantics.tostring()] = tree tree.tree_height = depth + 1 trees.append(tree) smaller_trees.extend(last_trees) last_trees = trees return smaller_trees + last_trees
else: print(f'fail') print(result) return result, toolbox.register("evaluate", eval) toolbox.register("select", tools.selAutomaticEpsilonLexicase) toolbox.register("mate", gp.cxOnePoint) toolbox.register("expr_mut", gp.genFull, min_=0, max_=2) toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset) pop = toolbox.population(n=10) hof = tools.HallOfFame(1) # test out mod on x_train p = gp.genFull(pset, min_=1, max_=2) tree = PrimitiveTree(p) print(tree) funct = gp.compile(tree, pset) t = funct print(f't is {t}') print(f'd.data[0] is {d.data[0]}') print(f'mod_x = {d.data[0][funct]}') mod_x = get_mod_x(d.data, funct) pop, log = algorithms.eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.1, ngen=4, halloffame=hof, verbose=True)
def rebuild_me(self): for a in NON_SERIALIZABLE: if not hasattr(self, a): setattr(self, a, []) self._setup_config(self.config_dict) self._setup_template(self.template) self.verbosity = 0 self.warm_start = True for key in sorted(self._config_dict.keys()): op_class, arg_types = TPOTOperatorClassFactory( key, self._config_dict[key], BaseClass=Operator, ArgBaseClass=ARGType, verbose=self.verbosity, ) if op_class: self.operators.append(op_class) self.arguments += arg_types self.operators_context = { "make_pipeline": make_pipeline, "make_union": make_union, "StackingEstimator": StackingEstimator, "FunctionTransformer": FunctionTransformer, "copy": copy, } setattr( self, '_pareto_front', tools.ParetoFront(similar=lambda ind1, ind2: np.allclose( ind1.fitness.values, ind2.fitness.values))) self._pbar = None self._setup_pset() self._setup_toolbox() self._pop = self._toolbox.population(n=self.population_size) if hasattr(self, 'pareto_front_fitted_pipelines_') and isinstance( self.pareto_front_fitted_pipelines_, dict): items = [ creator.Individual(PrimitiveTree([]).from_string(i, self._pset)) for i in self.pareto_front_fitted_pipelines_.keys() ] keys = [(lambda d: creator.FitnessMulti( (d.get('operator_count', 0), d.get('internal_cv_score', 0))))( self.evaluated_individuals_.get(k, {})) for k in self.pareto_front_fitted_pipelines_.keys()] elif hasattr(self, 'evaluated_individuals_') and isinstance( self.evaluated_individuals_, dict): items = [ creator.Individual(PrimitiveTree([]).from_string(i, self._pset)) for i in self.evaluated_individuals_.keys() ] keys = [ creator.FitnessMulti((d.get('operator_count', 0), d.get('internal_cv_score', 0))) for d in self.evaluated_individuals_.values() ] else: self.warm_start = False self.verbosity = 3 return items = add_attr(keys, items) setattr(self._pareto_front, 'items', items) setattr(self._pareto_front, 'keys', sorted(keys)) if hasattr(self, '_optimized_pipeline') and isinstance( self._optimized_pipeline, str): optimized_pipeline = creator.Individual( PrimitiveTree([]).from_string(self._optimized_pipeline, self._pset)) optimized_pipeline.__str__ = partial(PrimitiveTree.__str__, optimized_pipeline) keys = [ creator.FitnessMulti((d.get('operator_count', 0), d.get('internal_cv_score', 0))) for k, d in self.evaluated_individuals_.items() if k == optimized_pipeline.__str__() ] if len(keys) > 0: optimized_pipeline.fitness = keys[0] else: optimized_pipeline.fitness.values = (5000.0, -float("inf")) self._optimized_pipeline = optimized_pipeline setattr(self, '_last_optimized_pareto_front', [v for i in self._pareto_front.keys for v in i.values[-1:]]) if not hasattr(self, '_last_optimized_pareto_front_n_gens'): if hasattr(self, 'evaluated_individuals_'): last_gen = max([ d.get('generation') for d in list(self.evaluated_individuals_.values()) ]) else: last_gen = 0 setattr(self, '_last_optimized_pareto_front_n_gens', last_gen) else: last_gen = self._last_optimized_pareto_front_n_gens if not hasattr(self, 'evaluated_individuals_'): setattr( self, 'evaluated_individuals_', { p.__str__(): (lambda v: { 'generation': last_gen, 'mutation_count': 0, 'crossover_count': 0, 'predecessor': ('ROOT', ), 'operator_count': v[0], 'internal_cv_score': v[-1] })(self._pareto_front.keys[i].values) for i, p in enumerate(self._pareto_front.items) }) self.verbosity = 3 return self