Spaces:
Runtime error
Runtime error
| import matplotlib.pyplot as plt | |
| import pickle | |
| from src.cocktails.utilities.cocktail_generation_utilities.population import * | |
| from src.cocktails.utilities.glass_and_volume_utilities import glass_volume | |
| from src.cocktails.config import RECIPE2FEATURES_PATH | |
| def test_mutation_params(cocktail_reps): | |
| indexes = np.arange(cocktail_reps.shape[0]) | |
| np.random.shuffle(indexes) | |
| perfs = [] | |
| mutated_perfs = [] | |
| pop_params = dict(mutation_params=dict(p_add_ing=0.7, | |
| p_remove_ing=0.7, | |
| p_switch_ing=0.5, | |
| p_change_q=0.7, | |
| delta_change_q=0.3, | |
| asexual_rep=True, | |
| crossover=True, | |
| ingredient_addition=(0.1, 0.05)), | |
| nb_generations=100, | |
| pop_size=100, | |
| nb_elites=10, | |
| dist='mse', | |
| n_neighbors=5) | |
| for i in indexes[:20]: | |
| target = cocktail_reps[i] | |
| for j in range(100): | |
| parent = IndividualCocktail(pop_params=pop_params, | |
| target_affective_cluster=None, | |
| target=target.copy()) | |
| perfs.append(parent.perf) | |
| child = parent.get_child()[0] | |
| # child.compute_cocktail_rep() | |
| # child.compute_perf() | |
| if perfs[-1] != child.perf: | |
| mutated_perfs.append(child.perf) | |
| else: | |
| perfs.pop(-1) | |
| filtered_children = np.argwhere(np.array(mutated_perfs)==-100).flatten() | |
| non_filtered_ids = np.argwhere(np.logical_and(np.array(perfs)!=-100, np.array(mutated_perfs)!=-100)).flatten() | |
| print(f'Proportion of filtered: {filtered_children.size} / {len(mutated_perfs)} = {int(filtered_children.size / len(mutated_perfs)*100)}%') | |
| plt.figure() | |
| plt.scatter(np.array(perfs)[non_filtered_ids], np.array(mutated_perfs)[non_filtered_ids], s=100, alpha=0.5) | |
| plt.xlabel('parent perf') | |
| plt.ylabel('child perf') | |
| print(np.corrcoef(np.array(perfs)[non_filtered_ids], np.array(mutated_perfs)[non_filtered_ids])[0, 1]) | |
| plt.show() | |
| stop = 1 | |
| def test_crossover(cocktail_reps): | |
| indexes = np.arange(cocktail_reps.shape[0]) | |
| np.random.shuffle(indexes) | |
| perfs = [] | |
| mutated_perfs = [] | |
| pop_params = dict(mutation_params=dict(p_add_ing=0.7, | |
| p_remove_ing=0.7, | |
| p_switch_ing=0.5, | |
| p_change_q=0.7, | |
| delta_change_q=0.3, | |
| asexual_rep=True, | |
| crossover=True, | |
| ingredient_addition=(0.1, 0.05)), | |
| nb_generations=100, | |
| pop_size=100, | |
| nb_elites=10, | |
| dist='mse', | |
| n_neighbors=5) | |
| for i in indexes[:20]: | |
| for j in range(100): | |
| target = cocktail_reps[i] | |
| parent1 = IndividualCocktail(pop_params=pop_params, | |
| target_affective_cluster=None, | |
| target=target.copy()) | |
| parent2 = IndividualCocktail(pop_params=pop_params, | |
| target_affective_cluster=None, | |
| target=target.copy()) | |
| child = parent1.get_child_with(parent2)[0] | |
| # child.compute_cocktail_rep() | |
| # child.compute_perf() | |
| perfs.append((parent1.perf + parent2.perf)/2) | |
| if perfs[-1] != child.perf: | |
| mutated_perfs.append(child.perf) | |
| else: | |
| perfs.pop(-1) | |
| filtered_children = np.argwhere(np.array(mutated_perfs)==-100).flatten() | |
| non_filtered_ids = np.argwhere(np.logical_and(np.array(perfs)>-45, np.array(mutated_perfs)!=-100)).flatten() | |
| print(f'Proportion of filtered: {filtered_children.size} / {len(mutated_perfs)} = {int(filtered_children.size / len(mutated_perfs)*100)}%') | |
| plt.figure() | |
| plt.scatter(np.array(perfs)[non_filtered_ids], np.array(mutated_perfs)[non_filtered_ids], s=100, alpha=0.5) | |
| plt.xlabel('parent perf') | |
| plt.ylabel('child perf') | |
| print(np.corrcoef(np.array(perfs)[non_filtered_ids], np.array(mutated_perfs)[non_filtered_ids])[0, 1]) | |
| plt.show() | |
| stop = 1 | |
| def run_comparisons(): | |
| np.random.seed(0) | |
| indexes = np.arange(cocktail_reps.shape[0]) | |
| np.random.shuffle(indexes) | |
| for n_neighbors in [0, 5]: | |
| id_str_neigh = '5neigh_' if n_neighbors == 5 else '0_neigh_' | |
| for asexual_rep in [True, False]: | |
| id_str_as = id_str_neigh + 'asexual_' if asexual_rep else id_str_neigh | |
| for crossover in [True, False]: | |
| id_str = id_str_as + 'crossover_' if crossover else id_str_as | |
| if crossover or asexual_rep: | |
| mutation_params = dict(p_add_ing = 0.5, | |
| p_remove_ing = 0.5, | |
| p_change_q = 0.5, | |
| delta_change_q = 0.3, | |
| asexual_rep=asexual_rep, | |
| crossover=crossover, | |
| ingredient_addition = (0.1, 0.05)) | |
| nb_generations = 100 | |
| pop_size=100 | |
| nb_elites=10 | |
| dist = 'mse' | |
| results = dict() | |
| print(id_str) | |
| for i, ind in enumerate(indexes[:30]): | |
| print(i+1) | |
| target_ing_str = data['ingredients_str'][ind] | |
| target = cocktail_reps[ind] | |
| population = Population(nb_generations=nb_generations, pop_size=pop_size, nb_elite=nb_elites, | |
| target=target, dist=dist, mutation_params=mutation_params, | |
| n_neighbors=n_neighbors, target_ing_str=target_ing_str, true_prep_type=data['category'][ind]) | |
| population.run_evolution(verbose=False) | |
| best_scores, best_ind = population.get_best_score() | |
| recipes = [ind.get_recipe()[3] for ind in best_ind[:5]] | |
| results[str(ind)] = dict(best_scores=best_scores[:5], recipes=recipes, target=population.target_individual.get_recipe()[3]) | |
| with open(f'/home/cedric/Desktop/ga_tests_{id_str}.pickle', 'wb') as f: | |
| pickle.dump(results, f) | |
| def get_cocktail_distribution(cocktail_reps): | |
| return (np.mean(cocktail_reps, axis=0), np.cov(cocktail_reps, rowvar=0)) | |
| def sample_cocktails(cocktail_reps, n=10, target_affective_cluster=None, to_print=True): | |
| distrib = get_cocktail_distribution(cocktail_reps) | |
| sampled_cocktail_reps = np.random.multivariate_normal(distrib[0], distrib[1], size=n) | |
| recipes = [] | |
| closest_recipes = [] | |
| for i_c, cr in enumerate(sampled_cocktail_reps): | |
| population = setup_recipe_generation(cr.copy(), target_affective_cluster=target_affective_cluster) | |
| closest_recipes.append(population.nn_recipes[0]) | |
| best_scores, best_individuals = population.run_evolution() | |
| recipes.append(best_individuals[0].get_recipe()[3]) | |
| if to_print: | |
| print(f'Sample #{len(recipes)}:') | |
| print(recipes[-1]) | |
| print('Closest from dataset:') | |
| print(closest_recipes[-1]) | |
| stop = 1 | |
| return recipes, closest_recipes | |
| def setup_recipe_generation(target, known_target_dict=None, target_affective_cluster=None): | |
| # pop_params = dict(mutation_params=dict(p_add_ing=0.7, | |
| # p_remove_ing=0.7, | |
| # p_switch_ing=0.5, | |
| # p_change_q=0.7, | |
| # delta_change_q=0.3, | |
| # asexual_rep=True, | |
| # crossover=True, | |
| # ingredient_addition=(0.1, 0.05)), | |
| # nb_generations=2, #100 | |
| # pop_size=5, #100 | |
| # nb_elites=2, #10 | |
| # dist='mse', | |
| # n_neighbors=3) #5 | |
| pop_params = dict(mutation_params=dict(p_add_ing=0.4, | |
| p_remove_ing=1, | |
| p_switch_ing=0.5, | |
| p_change_q=1, | |
| delta_change_q=0.3, | |
| asexual_rep=True, | |
| crossover=True, | |
| ingredient_addition=(0.1, 0.05)), | |
| nb_generations=100, # 100 | |
| pop_size=100, # 100 | |
| nb_elites=10, # 10 | |
| dist='mse', | |
| n_neighbors=5) # 5 | |
| population = Population(target=target, target_affective_cluster=target_affective_cluster, known_target_dict=known_target_dict, pop_params=pop_params) | |
| return population | |
| def cocktailrep2recipe(cocktail_rep, unit='mL', target_affective_cluster=None, known_target_dict=None, n_output=1, return_ind=False, verbose=True, full_verbose=False, level=0): | |
| init_time = time.time() | |
| if verbose: print(' ' * level + 'Generating cocktail..') | |
| if cocktail_rep.ndim > 1: | |
| assert cocktail_rep.shape[0] == 1 | |
| cocktail_rep = cocktail_rep.flatten() | |
| # target_affective_cluster = target_affective_cluster[0] | |
| population = setup_recipe_generation(cocktail_rep.copy(), known_target_dict=known_target_dict, target_affective_cluster=target_affective_cluster) | |
| if full_verbose: | |
| print(' ' * (level + 2) + '3 nearest neighbors:') | |
| for i, recipe, score in zip(range(3), population.nn_recipes[:3], population.nn_scores[:3]): | |
| print(' ' * (level + 4) + f'#{i+1}, score: {score:.2f}') | |
| print(' ' * (level + 4) + recipe[1:].replace('None ()', '').replace('\t\t', ' ' * (level + 6))) | |
| best_scores, best_individuals = population.run_evolution(verbose=full_verbose, level=level+2) | |
| for i in range(n_output): | |
| best_individuals[i].make_recipe_fit_the_glass() | |
| instructions = [ind.get_instructions() for ind in best_individuals[:n_output]] | |
| recipes = [ind.get_recipe(unit=unit)[3] for ind in best_individuals[:n_output]] | |
| glasses = [ind.glass for ind in best_individuals[:n_output]] | |
| prep_types = [ind.prep_type for ind in best_individuals[:n_output]] | |
| for i, g, p, inst in zip(range(len(recipes)), glasses, prep_types, instructions): | |
| recipes[i] = recipes[i].replace('Recipe', 'Ingredients') + f'Serve in:\n {g.capitalize()} glass.\n' + inst | |
| if full_verbose: | |
| print(f'\n--------------\n{n_output} best results:') | |
| for i, recipe, score in zip(range(n_output), recipes, best_scores[:n_output]): | |
| print(f'#{i+1}, score: {score:.2f}') | |
| print(recipe) | |
| if verbose: print(' ' * (level + 2) + f'Generated in {int(time.time() - init_time)} seconds.') | |
| if return_ind: | |
| return recipes, best_scores[:n_output], best_individuals[:n_output] | |
| else: | |
| return recipes, best_scores[:n_output] | |
| def interpolate(cocktail_rep1, cocktail_rep2, alpha, verbose=False): | |
| recipe, score = cocktailrep2recipe(alpha * cocktail_rep1 + (1 - alpha) * cocktail_rep2, verbose=verbose) | |
| return recipe[0], score | |
| def interpolation_study(n_steps, cocktail_reps): | |
| alphas = np.arange(0, 1 + 1e-6, 1/(n_steps + 1)) | |
| indexes = np.random.choice(np.arange(cocktail_reps.shape[0]), size=2, replace=False) | |
| target_ing_str1, target_ing_str2 = data['ingredients_str'][indexes[0]], data['ingredients_str'][indexes[1]] | |
| cocktail_rep1, cocktail_rep2 = cocktail_reps[indexes[0]], cocktail_reps[indexes[1]] | |
| recipes, scores = [], [] | |
| for alpha in alphas: | |
| recipe, score = interpolate(cocktail_rep1, cocktail_rep2, alpha) | |
| recipes.append(recipe) | |
| scores.append(score[0]) | |
| print('Point A:') | |
| print_recipe(ingredient_str=target_ing_str2) | |
| for i, alpha in enumerate(alphas): | |
| print(f'Alpha = {alpha}, score = {scores[i]}') | |
| print(recipes[i]) | |
| print('Point B:') | |
| print_recipe(ingredient_str=target_ing_str1) | |
| stop = 1 | |
| def test_robustness_affective_cluster(cocktail_reps): | |
| indexes = np.arange(cocktail_reps.shape[0]) | |
| np.random.shuffle(indexes) | |
| matches = [] | |
| for i in indexes: | |
| target_ing_str = data['ingredients_str'][i] | |
| true_prep_type = data['category'][i] | |
| target = cocktail_reps[i] | |
| # get affective cluster | |
| recipes, best_scores, best_inds = cocktailrep2recipe(cocktail_rep=target, target_ing_str=target_ing_str, true_prep_type=true_prep_type, n_output=1, verbose=False, | |
| return_ind=True) | |
| matches.append(best_inds[0].does_affective_cluster_match()) | |
| print(np.mean(matches)) | |
| def test(cocktail_reps): | |
| indexes = np.arange(these_cocktail_reps.shape[0]) | |
| unnormalized_cr = np.array([data[k] for k in rep_keys]).transpose() | |
| for i in indexes: | |
| target_ing_str = data['ingredients_str'][i] | |
| true_prep_type = data['category'][i] | |
| target = these_cocktail_reps[i] | |
| # print('preptype:', true_prep_type) | |
| # print('cocktail unnormalized', np.sum(unnormalized_cr[i]), unnormalized_cr[i]) | |
| # print('cocktail hand normalized', np.sum(normalize_cocktail(unnormalized_cr[i])), normalize_cocktail(unnormalized_cr[i])) | |
| # print('cocktail rep normalized', np.sum(these_cocktail_reps[i]), these_cocktail_reps[i]) | |
| # print('cocktail rep normalized', np.sum(all_reps[i]), all_reps[i]) | |
| population = setup_recipe_generation(target.copy(), target_ing_str=target_ing_str, target_affective_cluster=None, true_prep_type=true_prep_type) | |
| target = population.target_individual | |
| target.compute_perf() | |
| if target.perf < -50: | |
| print(i) | |
| print_recipe(target_ing_str) | |
| if not target.is_alcohol_present(): print('No alcohol') | |
| if not target.is_total_volume_enough(): print('small volume') | |
| if not target.does_fit_glass(): | |
| print(target.end_volume) | |
| print(glass_volume[target.get_glass_type()] * 0.81) | |
| print('too much volume') | |
| if not target.is_alcohol_reasonable(): | |
| print(f'amount of alcohol too small or too large: {target.alcohol_precentage}') | |
| stop = 1 | |
| if __name__ == '__main__': | |
| these_cocktail_reps = COCKTAIL_REPS.copy() | |
| # test_crossover(these_cocktail_reps) | |
| # test_mutation_params(these_cocktail_reps) | |
| # test(these_cocktail_reps) | |
| # recipes, closest_recipes = sample_cocktails(these_cocktail_reps, n=10) | |
| # interpolation_study(n_steps=4, cocktail_reps=these_cocktail_reps) | |
| # test_robustness_affective_cluster(these_cocktail_reps) | |
| indexes = np.arange(these_cocktail_reps.shape[0]) | |
| np.random.shuffle(indexes) | |
| # test_crossover(mutation_params, dist) | |
| # test_mutation_params(mutation_params, dist) | |
| stop = 1 | |
| unnormalized_cr = np.array([data[k] for k in rep_keys]).transpose() | |
| for i in indexes: | |
| print(i) | |
| target_ing_str = data['ingredients_str'][i] | |
| target_prep_type = data['category'][i] | |
| target_glass = data['glass'][i] | |
| print('preptype:', target_prep_type) | |
| print('cocktail unnormalized', np.sum(unnormalized_cr[i]), unnormalized_cr[i]) | |
| print('cocktail hand normalized', np.sum(normalize_cocktail(unnormalized_cr[i])), normalize_cocktail(unnormalized_cr[i])) | |
| print('cocktail rep normalized', np.sum(these_cocktail_reps[i]), these_cocktail_reps[i]) | |
| print('cocktail rep normalized', np.sum(all_reps[i]), all_reps[i]) | |
| print(i) | |
| print('___________Target') | |
| nn_model = NearestNeighbors() | |
| nn_model.fit(these_cocktail_reps) | |
| dists, indexes = nn_model.kneighbors(these_cocktail_reps[i].reshape(1, -1)) | |
| print(indexes) | |
| print_recipe(target_ing_str) | |
| target = these_cocktail_reps[i] | |
| known_target_dict = dict(prep_type=target_prep_type, | |
| ing_str=target_ing_str, | |
| glass=target_glass) | |
| recipes, best_scores = cocktailrep2recipe(cocktail_rep=target, known_target_dict=known_target_dict, n_output=1, verbose=True, full_verbose=True) | |
| stop = 1 |