def test_make_decision(): dec = Decisions() decision, decision_point, sims = dec.make_decision( 'E', set(['S13', 'S14', 'H11']), [('W', 'S12'), ('N', 'H12')], [], random=True) # This will only work for naive decision maker of picking first valid card assert (decision in ['S13', 'S14']) assert_equal(decision_point, True) decision, decision_point, sims = dec.make_decision( 'E', set(['H13', 'H14', 'H11']), [('W', 'S12'), ('N', 'H12')], ['H13'], random=True) # This will only work for naive decision maker of picking first valid card assert (decision in ['H14', 'H13', 'H11']) assert_equal(decision_point, True) decision, decision_point, sims = dec.make_decision( 'E', set(['S13', 'S14', 'H11']), [('W', 'S12'), ('N', 'H12')], ['S13'], random=True) # This will only work for naive decision maker of picking first valid card assert_equal(decision, 'S14') assert_equal(decision_point, False)
def test_play_to_leaf_with_sims(): d = Deal(seed=0) disp = Displayer() dec = Decisions() sim = Simulator() e = GameEngine(disp, dec, sim) sims = sim.load_sims(0) d = e.play_to_leaf(d, sims, random=False) assert_equal(d.full_history[0][1], d.trick_tally)
def __init__(self, experiment, agent_kwargs): """ Load params """ # dump kwarg dictionary into the agent object for key, value in agent_kwargs.iteritems(): setattr(self, key, value) self.decisions = Decisions(self.decision_policy, self.stimulus_memory_n_timesteps) if experiment.is_simulation: self._simulated_agent_init(experiment)
def test_play_to_all_leaves(): d = Deal(seed=0) d.make_lead() # print(d.original_hands) disp = Displayer() dec = Decisions() sim = Simulator() e = GameEngine(disp, dec, sim) e.play_to_all_leaves(d) assert_equal(d.trick_no, 5) assert_equal(d.card_no, 17) assert_equal(d.current_trick, []) # we save this number from a previous run. Good to check we always traverse the whole tree assert_equal(d.leaf_nodes, 832)
def test_find_all_layouts_and_run_sims(): deal = { 'N': set(['C14', 'C13', 'C12', 'C11']), 'E': set(['S14', 'S13', 'H12', 'H11']), 'S': set(['D14', 'D13', 'H14', 'H13']), 'W': set(['D12', 'D11', 'S12', 'S11']) } d = Deal(deal=deal) sim = Simulator() dec = Decisions() disp = Displayer() e = GameEngine(disp, dec, sim) d.make_lead('D12') layouts = sim.find_layouts(d) # This should be the case because west has played a card already and north/south haven't assert (len(layouts[2]) > len(layouts[0]))
def test_play_to_leaf(): deal = { 'N': set(['C14', 'C13', 'C12', 'C11']), 'E': set(['S14', 'S13', 'H12', 'H11']), 'S': set(['D14', 'D13', 'H14', 'H13']), 'W': set(['D12', 'D11', 'S12', 'S11']) } d = Deal(deal=deal) disp = Displayer() dec = Decisions() sim = Simulator() e = GameEngine(disp, dec, sim) e.play_to_leaf(d) assert_equal(d.trick_no, 5) assert_equal(d.card_no, 17) assert_equal(d.current_trick, []) assert_equal(d.leaf_nodes, 1)
def test_generate_possible_layouts(): d = Deal(seed=0) disp = Displayer() dec = Decisions() sim = Simulator() e = GameEngine(disp, dec, sim) layouts = sim.generate_layouts('NS', set(['D12', 'D11', 'S12', 'S11']), set(['C14', 'C13', 'C12', 'C11']), d.all_cards, lead=set([])) assert_equal(len(layouts), scipy.special.comb(8, 4)) my_layout = { 'N': set(['C14', 'C13', 'C12', 'C11']), 'E': set(['S14', 'S13', 'H12', 'H11']), 'S': set(['D12', 'D11', 'S12', 'S11']), 'W': set(['D14', 'D13', 'H14', 'H13']) }
class Control: """ Control class """ def __init__(self): """ Initialise """ self.decisions = Decisions() self.action_rules = () def read_csv(self, file: str, **kwargs): """ Create data frame from csv """ # Find all couples of classification rules and try to create action rules self.decisions.read_csv(file, **kwargs) def load_pandas(self, data_frame: pd.DataFrame): """ Load data frame """ self.decisions.load_pandas(data_frame) def fit(self, stable_antecedents: List[str], flexible_antecedents: List[str], consequent: str, conf: float, supp: float, desired_classes: List[str] = None, desired_changes: List[list] = None, is_nan: bool = False, is_reduction: bool = True, min_stable_antecedents: int = 1, min_flexible_antecedents: int = 1): """ Get action rules. Define antecedent and consequent. - stable_antecedents - List of column names. - flexible_antecedents - List of column names. - consequent - Name of column. Confidence and support. - conf - value in % for confidence of classification rules. - supp - value in % for support of classification rules. Desired classes or desired changes must be entered. - desired_classes - List of decision states. For example ["1"]. DEFAULT: None - desired_changes - List of desired changes. For example [["0", "1"]]. DEFAULT: None Should nan values be used. - is_nan - True means nan values are used, False means nan values are not used. DEFAULT: FALSE Should the reduction table be used. - is_reduction - is reduction table used DEFAULT: TRUE Minimal number of stable and flexible couples - min_stable_antecedents - min. stable couples. DEFAULT: 1 - min_flexible_antecedents - min. flexible couples. DEFAULT: 1 """ if bool(desired_classes) != bool(desired_changes): desired_state = DesiredState(desired_classes=desired_classes, desired_changes=desired_changes) else: raise Exception( "Desired classes or desired changes must be entered") antecedents = stable_antecedents + flexible_antecedents self.decisions.prepare_data_fim(antecedents, consequent) self.decisions.fit_fim_apriori(conf=conf, support=supp) self.decisions.generate_decision_table() stable = self.decisions.decision_table[stable_antecedents] flex = self.decisions.decision_table[flexible_antecedents] target = self.decisions.decision_table[[consequent]] supp = self.decisions.support conf = self.decisions.confidence reduced_tables = Reduction(stable, flex, target, desired_state, supp, conf, is_nan) if is_reduction: reduced_tables.reduce() action_rules = ActionRules( reduced_tables.stable_tables, reduced_tables.flexible_tables, reduced_tables.decision_tables, desired_state, reduced_tables.supp, reduced_tables.conf, is_nan, min_stable_antecedents, min_flexible_antecedents) action_rules.fit() self.action_rules = action_rules.action_rules def get_action_rules(self) -> Tuple: """ Get action rules. """ return self.action_rules
def __init__(self): """ Initialise """ self.decisions = Decisions() self.action_rules = ()
deal.save_leaf_node() return deal def play_to_all_leaves(self, deal): # Play hand for the first time, reaching our first leaf node and noting down all other # decision nodes in self.decision_points deal = self.play_to_leaf(deal, random=True) # While there are still unexplored areas of game tree, go back to most recent decision # and make another one while deal.decision_points: last_decision_position = deal.decision_points[-1] deal.restore_position(last_decision_position) # Play the hand again from a specific position, noting down the card number and card # of the last decision made deal = self.play_to_leaf(deal, random=True) return deal.full_history if __name__ == '__main__': decisions = Decisions() simulator = Simulator() game = Engine(decisions, simulator) # game.play_to_leaf() # game.play_to_all_leaves()
class Simulator: """Our simulated mosquito. """ def __init__(self, experiment, agent_kwargs): """ Load params """ # dump kwarg dictionary into the agent object for key, value in agent_kwargs.iteritems(): setattr(self, key, value) self.decisions = Decisions(self.decision_policy, self.stimulus_memory_n_timesteps) if experiment.is_simulation: self._simulated_agent_init(experiment) def _simulated_agent_init(self, experiment): # defaults self.mass = 2.88e-6 # avg. mass of our colony (kg) =2.88 mg, self.time_max = 15. self.dt = 0.01 self.max_bins = int(np.ceil(self.time_max / self.dt)) # N bins # from gassian fit to experimental control data self.initial_velocity_mu = 0.18 self.initial_velocity_stdev = 0.08 # useful aliases self.experiment = experiment self.windtunnel = self.experiment.environment.windtunnel self.bounded = self.experiment.experiment_conditions['bounded'] self.boundary = self.windtunnel.boundary self.heat = self.experiment.environment.heat # useful lists TODO: get rid of? self.kinematics_list = ['position', 'velocity', 'acceleration'] # curvature? self.forces_list = ['total_f', 'random_f', 'stim_f'] self.other_list = ['tsi', 'times', 'decision', 'heat_signal', 'in_plume'] # mk forces self.flight = Flight(self.random_f_strength, self.stim_f_strength, self.damping_coeff) # turn thresh, in units deg s-1. # From Sharri: # it is the stdev of the broader of two Gaussians that fit the distribution of angular velocity # # create repulsion landscape # self._repulsion_funcs = repulsion_landscape3D.landscape(boundary=self.boundary) def fly(self, n_trajectories=1): """ runs _generate_flight n_trajectories times """ df_list = [] traj_i = 0 try: if self.verbose: print """Starting simulations with {} heat model and {} decision policy. If you run out of patience, press <CTL>-C to stop generating simulations and cut to the chase scene.""".format( self.heat.heat_model_name, self.decision_policy) while traj_i < n_trajectories: # print updates if self.verbose: sys.stdout.write("\rTrajectory {}/{}".format(traj_i + 1, n_trajectories)) sys.stdout.flush() array_dict = self._generate_flight() # if len(array_dict['velocity_x']) < 5: # hack to catch when optimizer makes trajectories explode # print "catching explosion" # break # add label column to enumerate the trajectories array_len = len(array_dict['tsi']) array_dict['trajectory_num'] = [traj_i] * array_len # mk df, add to list of dfs df = pd.DataFrame(array_dict) # df = df.set_index(['trajectory_num']) df_list.append(df) traj_i += 1 if traj_i == n_trajectories: if self.verbose: sys.stdout.write("\rSimulations finished. Performing deep magic.") sys.stdout.flush() except KeyboardInterrupt: print "\n Simulations interrupted at iteration {}. Moving along...".format(traj_i) pass observations = Observations() observations.kinematics = pd.concat(df_list) # concatenate all the data frames at once for performance boost. return observations def _generate_flight(self): """Generate a single trajectory using our model. First put everything into np arrays stored inside of a dictionary """ dt = self.dt m = self.mass vector_dict = self._initialize_vector_dict() # # dynamically create easy-to-read aliases for the contents of vector_dict # for key, value in vector_dict.iteritems(): # exec(key + " = vector_dict['" + key + "']") # unpack vector dict into nicer aliases in_plume = vector_dict['in_plume'] heat_signal = vector_dict['heat_signal'] position = vector_dict['position'] velocity = vector_dict['velocity'] acceleration = vector_dict['acceleration'] random_f = vector_dict['random_f'] stim_f = vector_dict['stim_f'] total_f = vector_dict['total_f'] decision = vector_dict['decision'] position[0] = self._set_init_position() velocity[0] = self._set_init_velocity() for tsi in vector_dict['tsi']: in_plume[tsi] = self.heat.check_in_plume_bounds(position[tsi]) # returns False for non-Bool plume decision[tsi], heat_signal[tsi] = self.decisions.make_decision(in_plume[tsi], velocity[tsi][1]) if heat_signal[tsi] == 'X': # this is an awful hack telling us to look up the gradient heat_signal[tsi] = self.heat.get_nearest_gradient(position[tsi]) stim_f[tsi], random_f[tsi], total_f[tsi] = self.flight.calc_forces(velocity[tsi], decision[tsi], heat_signal[tsi]) # calculate current acceleration acceleration[tsi] = total_f[tsi] / m # check if time is out, end loop before we solve for future velo, position if tsi == self.max_bins-1: # -1 because of how range() works vector_dict = self._land(tsi, vector_dict) break ################################################ # Calculate candidate velocity and positions ################################################ candidate_velo = velocity[tsi] + acceleration[tsi] * dt # make sure velocity doesn't diverge to infinity if system is unstable # this stops the optimizer from crashing candidate_velo = self._velocity_ceiling(candidate_velo) candidate_pos = position[tsi] + candidate_velo * dt ################################################ # test candidates ################################################ if self.bounded: candidate_pos, candidate_velo = self._collide_with_wall(candidate_pos, candidate_velo) position[tsi + 1] = candidate_pos velocity[tsi + 1] = candidate_velo # once flight is finished, make dictionary ready to be loaded into DF vector_dict = self._fix_vector_dict(vector_dict) return vector_dict def _land(self, tsi, V): ''' trim excess timebins in arrays ''' if tsi == 0: # hack for if we need to chop a trajectory at the very start for k, array in V.iteritems(): V[k] = array[:1] else: for k, array in V.iteritems(): V[k] = array[:tsi - 1] V[k] = array[:tsi - 1] return V def _collide_with_wall(self, candidate_pos, candidate_velo): walls = self.windtunnel.walls xpos, ypos, zpos = candidate_pos xvelo, yvelo, zvelo = candidate_velo teleport_distance = 0.005 # this is arbitrary crash = False # print "test", candidate_velo # x dim if xpos < walls.downwind: # too far behind crash = True xpos = walls.downwind + teleport_distance # teleport back inside if self.collision_type == 'elastic': xvelo *= -1. elif self.collision_type == 'part_elastic': xvelo *= -self.restitution_coeff elif self.collision_type == 'crash': xvelo = 0. else: raise ValueError("unknown collision type {}".format(self.collision_type)) if xpos > walls.upwind: # reached far (upwind) wall (end) crash = True xpos = walls.upwind - teleport_distance # teleport back inside if self.collision_type == 'elastic': xvelo *= -1. elif self.collision_type == 'part_elastic': xvelo *= -self.restitution_coeff elif self.collision_type == 'crash': xvelo = 0. # y dim if ypos < walls.left: # too left crash = True ypos = walls.left + teleport_distance if self.collision_type == 'elastic': yvelo *= -1. elif self.collision_type == 'part_elastic': yvelo *= -self.restitution_coeff elif self.collision_type == "crash": yvelo = 0. if ypos > walls.right: # too far right crash = True ypos = walls.right - teleport_distance if self.collision_type == 'elastic': yvelo *= -1. elif self.collision_type == 'part_elastic': yvelo *= -self.restitution_coeff elif self.collision_type == 'crash': yvelo = 0. # z dim if zpos > walls.ceiling: # too far above crash = True zpos = walls.ceiling - teleport_distance if self.collision_type == 'elastic': zvelo *= -1. elif self.collision_type == 'part_elastic': zvelo *= -self.restitution_coeff elif self.collision_type == "crash": zvelo = 0. if zpos < walls.floor: # too far below crash = True zpos = walls.floor + teleport_distance if self.collision_type == 'elastic': zvelo *= -1. elif self.collision_type == 'part_elastic': zvelo *= -self.restitution_coeff elif self.collision_type == 'crash': zvelo = 0. try: candidate_pos, candidate_velo = np.array([xpos, ypos, zpos]), np.array([xvelo, yvelo, zvelo]) except: print " cand velo", [xvelo, yvelo, zvelo], "before", candidate_velo return candidate_pos, candidate_velo def _initialize_vector_dict(self): """ initialize np arrays, store in dictionary """ V = {} for name in self.kinematics_list + self.forces_list: V[name] = np.full((self.max_bins, 3), np.nan) V['tsi'] = np.arange(self.max_bins) V['times'] = np.linspace(0, self.time_max, self.max_bins) V['in_plume'] = np.zeros(self.max_bins, dtype=bool) V['heat_signal'] = np.array([None] * self.max_bins) V['decision'] = np.array([None] * self.max_bins) return V def _set_init_velocity(self): initial_velocity_norm = np.random.normal(self.initial_velocity_mu, self.initial_velocity_stdev, 1) unit_vector = generate_random_unit_vector() velocity_vec = initial_velocity_norm * unit_vector return velocity_vec def _set_init_position(self): ''' puts the agent in an initial position, usually within the bounds of the cage Options: [the cage] door, or anywhere in the plane at x=.1 meters set initial velocity from fitted distribution ''' # generate random intial velocity condition using normal distribution fitted to experimental data if self.initial_position_selection == 'realistic': """these were calculated by taking selecting the initial positions of all observed trajectories in all conditions. Then, for each dimension, I calculated the distance of each initial position to the nearest wall in that dimension (i.e. for each z I calculated the distance to the floor and ceiling and selected the smallest distance. Then, Decisions aand""" downwind, upwind, left, right, floor, ceiling = self.boundary x_avg_dist_to_wall = 0.268 y_avg_dist_to_wall = 0.044 z_avg_dist_to_wall = 0.049 x = choose([(downwind + x_avg_dist_to_wall), (upwind - x_avg_dist_to_wall)]) y = choose([left + y_avg_dist_to_wall, (right - y_avg_dist_to_wall)]) z = ceiling - z_avg_dist_to_wall initial_position = np.array([x,y,z]) elif self.initial_position_selection == 'downwind_high': initial_position = np.array( [0.05, np.random.uniform(-0.127, 0.127), 0.2373]) # 0.2373 is mode of z pos distribution elif type(self.initial_position_selection) is list: initial_position = np.array(self.initial_position_selection) elif self.initial_position_selection == "door": # start trajectories as they exit the front door initial_position = np.array([0.1909, np.random.uniform(-0.0381, 0.0381), np.random.uniform(0., 0.1016)]) # FIXME cage is actually suspending above floor elif self.initial_position_selection == 'downwind_plane': initial_position = np.array([0.1, np.random.uniform(-0.127, 0.127), np.random.uniform(0., 0.254)]) else: raise Exception('invalid agent position specified: {}'.format(self.initial_position_selection)) return initial_position def _velocity_ceiling(self, candidate_velo): """check if we're seeing enormous velocities, which sometimes happens when running the optimization algoirithm. if so, cap the velocity instead of landing. this allows the optimizer to keep running. """ for i, velo in enumerate(candidate_velo): if velo > 20: candidate_velo[i] = 20. elif velo < -20: candidate_velo[i] = -20. return candidate_velo def _fix_vector_dict(self, dct): # prepare dict for loading into pandas (dataframe only accepts 1D vectors) # split xyz dicts into separate x, y, z vectors for dataframe fixed_dct = {} for kinematic in self.kinematics_list + self.forces_list: fixed_dct[kinematic + '_x'], fixed_dct[kinematic + '_y'], fixed_dct[kinematic + '_z'] = np.split( dct[kinematic], 3, axis=1) # migrate rest of dict for v in self.other_list: fixed_dct[v] = dct[v] # fix pandas bug when trying to load (R,1) arrays when it expects (R,) arrays for key, dct in fixed_dct.iteritems(): fixed_dct[key] = fixed_dct[key].reshape(len(dct)) if fixed_dct[key].size == 0: fixed_dct[key] = np.array([0.]) # hack so that kde calculation doesn't freeze on empty arrays return fixed_dct
cols = ['my_score', 'max_score'] df = pd.DataFrame(Y1, columns=cols) df['is_beast'] = df['my_score'] == df['max_score'] vc = df['is_beast'].value_counts() true_percentage = vc[True] / (vc[True] + vc[False]) * 100 return true_percentage attempt_count = 10000 X = np.random.randint(1, 7, (attempt_count, 4)) strategies = np.array([[4, 3, 2], [4, 4, 3], [5, 4, 3], [5, 4, 4], [5, 5, 3], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6, 6, 6], [5, 5, 4]]) all_results = [] for str in strategies: Y = get_true_perc(dc.get_value(X, str)) all_results.append(Y) print('True percentage {} : {}%'.format(str, Y)) print(max(all_results)) str_len = len(strategies) plt.plot(range(str_len), all_results) plt.plot(range(str_len), all_results, 'ro') x_ticks = strategies plt.xticks(range(str_len), x_ticks) plt.title('Decision Efficiency with {} training set'.format(attempt_count)) plt.xlabel('Input data') plt.ylabel('True Percentage %') plt.show()
def autofis_onecv(file_zip, file_train, file_test, parameters): # General parameters t_norm = parameters[3] max_size_of_premise = parameters[5] association_method = parameters[11] aggregation_method = parameters[12] # Gathering parameters # Formulation parameters: par_area, par_over, par_pcd = toolfis.get_formulation_parameters(parameters) # 1. Lecture & Fuzzification out1 = toolfis.lecture_fuz_one_cv(file_zip, file_train, file_test, parameters) ux_train, cbin_train = out1[0] ux_test, cbin_test = out1[1] num_premises_by_attribute, premises_by_attribute, ref_attributes, premises_contain_negation = out1[2] freq_classes = out1[3] report = [] # To save our results try: # 3. Formulation f2 = Formulation(ux_train, cbin_train, ref_attributes, premises_by_attribute, num_premises_by_attribute, premises_contain_negation) # Inputs given by user arbol = f2.gen_ARB(max_size_of_premise, t_norm, par_area, par_over, par_pcd) status = [0 if not i[0] else 1 for i in arbol] sum_status = sum(status) if sum_status != len(arbol): if sum_status == 0: raise ValueError("Error in Formulation Module. Any premise survived. " "Sorry, you can not continue in the next stage." "\nTry to change the configuration") else: arb = [i for i in arbol if i[0]] arbol, arb = arb, arbol number_classes = cbin_train.shape[1] report.append("\nFormulation:\n-----------------") report.append("Elementos acorde a la profundidad " + str(len(arbol)) + " del arbol") for i in range(len(arbol)): report.append('Profundidad ' + str(i + 1) + ': ' + str(arbol[i][1].shape)) # print 'Profundidad ' + str(i + 1) + ': ' + str(arbol[i][1].shape) # 4. Association: ex-Division f3 = Association(arbol, cbin_train) premises_ux_by_class = f3.division(association_method) status = [0 if not i[0] else 1 for i in premises_ux_by_class] if sum(status) != number_classes: raise ValueError("Error in Division Module. Some classes did not get premises. " "Sorry, you can not continue in the next stage." "\nTry to change the configuration") # 5. Aggregation: f4 = Aggregation(premises_ux_by_class, cbin_train) output_aggregation = f4.aggregation(aggregation_method) premises_weights_names = output_aggregation[0] estimation_classes = output_aggregation[1] status = [0 if not i[0] else 1 for i in premises_weights_names] if sum(status) != number_classes: raise ValueError("Error in Aggregation Module. Some classes did not get premises. " "Sorry, you can not continue in the next stage." "\nTry to change the configuration") final_premises_classes = [] report.append("\n\nPremises:\n=========") for i in range(len(premises_weights_names)): report.append("Premises of Class " + str(i) + ": " + str(premises_weights_names[i][0])) final_premises_classes.append(premises_weights_names[i][0]) report.append("weights_" + str(i) + ": " + str(premises_weights_names[i][1].T)) # 6. Decision: f5 = Decisions(estimation_classes, freq_classes) train_bin_prediction = f5.dec_max_pert() # 7. Evaluation f6 = Evaluation(premises_weights_names, final_premises_classes, freq_classes) metrics_train = f6.eval_train(cbin_train, train_bin_prediction) metrics_test = f6.eval_test(cbin_test, ux_test, t_norm) report.append("\nEvaluation Training:\n---------------------------") report.append("Accuracy on train dataset: " + str(metrics_train[0])) report.append("AUC in train dataset: " + str(metrics_train[1])) report.append("Recall: " + str(metrics_train[3])) report.append('Confusion matrix:\n' + str(metrics_train[2])) report.append("\nEvaluation Testing:\n---------------------------") report.append("Accuracy on test dataset: " + str(metrics_test[0])) report.append("AUC in test dataset: " + str(metrics_test[1])) report.append("Recall: " + str(metrics_test[3])) report.append("Confusion matrix:\n" + str(metrics_test[2])) # Metrics to eval: accuracy_test, auc_test, # [num_regras, total_rule_length, tamano_medio_das_regras]] metricas = [1, [metrics_train[0], metrics_test[0], metrics_train[1], metrics_test[1], metrics_test[4]]] except ValueError as e: print e report = e # .append("\n" + str(e)) metricas = [0, "No se termino el proceso, se detuvo en algun etapa"] return report, metricas