Example #1
0
def weighted_ranking(X_train, X_validation, X_train_val, X_test, y_train, y_validation, y_train_val, y_test, names, sensitive_ids, ranking_functions= [], clf=None, min_accuracy = 0.0, min_fairness = 0.0, min_robustness = 0.0, max_number_features: float = 1.0, max_search_time=np.inf, log_file=None, accuracy_scorer=make_scorer(roc_auc_score, greater_is_better=True, needs_threshold=True), model_hyperparameters=None):
	min_loss = np.inf

	start_time = time.time()

	fair_validation = None
	fair_test = None
	if type(sensitive_ids) != type(None):
		fair_validation = make_scorer(true_positive_rate_score, greater_is_better=True,
									  sensitive_data=X_validation[:, sensitive_ids[0]])
		fair_test = make_scorer(true_positive_rate_score, greater_is_better=True,
								sensitive_data=X_test[:, sensitive_ids[0]])

	#calculate rankings
	try:
		rankings = []
		for ranking_function_i in range(len(ranking_functions)):
			rankings.append(ranking_functions[ranking_function_i](X_train, y_train))
	except Exception as e:
		my_result = {'error': e}
		#with open(log_file, 'ab') as f_log:
		#	pickle.dump(my_result, f_log, protocol=pickle.HIGHEST_PROTOCOL)
		return {'success': False}

	def f_clf1(hps):
		weights = []
		for i in range(len(rankings)):
			weights.append(hps['weight' + str(i)])

		pipeline = Pipeline([
			('selection', WeightedRankingSelection(scores=rankings, weights=weights, k=hps['k'], names=np.array(names))),
			('clf', clf)
		])

		return pipeline

	stored_results = {}
	fail_counter = [0]

	def f_to_min1(hps):
		if str(hps) in stored_results:
			fail_counter[0] += 1
			return stored_results[str(hps)]
		fail_counter[0] = 0


		pipeline = f_clf1(hps)
		stored_results[str(hps)] = run_grid_search(pipeline, X_train, y_train, X_validation, y_validation,
												   accuracy_scorer, sensitive_ids,
												   min_fairness, min_accuracy, min_robustness, max_number_features,
												   model_hyperparameters=model_hyperparameters, start_time=start_time)

		stored_results[str(hps)]['updated_parameters'] = hps

		return stored_results[str(hps)]



	max_k = max(int(max_number_features * X_train.shape[1]), 1)
	space = {'k': scope.int(hp.quniform('k', 1, max_k, 1))}

	if len(rankings) > 1:
		for i in range(len(rankings)):
			space['weight' + str(i)] = hp.choice('weight' + str(i) + 'choice',
								  [
									  (0.0),
									  hp.lognormal('weight' + str(i) + 'specified', 0, 1)
								  ])
	else:
		space['weight' + str(0)] = 1.0

	number_of_evaluations = 0

	trials = Trials()
	i = 1
	success = False
	while True:
		if time.time() - start_time > max_search_time:
			break
		if len(stored_results) >= max_k:
			break
		if fail_counter[0] >= 10:
			break

		fmin(f_to_min1, space=space, algo=tpe.suggest, max_evals=i, trials=trials)

		number_of_evaluations += 1

		cv_fair = trials.trials[-1]['result']['cv_fair']
		validation_acc = trials.trials[-1]['result']['cv_acc']
		validation_robust = trials.trials[-1]['result']['cv_robust']

		my_result = trials.trials[-1]['result']

		my_result['number_evaluations'] = number_of_evaluations

		#check test results
		model = trials.trials[-1]['result']['model']
		model.fit(X_train_val, pd.DataFrame(y_train_val))


		test_acc = accuracy_scorer(model, X_test, pd.DataFrame(y_test))

		test_fair = 0.0
		if type(sensitive_ids) != type(None):
			test_fair = 1.0 - fair_test(model, X_test, pd.DataFrame(y_test))
		test_robust = 1.0 - robust_score_test(eps=0.1, X_test=X_test, y_test=y_test,
												  model=model.named_steps['clf'],
												  feature_selector=model.named_steps['selection'],
												  scorer=accuracy_scorer)

		my_result['test_fair'] = test_fair
		my_result['test_acc'] = test_acc
		my_result['test_robust'] = test_robust
		my_result['final_time'] = time.time() - start_time

		if cv_fair >= min_fairness and validation_acc >= min_accuracy and validation_robust >= min_robustness and not is_utility_defined(min_fairness, min_accuracy, min_robustness, max_number_features):
			my_result['Finished'] = True
			my_result['Validation_Satisfied'] = True

			if test_fair >= min_fairness and test_acc >= min_accuracy and test_robust >= min_robustness:
				success = True

			my_result['success_test'] = success
			with open(log_file, 'ab') as f_log:
				my_result_new = copy.deepcopy(my_result)
				my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
				my_result_new['model'] = None
				pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
			return {'success': success}


		if min_loss > trials.trials[-1]['result']['loss']:
			min_loss = trials.trials[-1]['result']['loss']
			with open(log_file, 'ab') as f_log:
				my_result_new = copy.deepcopy(my_result)
				my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
				my_result_new['model'] = None
				pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)

		i += 1

	my_result = {'number_evaluations': number_of_evaluations, 'success_test': False, 'final_time': time.time() - start_time, 'Finished': True}
	with open(log_file, 'ab') as f_log:
		my_result_new = copy.deepcopy(my_result)
		pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
	return {'success': False}
    def execute_feature_combo(feature_combo, number_of_evaluations):
        hps = {}
        for f_i in range(X_train.shape[1]):
            if f_i in feature_combo:
                hps['f_' + str(f_i)] = 1
            else:
                hps['f_' + str(f_i)] = 0

        result = f_to_min1(hps)

        cv_fair = result['cv_fair']
        cv_acc = result['cv_acc']
        cv_robust = result['cv_robust']
        cv_number_features = result['cv_number_features']

        my_result = result
        my_result['number_evaluations'] = number_of_evaluations

        model = result['model']
        model.fit(X_train_val, pd.DataFrame(y_train_val))

        test_acc = accuracy_scorer(model, X_test, pd.DataFrame(y_test))

        test_fair = 0.0
        if type(sensitive_ids) != type(None):
            test_fair = 1.0 - fair_test(model, X_test, pd.DataFrame(y_test))
        test_robust = 1.0 - robust_score_test(
            eps=0.1,
            X_test=X_test,
            y_test=y_test,
            model=model.named_steps['clf'],
            feature_selector=model.named_steps['selection'],
            scorer=accuracy_scorer)

        my_result['test_fair'] = test_fair
        my_result['test_acc'] = test_acc
        my_result['test_robust'] = test_robust
        my_result['final_time'] = time.time() - start_time

        if cv_fair >= min_fairness and cv_acc >= min_accuracy and cv_robust >= min_robustness and cv_number_features <= max_number_features and not is_utility_defined(
                min_fairness, min_accuracy, min_robustness,
                max_number_features):
            my_result['Finished'] = True
            my_result['Validation_Satisfied'] = True

            success = False
            if test_fair >= min_fairness and test_acc >= min_accuracy and test_robust >= min_robustness:
                success = True

            my_result['success_test'] = success
            with open(log_file, 'ab') as f_log:
                my_result_new = copy.deepcopy(my_result)
                my_result_new['selected_features'] = copy.deepcopy(
                    my_result_new['model'].named_steps['selection'])
                my_result_new['model'] = None
                pickle.dump(my_result_new,
                            f_log,
                            protocol=pickle.HIGHEST_PROTOCOL)

            return my_result, {'success': success}

        return my_result, {}
