diff --git a/tpot/evolvers/base_evolver.py b/tpot/evolvers/base_evolver.py index 62e0a7cc..4ef56588 100644 --- a/tpot/evolvers/base_evolver.py +++ b/tpot/evolvers/base_evolver.py @@ -890,8 +890,8 @@ def evaluate_population_selection_early_stop(self,survival_counts, thresholds=No threshold = thresholds[step] invalids = [] for i in range(len(offspring_scores)): - - if all([s*w>t*w for s,t,w in zip(offspring_scores[i],threshold,objective_function_signs) ]): + # fix: 'not' needed to fix logic (bug in original TPOT code meaning threshold logic was inverted); >= to make this work for scores that might be the same across all individuals in certain cases (e.g. on first of multiple stateful runs) + if not all([s*w>=t*w for s,t,w in zip(offspring_scores[i],threshold,objective_function_signs) ]): invalids.append(i) if len(invalids) > 0: @@ -908,7 +908,7 @@ def evaluate_population_selection_early_stop(self,survival_counts, thresholds=No # Remove based on selection if survival_counts is not None: if step < self.evaluation_early_stop_steps - 1 and survival_counts[step]>1: #don't do selection for the last loop since they are completed - k = survival_counts[step] + len(invalids) #TODO can remove the min if the selections method can ignore k>population size + k = survival_counts[step] # ambiguous which invalids objects from above this is supposed to refer to; removed (tbc) if len(cur_individuals)> 1 and k > self.n_jobs and k < len(cur_individuals): weighted_scores = np.array([s * self.objective_function_weights for s in offspring_scores ]) diff --git a/tpot/search_spaces/nodes/genetic_feature_selection.py b/tpot/search_spaces/nodes/genetic_feature_selection.py index f1df7fa2..1eb56419 100644 --- a/tpot/search_spaces/nodes/genetic_feature_selection.py +++ b/tpot/search_spaces/nodes/genetic_feature_selection.py @@ -183,8 +183,9 @@ def _mutate_remove(self, rng=None): p = to_remove / num_pos p = min(p, .5) - remove_mask = rng.choice([True, False], size=self.mask.shape, p=[p,1-p]) - self.mask = np.logical_and(self.mask, remove_mask) + # bugfix for logic flaw + keep_mask = rng.choice([False, True], size=self.mask.shape, p=[p,1-p]) + self.mask = np.logical_and(self.mask, keep_mask) if sum(self.mask) == 0: diff --git a/tpot/tpot_estimator/estimator.py b/tpot/tpot_estimator/estimator.py index 932422e7..a7b43744 100644 --- a/tpot/tpot_estimator/estimator.py +++ b/tpot/tpot_estimator/estimator.py @@ -657,7 +657,7 @@ def objective_function(pipeline_individual, if self.threshold_evaluation_pruning is not None or self.selection_evaluation_pruning is not None: - evaluation_early_stop_steps = self.cv + evaluation_early_stop_steps = n_folds # fix to work with cv object instead of int else: evaluation_early_stop_steps = None