From f347f5c6297f42ec00d50a4e3e4cd73add74372e Mon Sep 17 00:00:00 2001 From: kstaats Date: Sat, 18 May 2019 09:46:11 -0700 Subject: [PATCH] final update for Python 2.7 version of Karoo --- RELEASE_NOTES.txt | 22 +++++++++++++-- modules/karoo_gp_base_class.py | 50 ++++++++++++++++++---------------- modules/karoo_gp_pause.py | 12 ++++---- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 9423438..f34aa03 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,7 +1,25 @@ +2019 05/18 + +"My apology to the users of Karoo GP for the incredible gap between the most recent and this update. My research and +work have for the past year taken me in other directions. This update marks my return to an active effort in working on +Karoo, and GP applied to a growing research space. I appreciate your patience and understanding." --kai + +NOTE: this is the *final* update to the Python 2.7 version of Karoo. All future development will be in Python 3.x. + +And now, the updates: + +Fixed the Test function to evaluate the Tree selected by the user. + +Modified the menu option from 't'est to 'e'valulate from the Pause menu. + +Added a user defined (m)in node count, (f)ull set of features, or (b)oth as the gene_pool regulator. For more about +the "full set of features" see 2018 04/19 and the new 'swim' variable. + + 2018 05/18 -Fixed a bug which automically re-engaged the run after selecting a pause menu option if mid generation. Now, it -correctly again require an ENTER before continuing. +Fixed a bug which automically re-engaged the run after selecting a pause menu option if mid generation. Now, it again +requires ENTER before continuing. 2018 05/10 diff --git a/modules/karoo_gp_base_class.py b/modules/karoo_gp_base_class.py index 6854cdc..00c988b 100644 --- a/modules/karoo_gp_base_class.py +++ b/modules/karoo_gp_base_class.py @@ -2,7 +2,7 @@ # Define the methods and global variables used by Karoo GP # 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 -# version 2.1.2 +# version 2.1.3 ''' A NOTE TO THE NEWBIE, EXPERT, AND BRAVE @@ -253,7 +253,10 @@ class Base_GP(object): menu_dict = menu.pause(menu_dict) # call the external function menu.pause + ### 2) unpack values returned from menu.pause ### + input_a = menu_dict['input_a'] + input_b = menu_dict['input_b'] self.display = menu_dict['display'] self.tree_depth_min = menu_dict['tree_depth_min'] self.gen_max = menu_dict['gen_max'] @@ -263,50 +266,51 @@ class Base_GP(object): self.evolve_branch = menu_dict['evolve_branch'] self.evolve_cross = menu_dict['evolve_cross'] - ### 3) execute the user queries returned from menu.pause ### - if menu_dict['input_a'] == 'esc': return 0 # ENTER enables next step in generational, interactive, and debug display - elif menu_dict['input_a'] == 'test': # evaluate a Tree against the TEST data - expr = str(self.algo_sym) # might change this to algo_raw for more correct expression evaluation - result = self.fx_fitness_eval(expr, self.data_test, get_pred_labels = True) - print '\n\t\033[36mTree', menu_dict['input_b'], 'yields (raw):', self.algo_raw, '\033[0;0m' - print '\t\033[36mTree', menu_dict['input_b'], 'yields (sym):\033[1m', self.algo_sym, '\033[0;0m\n' - + ### 3) execute the user queries returned from menu.pause ### + if input_a == 'esc': return 0 # ENTER enables next step in generational, interactive, and debug display + + elif input_a == 'eval': # evaluate a Tree against the TEST data + self.fx_eval_poly(self.population_b[input_b]) # generate the raw and sympified expression for the given Tree using SymPy + #print '\n\t\033[36mTree', input_b, 'yields (raw):', self.algo_raw, '\033[0;0m' # print the raw expression + print '\t\033[36mTree', input_b, 'yields (sym):\033[1m', self.algo_sym, '\033[0;0m\n' # print the sympified expression + + result = self.fx_fitness_eval(str(self.algo_sym), self.data_test, get_pred_labels = True) # might change to algo_raw evaluation if self.kernel == 'c': self.fx_fitness_test_classify(result) # TF tested 2017 02/02 elif self.kernel == 'r': self.fx_fitness_test_regress(result) elif self.kernel == 'm': self.fx_fitness_test_match(result) # elif self.kernel == '[other]': self.fx_fitness_test_[other](result) - elif menu_dict['input_a'] == 'print_a': # print a Tree from population_a - self.fx_display_tree(self.population_a[menu_dict['input_b']]) + elif input_a == 'print_a': # print a Tree from population_a + self.fx_display_tree(self.population_a[input_b]) - elif menu_dict['input_a'] == 'print_b': # print a Tree from population_b - self.fx_display_tree(self.population_b[menu_dict['input_b']]) + elif input_a == 'print_b': # print a Tree from population_b + self.fx_display_tree(self.population_b[input_b]) - elif menu_dict['input_a'] == 'pop_a': # list all Trees in population_a + elif input_a == 'pop_a': # list all Trees in population_a print '' for tree_id in range(1, len(self.population_a)): self.fx_eval_poly(self.population_a[tree_id]) # extract the expression print '\t\033[36m Tree', self.population_a[tree_id][0][1], 'yields (sym):\033[1m', self.algo_sym, '\033[0;0m' - elif menu_dict['input_a'] == 'pop_b': # list all Trees in population_b + elif input_a == 'pop_b': # list all Trees in population_b print '' for tree_id in range(1, len(self.population_b)): self.fx_eval_poly(self.population_b[tree_id]) # extract the expression print '\t\033[36m Tree', self.population_b[tree_id][0][1], 'yields (sym):\033[1m', self.algo_sym, '\033[0;0m' - elif menu_dict['input_a'] == 'load': # load population_s to replace population_a + elif input_a == 'load': # load population_s to replace population_a self.fx_data_recover(self.filename['s']) # NEED TO replace 's' with a user defined filename - elif menu_dict['input_a'] == 'write': # write the evolving population_b to disk + elif input_a == 'write': # write the evolving population_b to disk self.fx_data_tree_write(self.population_b, 'b') print '\n\t All current members of the evolving population_b saved to karoo_gp/runs/[date-time]/population_b.csv' - elif menu_dict['input_a'] == 'cont': # check for added generations, then exit fx_karoo_pause and continue the run - if menu_dict['input_b'] > 0: self.gen_max = self.gen_max + menu_dict['input_b'] + elif input_a == 'cont': # check for added generations, then exit fx_karoo_pause and continue the run + if input_b > 0: self.gen_max = self.gen_max + input_b else: pass - elif menu_dict['input_a'] == 'quit': # quit and save run-time parameters to disk + elif input_a == 'quit': # quit and save run-time parameters to disk self.fx_data_params_write('Desktop') print '\n\t \033[32mYour Trees and runtime parameters are archived in karoo_gp/runs/[date-time]/\033[0;0m' if pause == 0: sys.exit() # force quit due to being one level below the while loop @@ -596,7 +600,7 @@ class Base_GP(object): # test the most fit Tree and write to the .txt log - self.fx_eval_poly(self.population_b[int(fittest_tree)]) # generate the raw and sympified equation for the given Tree using SymPy + self.fx_eval_poly(self.population_b[int(fittest_tree)]) # generate the raw and sympified expression for the given Tree using SymPy expr = str(self.algo_sym) # get simplified expression and process it by TF - tested 2017 02/02 result = self.fx_fitness_eval(expr, self.data_test, get_pred_labels = True) @@ -2515,7 +2519,7 @@ class Base_GP(object): ind = ind + '\t' print '' - self.fx_eval_poly(tree) # generate the raw and sympified equation for the entire Tree + self.fx_eval_poly(tree) # generate the raw and sympified expression for the entire Tree print '\t\033[36mTree', tree[0][1], 'yields (raw):', self.algo_raw, '\033[0;0m' print '\t\033[36mTree', tree[0][1], 'yields (sym):\033[1m', self.algo_sym, '\033[0;0m' @@ -2557,7 +2561,7 @@ class Base_GP(object): ind = ind + '\t' print '' - self.fx_eval_poly(tree) # generate the raw and sympified equation for the entire Tree + self.fx_eval_poly(tree) # generate the raw and sympified expression for the entire Tree print '\t\033[36mTree', tree[0][1], 'yields (raw):', self.algo_raw, '\033[0;0m' print '\t\033[36mTree', tree[0][1], 'yields (sym):\033[1m', self.algo_sym, '\033[0;0m' diff --git a/modules/karoo_gp_pause.py b/modules/karoo_gp_pause.py index 4afe573..265aff5 100644 --- a/modules/karoo_gp_pause.py +++ b/modules/karoo_gp_pause.py @@ -1,7 +1,7 @@ # Karoo GP Pause Menu # A text-based user interface for mid-run parameter configuration and population studies # by Kai Staats, MSc; see LICENSE.md -# version 2.1.2 +# version 2.1.3 def pause(menu_dict): @@ -13,7 +13,7 @@ def pause(menu_dict): Arguments required: menu_dict ''' - options = ['','?','help','i','m','g','s','db','ts','min','bal','l','pop','t','p','id','dir','load','w','cont','q'] + options = ['','?','help','i','m','g','s','db','ts','min','bal','l','pop','e','p','id','dir','load','w','cont','q'] while True: try: @@ -40,7 +40,7 @@ def pause(menu_dict): print '' print '\t\033[36m\033[1m l \t\033[0;0m list Trees with leading fitness scores' print '\t\033[36m\033[1m pop \t\033[0;0m list Trees in current population' - print '\t\033[36m\033[1m t \t\033[0;0m evaluate a single Tree against the test data' + print '\t\033[36m\033[1m e \t\033[0;0m evaluate a single Tree against the test data' print '\t\033[36m\033[1m p \t\033[0;0m print a single Tree to screen' print '' print '\t\033[36m\033[1m id \t\033[0;0m display current generation ID' @@ -159,16 +159,16 @@ def pause(menu_dict): if menu_dict['gen_id'] == 1: menu_dict['input_a'] = 'pop_a' else: menu_dict['input_a'] = 'pop_b' - elif menu == 't': # evaluate a Tree against the TEST data + elif menu == 'e': # evaluate a Tree against the TEST data if menu_dict['gen_id'] == 1: print '\n\t\033[32m You cannot evaluate the foundation population. Be patient ...\033[0;0m' else: # gen_id > 1 while True: try: - query = raw_input('\n\t Select a Tree to test: ') + query = raw_input('\n\t Select a Tree to evaluate: ') if query not in str(range(1, menu_dict['pop_b_len'])) or query == '0': raise ValueError() elif query == '': break - else: menu_dict['input_a'] = 'test'; menu_dict['input_b'] = int(query); break + else: menu_dict['input_a'] = 'eval'; menu_dict['input_b'] = int(query); break except ValueError: print '\n\t\033[32m Enter a number from 1 including %s. Try again ...\033[0;0m' %str(menu_dict['pop_b_len'] - 1) except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'