def hyperparameter_optimization(X_train,
                                X_validation,
                                X_train_val,
                                X_test,
                                y_train,
                                y_validation,
                                y_train_val,
                                y_test,
                                names,
                                sensitive_ids,
                                ranking_functions=[],
                                clf=None,
                                min_accuracy=0.0,
                                min_fairness=0.0,
                                min_robustness=0.0,
                                max_number_features=None,
                                max_search_time=np.inf,
                                log_file=None,
                                algo=tpe.suggest,
                                accuracy_scorer=make_scorer(
                                    roc_auc_score,
                                    greater_is_better=True,
                                    needs_threshold=True),
                                avoid_robustness=False,
                                model_hyperparameters=None):
    min_loss = np.inf
    start_time = time.time()

    fair_validation = None
    fair_test = None
    if type(sensitive_ids) != type(None):
        fair_validation = make_scorer(
            true_positive_rate_score,
            greater_is_better=True,
            sensitive_data=X_validation[:, sensitive_ids[0]])
        fair_test = make_scorer(true_positive_rate_score,
                                greater_is_better=True,
                                sensitive_data=X_test[:, sensitive_ids[0]])

    stored_results = {}  #avoid duplicate hyperparameters

    def f_clf1(hps):
        mask = np.zeros(len(hps), dtype=bool)
        for k, v in hps.items():
            mask[int(k.split('_')[1])] = v

        #repair number of features if neccessary
        max_k = max(int(max_number_features * X_train.shape[1]), 1)
        if np.sum(mask) > max_k:
            id_features_used = np.nonzero(mask)[
                0]  # indices where features are used
            np.random.shuffle(id_features_used)  # shuffle ids
            ids_tb_deactived = id_features_used[max_k:]  # deactivate features
            for item_to_remove in ids_tb_deactived:
                mask[item_to_remove] = False

        for mask_i in range(len(mask)):
            hps['f_' + str(mask_i)] = mask[mask_i]

        pipeline = Pipeline([('selection', MaskSelection(mask)), ('clf', clf)])

        return pipeline, hps

    def f_to_min1(hps):
        if str(hps) in stored_results:
            return stored_results[str(hps)]

        pipeline, hps = f_clf1(hps)

        if np.sum(pipeline.named_steps['selection'].mask) == 0:
            stored_results[str(hps)] = {
                'loss': 4,
                'status': STATUS_OK,
                'model': pipeline,
                'cv_fair': 0.0,
                'cv_acc': 0.0,
                'cv_robust': 0.0,
                'cv_number_features': 1.0
            }
            return stored_results[str(hps)]

        stored_results[str(hps)] = run_grid_search(
            pipeline,
            X_train,
            y_train,
            X_validation,
            y_validation,
            accuracy_scorer,
            sensitive_ids,
            min_fairness,
            min_accuracy,
            min_robustness,
            max_number_features,
            model_hyperparameters=model_hyperparameters,
            start_time=start_time,
            avoid_robustness=avoid_robustness)

        stored_results[str(hps)]['updated_parameters'] = hps

        return stored_results[str(hps)]

    space = {}
    for f_i in range(X_train.shape[1]):
        space['f_' + str(f_i)] = hp.randint('f_' + str(f_i), 2)

    number_of_evaluations = 0

    trials = Trials()
    i = 1
    success = False
    fail_counter = [0]

    while True:
        if time.time() - start_time > max_search_time:
            break
        if fail_counter[0] >= 10:
            fail_counter[0] += 1
            break
        fail_counter[0] = 0

        fmin(f_to_min1, space=space, algo=algo, max_evals=i, trials=trials)

        #update repair in database
        try:
            current_trial = trials.trials[-1]
            if type(current_trial['result']['updated_parameters']) != type(
                    None):
                trials._dynamic_trials[-1]['misc']['vals'] = map_hyper2vals(
                    current_trial['result']['updated_parameters'])
        except:
            print("found an error in repair")

        number_of_evaluations += 1

        cv_fair = trials.trials[-1]['result']['cv_fair']
        validation_acc = trials.trials[-1]['result']['cv_acc']
        validation_robust = trials.trials[-1]['result']['cv_robust']
        cv_number_features = trials.trials[-1]['result']['cv_number_features']

        my_result = trials.trials[-1]['result']

        my_result['number_evaluations'] = number_of_evaluations

        model = trials.trials[-1]['result']['model']
        model.fit(X_train_val, pd.DataFrame(y_train_val))

        test_acc = accuracy_scorer(model, X_test, pd.DataFrame(y_test))
        test_fair = 0.0
        if type(sensitive_ids) != type(None):
            test_fair = 1.0 - fair_test(model, X_test, pd.DataFrame(y_test))

        test_robust = 0.0
        if not avoid_robustness:
            test_robust = 1.0 - robust_score_test(
                eps=0.1,
                X_test=X_test,
                y_test=y_test,
                model=model.named_steps['clf'],
                feature_selector=model.named_steps['selection'],
                scorer=accuracy_scorer)

        my_result['test_fair'] = test_fair
        my_result['test_acc'] = test_acc
        my_result['test_robust'] = test_robust
        my_result['final_time'] = time.time() - start_time

        if cv_fair >= min_fairness and validation_acc >= min_accuracy and validation_robust >= min_robustness and cv_number_features <= max_number_features and not is_utility_defined(
                min_fairness, min_accuracy, min_robustness,
                max_number_features):
            my_result['Finished'] = True
            my_result['Validation_Satisfied'] = True

            if test_fair >= min_fairness and test_acc >= min_accuracy and test_robust >= min_robustness:
                success = True

            my_result['success_test'] = success
            with open(log_file, 'ab') as f_log:
                my_result_new = copy.deepcopy(my_result)
                my_result_new['selected_features'] = copy.deepcopy(
                    my_result_new['model'].named_steps['selection'])
                my_result_new['model'] = None
                pickle.dump(my_result_new,
                            f_log,
                            protocol=pickle.HIGHEST_PROTOCOL)
            return {'success': success}

        if min_loss > trials.trials[-1]['result']['loss']:
            min_loss = trials.trials[-1]['result']['loss']
            with open(log_file, 'ab') as f_log:
                my_result_new = copy.deepcopy(my_result)
                my_result_new['selected_features'] = copy.deepcopy(
                    my_result_new['model'].named_steps['selection'])
                my_result_new['model'] = None
                pickle.dump(my_result_new,
                            f_log,
                            protocol=pickle.HIGHEST_PROTOCOL)

        i += 1

    my_result = {
        'number_evaluations': number_of_evaluations,
        'success_test': False,
        'final_time': time.time() - start_time,
        'Finished': True
    }
    with open(log_file, 'ab') as f_log:
        my_result_new = copy.deepcopy(my_result)
        pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
    return {'success': False}
Example #4
0
	def objective(features, min_loss):
		if 'success' in cheating_global.successfull_result[hash]:
			return [0.0, 0.0, 0.0, 0.0, min_loss]

		if np.sum(features) == 0:
			return [0.0, 0.0, 0.0, 0.0, min_loss]

		pipeline = f_clf1(features)

		my_result = run_grid_search(pipeline, X_train, y_train, X_validation, y_validation,
									  accuracy_scorer, sensitive_ids,
									  min_fairness, min_accuracy, min_robustness, max_number_features,
									  model_hyperparameters=model_hyperparameters, start_time=start_time)

		new_pipeline = copy.deepcopy(my_result['model'])

		validation_acc = my_result['cv_acc']
		validation_fair = my_result['cv_fair']
		validation_robust = my_result['cv_robust']
		loss = my_result['loss']

		cheating_global.successfull_result[hash]['cv_number_evaluations'] += 1

		validation_simplicity = 1.0 - my_result['cv_number_features']

		#check constraints for test set
		my_result['number_evaluations'] = cheating_global.successfull_result[hash]['cv_number_evaluations']

		new_pipeline.fit(X_train_val, pd.DataFrame(y_train_val))

		test_acc = accuracy_scorer(new_pipeline, X_test, pd.DataFrame(y_test))

		test_fair = 0.0
		if type(sensitive_ids) != type(None):
			test_fair = 1.0 - fair_test(new_pipeline, X_test, pd.DataFrame(y_test))
		test_robust = 1.0 - robust_score_test(eps=0.1, X_test=X_test, y_test=y_test,
											  model=new_pipeline.named_steps['clf'],
											  feature_selector=new_pipeline.named_steps['selection'],
											  scorer=accuracy_scorer)

		my_result['test_fair'] = test_fair
		my_result['test_acc'] = test_acc
		my_result['test_robust'] = test_robust
		my_result['final_time'] = time.time() - start_time

		if validation_fair >= min_fairness and validation_acc >= min_accuracy and validation_robust >= min_robustness  and not is_utility_defined(min_fairness, min_accuracy, min_robustness, max_number_features):
			my_result['Finished'] = True
			my_result['Validation_Satisfied'] = True

			success = False
			if test_fair >= min_fairness and test_acc >= min_accuracy and test_robust >= min_robustness:
				success = True

			cheating_global.successfull_result[hash]['success'] = success

			my_result['success_test'] = success
			with open(log_file, 'ab') as f_log:
				my_result_new = copy.deepcopy(my_result)
				my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
				my_result_new['model'] = None
				pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
			return [validation_acc, validation_fair, validation_robust, validation_simplicity, min_loss]


		if min_loss > loss:
			min_loss = loss
			with open(log_file, 'ab') as f_log:
				my_result_new = copy.deepcopy(my_result)
				my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
				my_result_new['model'] = None
				pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)

		return [validation_acc, validation_fair, validation_robust, validation_simplicity, min_loss]
