Created
January 15, 2013 10:42
-
-
Save lukehorvat/4537835 to your computer and use it in GitHub Desktop.
An introduction to genetic programming with esec demonstrating decision tree induction.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from esec import esdl_eval | |
from esec.species.tgp import Instruction, DecisionInstructionWithState | |
from esec.landscape.tgp import TGPFitness | |
#define the attributes of a Saturday morning | |
OUTLOOK = ('SUNNY', 'OVERCAST', 'RAIN') | |
HUMIDITY = ('HIGH', 'NORMAL') | |
WINDY = (True, False) | |
#define the state object to store attributes of a Saturday morning | |
class SaturdayMorning(object): | |
def __init__(self, outlook, humidity, windy): | |
self.outlook = outlook | |
self.humidity = humidity | |
self.windy = windy | |
def classification(self): | |
if self.outlook == 'SUNNY': | |
return 0 if self.humidity == 'HIGH' else 1 | |
elif self.outlook == 'OVERCAST': | |
return 1 | |
elif self.outlook == 'RAIN': | |
return 0 if self.windy else 1 | |
#define the fitness cases | |
fitness_cases = [SaturdayMorning(outlook, humidity, windy) for outlook in OUTLOOK for humidity in HUMIDITY for windy in WINDY] | |
#define the fitness evaluator for individuals | |
@esdl_eval | |
def decision_tree_induction(indiv): | |
score = 0 | |
for fitness_case in fitness_cases: | |
if indiv.evaluate(indiv, state=fitness_case, terminals=[0, 1]) == fitness_case.classification(): | |
score += 1 | |
return TGPFitness([score, len(indiv[0])]) | |
#define the instruction set | |
instructions = [ | |
# evaluate the 1st, 2nd or 3rd parameter based on the conditions | |
DecisionInstructionWithState(lambda fitness_case: 1 if fitness_case.outlook == 'SUNNY' else (2 if fitness_case.outlook == 'OVERCAST' else 3), param_count=3, name='OUT'), | |
DecisionInstructionWithState(lambda fitness_case: 1 if fitness_case.humidity == 'HIGH' else 2, param_count=2, name='HUM'), | |
DecisionInstructionWithState(lambda fitness_case: 1 if fitness_case.windy else 2, param_count=2, name='WIND'), | |
] | |
#define the system definition | |
esdl_system_definition = r''' | |
FROM random_tgp(instructions=instructions, terminals=2, deepest=4) SELECT (size) population | |
YIELD population | |
BEGIN generation | |
FROM population \ | |
SELECT (0.9*size) to_cross, (0.02*size) to_mutate, (0.08*size) to_reproduce \ | |
USING fitness_proportional | |
FROM to_cross SELECT offspring1 USING crossover_one(deepest_result, terminal_prob=0.1) | |
FROM to_mutate SELECT offspring2 USING mutate_random(deepest_result) | |
FROM offspring1, offspring2, to_reproduce SELECT (size) population | |
YIELD population | |
END generation | |
''' | |
#define the experiment configuration | |
config = { | |
'landscape': decision_tree_induction, | |
'system': { | |
'instructions': instructions, | |
'definition': esdl_system_definition, | |
'size': 500, | |
'deepest_result': 17, | |
}, | |
'monitor': { | |
'report': 'gen+births+best+local+best_length+time_delta+best_genome', | |
'summary': 'status+best+best_length+best_phenome', | |
'limits': { | |
'iterations': 50, | |
'fitness': TGPFitness([len(fitness_cases), 0]), | |
} | |
}, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment