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 |