Example #5
0
def fullfeatures(X_train, X_validation, X_train_val, X_test, y_train, y_validation, y_train_val, y_test, names, sensitive_ids, ranking_functions= [], clf=None, min_accuracy = 0.0, min_fairness = 0.0, min_robustness = 0.0, max_number_features = None, max_search_time=np.inf, log_file=None, accuracy_scorer=make_scorer(roc_auc_score, greater_is_better=True, needs_threshold=True), model_hyperparameters=None):
	start_time = time.time()

	fair_validation = None
	fair_test = None
	if type(sensitive_ids) != type(None):
		fair_validation = make_scorer(true_positive_rate_score, greater_is_better=True,
									  sensitive_data=X_validation[:, sensitive_ids[0]])
		fair_test = make_scorer(true_positive_rate_score, greater_is_better=True,
								sensitive_data=X_test[:, sensitive_ids[0]])

	def f_to_min1():
		mask = np.array([True for f_i in range(X_train.shape[1])])

		pipeline = Pipeline([
			('selection', MaskSelection(mask)),
			('clf', clf)
		])

		grid_result = run_grid_search(pipeline, X_train, y_train, X_validation, y_validation,
									  accuracy_scorer, sensitive_ids,
									  min_fairness, min_accuracy, min_robustness, max_number_features,
									  model_hyperparameters=model_hyperparameters, start_time=start_time)

		return grid_result

	space = {}
	for f_i in range(X_train.shape[1]):
		space['f_' + str(f_i)] = hp.randint('f_' + str(f_i), 2)

	number_of_evaluations = 0

	result = f_to_min1()

	number_of_evaluations += 1

	cv_fair = result['cv_fair']
	cv_acc = result['cv_acc']
	cv_robust = result['cv_robust']
	cv_number_features = result['cv_number_features']

	my_result = result

	my_result['number_evaluations'] = number_of_evaluations

	model = result['model']
	model.fit(X_train_val, pd.DataFrame(y_train_val))

	test_acc = accuracy_scorer(model, X_test, pd.DataFrame(y_test))

	test_fair = 0.0
	if type(sensitive_ids) != type(None):
		test_fair = 1.0 - fair_test(model, X_test, pd.DataFrame(y_test))
	test_robust = 1.0 - robust_score_test(eps=0.1, X_test=X_test, y_test=y_test,
										  model=model.named_steps['clf'],
										  feature_selector=model.named_steps['selection'],
										  scorer=accuracy_scorer)

	my_result['test_fair'] = test_fair
	my_result['test_acc'] = test_acc
	my_result['test_robust'] = test_robust
	my_result['final_time'] = time.time() - start_time

	if cv_fair >= min_fairness and cv_acc >= min_accuracy and cv_robust >= min_robustness and cv_number_features <= max_number_features  and not is_utility_defined(min_fairness, min_accuracy, min_robustness, max_number_features):
		my_result['Finished'] = True
		my_result['Validation_Satisfied'] = True

		success = False
		if test_fair >= min_fairness and test_acc >= min_accuracy and test_robust >= min_robustness:
			success = True

		my_result['success_test'] = success
		with open(log_file, 'ab') as f_log:
			my_result_new = copy.deepcopy(my_result)
			my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
			my_result_new['model'] = None
			pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
		return {'success': success}

	with open(log_file, 'ab') as f_log:
		my_result_new = copy.deepcopy(my_result)
		my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
		my_result_new['model'] = None
		pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)


	my_result = {'number_evaluations': number_of_evaluations, 'success_test': False, 'final_time': time.time() - start_time,
				 'Finished': True}
	with open(log_file, 'ab') as f_log:
		my_result_new = copy.deepcopy(my_result)
		pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
	return {'success': False}
