version 2.0
parent
29d4bf227d
commit
98cf28a2f5
|
@ -1,3 +1,36 @@
|
||||||
|
2018 04/12
|
||||||
|
|
||||||
|
1) Merged 'Karoo GP Server' and 'Karoo GP Main' into a single 'Karoo GP'. So, just one user script now that provides the
|
||||||
|
user interface (TUI) or scripting (comnand line). There are now 3 ways to run Karoo:
|
||||||
|
|
||||||
|
a) $ run karoo_gp.py
|
||||||
|
b) $ run karoo_gp.py [path/][dataset.csv]
|
||||||
|
c) $ run karoo_gp.py -fil [path/][dataset.csv] -[arg] [val] -[arg] [val] ... etc.
|
||||||
|
|
||||||
|
Where [arg][val] are the sysargs defined in the body of karoo_gp.py and the User Guide. Both (a) and (b) will auto-
|
||||||
|
run the Desktop interface, providing a user query for each entry and holding the user within the script until quit;
|
||||||
|
(c) will skip the user query and go directly into execution, dropping the user back to the command line at the end of
|
||||||
|
the run (for scripting).
|
||||||
|
|
||||||
|
|
||||||
|
2) Merged the 'menu' ranges into the while loops, directly (to reduce line count).
|
||||||
|
|
||||||
|
3) Added the 2**(tree_depth_base +1) - 1 to the tree_depth_min calculation (could have done this a long time ago).
|
||||||
|
|
||||||
|
4) Auto-calc the number of trees entered into the Tournament (was previously hard coded to 7 assuming a pop 100).
|
||||||
|
|
||||||
|
5) Added [-evr, -evp, -evb, -evc] to the sysargs to support a change in the balance of the genetic operators mid-run.
|
||||||
|
|
||||||
|
6) Merged fx_evolve_branch_top_copy with fx_evolve_branch_body_copy as they were alway called sequencially and required
|
||||||
|
the same input values.
|
||||||
|
|
||||||
|
7) Merged fx_evolve_tree_renum into fx_eval_generation as both are used only once, as the former was but 2 lines of code.
|
||||||
|
|
||||||
|
8) Finally finished commenting all "Called by: ___" statements in each function header.
|
||||||
|
|
||||||
|
I've been productive!
|
||||||
|
|
||||||
|
|
||||||
2018 04/01
|
2018 04/01
|
||||||
|
|
||||||
Two major updates, as follows:
|
Two major updates, as follows:
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
# Karoo GP (desktop + server combined)
|
||||||
|
# Use Genetic Programming for Classification and Symbolic Regression
|
||||||
|
# by Kai Staats, MSc; see LICENSE.md
|
||||||
|
# version 2.0
|
||||||
|
|
||||||
|
'''
|
||||||
|
A word to the newbie, expert, and brave--
|
||||||
|
Even if you are highly experienced in Genetic Programming, it is recommended that you review the 'Karoo User Guide'
|
||||||
|
before running this application. While your computer will not burst into flames nor will the sun collapse into a black
|
||||||
|
hole if you do not, you will likely find more enjoyment of this particular flavour of GP with a little understanding
|
||||||
|
of its intent and design.
|
||||||
|
|
||||||
|
Without any arguments, Karoo GP relies entirely upon the scripted settings and the datasets located in karoo_gp/files/.
|
||||||
|
|
||||||
|
$ python karoo_gp_main.py
|
||||||
|
|
||||||
|
(or from iPython)
|
||||||
|
|
||||||
|
$ run karoo_gp_main.py
|
||||||
|
|
||||||
|
|
||||||
|
If you include the path to an external dataset, it will auto-load at launch:
|
||||||
|
|
||||||
|
$ python karoo_gp_main.py /[path]/[to_your]/[filename].csv
|
||||||
|
|
||||||
|
|
||||||
|
You can include a one or more additional arguments, they will override the default values, as follows:
|
||||||
|
|
||||||
|
-ker [r,c,m] fitness function: (r)egression, (c)lassification, or (m)atching
|
||||||
|
-typ [f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half
|
||||||
|
-bas [3...10] maximum Tree depth for the initial population
|
||||||
|
-max [3...10] maximum Tree depth for the entire run
|
||||||
|
-min [3...100] minimum number of nodes
|
||||||
|
-pop [10...1000] maximum population
|
||||||
|
-gen [1...100] number of generations
|
||||||
|
-tor [1...100] number of trees selected for the tournament
|
||||||
|
-evr [0.0 ... 1.0] fraction percent of genetic operator Reproduction
|
||||||
|
-evp [0.0 ... 1.0] fraction percent of genetic operator Point Mutation
|
||||||
|
-evb [0.0 ... 1.0] fraction percent of genetic operator Branch Mutation
|
||||||
|
-evc [0.0 ... 1.0] fraction percent of genetic operator Crossover
|
||||||
|
|
||||||
|
If you include any of the above flags, then you *must* also include a flag to load an external dataset.
|
||||||
|
|
||||||
|
-fil [filename] an external dataset
|
||||||
|
|
||||||
|
|
||||||
|
An example is given, as follows:
|
||||||
|
|
||||||
|
$ python karoo_gp_server.py -ker c -typ r -bas 4 -fil /[path]/[to_your]/[filename].csv
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys; #sys.path.append('modules/') # add directory 'modules' to the current path
|
||||||
|
import argparse
|
||||||
|
import karoo_gp_base_class; gp = karoo_gp_base_class.Base_GP()
|
||||||
|
|
||||||
|
os.system('clear')
|
||||||
|
print '\n\033[36m\033[1m'
|
||||||
|
print '\t ** ** ****** ***** ****** ****** ****** ******'
|
||||||
|
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
||||||
|
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
||||||
|
print '\t **** ******** ****** ** ** ** ** ** *** *******'
|
||||||
|
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
||||||
|
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
||||||
|
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
||||||
|
print '\t ** ** ** ** ** ** ****** ****** ****** **'
|
||||||
|
print '\033[0;0m'
|
||||||
|
print '\t\033[36m Genetic Programming in Python - by Kai Staats, version 1.2\033[0;0m'
|
||||||
|
print ''
|
||||||
|
|
||||||
|
|
||||||
|
#++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
# User Interface Configuation |
|
||||||
|
#++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
if len(sys.argv) < 3: # either no command line argument (1) or the filename (2) was provided
|
||||||
|
|
||||||
|
# menu = ['c','r','m','p',''] # inserted all menus directly into while loops on 2018 05/07
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
query = raw_input('\t Select (c)lassification, (r)egression, (m)atching, or (p)lay (default m): ')
|
||||||
|
if query not in ['c','r','m','p','']: raise ValueError()
|
||||||
|
kernel = query or 'm'; break
|
||||||
|
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
if kernel == 'p':
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_type = raw_input('\t Select (f)ull or (g)row (default g): ')
|
||||||
|
if tree_type not in ['f','g','']: raise ValueError()
|
||||||
|
tree_type = tree_type or 'f'; break
|
||||||
|
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_depth_base = raw_input('\t Enter the depth of the Tree (default 1): ')
|
||||||
|
if tree_depth_base not in str(range(1,11)) or tree_depth_base == '0': raise ValueError()
|
||||||
|
elif tree_depth_base == '': tree_depth_base = 1; break
|
||||||
|
tree_depth_base = int(tree_depth_base); break
|
||||||
|
except ValueError: print '\t\033[32m Enter a number from 1 including 10. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
tree_depth_max = tree_depth_base
|
||||||
|
tree_depth_min = 3
|
||||||
|
tree_pop_max = 1
|
||||||
|
generation_max = 1
|
||||||
|
tourn_size = 0
|
||||||
|
display = 'm'
|
||||||
|
# evolve_repro, evolve_point, evolve_branch, evolve_cross, tourn_size, precision, filename are not required
|
||||||
|
|
||||||
|
else: # if any other kernel is selected
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_type = raw_input('\t Select (f)ull, (g)row, or (r)amped 50/50 method (default r): ')
|
||||||
|
if tree_type not in ['f','g','r','']: raise ValueError()
|
||||||
|
tree_type = tree_type or 'r'; break
|
||||||
|
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_depth_base = raw_input('\t Enter depth of the \033[3minitial\033[0;0m population of Trees (default 3): ')
|
||||||
|
if tree_depth_base not in str(range(1,11)) or tree_depth_base == '0': raise ValueError()
|
||||||
|
elif tree_depth_base == '': tree_depth_base = 3; break
|
||||||
|
tree_depth_base = int(tree_depth_base); break
|
||||||
|
except ValueError: print '\t\033[32m Enter a number from 1 including 10. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
if tree_type == 'f': tree_depth_max = tree_depth_base
|
||||||
|
else: # if type is Full, tree_depth_max is equal to tree_depth_base (initial pop setting)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_depth_max = raw_input('\t Enter maximum Tree depth (default %i): ' %tree_depth_base)
|
||||||
|
if tree_depth_max not in str(range(tree_depth_base,11)): raise ValueError()
|
||||||
|
elif tree_depth_max == '': tree_depth_max = tree_depth_base
|
||||||
|
tree_depth_max = int(tree_depth_max)
|
||||||
|
if tree_depth_max < tree_depth_base: raise ValueError() # if max is set to < min 20170918
|
||||||
|
else: break
|
||||||
|
except ValueError: print '\t\033[32m Enter a number > or = the initial Tree depth. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
max_nodes = 2**(tree_depth_base +1) - 1 # auto calc the max number of nodes for the given depth
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_depth_min = raw_input('\t Enter minimum number of nodes for any given Tree (default 3; max %s): ' %str(max_nodes))
|
||||||
|
if tree_depth_min not in str(range(3,max_nodes)) or tree_depth_min == '0' or tree_depth_min == '1' or tree_depth_min == '2': raise ValueError()
|
||||||
|
elif tree_depth_min == '': tree_depth_min = 3
|
||||||
|
tree_depth_min = int(tree_depth_min); break
|
||||||
|
except ValueError: print '\t\033[32m Enter a number from 3 including %s. Try again ...\n\033[0;0m' %str(max_nodes)
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tree_pop_max = raw_input('\t Enter number of Trees in each population (default 100): ')
|
||||||
|
if tree_pop_max not in str(range(1,1001)) or tree_pop_max == '0': raise ValueError()
|
||||||
|
elif tree_pop_max == '': tree_pop_max = 100
|
||||||
|
tree_pop_max = int(tree_pop_max); break
|
||||||
|
except ValueError: print '\t\033[32m Enter a number from 1 including 1000. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
tourn_size = int(tree_pop_max * 0.07) # default 7% can be changed by selecting Generation, 'ts', and then enter the run.
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
generation_max = raw_input('\t Enter max number of generations (default 10): ')
|
||||||
|
if generation_max not in str(range(1,101)) or generation_max == '0': raise ValueError()
|
||||||
|
elif generation_max == '': generation_max = 10
|
||||||
|
generation_max = int(generation_max); break
|
||||||
|
except ValueError: print '\t\033[32m Enter a number from 1 including 100. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
display = raw_input('\t Display (i)nteractive, (g)eneration, (m)iminal, (s)ilent, or (d)e(b)ug (default m): ')
|
||||||
|
if display not in ['i','g','m','s','db','']: raise ValueError()
|
||||||
|
display = display or 'm'; break
|
||||||
|
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
||||||
|
except KeyboardInterrupt: sys.exit()
|
||||||
|
|
||||||
|
evolve_repro = int(0.1 * tree_pop_max) # quantity of a population generated through Reproduction
|
||||||
|
evolve_point = int(0.0 * tree_pop_max) # quantity of a population generated through Point Mutation
|
||||||
|
evolve_branch = int(0.2 * tree_pop_max) # quantity of a population generated through Branch Mutation
|
||||||
|
evolve_cross = int(0.7 * tree_pop_max) # quantity of a population generated through Crossover
|
||||||
|
filename = '' # not required unless an external file is referenced
|
||||||
|
precision = 6 # number of floating points for the round function in 'fx_fitness_eval'
|
||||||
|
mode = 'm' # pause when complete, awaiting further user interaction
|
||||||
|
|
||||||
|
|
||||||
|
#++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
# Command Line Configuation |
|
||||||
|
#++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
else: # two or more command line argument were provided
|
||||||
|
|
||||||
|
ap = argparse.ArgumentParser(description = 'Karoo GP Server')
|
||||||
|
ap.add_argument('-ker', action = 'store', dest = 'kernel', default = 'c', help = '[c,r,m] fitness function: (r)egression, (c)lassification, or (m)atching')
|
||||||
|
ap.add_argument('-typ', action = 'store', dest = 'type', default = 'r', help = '[f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half')
|
||||||
|
ap.add_argument('-bas', action = 'store', dest = 'depth_base', default = 4, help = '[3...10] maximum Tree depth for the initial population')
|
||||||
|
ap.add_argument('-max', action = 'store', dest = 'depth_max', default = 4, help = '[3...10] maximum Tree depth for the entire run')
|
||||||
|
ap.add_argument('-min', action = 'store', dest = 'depth_min', default = 3, help = '[3...100] minimum number of nodes')
|
||||||
|
ap.add_argument('-pop', action = 'store', dest = 'pop_max', default = 100, help = '[10...1000] maximum population')
|
||||||
|
ap.add_argument('-gen', action = 'store', dest = 'gen_max', default = 10, help = '[1...100] number of generations')
|
||||||
|
ap.add_argument('-tor', action = 'store', dest = 'tor_size', default = 7, help = '[1...max pop] tournament size')
|
||||||
|
ap.add_argument('-evr', action = 'store', dest = 'evo_r', default = 0.1, help = '[0.0-1.0] fraction of pop generated through Reproduction')
|
||||||
|
ap.add_argument('-evp', action = 'store', dest = 'evo_p', default = 0.0, help = '[0.0-1.0] fraction of pop generated through Point Mutation')
|
||||||
|
ap.add_argument('-evb', action = 'store', dest = 'evo_b', default = 0.2, help = '[0.0-1.0] fraction of pop generated through Branch Mutation')
|
||||||
|
ap.add_argument('-evc', action = 'store', dest = 'evo_c', default = 0.7, help = '[0.0-1.0] fraction of pop generated through Crossover')
|
||||||
|
ap.add_argument('-fil', action = 'store', dest = 'filename', default = '', help = '/path/to_your/[data].csv')
|
||||||
|
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
# pass the argparse defaults and/or user inputs to the required variables
|
||||||
|
kernel = str(args.kernel)
|
||||||
|
tree_type = str(args.type)
|
||||||
|
tree_depth_base = int(args.depth_base)
|
||||||
|
tree_depth_max = int(args.depth_max)
|
||||||
|
tree_depth_min = int(args.depth_min)
|
||||||
|
tree_pop_max = int(args.pop_max)
|
||||||
|
generation_max = int(args.gen_max)
|
||||||
|
tourn_size = int(args.tor_size)
|
||||||
|
evolve_repro = int(float(args.evo_r) * tree_pop_max) # quantity of each population generated through Reproduction
|
||||||
|
evolve_point = int(float(args.evo_p) * tree_pop_max) # quantity of each population generated through Point Mutation
|
||||||
|
evolve_branch = int(float(args.evo_b) * tree_pop_max) # quantity of each population generated through Branch Mutation
|
||||||
|
evolve_cross = int(float(args.evo_c) * tree_pop_max) # quantity of each population generated through Crossover
|
||||||
|
filename = str(args.filename)
|
||||||
|
|
||||||
|
display = 's' # display mode is set to (s)ilent
|
||||||
|
precision = 6 # number of floating points for the round function in 'fx_fitness_eval'
|
||||||
|
mode = 's' # drop back to the command line when complete
|
||||||
|
|
||||||
|
|
||||||
|
#++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
# Pass all settings to the base_class |
|
||||||
|
#++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
gp.fx_karoo_gp(kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, generation_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, mode)
|
||||||
|
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Define the methods and global variables used by Karoo GP
|
# Define the methods and global variables used by Karoo GP
|
||||||
# by Kai Staats, MSc; see LICENSE.md
|
# by Kai Staats, MSc; see LICENSE.md
|
||||||
# Thanks to Emmanuel Dufourq and Arun Kumar for support during 2014-15 devel; TensorFlow support provided by Iurii Milovanov
|
# Thanks to Emmanuel Dufourq and Arun Kumar for support during 2014-15 devel; TensorFlow support provided by Iurii Milovanov
|
||||||
# version 1.1
|
# version 2.0
|
||||||
|
|
||||||
'''
|
'''
|
||||||
A NOTE TO THE NEWBIE, EXPERT, AND BRAVE
|
A NOTE TO THE NEWBIE, EXPERT, AND BRAVE
|
||||||
|
@ -134,7 +134,7 @@ class Base_GP(object):
|
||||||
# Methods to Run Karoo GP |
|
# Methods to Run Karoo GP |
|
||||||
#+++++++++++++++++++++++++++++++++++++++++++++
|
#+++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
def fx_karoo_gp(self, kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, generation_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, app):
|
def fx_karoo_gp(self, kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, generation_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, mode):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
This method enables the engagement of the entire Karoo GP application. It is used by both the desktop and server
|
This method enables the engagement of the entire Karoo GP application. It is used by both the desktop and server
|
||||||
|
@ -207,7 +207,7 @@ class Base_GP(object):
|
||||||
print ''
|
print ''
|
||||||
print '\033[3m Congrats!\033[0;0m Your Karoo GP run is complete.\n'
|
print '\033[3m Congrats!\033[0;0m Your Karoo GP run is complete.\n'
|
||||||
|
|
||||||
if app == 's': self.fx_data_params_write('Server')
|
if mode == 's': self.fx_data_params_write('Server')
|
||||||
else:
|
else:
|
||||||
self.fx_data_params_write('Desktop')
|
self.fx_data_params_write('Desktop')
|
||||||
print '\n\t\033[36m Type \033[1m?\033[0;0m\033[36m to review your options or \033[1mq\033[0;0m\033[36m to quit.\033[0;0m\n'
|
print '\n\t\033[36m Type \033[1m?\033[0;0m\033[36m to review your options or \033[1mq\033[0;0m\033[36m to quit.\033[0;0m\n'
|
||||||
|
@ -319,9 +319,9 @@ class Base_GP(object):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
print '\n\t The current tournament size is:', self.tourn_size
|
print '\n\t The current tournament size is:', self.tourn_size
|
||||||
query = raw_input('\t Adjust the tournament size (suggest 10): ')
|
query = raw_input('\t Adjust the tournament size (suggest 7): ')
|
||||||
if query not in str(menu) or query == '0' or query == '1': raise ValueError() # not ideal 20170918
|
if query not in str(menu) or query == '0' or query == '1': raise ValueError() # not ideal 20170918
|
||||||
elif query == '': break
|
elif query == '': break # retain the existing value
|
||||||
self.tourn_size = int(query); break
|
self.tourn_size = int(query); break
|
||||||
except ValueError: print '\n\t\033[32m Enter a number from 2 including', str(self.tree_pop_max) + ".", 'Try again ...\033[0;0m'
|
except ValueError: print '\n\t\033[32m Enter a number from 2 including', str(self.tree_pop_max) + ".", 'Try again ...\033[0;0m'
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ class Base_GP(object):
|
||||||
print '\n\t The current minimum number of nodes is:', self.tree_depth_min
|
print '\n\t The current minimum number of nodes is:', self.tree_depth_min
|
||||||
query = raw_input('\t Adjust the minimum number of nodes for all Trees (min 3): ')
|
query = raw_input('\t Adjust the minimum number of nodes for all Trees (min 3): ')
|
||||||
if query not in str(menu) or query == '0' or query == '1' or query == '2': raise ValueError() # not ideal 20170918
|
if query not in str(menu) or query == '0' or query == '1' or query == '2': raise ValueError() # not ideal 20170918
|
||||||
elif query == '': break
|
elif query == '': break # retain the existing value
|
||||||
self.tree_depth_min = int(query); break
|
self.tree_depth_min = int(query); break
|
||||||
except ValueError: print '\n\t\033[32m Enter a number from 3 including 1000. Try again ...\033[0;0m'
|
except ValueError: print '\n\t\033[32m Enter a number from 3 including 1000. Try again ...\033[0;0m'
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ class Base_GP(object):
|
||||||
try:
|
try:
|
||||||
query = raw_input('\t Enter quantity of Trees to be generated by Reproduction: ')
|
query = raw_input('\t Enter quantity of Trees to be generated by Reproduction: ')
|
||||||
if query not in str(menu): raise ValueError()
|
if query not in str(menu): raise ValueError()
|
||||||
elif query == '': break
|
elif query == '': break # retain the existing value
|
||||||
tmp_repro = int(query); break # replaced int(float(query)) 20170918
|
tmp_repro = int(query); break # replaced int(float(query)) 20170918
|
||||||
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ class Base_GP(object):
|
||||||
try:
|
try:
|
||||||
query = raw_input('\t Enter quantity of Trees to be generated by Point Mutation: ')
|
query = raw_input('\t Enter quantity of Trees to be generated by Point Mutation: ')
|
||||||
if query not in str(menu): raise ValueError()
|
if query not in str(menu): raise ValueError()
|
||||||
elif query == '': break
|
elif query == '': break # retain the existing value
|
||||||
tmp_point = int(query); break # replaced int(float(query)) 20170918
|
tmp_point = int(query); break # replaced int(float(query)) 20170918
|
||||||
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ class Base_GP(object):
|
||||||
try:
|
try:
|
||||||
query = raw_input('\t Enter quantity of Trees to be generated by Branch Mutation: ')
|
query = raw_input('\t Enter quantity of Trees to be generated by Branch Mutation: ')
|
||||||
if query not in str(menu): raise ValueError()
|
if query not in str(menu): raise ValueError()
|
||||||
elif query == '': break
|
elif query == '': break # retain the existing value
|
||||||
tmp_branch = int(query); break # replaced int(float(query)) 20170918
|
tmp_branch = int(query); break # replaced int(float(query)) 20170918
|
||||||
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ class Base_GP(object):
|
||||||
try:
|
try:
|
||||||
query = raw_input('\t Enter quantity of Trees to be generated by Crossover: ')
|
query = raw_input('\t Enter quantity of Trees to be generated by Crossover: ')
|
||||||
if query not in str(menu): raise ValueError()
|
if query not in str(menu): raise ValueError()
|
||||||
elif query == '': break
|
elif query == '': break # retain the existing value
|
||||||
tmp_cross = int(query); break # replaced int(float(query)) 20170918
|
tmp_cross = int(query); break # replaced int(float(query)) 20170918
|
||||||
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
except ValueError: print '\n\t\033[32m Enter a number from 0 including 1000. Try again ...\033[0;0m'
|
||||||
|
|
||||||
|
@ -648,6 +648,8 @@ class Base_GP(object):
|
||||||
This method is used to load a saved population of Trees, as invoked through the (pause) menu where population_s
|
This method is used to load a saved population of Trees, as invoked through the (pause) menu where population_s
|
||||||
replaces population_a in the /[path]/karoo_gp/runs/ directory.
|
replaces population_a in the /[path]/karoo_gp/runs/ directory.
|
||||||
|
|
||||||
|
Called by: fx_karoo_pause
|
||||||
|
|
||||||
Arguments required: population size
|
Arguments required: population size
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -891,7 +893,7 @@ class Base_GP(object):
|
||||||
'tree_type' is either (f)ull or (g)row. Note, however, that when the user selects 'ramped 50/50' at launch,
|
'tree_type' is either (f)ull or (g)row. Note, however, that when the user selects 'ramped 50/50' at launch,
|
||||||
it is still (f) or (g) which are passed to this method.
|
it is still (f) or (g) which are passed to this method.
|
||||||
|
|
||||||
This method is called by: fx_init_construct, fx_evolve_crossover, fx_evolve_grow_mutate
|
Called by: fx_init_construct, fx_evolve_crossover, fx_evolve_grow_mutate
|
||||||
|
|
||||||
Arguments required: TREE_ID, tree_type, tree_depth_base
|
Arguments required: TREE_ID, tree_type, tree_depth_base
|
||||||
'''
|
'''
|
||||||
|
@ -1203,7 +1205,7 @@ class Base_GP(object):
|
||||||
to the original variables listed across the top of each column of data.csv. Therefore, we must re-assign
|
to the original variables listed across the top of each column of data.csv. Therefore, we must re-assign
|
||||||
the respective values for each subsequent row in the data .csv, for each Tree's unique expression.
|
the respective values for each subsequent row in the data .csv, for each Tree's unique expression.
|
||||||
|
|
||||||
Called by: fx_karoo_pause, fx_fitness_gym, fx_fitness_eval, fx_fitness_gene_pool, fx_display_tree
|
Called by: fx_karoo_pause, fx_data_params_write, fx_eval_label, fx_fitness_gym, fx_fitness_gene_pool, fx_display_tree
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -1294,7 +1296,9 @@ class Base_GP(object):
|
||||||
print '\n Evaluate all Trees in Generation', self.generation_id
|
print '\n Evaluate all Trees in Generation', self.generation_id
|
||||||
if self.display == 'i': self.fx_karoo_pause(0)
|
if self.display == 'i': self.fx_karoo_pause(0)
|
||||||
|
|
||||||
self.fx_evolve_tree_renum(self.population_b) # population renumber
|
for tree_id in range(1, len(self.population_b)): # renumber all Trees in given population - merged fx_evolve_tree_renum 2018 04/12
|
||||||
|
self.population_b[tree_id][0][1] = tree_id
|
||||||
|
|
||||||
self.fx_fitness_gym(self.population_b) # run 'fx_eval', 'fx_fitness', 'fx_fitness_store', and fitness record
|
self.fx_fitness_gym(self.population_b) # run 'fx_eval', 'fx_fitness', 'fx_fitness_store', and fitness record
|
||||||
self.fx_data_tree_write(self.population_b, 'a') # archive current population as foundation for next generation
|
self.fx_data_tree_write(self.population_b, 'a') # archive current population as foundation for next generation
|
||||||
|
|
||||||
|
@ -1325,7 +1329,7 @@ class Base_GP(object):
|
||||||
fitness for that generation. It is important to note that Part 3 does *not* in any way influence the Tournament
|
fitness for that generation. It is important to note that Part 3 does *not* in any way influence the Tournament
|
||||||
Selection which is a stand-alone process.
|
Selection which is a stand-alone process.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_gp, fx_eval_generations
|
||||||
|
|
||||||
Arguments required: population
|
Arguments required: population
|
||||||
'''
|
'''
|
||||||
|
@ -1412,7 +1416,7 @@ class Base_GP(object):
|
||||||
'pairwise_fitness' - an array of the element-wise results of applying corresponding fitness kernel function
|
'pairwise_fitness' - an array of the element-wise results of applying corresponding fitness kernel function
|
||||||
'fitness' - aggregated scalar fitness score
|
'fitness' - aggregated scalar fitness score
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_pause, fx_data_params_write, fx_fitness_gym
|
||||||
|
|
||||||
Arguments required: expr, data
|
Arguments required: expr, data
|
||||||
'''
|
'''
|
||||||
|
@ -1456,10 +1460,6 @@ class Base_GP(object):
|
||||||
origin. At the time of this writing, an odd number of class labels will generate an extra bin on the positive
|
origin. At the time of this writing, an odd number of class labels will generate an extra bin on the positive
|
||||||
side of origin as it has not yet been determined the effect of enabling the middle bin to include both a
|
side of origin as it has not yet been determined the effect of enabling the middle bin to include both a
|
||||||
negative and positive result.
|
negative and positive result.
|
||||||
|
|
||||||
Called by:
|
|
||||||
|
|
||||||
Arguments required: result, solution
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# was breaking with upgrade from Tensorflow 1.1 to 1.3; fixed by Iurii by replacing [] with () as of 20171026
|
# was breaking with upgrade from Tensorflow 1.1 to 1.3; fixed by Iurii by replacing [] with () as of 20171026
|
||||||
|
@ -1522,7 +1522,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Extract expression tree from the string algo_sym and transform into TensorFlow (TF) graph.
|
Extract expression tree from the string algo_sym and transform into TensorFlow (TF) graph.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_fitness_eval
|
||||||
|
|
||||||
Arguments required: expr, tensors
|
Arguments required: expr, tensors
|
||||||
'''
|
'''
|
||||||
|
@ -1537,7 +1537,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Chains a sequence of boolean operations (e.g. 'a and b and c') into a single TensorFlow (TF) sub graph.
|
Chains a sequence of boolean operations (e.g. 'a and b and c') into a single TensorFlow (TF) sub graph.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_fitness_node_parse
|
||||||
|
|
||||||
Arguments required: values, operation, tensors
|
Arguments required: values, operation, tensors
|
||||||
'''
|
'''
|
||||||
|
@ -1547,14 +1547,14 @@ class Base_GP(object):
|
||||||
return operation(x, self.fx_fitness_chain_bool(values[1:], operation, tensors))
|
return operation(x, self.fx_fitness_chain_bool(values[1:], operation, tensors))
|
||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def fx_fitness_chain_compare(self, comparators, ops, tensors):
|
def fx_fitness_chain_compare(self, comparators, ops, tensors):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Chains a sequence of comparison operations (e.g. 'a > b < c') into a single TensorFlow (TF) sub graph.
|
Chains a sequence of comparison operations (e.g. 'a > b < c') into a single TensorFlow (TF) sub graph.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_fitness_node_parse
|
||||||
|
|
||||||
Arguments required: comparators, ops, tensors
|
Arguments required: comparators, ops, tensors
|
||||||
'''
|
'''
|
||||||
|
@ -1572,7 +1572,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Recursively transforms parsed expression tree into TensorFlow (TF) graph.
|
Recursively transforms parsed expression tree into TensorFlow (TF) graph.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_fitness_expr_parse, fx_fitness_chain_bool, fx_fitness_chain_compare
|
||||||
|
|
||||||
Arguments required: node, tensors
|
Arguments required: node, tensors
|
||||||
'''
|
'''
|
||||||
|
@ -1617,7 +1617,7 @@ class Base_GP(object):
|
||||||
elif solution - 1 - skew < result <= solution - skew; fitness = 1: # check for class bins between first and last
|
elif solution - 1 - skew < result <= solution - skew; fitness = 1: # check for class bins between first and last
|
||||||
else: fitness = 0 # no class match
|
else: fitness = 0 # no class match
|
||||||
|
|
||||||
Called by:
|
Called by: fx_fitness_eval
|
||||||
|
|
||||||
Arguments required: result
|
Arguments required: result
|
||||||
'''
|
'''
|
||||||
|
@ -1641,7 +1641,7 @@ class Base_GP(object):
|
||||||
be used to apply pressure to the evolutionary process to select from a set of trees with the same fitness function
|
be used to apply pressure to the evolutionary process to select from a set of trees with the same fitness function
|
||||||
the one(s) with the simplest (shortest) multivariate expression.
|
the one(s) with the simplest (shortest) multivariate expression.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_fitness_gym
|
||||||
|
|
||||||
Arguments required: tree, fitness
|
Arguments required: tree, fitness
|
||||||
'''
|
'''
|
||||||
|
@ -1670,7 +1670,7 @@ class Base_GP(object):
|
||||||
Stronger boundary parameters (a reduced gap between the min and max number of nodes) may invoke more compact
|
Stronger boundary parameters (a reduced gap between the min and max number of nodes) may invoke more compact
|
||||||
solutions, but also runs the risk of elitism, even total population die-off where a healthy population once existed.
|
solutions, but also runs the risk of elitism, even total population die-off where a healthy population once existed.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_reproduce, fx_nextgen_point_mutate, fx_nextgen_branch_mutate, fx_nextgen_crossover
|
||||||
|
|
||||||
Arguments required: tourn_size
|
Arguments required: tourn_size
|
||||||
'''
|
'''
|
||||||
|
@ -1767,7 +1767,7 @@ class Base_GP(object):
|
||||||
|
|
||||||
This method is automatically invoked with every Tournament Selection ('fx_fitness_tournament').
|
This method is automatically invoked with every Tournament Selection ('fx_fitness_tournament').
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_gp, fx_karoo_continue
|
||||||
|
|
||||||
Arguments required: none
|
Arguments required: none
|
||||||
'''
|
'''
|
||||||
|
@ -1807,7 +1807,7 @@ class Base_GP(object):
|
||||||
y_pred = result, the predicted labels generated by Karoo GP
|
y_pred = result, the predicted labels generated by Karoo GP
|
||||||
y_true = solution, the true labels associated with the data
|
y_true = solution, the true labels associated with the data
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_pause
|
||||||
|
|
||||||
Arguments required: result
|
Arguments required: result
|
||||||
'''
|
'''
|
||||||
|
@ -1827,7 +1827,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Print the Fitness score and Mean Squared Error for a REGRESSION run against the test data.
|
Print the Fitness score and Mean Squared Error for a REGRESSION run against the test data.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_pause
|
||||||
|
|
||||||
Arguments required: result
|
Arguments required: result
|
||||||
|
|
||||||
|
@ -1848,7 +1848,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Print the accuracy for a MATCH kernel run against the test data.
|
Print the accuracy for a MATCH kernel run against the test data.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_pause
|
||||||
|
|
||||||
Arguments required: result
|
Arguments required: result
|
||||||
'''
|
'''
|
||||||
|
@ -1951,7 +1951,7 @@ class Base_GP(object):
|
||||||
|
|
||||||
if self.display != 's':
|
if self.display != 's':
|
||||||
if self.display == 'i': print ''
|
if self.display == 'i': print ''
|
||||||
print ' Perform', self.evolve_branch, 'Full or Grow Mutations ...'
|
print ' Perform', self.evolve_branch, 'Branch Mutations ...'
|
||||||
if self.display == 'i': self.fx_karoo_pause(0)
|
if self.display == 'i': self.fx_karoo_pause(0)
|
||||||
|
|
||||||
for n in range(self.evolve_branch): # quantity of Trees to be generated through mutation
|
for n in range(self.evolve_branch): # quantity of Trees to be generated through mutation
|
||||||
|
@ -2026,7 +2026,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Mutate a single point in any Tree (Grow or Full).
|
Mutate a single point in any Tree (Grow or Full).
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_point_mutate
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2065,7 +2065,7 @@ class Base_GP(object):
|
||||||
shape of the Tree must remain identical, each node is mutated sequentially (copied from the new Tree to replace
|
shape of the Tree must remain identical, each node is mutated sequentially (copied from the new Tree to replace
|
||||||
the old, node for node), where functions remain functions and terminals remain terminals.
|
the old, node for node), where functions remain functions and terminals remain terminals.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_branch_mutate
|
||||||
|
|
||||||
Arguments required: tree, branch
|
Arguments required: tree, branch
|
||||||
'''
|
'''
|
||||||
|
@ -2115,7 +2115,7 @@ class Base_GP(object):
|
||||||
If however a function mutates into a terminal, the entire branch beneath the function is deleted from the array
|
If however a function mutates into a terminal, the entire branch beneath the function is deleted from the array
|
||||||
and the entire array is updated, to fix parent/child links, associated arities, and node IDs.
|
and the entire array is updated, to fix parent/child links, associated arities, and node IDs.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_branch_mutate
|
||||||
|
|
||||||
Arguments required: tree, branch
|
Arguments required: tree, branch
|
||||||
'''
|
'''
|
||||||
|
@ -2170,9 +2170,9 @@ class Base_GP(object):
|
||||||
|
|
||||||
if self.display == 'db': print '\n\033[36m This is the new Tree to be inserted at node\033[1m', branch_top, '\033[0;0m\033[36min tourn_winner:\033[0;0m\n', self.tree; self.fx_karoo_pause(0)
|
if self.display == 'db': print '\n\033[36m This is the new Tree to be inserted at node\033[1m', branch_top, '\033[0;0m\033[36min tourn_winner:\033[0;0m\n', self.tree; self.fx_karoo_pause(0)
|
||||||
|
|
||||||
|
tree = self.fx_evolve_branch_insert(tree, branch) # insert new 'gp.tree' at point of mutation ('branch_top') in 'tree' ('tourn_winner')
|
||||||
|
# tree = self.fx_evolve_branch_body_copy(tree) # copy remaining nodes in new 'gp.tree' to 'tree' ('tourn_winner')
|
||||||
# because we already know the maximum depth to which this branch can grow, there is no need to prune after insertion
|
# because we already know the maximum depth to which this branch can grow, there is no need to prune after insertion
|
||||||
tree = self.fx_evolve_branch_top_copy(tree, branch) # copy root of new 'gp.tree' to point of mutation ('branch_top') in 'tree' ('tourn_winner')
|
|
||||||
tree = self.fx_evolve_branch_body_copy(tree) # copy remaining nodes in new 'gp.tree' to 'tree' ('tourn_winner')
|
|
||||||
|
|
||||||
tree = self.fx_evolve_fitness_wipe(tree) # wipe fitness data
|
tree = self.fx_evolve_fitness_wipe(tree) # wipe fitness data
|
||||||
|
|
||||||
|
@ -2190,7 +2190,7 @@ class Base_GP(object):
|
||||||
passed to 'offspring' which will receive 'branch_a'. With the second run, 'parent_a' is passed to 'offspring' which
|
passed to 'offspring' which will receive 'branch_a'. With the second run, 'parent_a' is passed to 'offspring' which
|
||||||
will receive 'branch_b'.
|
will receive 'branch_b'.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_crossover
|
||||||
|
|
||||||
Arguments required: parent, branch_x, offspring, branch_y (parents_a / _b, branch_a / _b from 'fx_nextgen_crossover')
|
Arguments required: parent, branch_x, offspring, branch_y (parents_a / _b, branch_a / _b from 'fx_nextgen_crossover')
|
||||||
'''
|
'''
|
||||||
|
@ -2233,8 +2233,8 @@ class Base_GP(object):
|
||||||
if self.display == 'db':
|
if self.display == 'db':
|
||||||
print '\n\033[36m ... and insert it into a copy of the second parent in place of the selected branch\033[1m', branch_y,':\033[0;0m\n', offspring; self.fx_karoo_pause(0)
|
print '\n\033[36m ... and insert it into a copy of the second parent in place of the selected branch\033[1m', branch_y,':\033[0;0m\n', offspring; self.fx_karoo_pause(0)
|
||||||
|
|
||||||
offspring = self.fx_evolve_branch_top_copy(offspring, branch_y) # copy root of 'branch_y' ('gp.tree') to 'offspring'
|
offspring = self.fx_evolve_branch_insert(offspring, branch_y) # insert new 'branch_y' ('gp.tree') at point of mutation ('branch_top') in 'offspring' ('tourn_winner')
|
||||||
offspring = self.fx_evolve_branch_body_copy(offspring) # copy remaining nodes in 'branch_y' ('gp.tree') to 'offspring'
|
# offspring = self.fx_evolve_branch_body_copy(offspring) # copy remaining nodes in 'branch_y' ('gp.tree') to 'offspring'
|
||||||
offspring = self.fx_evolve_tree_prune(offspring, self.tree_depth_max) # prune to the max Tree depth + adjustment - tested 2016 07/10
|
offspring = self.fx_evolve_tree_prune(offspring, self.tree_depth_max) # prune to the max Tree depth + adjustment - tested 2016 07/10
|
||||||
|
|
||||||
offspring = self.fx_evolve_fitness_wipe(offspring) # wipe fitness data
|
offspring = self.fx_evolve_fitness_wipe(offspring) # wipe fitness data
|
||||||
|
@ -2251,7 +2251,7 @@ class Base_GP(object):
|
||||||
method to select a region of the 'tourn_winner' which is then converted to a stand-alone tree. As such, it is
|
method to select a region of the 'tourn_winner' which is then converted to a stand-alone tree. As such, it is
|
||||||
imperative that the nodes be in the correct order, else all kinds of bad things happen.
|
imperative that the nodes be in the correct order, else all kinds of bad things happen.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_branch, fx_nextgen_crossover
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2269,58 +2269,42 @@ class Base_GP(object):
|
||||||
return branch
|
return branch
|
||||||
|
|
||||||
|
|
||||||
def fx_evolve_branch_top_copy(self, tree, branch):
|
def fx_evolve_branch_insert(self, tree, branch):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Copy the point of mutation ('branch_top') from 'gp.tree' to 'tree'.
|
This method enables the insertion of Tree in place of a branch. It works with 3 inputs: local 'tree' is being
|
||||||
|
modified; local 'branch' is a section of 'tree' which will be removed; and the global 'gp.tree' (recycling this
|
||||||
|
variable from initial population generation) is the new Tree to be insertd into 'tree', replacing 'branch'.
|
||||||
|
|
||||||
This method works with 3 inputs: local 'tree' is being modified; local 'branch' is a section of 'tree' which
|
The end result is a Tree with a mutated branch. Pretty cool, huh?
|
||||||
will be removed; and global 'gp.tree' (recycling from initial population generation) is the new Tree to be
|
|
||||||
copied into 'tree', replacing 'branch'.
|
|
||||||
|
|
||||||
This method is used in both Grow Mutation and Crossover.
|
Called by: fx_evolve_grow_mutate, fx_evolve_grow_crossover
|
||||||
|
|
||||||
Called by:
|
|
||||||
|
|
||||||
Arguments required: tree, branch
|
Arguments required: tree, branch
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
### insert branch_top from 'gp.tree' into 'tree' ### *_branch_top_copy merged with *_body_copy 2018 04/12
|
||||||
|
|
||||||
branch_top = int(branch[0])
|
branch_top = int(branch[0])
|
||||||
|
|
||||||
tree[5][branch_top] = 'func' # update type ('func' to 'term' or 'term' to 'term'); this modifies gp.tree[5[1] from 'root' to 'func'
|
tree[5][branch_top] = 'func' # update type ('func' to 'term' or 'term' to 'term'); this modifies gp.tree[5][1] from 'root' to 'func'
|
||||||
tree[6][branch_top] = self.tree[6][1] # copy node_label from new tree
|
tree[6][branch_top] = self.tree[6][1] # copy node_label from new tree
|
||||||
tree[8][branch_top] = self.tree[8][1] # copy node_arity from new tree
|
tree[8][branch_top] = self.tree[8][1] # copy node_arity from new tree
|
||||||
|
|
||||||
tree = np.delete(tree, branch[1:], axis = 1) # delete all nodes beneath point of mutation ('branch_top')
|
tree = np.delete(tree, branch[1:], axis = 1) # delete all nodes beneath point of mutation ('branch_top')
|
||||||
|
|
||||||
c_buffer = self.fx_evolve_c_buffer(tree, branch_top) # generate c_buffer for point of mutation ('branch_top')
|
c_buffer = self.fx_evolve_c_buffer(tree, branch_top) # generate c_buffer for point of mutation ('branch_top')
|
||||||
tree = self.fx_evolve_child_insert(tree, branch_top, c_buffer) # insert new nodes
|
tree = self.fx_evolve_child_insert(tree, branch_top, c_buffer) # insert a single new node ('branch_top')
|
||||||
tree = self.fx_evolve_node_renum(tree) # renumber all 'NODE_ID's
|
tree = self.fx_evolve_node_renum(tree) # renumber all 'NODE_ID's
|
||||||
|
|
||||||
if self.display == 'db':
|
if self.display == 'db':
|
||||||
print '\n\t ... inserted node 1 of', len(self.tree[3])-1
|
print '\n\t ... inserted node 1 of', len(self.tree[3])-1
|
||||||
print '\n\033[36m This is the Tree after a new node is inserted:\033[0;0m\n', tree; self.fx_karoo_pause(0)
|
print '\n\033[36m This is the Tree after a new node is inserted:\033[0;0m\n', tree; self.fx_karoo_pause(0)
|
||||||
|
|
||||||
return tree
|
|
||||||
|
|
||||||
|
### insert branch_body from 'gp.tree' into 'tree' ### *_branch_top_copy merged with *_body_copy 2018 04/12
|
||||||
def fx_evolve_branch_body_copy(self, tree):
|
|
||||||
|
|
||||||
'''
|
|
||||||
Copy the body of 'gp.tree' to 'tree', one node at a time.
|
|
||||||
|
|
||||||
This method works with 3 inputs: local 'tree' is being modified; local 'branch' is a section of 'tree' which
|
node_count = 2 # set node count for 'gp.tree' to 2 as the new root has already replaced 'branch_top' (above)
|
||||||
will be removed; and global 'gp.tree' (recycling from initial population generation) is the new Tree to be
|
|
||||||
copied into 'tree', replacing 'branch'.
|
|
||||||
|
|
||||||
This method is used in both Grow Mutation and Crossover.
|
|
||||||
|
|
||||||
Called by:
|
|
||||||
|
|
||||||
Arguments required: tree
|
|
||||||
'''
|
|
||||||
|
|
||||||
node_count = 2 # set node count for 'gp.tree' to 2 as the new root has already replaced 'branch_top' in 'fx_evolve_branch_top_copy'
|
|
||||||
|
|
||||||
while node_count < len(self.tree[3]): # increment through all nodes in the new Tree ('gp.tree'), starting with node 2
|
while node_count < len(self.tree[3]): # increment through all nodes in the new Tree ('gp.tree'), starting with node 2
|
||||||
|
|
||||||
|
@ -2357,9 +2341,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
This method prepares a stand-alone Tree as a copy of the given branch.
|
This method prepares a stand-alone Tree as a copy of the given branch.
|
||||||
|
|
||||||
This method is used with Crossover.
|
Called by: fx_evolve_crossover
|
||||||
|
|
||||||
Called by:
|
|
||||||
|
|
||||||
Arguments required: tree, branch
|
Arguments required: tree, branch
|
||||||
'''
|
'''
|
||||||
|
@ -2407,7 +2389,7 @@ class Base_GP(object):
|
||||||
This method is currently called from the evolution methods, but will soon (I hope) be called from the first
|
This method is currently called from the evolution methods, but will soon (I hope) be called from the first
|
||||||
generation Tree generation methods (above) such that the same method may be used repeatedly.
|
generation Tree generation methods (above) such that the same method may be used repeatedly.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_child_link_fix, fx_evolve_banch_top_copy, fx_evolve_branch_body_copy
|
||||||
|
|
||||||
Arguments required: tree, node
|
Arguments required: tree, node
|
||||||
'''
|
'''
|
||||||
|
@ -2435,7 +2417,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Link each parent node to its children.
|
Link each parent node to its children.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_child_link_fix
|
||||||
|
|
||||||
Arguments required: tree, node, c_buffer
|
Arguments required: tree, node, c_buffer
|
||||||
'''
|
'''
|
||||||
|
@ -2476,7 +2458,7 @@ class Base_GP(object):
|
||||||
|
|
||||||
This is required anytime the size of the array 'gp.tree' has been modified, as with both Grow and Full mutation.
|
This is required anytime the size of the array 'gp.tree' has been modified, as with both Grow and Full mutation.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_grow_mutate, fx_evolve_crossover, fx_evolve_branch_body_copy, fx_evolve_branch_copy
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2495,7 +2477,7 @@ class Base_GP(object):
|
||||||
'''
|
'''
|
||||||
Insert child nodes.
|
Insert child nodes.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_branch_insert
|
||||||
|
|
||||||
Arguments required: tree, node, c_buffer
|
Arguments required: tree, node, c_buffer
|
||||||
'''
|
'''
|
||||||
|
@ -2553,7 +2535,7 @@ class Base_GP(object):
|
||||||
of whack and the expression will work perfectly. This is maintained for the sole purpose of granting the user
|
of whack and the expression will work perfectly. This is maintained for the sole purpose of granting the user
|
||||||
a friendly, makes-sense interface which can be read in both directions.
|
a friendly, makes-sense interface which can be read in both directions.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_branch_copy
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2586,7 +2568,7 @@ class Base_GP(object):
|
||||||
This is required after a function has been replaced by a terminal, as may occur with both Grow mutation and
|
This is required after a function has been replaced by a terminal, as may occur with both Grow mutation and
|
||||||
Crossover.
|
Crossover.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_grow_mutate, fx_evolve_tree_prune
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2611,7 +2593,7 @@ class Base_GP(object):
|
||||||
This is required after a new generation is evolved as the NODE_ID numbers are carried forward from the previous
|
This is required after a new generation is evolved as the NODE_ID numbers are carried forward from the previous
|
||||||
generation but are no longer in order.
|
generation but are no longer in order.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_grow_mutate, fx_evolve_crossover, fx_evolve_branch_insert, fx_evolve_branch_copy
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2631,7 +2613,7 @@ class Base_GP(object):
|
||||||
This is required after a new generation is evolved as the fitness of the same Tree prior to its mutation will
|
This is required after a new generation is evolved as the fitness of the same Tree prior to its mutation will
|
||||||
no longer apply.
|
no longer apply.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_nextgen_reproduce, fx_nextgen_point_mutate, fx_nextgen_full_mutate, fx_nextgen_grow_mutate, fx_nextgen_crossover
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2648,7 +2630,7 @@ class Base_GP(object):
|
||||||
(branch) or a full tree, and it will operate correctly. The input value 'depth' becomes the new maximum depth,
|
(branch) or a full tree, and it will operate correctly. The input value 'depth' becomes the new maximum depth,
|
||||||
where depth is defined as the local maximum + the user defined adjustment.
|
where depth is defined as the local maximum + the user defined adjustment.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_evolve_crossover
|
||||||
|
|
||||||
Arguments required: tree, depth
|
Arguments required: tree, depth
|
||||||
'''
|
'''
|
||||||
|
@ -2673,26 +2655,6 @@ class Base_GP(object):
|
||||||
|
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
|
|
||||||
def fx_evolve_tree_renum(self, population):
|
|
||||||
|
|
||||||
'''
|
|
||||||
Renumber all 'TREE_ID' in a given population.
|
|
||||||
|
|
||||||
This is required after a new generation is evolved as the TREE_ID numbers are carried forward from the previous
|
|
||||||
generation but are no longer in order.
|
|
||||||
|
|
||||||
Called by:
|
|
||||||
|
|
||||||
Arguments required: population
|
|
||||||
'''
|
|
||||||
|
|
||||||
for tree_id in range(1, len(population)):
|
|
||||||
|
|
||||||
population[tree_id][0][1] = tree_id # renumber all Trees in given population
|
|
||||||
|
|
||||||
return population
|
|
||||||
|
|
||||||
|
|
||||||
def fx_evolve_pop_copy(self, pop_a, title):
|
def fx_evolve_pop_copy(self, pop_a, title):
|
||||||
|
|
||||||
|
@ -2702,7 +2664,7 @@ class Base_GP(object):
|
||||||
Simply copying a list of arrays generates a pointer to the original list. Therefore we must append each array
|
Simply copying a list of arrays generates a pointer to the original list. Therefore we must append each array
|
||||||
to a new, empty array and then build a list of those new arrays.
|
to a new, empty array and then build a list of those new arrays.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_gp, fx_karoo_continue
|
||||||
|
|
||||||
Arguments required: pop_a, title
|
Arguments required: pop_a, title
|
||||||
'''
|
'''
|
||||||
|
@ -2728,7 +2690,7 @@ class Base_GP(object):
|
||||||
|
|
||||||
This method displays all sequential node_ids from 'start' node through bottom, within the given tree.
|
This method displays all sequential node_ids from 'start' node through bottom, within the given tree.
|
||||||
|
|
||||||
Called by:
|
Called by: fx_karoo_gp, fx_karoo_pause
|
||||||
|
|
||||||
Arguments required: tree
|
Arguments required: tree
|
||||||
'''
|
'''
|
||||||
|
@ -2737,7 +2699,7 @@ class Base_GP(object):
|
||||||
print '\n\033[1m\033[36m Tree ID', int(tree[0][1]), '\033[0;0m'
|
print '\n\033[1m\033[36m Tree ID', int(tree[0][1]), '\033[0;0m'
|
||||||
|
|
||||||
for depth in range(0, self.tree_depth_max + 1): # increment through all possible Tree depths - tested 2016 07/09
|
for depth in range(0, self.tree_depth_max + 1): # increment through all possible Tree depths - tested 2016 07/09
|
||||||
print '\n', ind,'\033[36m Tree Depth:', depth, 'of', tree[2][1], '\033[0;0m'
|
print '\n', ind,'\033[36m Tree Depth:', depth, 'of', tree[2][1], '\033[0`;0m'
|
||||||
|
|
||||||
for node in range(1, len(tree[3])): # increment through all nodes (redundant, I know)
|
for node in range(1, len(tree[3])): # increment through all nodes (redundant, I know)
|
||||||
if int(tree[4][node]) == depth:
|
if int(tree[4][node]) == depth:
|
||||||
|
@ -2764,9 +2726,7 @@ class Base_GP(object):
|
||||||
|
|
||||||
This method displays all sequential node_ids from 'start' node through bottom, within the given branch.
|
This method displays all sequential node_ids from 'start' node through bottom, within the given branch.
|
||||||
|
|
||||||
This method is not used by Karoo GP at this time.
|
Called by: This method is not used by Karoo GP at this time.
|
||||||
|
|
||||||
Called by:
|
|
||||||
|
|
||||||
Arguments required: tree, start
|
Arguments required: tree, start
|
||||||
'''
|
'''
|
||||||
|
|
187
karoo_gp_main.py
187
karoo_gp_main.py
|
@ -1,187 +0,0 @@
|
||||||
# Karoo GP Main (desktop)
|
|
||||||
# Use Genetic Programming for Classification and Symbolic Regression
|
|
||||||
# by Kai Staats, MSc; see LICENSE.md
|
|
||||||
# version 1.1
|
|
||||||
|
|
||||||
'''
|
|
||||||
A word to the newbie, expert, and brave--
|
|
||||||
Even if you are highly experienced in Genetic Programming, it is recommended that you review the 'Karoo User Guide'
|
|
||||||
before running this application. While your computer will not burst into flames nor will the sun collapse into a black
|
|
||||||
hole if you do not, you will likely find more enjoyment of this particular flavour of GP with a little understanding
|
|
||||||
of its intent and design.
|
|
||||||
|
|
||||||
KAROO GP DESKTOP
|
|
||||||
This is the Karoo GP desktop application. It presents a simple yet functional user interface for configuring each
|
|
||||||
Karoo GP run. While this can be launched on a remote server, you may find that once you get the hang of using Karoo,
|
|
||||||
and are in more of a production mode than one of experimentation, using karoo_gp_server.py is more to your liking as
|
|
||||||
it provides both a scripted and/or command-line launch vehicle.
|
|
||||||
|
|
||||||
To launch Karoo GP desktop:
|
|
||||||
|
|
||||||
$ python karoo_gp_main.py
|
|
||||||
|
|
||||||
(or from iPython)
|
|
||||||
|
|
||||||
$ run karoo_gp_main.py
|
|
||||||
|
|
||||||
|
|
||||||
If you include the path to an external dataset, it will auto-load at launch:
|
|
||||||
|
|
||||||
$ python karoo_gp_main.py /[path]/[to_your]/[filename].csv
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys; sys.path.append('modules/') # add directory 'modules' to the current path
|
|
||||||
import os
|
|
||||||
import karoo_gp_base_class; gp = karoo_gp_base_class.Base_GP()
|
|
||||||
|
|
||||||
os.system('clear')
|
|
||||||
print '\n\033[36m\033[1m'
|
|
||||||
print '\t ** ** ****** ***** ****** ****** ****** ******'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t **** ******** ****** ** ** ** ** ** *** *******'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ****** ****** ****** **'
|
|
||||||
print '\033[0;0m'
|
|
||||||
print '\t\033[36m Genetic Programming in Python - by Kai Staats, version 1.1\033[0;0m'
|
|
||||||
print ''
|
|
||||||
|
|
||||||
|
|
||||||
#++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
# User Defined Configuration |
|
|
||||||
#++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
'''
|
|
||||||
Karoo GP queries the user for key parameters, some of which may be adjusted during run-time at user invoked pauses.
|
|
||||||
See the User Guide for meaning and value of each of the following parameters. The server version of Karoo enables
|
|
||||||
all parameters to be configured via command-line arguments.
|
|
||||||
'''
|
|
||||||
|
|
||||||
menu = ['c','r','m','p','']
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
kernel = raw_input('\t Select (c)lassification, (r)egression, (m)atching, or (p)lay (default m): ')
|
|
||||||
if kernel not in menu: raise ValueError()
|
|
||||||
kernel = kernel or 'm'; break
|
|
||||||
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
if kernel == 'p':
|
|
||||||
|
|
||||||
menu = ['f','g','']
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tree_type = raw_input('\t Select (f)ull or (g)row method (default f): ')
|
|
||||||
if tree_type not in menu: raise ValueError()
|
|
||||||
tree_type = tree_type or 'f'; break
|
|
||||||
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
menu = ['f','g','r','']
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tree_type = raw_input('\t Select (f)ull, (g)row, or (r)amped 50/50 method (default r): ')
|
|
||||||
if tree_type not in menu: raise ValueError()
|
|
||||||
tree_type = tree_type or 'r'; break
|
|
||||||
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
menu = range(1,11)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tree_depth_base = raw_input('\t Enter depth of the \033[3minitial\033[0;0m population of Trees (default 3): ')
|
|
||||||
if tree_depth_base not in str(menu) or tree_depth_base == '0': raise ValueError()
|
|
||||||
elif tree_depth_base == '': tree_depth_base = 3; break
|
|
||||||
tree_depth_base = int(tree_depth_base); break
|
|
||||||
except ValueError: print '\t\033[32m Enter a number from 1 including 10. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
|
|
||||||
if kernel == 'p': # if the Play kernel is selected
|
|
||||||
tree_depth_max = tree_depth_base
|
|
||||||
tree_depth_min = 0
|
|
||||||
tree_pop_max = 1
|
|
||||||
generation_max = 1
|
|
||||||
display = 'm'
|
|
||||||
# evolve_repro = evolve_point = evolve_branch = evolve_cross = ''
|
|
||||||
# tourn_size = ''
|
|
||||||
# precision = ''
|
|
||||||
# filename = ''
|
|
||||||
|
|
||||||
else: # if any other kernel is selected
|
|
||||||
|
|
||||||
if tree_type == 'f': tree_depth_max = tree_depth_base
|
|
||||||
else: # if type is Full, the maximum Tree depth for the full run is equal to the initial population
|
|
||||||
|
|
||||||
menu = range(tree_depth_base,11)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tree_depth_max = raw_input('\t Enter maximum Tree depth (default %i): ' %tree_depth_base)
|
|
||||||
if tree_depth_max not in str(menu): raise ValueError()
|
|
||||||
elif tree_depth_max == '': tree_depth_max = tree_depth_base
|
|
||||||
tree_depth_max = int(tree_depth_max)
|
|
||||||
if tree_depth_max < tree_depth_base: raise ValueError() # an ugly exception to the norm 20170918
|
|
||||||
else: break
|
|
||||||
except ValueError: print '\t\033[32m Enter a number >= the initial Tree depth. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
menu = range(3,101)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tree_depth_min = raw_input('\t Enter minimum number of nodes for any given Tree (default 3): ')
|
|
||||||
if tree_depth_min not in str(menu) or tree_depth_min == '0': raise ValueError()
|
|
||||||
elif tree_depth_min == '': tree_depth_min = 3
|
|
||||||
tree_depth_min = int(tree_depth_min); break
|
|
||||||
except ValueError: print '\t\033[32m Enter a number from 3 to 2^(depth + 1) - 1 including 100. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
menu = range(10,1001)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tree_pop_max = raw_input('\t Enter number of Trees in each population (default 100): ')
|
|
||||||
if tree_pop_max not in str(menu) or tree_pop_max == '0': raise ValueError()
|
|
||||||
elif tree_pop_max == '': tree_pop_max = 100
|
|
||||||
tree_pop_max = int(tree_pop_max); break
|
|
||||||
except ValueError: print '\t\033[32m Enter a number from 10 including 1000. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
menu = range(1,101)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
generation_max = raw_input('\t Enter max number of generations (default 10): ')
|
|
||||||
if generation_max not in str(menu) or generation_max == '0': raise ValueError()
|
|
||||||
elif generation_max == '': generation_max = 10
|
|
||||||
generation_max = int(generation_max); break
|
|
||||||
except ValueError: print '\t\033[32m Enter a number from 1 including 100. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
menu = ['i','g','m','s','db','']
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
display = raw_input('\t Display (i)nteractive, (g)eneration, (m)iminal, (s)ilent, or (d)e(b)ug (default m): ')
|
|
||||||
if display not in menu: raise ValueError()
|
|
||||||
display = display or 'm'; break
|
|
||||||
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
|
|
||||||
except KeyboardInterrupt: sys.exit()
|
|
||||||
|
|
||||||
|
|
||||||
# define the ratio between types of mutation, where all sum to 1.0; can be adjusted in 'i'nteractive mode
|
|
||||||
evolve_repro = int(0.1 * tree_pop_max) # quantity of a population generated through Reproduction
|
|
||||||
evolve_point = int(0.0 * tree_pop_max) # quantity of a population generated through Point Mutation
|
|
||||||
evolve_branch = int(0.2 * tree_pop_max) # quantity of a population generated through Branch Mutation
|
|
||||||
evolve_cross = int(0.7 * tree_pop_max) # quantity of a population generated through Crossover
|
|
||||||
|
|
||||||
tourn_size = 7 # qty of individuals entered into each tournament (standard = 7%); can be adjusted in 'i'nteractive mode
|
|
||||||
precision = 6 # the number of floating points for the round function in 'fx_fitness_eval'; hard coded
|
|
||||||
filename = '' # not required unless an external file is referenced
|
|
||||||
|
|
||||||
# pass all user defined settings to the base_class and launch Karoo GP
|
|
||||||
gp.fx_karoo_gp(kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, generation_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, 'm')
|
|
||||||
|
|
||||||
print 'You seem to have found your way back to the Desktop. Huh.'
|
|
||||||
sys.exit()
|
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
# Karoo GP Server
|
|
||||||
# Use Genetic Programming for Classification and Symbolic Regression
|
|
||||||
# by Kai Staats, MSc; see LICENSE.md
|
|
||||||
# version 1.1
|
|
||||||
|
|
||||||
'''
|
|
||||||
A word to the newbie, expert, and brave--
|
|
||||||
Even if you are highly experienced in Genetic Programming, it is recommended that you review the 'Karoo User Guide'
|
|
||||||
before running this application. While your computer will not burst into flames nor will the sun collapse into a black
|
|
||||||
hole if you do not, you will likely find more enjoyment of this particular flavour of GP with a little understanding
|
|
||||||
of its intent and design.
|
|
||||||
|
|
||||||
KAROO GP SERVER
|
|
||||||
This is the Karoo GP server application. It can be internally scripted, fully command-line configured, or a combination
|
|
||||||
of both. If this is your first time using Karoo GP, please run the desktop application karoo_gp_main.py first in order
|
|
||||||
that you come to understand the full functionality of this particular Genetic Programming platform.
|
|
||||||
|
|
||||||
To launch Karoo GP server:
|
|
||||||
|
|
||||||
$ python karoo_gp_server.py
|
|
||||||
|
|
||||||
(or from iPython)
|
|
||||||
|
|
||||||
$ run karoo_gp_server.py
|
|
||||||
|
|
||||||
|
|
||||||
Without any arguments, Karoo GP relies entirely upon the scripted settings and the datasets located in karoo_gp/files/.
|
|
||||||
|
|
||||||
If you include the path to an external dataset, it will auto-load at launch:
|
|
||||||
|
|
||||||
$ python karoo_gp_server.py /[path]/[to_your]/[filename].csv
|
|
||||||
|
|
||||||
|
|
||||||
You can include a number of additional arguments which override the default values, as follows:
|
|
||||||
|
|
||||||
-ker [r,c,m] fitness function: (r)egression, (c)lassification, or (m)atching
|
|
||||||
-typ [f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half
|
|
||||||
-bas [3...10] maximum Tree depth for the initial population
|
|
||||||
-max [3...10] maximum Tree depth for the entire run
|
|
||||||
-min [3...100] minimum number of nodes
|
|
||||||
-pop [10...1000] maximum population
|
|
||||||
-gen [1...100] number of generations
|
|
||||||
-tor [1...100] number of trees selected for the tournament
|
|
||||||
-fil [filename] an external dataset
|
|
||||||
|
|
||||||
Note that if you include any of the above flags, then you must also include a flag to load an external dataset.
|
|
||||||
|
|
||||||
An example is given, as follows:
|
|
||||||
|
|
||||||
$ python karoo_gp_server.py -ker c -typ r -bas 4 -fil /[path]/[to_your]/[filename].csv
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys; sys.path.append('modules/') # to add the directory 'modules' to the current path
|
|
||||||
import os
|
|
||||||
import argparse
|
|
||||||
import karoo_gp_base_class; gp = karoo_gp_base_class.Base_GP()
|
|
||||||
|
|
||||||
os.system('clear')
|
|
||||||
print '\n\033[36m\033[1m'
|
|
||||||
print '\t ** ** ****** ***** ****** ****** ****** ******'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t **** ******** ****** ** ** ** ** ** *** *******'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ** ** ** ** ** ** **'
|
|
||||||
print '\t ** ** ** ** ** ** ****** ****** ****** **'
|
|
||||||
print '\033[0;0m'
|
|
||||||
print '\t\033[36m Genetic Programming in Python - by Kai Staats, version 1.1\033[0;0m'
|
|
||||||
print ''
|
|
||||||
|
|
||||||
ap = argparse.ArgumentParser(description = 'Karoo GP Server')
|
|
||||||
ap.add_argument('-ker', action = 'store', dest = 'kernel', default = 'c', help = '[c,r,m] fitness function: (r)egression, (c)lassification, or (m)atching')
|
|
||||||
ap.add_argument('-typ', action = 'store', dest = 'type', default = 'r', help = '[f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half')
|
|
||||||
ap.add_argument('-bas', action = 'store', dest = 'depth_base', default = 3, help = '[3...10] maximum Tree depth for the initial population')
|
|
||||||
ap.add_argument('-max', action = 'store', dest = 'depth_max', default = 5, help = '[3...10] maximum Tree depth for the entire run')
|
|
||||||
ap.add_argument('-min', action = 'store', dest = 'depth_min', default = 3, help = '[3...100] minimum number of nodes')
|
|
||||||
ap.add_argument('-pop', action = 'store', dest = 'pop_max', default = 100, help = '[10...1000] maximum population')
|
|
||||||
ap.add_argument('-gen', action = 'store', dest = 'gen_max', default = 10, help = '[1...100] number of generations')
|
|
||||||
ap.add_argument('-tor', action = 'store', dest = 'tor_size', default = 7, help = '[1...max pop] tournament size')
|
|
||||||
ap.add_argument('-fil', action = 'store', dest = 'filename', default = '', help = '/path/to_your/[data].csv')
|
|
||||||
|
|
||||||
args = ap.parse_args()
|
|
||||||
|
|
||||||
# pass the argparse defaults and/or user inputs to the required variables
|
|
||||||
kernel = str(args.kernel)
|
|
||||||
tree_type = str(args.type)
|
|
||||||
tree_depth_base = int(args.depth_base)
|
|
||||||
tree_depth_max = int(args.depth_max)
|
|
||||||
tree_depth_min = int(args.depth_min)
|
|
||||||
tree_pop_max = int(args.pop_max)
|
|
||||||
generation_max = int(args.gen_max)
|
|
||||||
tourn_size = int(args.tor_size)
|
|
||||||
filename = str(args.filename)
|
|
||||||
|
|
||||||
evolve_repro = int(0.1 * tree_pop_max) # quantity of a population generated through Reproduction
|
|
||||||
evolve_point = int(0.0 * tree_pop_max) # quantity of a population generated through Point Mutation
|
|
||||||
evolve_branch = int(0.2 * tree_pop_max) # quantity of a population generated through Branch Mutation
|
|
||||||
evolve_cross = int(0.7 * tree_pop_max) # quantity of a population generated through Crossover
|
|
||||||
|
|
||||||
display = 's' # display mode is set to (s)ilent
|
|
||||||
precision = 6 # the number of floating points for the round function in 'fx_fitness_eval'
|
|
||||||
|
|
||||||
# pass all user defined settings to the base_class and launch Karoo GP
|
|
||||||
gp.fx_karoo_gp(kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, generation_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, 's')
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
|
|
Loading…
Reference in New Issue