Example #6
0
def exhaustive(X_train, X_validation, X_train_val, X_test, y_train, y_validation, y_train_val, y_test, names, sensitive_ids, ranking_functions= [], clf=None, min_accuracy = 0.0, min_fairness = 0.0, min_robustness = 0.0, max_number_features = None, max_search_time=np.inf, log_file=None, accuracy_scorer=make_scorer(roc_auc_score, greater_is_better=True, needs_threshold=True), model_hyperparameters=None):
	min_loss = np.inf
	start_time = time.time()

	fair_validation = None
	fair_test = None
	if type(sensitive_ids) != type(None):
		fair_validation = make_scorer(true_positive_rate_score, greater_is_better=True,
									  sensitive_data=X_validation[:, sensitive_ids[0]])
		fair_test = make_scorer(true_positive_rate_score, greater_is_better=True,
								sensitive_data=X_test[:, sensitive_ids[0]])

	def f_clf1(hps):
		mask = np.zeros(len(hps), dtype=bool)
		for k, v in hps.items():
			mask[int(k.split('_')[1])] = v

		#repair number of features if neccessary
		max_k = max(int(max_number_features * X_train.shape[1]), 1)
		if np.sum(mask) > max_k:
			id_features_used = np.nonzero(mask)[0]  # indices where features are used
			np.random.shuffle(id_features_used)  # shuffle ids
			ids_tb_deactived = id_features_used[max_k:]  # deactivate features
			for item_to_remove in ids_tb_deactived:
				mask[item_to_remove] = False

		for mask_i in range(len(mask)):
			hps['f_' + str(mask_i)] = mask[mask_i]

		model = Pipeline([
			('selection', MaskSelection(mask)),
			('clf', clf)
		])

		return model, hps

	def f_to_min1(hps):
		pipeline, hps = f_clf1(hps)

		if np.sum(pipeline.named_steps['selection'].mask) == 0:
			return {'loss': 4, 'status': STATUS_OK, 'model': pipeline, 'cv_fair': 0.0, 'cv_acc': 0.0, 'cv_robust': 0.0, 'cv_number_features': 1.0}

		grid_result = run_grid_search(pipeline, X_train, y_train, X_validation, y_validation,
									  accuracy_scorer, sensitive_ids,
									  min_fairness, min_accuracy, min_robustness, max_number_features,
									  model_hyperparameters=model_hyperparameters, start_time=start_time)

		grid_result['updated_parameters'] = hps
		return grid_result

	space = {}
	for f_i in range(X_train.shape[1]):
		space['f_' + str(f_i)] = hp.randint('f_' + str(f_i), 2)

	number_of_evaluations = 0

	max_k = max(int(max_number_features * X_train.shape[1]), 1)

	for l in range(1, max_k + 1):
		for feature_combo in itertools.combinations(range(X_train.shape[1]), l):

			hps = {}
			for f_i in range(X_train.shape[1]):
				if f_i in feature_combo:
					hps['f_' + str(f_i)] = 1
				else:
					hps['f_' + str(f_i)] = 0

			result = f_to_min1(hps)

			number_of_evaluations += 1

			cv_fair = result['cv_fair']
			cv_acc = result['cv_acc']
			cv_robust = result['cv_robust']
			cv_number_features = result['cv_number_features']

			my_result = result

			my_result['number_evaluations'] = number_of_evaluations

			##check on test
			model = result['model']
			model.fit(X_train_val, pd.DataFrame(y_train_val))

			test_acc = accuracy_scorer(model, X_test, pd.DataFrame(y_test))

			test_fair = 0.0
			if type(sensitive_ids) != type(None):
				test_fair = 1.0 - fair_test(model, X_test, pd.DataFrame(y_test))
			test_robust = 1.0 - robust_score_test(eps=0.1, X_test=X_test, y_test=y_test,
												  model=model.named_steps['clf'],
												  feature_selector=model.named_steps['selection'],
												  scorer=accuracy_scorer)

			my_result['test_fair'] = test_fair
			my_result['test_acc'] = test_acc
			my_result['test_robust'] = test_robust
			my_result['final_time'] = time.time() - start_time

			if cv_fair >= min_fairness and cv_acc >= min_accuracy and cv_robust >= min_robustness and cv_number_features <= max_number_features and not is_utility_defined(min_fairness, min_accuracy, min_robustness, max_number_features):
				my_result['Finished'] = True
				my_result['Validation_Satisfied'] = True

				success = False
				if test_fair >= min_fairness and test_acc >= min_accuracy and test_robust >= min_robustness:
					success = True

				my_result['success_test'] = success
				with open(log_file, 'ab') as f_log:
					my_result_new = copy.deepcopy(my_result)
					my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
					my_result_new['model'] = None
					pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
				return {'success': success}

			if min_loss > my_result['loss']:
				min_loss = my_result['loss']
				with open(log_file, 'ab') as f_log:
					my_result_new = copy.deepcopy(my_result)
					my_result_new['selected_features'] = copy.deepcopy(my_result_new['model'].named_steps['selection'])
					my_result_new['model'] = None
					pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)

	my_result = {'number_evaluations': number_of_evaluations, 'success_test': False, 'final_time': time.time() - start_time,
				 'Finished': True}
	with open(log_file, 'ab') as f_log:
		my_result_new = copy.deepcopy(my_result)
		pickle.dump(my_result_new, f_log, protocol=pickle.HIGHEST_PROTOCOL)
	return {'success': False}