{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Evolutionary Algorithm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "the Evolutionary Algorithm that is supposed to create new recipes based on the Recipe Matrices that are created during the *Recipe Analysis* step.\n", "\n", "The Population of the Evolutional Algorithm consists of a set of recipe trees. Each Recipe Tree consists of several Nodes where each node is of one of the following Types:\n", "\n", "* **Ingredient Node:**\n", " these are the leaf nodes. Containing an ingredient. The score is determined by the actions, that are applied if you follow up the path. At the Moment it measures how many duplicate actions are applied.\n", "* **Action Node:**\n", " An Action that is applied on it's child and this child's subtree. Score indicates the average likelihood that this action is applied on the ingredients inside the subtree\n", "* **Mix Node:**\n", " Mixing ingredients together. This is also the only Node that can have more than one child. The score is the average of all pairwise likelihoods that two ingredients are mixed togethter" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sys\n", "sys.path.append(\"../\")\n", "sys.path.append(\"../RecipeAnalysis/\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "/home/jonas/.local/lib/python3.7/site-packages/ipykernel_launcher.py:39: TqdmExperimentalWarning:\n", "\n", "Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", "\n" ] } ], "source": [ "import settings\n", "\n", "import pycrfsuite\n", "\n", "import json\n", "\n", "import db.db_settings as db_settings\n", "from db.database_connection import DatabaseConnection\n", "\n", "from Tagging.conllu_generator import ConlluGenerator\n", "from Tagging.crf_data_generator import *\n", "\n", "from RecipeAnalysis.Recipe import Ingredient\n", "\n", "import ea_tools\n", "\n", "from difflib import SequenceMatcher\n", "\n", "import numpy as np\n", "\n", "import ActionGroups as AG\n", "\n", "import plotly.graph_objs as go\n", "from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot\n", "from plotly.subplots import make_subplots\n", "init_notebook_mode(connected=True)\n", "\n", "from graphviz import Digraph\n", "\n", "import itertools\n", "\n", "import random\n", "\n", "import plotly.io as pio\n", "pio.renderers.default = \"jupyterlab\"\n", "\n", "from IPython.display import Markdown, HTML, display\n", "\n", "from tqdm.autonotebook import tqdm\n", "\n", "from copy import deepcopy" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def gaussian(x, mu, sig):\n", " return 1./(np.sqrt(2.*np.pi)*sig)*np.exp(-np.power((x - mu)/sig, 2.)/2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## load adjacency matrices" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import dill\n", "m_act = dill.load(open(\"../RecipeAnalysis/m_act.dill\", \"rb\"))\n", "m_mix = dill.load(open(\"../RecipeAnalysis/m_mix.dill\", \"rb\"))\n", "m_base_act = dill.load(open(\"../RecipeAnalysis/m_base_act.dill\", \"rb\"))\n", "m_base_mix = dill.load(open(\"../RecipeAnalysis/m_base_mix.dill\", \"rb\"))\n", "\n", "\n", "m_grouped_mix = dill.load(open(\"../RecipeAnalysis/m_grouped_mix_raw.dill\", \"rb\"))\n", "m_grouped_act = dill.load(open(\"../RecipeAnalysis/m_grouped_act_raw.dill\", \"rb\"))\n", "m_grouped_base_act = dill.load(open(\"../RecipeAnalysis/m_grouped_base_act_raw.dill\", \"rb\"))\n", "\n", "\n", "#m_act.apply_threshold(3)\n", "#m_mix.apply_threshold(3)\n", "#m_base_act.apply_threshold(5)\n", "#m_base_mix.apply_threshold(5)\n", "\n", "\n", "#c_act = m_act.get_csr()\n", "#c_mix = m_mix.get_csr()\n", "#c_base_act = m_base_act.get_csr()\n", "#c_base_mix = m_base_mix.get_csr()\n", "\n", "m_act.compile()\n", "m_mix.compile()\n", "m_base_act.compile()\n", "m_base_mix.compile()\n", "\n", "m_grouped_mix.compile()\n", "m_grouped_act.compile()\n", "m_grouped_base_act.compile()\n", "\n", "c_act = m_act._csr\n", "c_mix = m_mix._csr\n", "c_base_act = m_base_act._csr\n", "c_base_mix = m_base_mix._csr" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "c_grouped_mix = m_grouped_mix._csr\n", "c_grouped_act = m_grouped_act._csr\n", "c_grouped_base_act = m_grouped_base_act._csr" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "actions = m_act.get_labels()[0]" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "base_ingredients = m_base_mix.get_labels()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "sym_label_buffer = {}\n", "fw_label_buffer = {}\n", "bw_label_buffer = {}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### helper functions for adjacency matrices" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def get_sym_adjacent(key, m, c):\n", " index = m._label_index[key]\n", " i1 = c[index,:].nonzero()[1]\n", " i2 = c[:,index].nonzero()[0]\n", " \n", " i = np.concatenate((i1,i2))\n", " \n", " if m in sym_label_buffer:\n", " names = sym_label_buffer[m][i]\n", " else:\n", " names = np.array(m.get_labels())\n", " sym_label_buffer[m] = names\n", " names = names[i]\n", " \n", " counts = np.concatenate((c[index, i1].toarray().flatten(), c[i2, index].toarray().flatten()))\n", " \n", " s = np.argsort(-counts)\n", " \n", " return names[s], counts[s]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def get_forward_adjacent(key, m, c):\n", " index = m._x_label_index[key]\n", " i = c[index,:].nonzero()[1]\n", " \n", " if m in fw_label_buffer:\n", " names = fw_label_buffer[m][i]\n", " else:\n", " names = np.array(m._y_labels)\n", " fw_label_buffer[m] = names\n", " names = names[i]\n", " \n", " \n", " counts = c[index, i].toarray().flatten()\n", " \n", " s = np.argsort(-counts)\n", " \n", " return names[s], counts[s]" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def get_backward_adjacent(key, m, c):\n", " index = m._y_label_index[key]\n", " i = c[:,index].nonzero()[0]\n", " \n", " if m in bw_label_buffer:\n", " names = bw_label_buffer[m][i]\n", " else:\n", " names = np.array(m._x_labels)\n", " bw_label_buffer[m] = names\n", " names = names[i]\n", " \n", " \n", " counts = c[i, index].toarray().flatten()\n", " \n", " s = np.argsort(-counts)\n", " \n", " return names[s], counts[s]" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def sym_sum(key, m, c):\n", " return np.sum(get_sym_adjacent(key,m,c)[1])\n", "\n", "def fw_sum(key, m, c):\n", " return np.sum(get_forward_adjacent(key,m,c)[1])\n", "\n", "def bw_sum(key, m, c):\n", " return np.sum(get_backward_adjacent(key,m,c)[1])" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "def to_grouped_ingredient(ing:Ingredient):\n", " groups = set()\n", " for act in ing._action_set:\n", " groups.add(AG.groups[act])\n", " grouped_ingredient = Ingredient(ing._base_ingredient)\n", " for g in groups:\n", " grouped_ingredient.apply_action(g)\n", " return grouped_ingredient" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### different score functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### normalizations" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "def fw_normalization_factor(key, m, c, quotient_func):\n", " ia = m._x_label_index[key]\n", " \n", " occurances = c[ia,:].nonzero()[1]\n", " \n", " return 1. / quotient_func(c[ia,occurances].toarray())\n", "\n", "def bw_normalization_factor(key, m, c, quotient_func):\n", " ib = m._y_label_index[key]\n", " \n", " occurances = c[:,ib].nonzero()[0]\n", " \n", " return 1. / quotient_func(c[occurances,ib].toarray())\n", "\n", "def sym_normalization_factor(key, m, c, quotient_func):\n", " ii = m._label_index[key]\n", " \n", " fw_occurances = c[ii,:].nonzero()[1]\n", " bw_occurances = c[:,ii].nonzero()[0]\n", " \n", " return 1. / quotient_func(np.concatenate(\n", " [c[ii,fw_occurances].toarray().flatten(),\n", " c[bw_occurances,ii].toarray().flatten()]\n", " ))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def sym_p_a_given_b(key_a, key_b, m, c, quot_func = np.max):\n", " ia = m._label_index[key_a]\n", " ib = m._label_index[key_b]\n", " \n", " v = c[ia,ib] + c[ib,ia]\n", " \n", " return v * sym_normalization_factor(key_b, m, c, quot_func)\n", "\n", "def fw_p_a_given_b(key_a, key_b, m, c, quot_func = np.max):\n", " ia = m._x_label_index[key_a]\n", " ib = m._y_label_index[key_b]\n", " \n", " v = c[ia,ib]\n", " \n", " return v * bw_normalization_factor(key_b, m, c, quot_func)\n", "\n", "def bw_p_a_given_b(key_a, key_b, m, c, quot_func = np.max):\n", " ia = m._y_label_index[key_a]\n", " ib = m._x_label_index[key_b]\n", " \n", " v = c[ib,ia]\n", " \n", " return v * fw_normalization_factor(key_b, m, c, quot_func)\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def sym_score(key_a, key_b, m, c):\n", "\n", " ia = m._label_index[key_a]\n", " ib = m._label_index[key_b]\n", " \n", " v = c[ia,ib] + c[ib,ia]\n", " \n", " if v == 0:\n", " return 0\n", " \n", " return max((v/sym_sum(key_a, m, c)), (v/sym_sum(key_b, m, c)))\n", "\n", "def asym_score(key_a, key_b, m, c):\n", " ia = m._x_label_index[key_a]\n", " ib = m._y_label_index[key_b]\n", " \n", " v = c[ia,ib]\n", " \n", " if v == 0:\n", " return 0\n", " \n", " return max(v/fw_sum(key_a, m, c), v/bw_sum(key_b, m, c))" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "def p_ingredient_unprepared(base_ing):\n", " ing = Ingredient(base_ing)\n", " base_sum = sym_sum(base_ing, m_base_mix, c_base_mix)\n", " specialized_sum = sym_sum(ing.to_json(), m_mix, c_mix)\n", " return specialized_sum / base_sum" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**new probability for preprocess ingredients:**" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "PREPARE_RATIO_THRESHOLD = 0.35\n", "HEAT_RATIO_THRESHOLD = 0.65\n", "\n", "PREPARE_SCORE_EPS = 0.1\n", "HEAT_SCORE_EPS = 0.1\n", "\n", "def prepare_ratio(ing:str):\n", " try:\n", " keys, values = m_grouped_act.get_backward_adjacent(Ingredient(ing).to_json())\n", " except KeyError:\n", " return 0\n", " action_dict = dict(zip(keys,values))\n", " if 'prepare' not in action_dict:\n", " return 0\n", " if 'heat' not in action_dict:\n", " return 1\n", " return action_dict['prepare'] / action_dict['heat']\n", "\n", "def random_prepare(ing:str):\n", " \"\"\"\n", " returns randomly a boolean value if ing should be prepared, w.r.t. the prepare_ration function\n", " \"\"\"\n", " \n", " return prepare_ratio(ing) > np.random.normal(PREPARE_RATIO_THRESHOLD,0.1)\n", "\n", "def heat_ratio(ingredient:str):\n", " try:\n", " action_set, action_weights = m_grouped_base_act.get_backward_adjacent(ingredient)\n", " except KeyError:\n", " return 0\n", " d = dict(zip(action_set, action_weights))\n", " \n", " if 'prepare' not in d:\n", " return 1\n", " if 'heat' not in d:\n", " return 0\n", " \n", " ratio = 1 - d['prepare'] / d['heat']\n", " \n", " return ratio\n", "\n", "def random_heated(ingredient:str):\n", " ratio = heat_ratio(ingredient)\n", " \n", " return ratio > np.random.normal(HEAT_RATIO_THRESHOLD,0.15)\n", "\n", "def prepare_score(ingredient:Ingredient):\n", " ing_str = ingredient._base_ingredient\n", " \n", " g_ing = to_grouped_ingredient(ingredient)\n", " \n", " ratio = prepare_ratio(ing_str)\n", " \n", " if ratio > PREPARE_RATIO_THRESHOLD + PREPARE_SCORE_EPS:\n", " if 'prepare' not in g_ing._action_set:\n", " return 0\n", " \n", " if ratio < PREPARE_RATIO_THRESHOLD - PREPARE_SCORE_EPS:\n", " if 'prepare' in g_ing._action_set:\n", " return 0\n", " \n", " return 1\n", "\n", "def heat_score(ingredient:Ingredient):\n", " ing_str = ingredient._base_ingredient\n", " \n", " g_ing = to_grouped_ingredient(ingredient)\n", " \n", " ratio = heat_ratio(ing_str)\n", " \n", " if ratio > HEAT_RATIO_THRESHOLD + HEAT_SCORE_EPS:\n", " if 'heat' not in g_ing._action_set:\n", " return 0\n", " \n", " if ratio < HEAT_RATIO_THRESHOLD - HEAT_SCORE_EPS:\n", " if 'heat' in g_ing._action_set:\n", " return 0\n", " \n", " return 1\n" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "def relative_action_rank(ingredient:str, action:str):\n", " action_set, action_weights = m_base_act.get_backward_adjacent(ingredient)\n", " if action not in action_set or len(action_set) <= 1:\n", " return 0\n", " return 1 - action_set.tolist().index(action) / (len(action_set) - 1)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "def filter_set_by_group(act_set, act_w, group):\n", " new_act_set = []\n", " new_act_w = []\n", " for i in range(len(act_set)):\n", " if act_set[i] in AG.inverse_groups[group]:\n", " new_act_set.append(act_set[i])\n", " new_act_w.append(act_w[i])\n", " return np.array(new_act_set), np.array(new_act_w)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## better normalized scores:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "def normalized_score(key, matrix):\n", " sum_key = matrix.get_sum(key)\n", " keys, values = matrix.get_adjacent(key)\n", " normalized_values = np.array([(values[i] / matrix.get_sum(keys[i])) * (values[i] / sum_key) for i in range(len(keys))])\n", " sort = np.argsort(-normalized_values)\n", " return keys[sort], normalized_values[sort]\n", "\n", "def forward_normalized_score(key, matrix):\n", " sum_key = matrix.get_fw_sum(key)\n", " keys, values = matrix.get_forward_adjacent(key)\n", " normalized_values = np.array([(values[i] / matrix.get_bw_sum(keys[i])) * (values[i] / sum_key) for i in range(len(keys))])\n", " sort = np.argsort(-normalized_values)\n", " return keys[sort], normalized_values[sort]\n", "\n", "def backward_normalized_score(key, matrix):\n", " sum_key = matrix.get_bw_sum(key)\n", " keys, values = matrix.get_backward_adjacent(key)\n", " normalized_values = np.array([(values[i] / matrix.get_fw_sum(keys[i])) * (values[i] / sum_key) for i in range(len(keys))])\n", " sort = np.argsort(-normalized_values)\n", " return keys[sort], normalized_values[sort]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Helper class for instructions" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "class RecipeInstructionState(object):\n", " def __init__(self):\n", " self.current_step = 1\n", " self.id_to_state = {}\n", " self.instructions_by_step = {}\n", " self.step_by_nodeid = {}\n", " self.text_by_nodeid = {}\n", " self.ingredients = set()\n", " \n", " def _add_instruction(self, node_id):\n", " s = self.text_by_nodeid[node_id]\n", " self.instructions_by_step[self.current_step] = s\n", " self.step_by_nodeid[node_id] = self.current_step\n", " self.current_step += 1\n", " return self.current_step - 1\n", " \n", " def add_text(self, node_id, text, is_instruction=False, is_ingredient=False):\n", " self.text_by_nodeid[node_id] = text\n", " if is_instruction:\n", " self._add_instruction(node_id)\n", " if is_ingredient:\n", " self.ingredients.add(text)\n", " \n", " def exists_any_instruction(self, node_ids:list):\n", " \"\"\"check if any instruction exists for list of id's\n", " \"\"\"\n", " \n", " for node_id in node_ids:\n", " if node_id in self.step_by_nodeid:\n", " return True\n", " return False\n", " \n", " def to_markdown(self):\n", " \n", " md_text = \"**Ingredients**:\\n\"\n", " \n", " for ing in self.ingredients:\n", " md_text += f\" * {ing}\\n\"\n", " \n", " md_text += \"\\n\\n**Instructions**:\\n\\n\"\n", " md_text += \"| Step | Instruction |\\n\"\n", " md_text += \"| ----:|:----------- |\\n\"\n", " \n", " for step in range(1, self.current_step):\n", " md_text += f\"| {step} | {self.instructions_by_step[step]} |\\n\"\n", " \n", " return Markdown(md_text)\n", " \n", " \n", " \n", " \n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Recipe Tree\n", "### Tree Node Base Class" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "class RecipeTreeNode(object):\n", " \n", " id = 0\n", " \n", " def __init__(self, name, constant=False, single_child=False):\n", " self._constant = constant\n", " self._name = name\n", " self._parent = None\n", " \n", " self._id = str(RecipeTreeNode.id)\n", " RecipeTreeNode.id += 1\n", " \n", " self._single_child = single_child\n", " \n", " if self._single_child:\n", " self._child = None\n", " \n", " def child():\n", " return self._child\n", " \n", " def remove_child(c):\n", " assert c == self._child\n", " self._child._parent = None\n", " self._child = None\n", " \n", " def childs():\n", " c = self.child()\n", " if c is None:\n", " return set()\n", " return set([c])\n", " \n", " def add_child(n):\n", " self._child = n\n", " n._parent = self\n", " \n", " self.child = child\n", " self.childs = childs\n", " self.add_child = add_child\n", " self.remove_child = remove_child\n", " else:\n", " self._childs = set()\n", " \n", " def childs():\n", " return self._childs\n", " \n", " def add_child(n):\n", " self._childs.add(n)\n", " n._parent = self\n", " \n", " def remove_child(c):\n", " assert c in self._childs\n", " c._parent = None\n", " self._childs.remove(c)\n", " \n", " self.childs = childs\n", " self.add_child = add_child\n", " self.remove_child = remove_child\n", " \n", " def parent(self):\n", " return self._parent\n", " \n", " def root(self):\n", " if self._parent is None:\n", " return self\n", " return self._parent.root()\n", " \n", " def name(self):\n", " return self._name\n", " \n", " def traverse(self):\n", " l = []\n", " \n", " for c in self.childs():\n", " l += c.traverse()\n", " \n", " return [self] + l\n", " \n", " def traverse_ingredients(self):\n", " ingredient_set = []\n", " for c in self.childs():\n", " ingredient_set += c.traverse_ingredients()\n", " \n", " return ingredient_set\n", " \n", " def remove(self):\n", " p = self.parent()\n", " childs = self.childs().copy()\n", " \n", " assert p is None or not (len(childs) > 1 and p._single_child)\n", " \n", " for c in childs:\n", " self.remove_child(c)\n", " \n", " if p is not None:\n", " p.remove_child(self)\n", " \n", " if self._single_child and self._child is not None and p._name == self._child._name:\n", " # two adjacent nodes with same name would remain after deletion.\n", " # merge them! (by adding the child's childs to our parent instead of our childs)\n", " childs = self._child.childs()\n", " self._child.remove()\n", " \n", " \n", " for c in childs:\n", " p.add_child(c)\n", " \n", " def insert_before(self, n):\n", " p = self._parent\n", " if p is not None:\n", " p.remove_child(self)\n", " p.add_child(n)\n", " n.add_child(self)\n", " \n", " def mutate(self):\n", " n_node = self.n_node_mutate_options()\n", " n_edge = self.n_edge_mutate_options()\n", " \n", " choice = random.choice(range(n_node + n_edge))\n", " if choice < n_node:\n", " self.mutate_node()\n", " else:\n", " self.mutate_edges()\n", " \n", " def mutate_edges(self):\n", " ings = self.traverse_ingredients()\n", " ing = random.choice(ings)\n", " \n", " a, w = get_backward_adjacent(ing._base_ingredient, m_base_act, c_base_act)\n", " \n", " if len(a) > 0:\n", " \n", " action = ea_tools.wheel_of_fortune_selection(a,w)\n", " self.insert_before(ActionNode(action))\n", " \n", " else:\n", " print(\"Warning: cannot find matching action node for mutation\")\n", " \n", " def mutate_node(self):\n", " raise NotImplementedError\n", " \n", " def n_node_mutate_options(self):\n", " \n", " return 0 if self._constant else 1\n", " \n", " def n_edge_mutate_options(self):\n", " n = 1 if self._parent is not None else 0\n", " return n\n", " \n", " def n_mutate_options(self):\n", " return self.n_edge_mutate_options() + self.n_node_mutate_options()\n", " \n", " def dot_node(self, dot):\n", " raise NotImplementedError()\n", " \n", " def dot(self, d=None):\n", " if d is None:\n", " d = Digraph()\n", " self.dot_node(d)\n", " \n", " else:\n", " self.dot_node(d)\n", " if self._parent is not None:\n", " d.edge(self._parent._id, self._id)\n", " \n", " \n", " for c in self.childs():\n", " c.dot(d)\n", " \n", " return d\n", " \n", " def simplify(self):\n", " # simplify nodes (mainly used to delete doubled Mix Nodes)\n", " for c in self.childs().copy():\n", " c.simplify()\n", " \n", " def serialize(self):\n", " r = {}\n", " r['type'] = str(self.__class__.__name__)\n", " r['id'] = self._id\n", " r['parent'] = self._parent._id if self._parent is not None else None\n", " r['name'] = self._name\n", " r['childs'] = [c._id for c in self.childs()]\n", " r['constant'] = self._constant\n", " r['single_child'] = self._single_child\n", " \n", " return r\n", " \n", " def serialize_subtree(self):\n", " return [n.serialize() for n in self.traverse()]\n", " \n", " def node_score(self):\n", " raise NotImplementedError()\n", " \n", " def to_instruction(self, state:RecipeInstructionState):\n", " # create an instruction out of a recipe Tree\n", " raise NotImplementedError()\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mix Node" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the Node Score: just make a simple lookup whether this combination is seen or not. So the node Score is defined as:\n" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "class MixNode(RecipeTreeNode):\n", " def __init__(self, constant=False):\n", " super().__init__(\"mix\", constant, single_child=False)\n", " \n", " def dot_node(self, dot):\n", " dot.node(self._id, label=f\"< {self._name}
node score: {self.node_score():.4f}>\", shape=\"diamond\", style=\"filled\", color=\"#d5e8d4\")\n", " \n", " def split(self, set_above, set_below, node_between):\n", " assert len(set_above.difference(self.childs())) == 0\n", " assert len(set_below.difference(self.childs())) == 0\n", " \n", " n_above = MixNode()\n", " n_below = MixNode()\n", " \n", " p = self.parent()\n", " \n", " for c in self.childs().copy():\n", " self.remove_child(c)\n", " self.remove()\n", " \n", " for c in set_below:\n", " n_below.add_child(c)\n", " \n", " for c in set_above:\n", " n_above.add_child(c)\n", " \n", " n_above.add_child(node_between)\n", " node_between.add_child(n_below)\n", " \n", " if p is not None:\n", " p.add_child(n_above)\n", " \n", " # test whether the mix nodes are useless\n", " if len(n_above.childs()) == 1:\n", " n_above.remove()\n", " \n", " if len(n_below.childs()) == 1:\n", " n_below.remove()\n", " \n", " def n_node_mutate_options(self):\n", " return 0 if self._constant or len(self.childs()) <= 2 else len(self.childs())\n", " \n", " def mutate_node(self):\n", " \n", " childs = self.childs()\n", " \n", " if len(childs) <= 2:\n", " print(\"Warning: cannot modify mix node\")\n", " return\n", " \n", " childs = random.sample(childs, len(childs))\n", " \n", " n = random.choice(range(1, len(childs)-1))\n", " \n", " ings = self.traverse_ingredients()\n", " ing = random.choice(ings)\n", " \n", " base_ing = ing._base_ingredient\n", " act = None\n", " try:\n", " a, w = m_base_act.get_backward_adjacent(base_ing)\n", " act = ea_tools.wheel_of_fortune_selection(a,w)\n", " except ValueError:\n", " print(\"Warning: cannot mutate given node\")\n", " \n", " if act is not None:\n", " between_node = ActionNode(act)\n", "\n", " self.split(set(childs[:n]), set(childs[n:]), between_node)\n", " \n", " \n", " def node_score(self):\n", " child_ingredients = [c.traverse_ingredients() for c in self.childs()]\n", " \n", " tmp_set = set()\n", " cumulative_sets = []\n", " \n", " pairwise_tuples = []\n", " \n", " for c in child_ingredients:\n", " if len(tmp_set) > 0:\n", " cumulative_sets.append(tmp_set)\n", " pairwise_tuples += [x for x in itertools.product(tmp_set, c)]\n", " tmp_set = tmp_set.union(set(c))\n", " \n", " s_base = 0\n", " s = 0\n", " \n", " for ing_a, ing_b in pairwise_tuples:\n", " try:\n", " #s_base += sym_score(ing_a._base_ingredient, ing_b._base_ingredient, m_base_mix, c_base_mix)\n", " \n", " #s += sym_score(ing_a.to_json(), ing_b.to_json(), m_mix, c_mix)\n", " \n", " # old method:\n", " #p1 = sym_p_a_given_b(ing_a.to_json(), ing_b.to_json(), m_mix, c_mix)\n", " #p2 = sym_p_a_given_b(ing_b.to_json(), ing_a.to_json(), m_mix, c_mix)\n", " #s += 0.5 * p1 + 0.5 * p2\n", " \n", " #grouped_ing_a = to_grouped_ingredient(ing_a)\n", " #grouped_ing_b = to_grouped_ingredient(ing_b)\n", " \n", " #ia = m_grouped_mix._label_index[grouped_ing_a.to_json()]\n", " #ib = m_grouped_mix._label_index[grouped_ing_b.to_json()]\n", " \n", " #if c_grouped_mix[ia,ib] > 0 or c_grouped_mix[ib,ia] > 0:\n", " # s += 1\n", " \n", " ia = m_mix._label_index[ing_a.to_json()]\n", " ib = m_mix._label_index[ing_b.to_json()]\n", " \n", " if c_mix[ia,ib] > 0 or c_mix[ib,ia] > 0:\n", " s += 1\n", " \n", " \n", " \n", " except KeyError as e:\n", " pass\n", " \n", " #s_base /= len(pairwise_tuples)\n", " s /= len(pairwise_tuples)\n", " \n", " #return 0.5 * (s_base + s)\n", " return s\n", " \n", " def simplify(self):\n", " for c in self.childs().copy():\n", " c.simplify()\n", " \n", " # if our parent is also a Mix Node, we can just delete ourselve\n", " p = self.parent()\n", " \n", " if p is not None:\n", " if type(p) == MixNode:\n", " # just delete ourselve\n", " self.remove()\n", " \n", " def to_instruction(self, state:RecipeInstructionState = None):\n", " \"\"\"\n", " returns a RecipeInstructionState\n", " \"\"\"\n", " \n", " def english_enum(items, use_and=True):\n", " if len(items) > 1 and use_and:\n", " return \", \".join(items[:-1]) + \" and \" + items[-1]\n", " return \", \".join(items)\n", " \n", " if state is None:\n", " state = RecipeInstructionState()\n", " \n", " for c in self.childs():\n", " c.to_instruction(state)\n", " \n", " \n", " text = \"\"\n", " \n", " # children with instructions\n", " instruction_childs = []\n", " \n", " # children without instructions\n", " base_childs = []\n", " \n", " # childre without instructions that are ingredients\n", " ingredient_childs = []\n", " \n", " for c in self.childs():\n", " assert type(c) != MixNode\n", " if type(c) == IngredientNode:\n", " ingredient_childs.append(c)\n", " elif c._id not in state.step_by_nodeid:\n", " # action node with no step so far, so a base child\n", " base_childs.append(c)\n", " else:\n", " instruction_childs.append(c)\n", " \n", " if len(base_childs) > 0:\n", " use_and= len(ingredient_childs)==0 and len(instruction_childs)==0\n", " text = english_enum([state.text_by_nodeid[c._id] for c in base_childs], use_and=use_and)\n", " \n", " \n", " if len(ingredient_childs) > 0:\n", " if len(base_childs) > 0:\n", " text += \" and mix it with \" + english_enum([state.text_by_nodeid[c._id] for c in ingredient_childs])\n", " \n", " else:\n", " text = \"Mix \" + english_enum([state.text_by_nodeid[c._id] for c in ingredient_childs])\n", " \n", " if len(instruction_childs) > 0:\n", " if len(base_childs) == 0 and len(ingredient_childs) == 0:\n", " text = \"Mix together the results of \"\n", " else:\n", " text += \" and mix it together with the results of \"\n", " \n", " text += english_enum([f\"step {state.step_by_nodeid[c._id]}\" for c in instruction_childs])\n", " \n", " text += \".\"\n", " \n", " if type(self.parent()) == ActionNode:\n", " state.add_text(self._id, text, is_instruction=False)\n", " else:\n", " state.add_text(self._id, text, is_instruction=True)\n", " \n", " \n", " return state\n", " \n", " \n", " \n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Ingredient Node Class" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "n_wanted_actions = 2\n", "gaussian_normalize_factor = 1 / gaussian(n_wanted_actions, n_wanted_actions, 1)\n", "\n", "class IngredientNode(RecipeTreeNode):\n", " def __init__(self, name, constant=False):\n", " super().__init__(name, constant, single_child=True)\n", " \n", " def get_actions(self):\n", " a_list = []\n", " n = self.parent()\n", " while n is not None:\n", " if type(n) == ActionNode:\n", " a_list.append(n.name())\n", " n = n.parent()\n", " return a_list\n", " \n", " def mutate_node(self):\n", " if self._constant:\n", " return\n", " mixes, weights = m_base_mix.get_adjacent(self._name)\n", " self._name = ea_tools.wheel_of_fortune_selection(mixes, weights)\n", " \n", " #self._name = random.choice(base_ingredients)\n", " #TODO: change w.r.t. mixing probabilities \n", " \n", " def traverse_ingredients(self):\n", " return [Ingredient(self._name)]\n", " \n", " def duplicate_actions_score(self, actions):\n", " \n", " if len(actions) == 0:\n", " return 1\n", " \n", " seen_actions = set()\n", " n_duplicates = 0\n", " for act in actions:\n", " if act in seen_actions:\n", " n_duplicates += 1\n", " else:\n", " seen_actions.add(act)\n", " \n", " duplicate_actions_score = len(seen_actions) / len(actions)\n", " \n", " return duplicate_actions_score\n", " \n", " def duplicate_groups_score(self, actions):\n", " if len(actions) == 0:\n", " return 1\n", " groups = [AG.groups[a] for a in actions]\n", " groups_set = set(groups)\n", " \n", " return len(groups_set) / len(groups)\n", " \n", " def node_score(self):\n", " actions = self.get_actions()\n", " \n", " ing = Ingredient(self._name)\n", " for a in actions:\n", " ing.apply_action(a)\n", " \n", " heat = heat_score(ing)\n", " prepare = prepare_score(ing)\n", " \n", " score = (heat + prepare) / 2\n", " score *= self.duplicate_actions_score(actions)\n", " \n", " return score\n", " \n", " \"\"\"\n", " actions = self.get_actions()\n", " \n", " if len(actions) == 0:\n", " if p_ingredient_unprepared(self._name) < 0.2:\n", " return 0\n", " return 1\n", " \n", " seen_actions = set()\n", " n_duplicates = 0\n", " for act in actions:\n", " if act in seen_actions:\n", " n_duplicates += 1\n", " else:\n", " seen_actions.add(act)\n", " \n", " duplicate_actions_score = len(seen_actions) / len(actions)\n", " \n", " return duplicate_actions_score\n", " \"\"\"\n", " \n", " \n", " def dot_node(self, dot):\n", " dot.node(self._id, label=f\"< {self._name}
node score:{self.node_score():.4f}>\", shape=\"box\", style=\"filled\", color=\"#ffe6cc\")\n", " \n", " def to_instruction(self, state:RecipeInstructionState = None):\n", " state.add_text(self._id, self._name, is_instruction=False, is_ingredient=True)\n", " return state" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Action Node Class" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "class ActionNode(RecipeTreeNode):\n", " def __init__(self, name, constant=False):\n", " super().__init__(name, constant, single_child=True)\n", " \n", " def n_node_mutate_options(self):\n", " # beacause we can change or remove ourselve!\n", " return 0 if self._constant else 2 \n", " def mutate_node(self):\n", " if random.choice(range(2)) == 0:\n", " # change action\n", " ings = self.traverse_ingredients()\n", " ing = np.random.choice(ings)\n", " base_ing = ing._base_ingredient\n", " try:\n", " a, w = m_base_act.get_backward_adjacent(base_ing)\n", " self._name = ea_tools.wheel_of_fortune_selection(a,w)\n", " except ValueError:\n", " print(\"Warning: cannot mutate given node\")\n", " else:\n", " # delete\n", " self.remove()\n", " \n", " def traverse_ingredients(self):\n", " ingredient_set = super().traverse_ingredients()\n", " for ing in ingredient_set:\n", " ing.apply_action(self._name)\n", " \n", " return ingredient_set\n", " \n", " def node_score(self):\n", " ings = self.child().traverse_ingredients()\n", " \n", " s = 0\n", " \n", " for ing in ings:\n", " try:\n", " \n", " i_act = m_act._x_label_index[self.name()]\n", " i_ing = m_act._y_label_index[ing.to_json()]\n", " \n", " if c_act[i_act,i_ing] > 0:\n", " s += 1\n", " \n", " except KeyError as e:\n", " #print(f\"WARNING: no entry found for: {str(e)}\")\n", " pass\n", " \n", " ''' # old method:\n", " for ing in ings:\n", " try:\n", " #score = asym_score(self._name, ing.to_json(), m_act, c_act)\n", " #base_score = asym_score(self._name, ing._base_ingredient, m_base_act, c_base_act)\n", " \n", " score = fw_p_a_given_b(self._name, ing._base_ingredient, m_base_act, c_base_act)\n", " \n", " s += score\n", " except KeyError as e:\n", " pass\n", " '''\n", " \n", " \n", " return s / len(ings)\n", " \n", " def dot_node(self, dot):\n", " dot.node(self._id, label=f\"< {self._name}
node score: {self.node_score():.4f}>\", shape=\"ellipse\", style=\"filled\", color=\"#dae8fc\")\n", " \n", " def to_instruction(self, state:RecipeInstructionState = None):\n", " \n", " if state is None:\n", " state = RecipeInstructionState()\n", " \n", " for c in self.childs():\n", " c.to_instruction(state)\n", " \n", " c = self._child\n", " \n", " if type(c) == MixNode:\n", " text = state.text_by_nodeid[c._id] + f\" Then {self._name} it.\"\n", " state.add_text(self._id, text, True)\n", " elif type(c) == IngredientNode:\n", " text = f\"{self._name} {state.text_by_nodeid[c._id]}\"\n", " state.add_text(self._id, text, False)\n", " \n", " elif type(c) == ActionNode:\n", " if c._id in state.step_by_nodeid:\n", " text = f\"{self._name} the result of step {state.step_by_nodeid[c._id]}\"\n", " else:\n", " prev_words = state.text_by_nodeid[c._id].split()\n", " text = f\"{prev_words[0]} and {self._name} {' '.join(prev_words[1:])}\"\n", " state.add_text(self._id, text, True)\n", " \n", " return state\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tree Class" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [], "source": [ "class Tree(object):\n", " @staticmethod\n", " def build_initial_tree(ingredients: list, main_ingredients: list, max_n = 20, wheel_turns = 2):\n", " \n", " assert set(main_ingredients).issubset(set(ingredients))\n", "\n", " def does_action_match(ingredient:str, action:str, t = 0.6):\n", " return relative_action_rank(ingredient, action) > t\n", "\n", "\n", " # choose randomly an action for each ingredient by the \"wheel of fortune\" method\n", " actions_for_ing = {}\n", " for ing in ingredients:\n", " actions_for_ing[ing] = set()\n", " action_set, action_weights = m_base_act.get_backward_adjacent(ing)\n", " if random_heated(ing):\n", " #print(action_set)\n", " action_set, action_weights = filter_set_by_group(action_set, action_weights, \"heat\")\n", " #print(action_set)\n", " for i in range(wheel_turns):\n", " if ing in main_ingredients:\n", " # if main ingredient: choose by action probability\n", " w = np.array(list(action_weights), dtype=float)\n", " w *= (1.0 / np.sum(w))\n", " action = np.random.choice(list(action_set), size=1, replace=False, p=w)[0]\n", " else:\n", " # else: choose rank based\n", " action = ea_tools.wheel_of_fortune_selection(action_set[:max_n], action_weights[:max_n])\n", " actions_for_ing[ing].add(action)\n", " #print(f\"action {action} for ing {ing}\")\n", " #print(ing, action)\n", "\n", " # create ingredient nodes:\n", " ingredient_nodes = {}\n", "\n", " # create ingredient nodes:\n", " for ing in ingredients:\n", " new_node = IngredientNode(ing, constant=False)\n", "\n", " # check if we should do a preparation step\n", " if random_prepare(ing):\n", " # choose a preparation cooking action\n", " action_set, action_weights = m_act.get_backward_adjacent(Ingredient(ing).to_json())\n", " action_set, action_weights = filter_set_by_group(action_set, action_weights, \"prepare\")\n", " if len(action_set) > 0:\n", " action = ea_tools.wheel_of_fortune_selection(action_set[:max_n], action_weights[:max_n])\n", " act_node = ActionNode(action)\n", " act_node.add_child(new_node)\n", " new_node = act_node\n", "\n", "\n", " ingredient_nodes[ing] = new_node\n", "\n", " # starting now with the actions found for the main ingredients and try to match all ingredients together\n", " # with that:\n", "\n", " unprocessed_ings = set(filter(lambda x: len(actions_for_ing[x]) > 0, ingredients))\n", " unprocessed_main_ings = set(filter(lambda x: len(actions_for_ing[x]) > 0, main_ingredients))\n", "\n", " while len(unprocessed_main_ings) > 0:\n", " main_ing = unprocessed_main_ings.pop()\n", "\n", " # random action for that ing:\n", " act = actions_for_ing[main_ing].pop()\n", "\n", " act_node = ActionNode(act)\n", " mix_node = MixNode()\n", " mix_node.add_child(ingredient_nodes[main_ing])\n", " act_node.add_child(mix_node)\n", " ingredient_nodes[main_ing] = act_node\n", "\n", " unprocessed_ings.remove(main_ing)\n", "\n", " for ing in unprocessed_ings.copy():\n", " if does_action_match(ing, act):\n", " mix_node.add_child(ingredient_nodes[ing])\n", " ingredient_nodes[ing] = act_node\n", " unprocessed_ings.remove(ing)\n", " if ing in unprocessed_main_ings:\n", " unprocessed_main_ings.remove(ing)\n", "\n", " if len(mix_node.childs()) == 1:\n", " mix_node.remove()\n", "\n", " # now make the same with all remaining ingredients:\n", " while len(unprocessed_ings) > 0:\n", " current_ing = unprocessed_ings.pop() \n", "\n", " # random action for that ing:\n", " act = actions_for_ing[current_ing].pop()\n", "\n", " act_node = ActionNode(act)\n", " mix_node = MixNode()\n", " mix_node.add_child(ingredient_nodes[current_ing])\n", " act_node.add_child(mix_node)\n", "\n", " ingredient_nodes[current_ing] = act_node\n", "\n", "\n", " for ing in unprocessed_ings.copy():\n", " if does_action_match(ing, act):\n", " mix_node.add_child(ingredient_nodes[ing])\n", " ingredient_nodes[ing] = act_node\n", " unprocessed_ings.remove(ing)\n", "\n", " if len(mix_node.childs()) == 1:\n", " mix_node.remove()\n", "\n", "\n", " root_layer = set([n.root() for n in ingredient_nodes.values()])\n", "\n", " root_layer_without_parents = []\n", " for node in root_layer:\n", " if node.parent() is None:\n", " root_layer_without_parents.append(node)\n", "\n", " if len(root_layer_without_parents) == 1:\n", " root_node = root_layer_without_parents[0]\n", "\n", " else:\n", " root_node = MixNode()\n", " for r in root_layer_without_parents:\n", " root_node.add_child(r)\n", " \n", " return root_node\n", "\n", "\n", " \n", " @staticmethod\n", " def find_ingredients(constant_ingredients, main_ingredients, min_additional:int, max_additional:int, top_ings:int=3, ing_range=50):\n", " '''\n", " create an initial set of ingredients, based on given constant ingredients.\n", " min_additional and max_additional gives the range of ingredients that are added to our set\n", " '''\n", " \n", " seen_items = set(constant_ingredients)\n", "\n", " items = []\n", " scores = []\n", "\n", " assert set(main_ingredients).issubset(set(constant_ingredients))\n", "\n", " # additional ingredients are choosen w.r.t all given ingredients\n", " n_additional_ings = np.random.randint(min_additional, max_additional + 1)\n", "\n", " # extra ings are ingredients choosen specially for the main ingredient\n", " n_extra_ings = int((len(main_ingredients) / len(constant_ingredients)) * n_additional_ings)\n", "\n", " if n_extra_ings > n_additional_ings:\n", " n_extra_ings = n_additional_ings\n", "\n", "\n", " # choose extra ingredients\n", " extra_candidates = []\n", " extra_weights = []\n", "\n", " for ing in main_ingredients:\n", " candidates, weights = normalized_score(ing, m_base_mix)\n", " extra_candidates.append(candidates[:ing_range])\n", " extra_weights.append(weights[:ing_range])\n", "\n", " extra_ingredients = ea_tools.combined_wheel_of_fortune_selection(extra_candidates,\n", " extra_weights,\n", " n_extra_ings)\n", "\n", " for ing in constant_ingredients:\n", " # find best matching ingredients\n", " best_items = []\n", " best_scores = []\n", "\n", " candidates, weights = m_base_mix.get_adjacent(ing)\n", " i = 0\n", " while i < len(candidates) and len(best_items) < top_ings:\n", " if candidates[i] not in seen_items:\n", " best_items.append(candidates[i])\n", " best_scores.append(weights[i])\n", " i += 1\n", "\n", " items.append(best_items)\n", " scores.append(best_scores)\n", "\n", " #TODO: error handling if too few options are availabale!\n", "\n", " additional_ingredients = ea_tools.combined_wheel_of_fortune_selection(items,\n", " scores,\n", " n_additional_ings - n_extra_ings)\n", " \n", " return list(constant_ingredients) + list(additional_ingredients) + list(extra_ingredients)\n", "\n", " @staticmethod\n", " def from_ingredients(ingredients: list, main_ingredients: list, min_additional=0, max_additional=10):\n", " root = None\n", " \n", " constant_ingredients = ingredients\n", " \n", " if max_additional > 0:\n", " ingredients = Tree.find_ingredients(ingredients, main_ingredients, min_additional=min_additional, max_additional=max_additional)\n", " \n", " \n", " root = Tree.build_initial_tree(ingredients, main_ingredients)\n", " \n", " # mark initial ingredient nodes as constant:\n", " nodes = root.traverse()\n", " for node in nodes:\n", " if type(node) == IngredientNode:\n", " if node.name() in constant_ingredients:\n", " node._constant = True\n", " \n", " return Tree(root, main_ingredients)\n", " \n", " @staticmethod\n", " def from_serialization(s, main_ingredients = None):\n", " def empty_node(raw_n):\n", " if raw_n['type'] == \"MixNode\":\n", " node = MixNode(raw_n['constant'])\n", " elif raw_n['type'] == \"IngredientNode\":\n", " node = IngredientNode(raw_n['name'], raw_n['constant'])\n", " elif raw_n['type'] == \"ActionNode\":\n", " node = ActionNode(raw_n['name'], raw_n['constant'])\n", " else:\n", " print(\"unknown node detected\")\n", " return\n", " \n", " return node\n", " \n", " nodes = {}\n", " for n in s:\n", " nodes[n['id']] = empty_node(n)\n", " \n", " for n in s:\n", " childs = n['childs']\n", " id = n['id']\n", " for c in childs:\n", " nodes[id].add_child(nodes[c])\n", " \n", " return Tree(nodes[s[0]['id']], main_ingredients)\n", " \n", " \n", " def __init__(self, root, main_ingredients=None):\n", " # create a dummy entry node\n", " self._root = RecipeTreeNode(\"root\", single_child=True)\n", " self._root.add_child(root)\n", " self._touched = True\n", " self._main_ingredients = main_ingredients\n", " \n", " def root(self):\n", " return self._root.child()\n", " \n", " def mutate(self):\n", " self._touched = True\n", " nodes = self.root().traverse()\n", " weights = [n.n_mutate_options() for n in nodes]\n", " \n", " n = random.choices(nodes, weights)[0]\n", " \n", " n.mutate()\n", " \n", " # check for simplification after modification\n", " self.root().simplify()\n", " \n", " def dot(self):\n", " return self.root().dot()\n", " \n", " def serialize(self):\n", " return [n.serialize() for n in self.root().traverse()]\n", " \n", " def structure_score(self):\n", " n_duplicates = 0\n", " \n", " \n", " def collect_scores(self):\n", " self._mix_scores = []\n", " self._act_scores = []\n", " self._ing_scores = []\n", " \n", " nodes = self.root().traverse()\n", " self._n_mix_nodes = 0\n", " self._n_act_nodes = 0\n", " self._n_ing_nodes = 0\n", " \n", " s = 0\n", " for n in nodes:\n", " if type(n) == MixNode:\n", " self._mix_scores.append(n.node_score())\n", " self._n_mix_nodes += 1\n", " if type(n) == ActionNode:\n", " self._act_scores.append(n.node_score())\n", " self._n_act_nodes += 1\n", " if type(n) == IngredientNode:\n", " self._ing_scores.append(n.node_score())\n", " self._n_ing_nodes += 1\n", " \n", " seen_ingredients = set()\n", " self._n_duplicates = 0\n", " \n", " for n in nodes:\n", " if type(n) == IngredientNode:\n", " if n.name() in seen_ingredients:\n", " self._n_duplicates += 1\n", " else:\n", " seen_ingredients.add(n.name())\n", " \n", " self._mix_scores = np.array(self._mix_scores)\n", " self._act_scores = np.array(self._act_scores)\n", " self._ing_scores = np.array(self._ing_scores)\n", " \n", " \n", " def mix_scores(self):\n", " return self._mix_scores\n", " \n", " def action_scores(self):\n", " return self._act_scores\n", " \n", " def ing_scores(self):\n", " return self._ing_scores\n", " \n", " def main_ingredient_score(self):\n", " if self._main_ingredients is None:\n", " return 1\n", " \n", " ings = self.root().traverse_ingredients()\n", " \n", " actions_for_ing = {}\n", " score_for_ing = {}\n", " \n", " for ing in ings:\n", " if ing._base_ingredient in self._main_ingredients:\n", " actions_for_ing[ing._base_ingredient] = ing._action_set\n", " score_for_ing[ing._base_ingredient] = 0\n", " \n", " for ing in self._main_ingredients:\n", " for act in actions_for_ing[ing]:\n", " s = fw_p_a_given_b(act, ing, m_base_act, c_base_act)\n", " if s > 0.5:\n", " score_for_ing[ing] = 1\n", " \n", " return sum([score_for_ing[ing] for ing in self._main_ingredients]) / len(self._main_ingredients)\n", " \n", " \n", " def score(self):\n", " if not self._touched:\n", " return self._score\n", " \n", " self.collect_scores()\n", " s_mix = self.mix_scores()\n", " s_act = self.action_scores()\n", " s_ing = self.ing_scores()\n", " \n", " n = len(s_mix) + len(s_act) + len(s_ing)\n", " \n", " avg_mix = np.average(s_mix) if len(s_mix) > 0 else 1\n", " avg_act = np.average(s_act) if len(s_act) > 0 else 1\n", " avg_ing = np.average(s_ing) if len(s_ing) > 0 else 1\n", " \n", " sum_mix = np.sum(s_mix) if len(s_mix) > 0 else 0\n", " sum_act = np.sum(s_act) if len(s_act) > 0 else 0\n", " sum_ing = np.sum(s_ing) if len(s_ing) > 0 else 0\n", " \n", " self._touched = False\n", " contains_main_ingred = True\n", " \n", " base_main_ings = [i._base_ingredient for i in self.root().traverse_ingredients()]\n", " for ing in self._main_ingredients:\n", " if ing not in base_main_ings:\n", " contains_main_ingred = False\n", " self._score = 0\n", " break\n", " \n", " if contains_main_ingred:\n", " # boost creativity\n", " if len(s_act) < 3:\n", " self._score = 0\n", " elif len(s_ing) < 3:\n", " self._score = 0\n", " else:\n", " self._score = np.prod(s_mix) * ((sum_act + sum_ing) / n)\n", " self._score *= (len(s_ing) - self._n_duplicates) / len(s_ing)\n", " #self._score = 0.95 * self._score + 0.05 * self.main_ingredient_score()\n", "\n", " return self._score\n", " \n", " def copy(self):\n", " return Tree.from_serialization(self.serialize(), self._main_ingredients)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Population" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [], "source": [ "class Population(object):\n", " def __init__(self, start_ingredients, main_ingredients, n_population = 50, min_additional=0, max_additional=15, mutations=3):\n", " self.population = []\n", " for i in tqdm(range(n_population), desc=\"build initial population\"):\n", " self.population.append(Tree.from_ingredients(start_ingredients, main_ingredients, min_additional=min_additional, max_additional=max_additional))\n", " self._n = n_population\n", " self._n_mutations = mutations\n", " \n", " def mutate(self):\n", " for tree in self.population.copy():\n", " t_clone = tree.copy()\n", " for i in range(self._n_mutations):\n", " t_clone.mutate()\n", " #t_clone.mutate()\n", " #t_clone.mutate()\n", " self.population.append(t_clone)\n", " \n", " def pairwise_competition(self):\n", " new_population = []\n", " indices = list(range(len(self.population)))\n", " random.shuffle(indices)\n", " \n", " for i in range(len(self.population) // 2):\n", " i_a = indices[2*i]\n", " i_b = indices[2*i+1]\n", " \n", " \n", " if self.population[i_a].score() > self.population[i_b].score():\n", " new_population.append(self.population[i_a])\n", " else:\n", " new_population.append(self.population[i_b])\n", " \n", " self.population = new_population\n", " \n", " def crossover(self):\n", " # shuffle indices\n", " indices = list(range(len(self.population) // 2))\n", " indices = [i + len(self.population) // 2 for i in indices]\n", " random.shuffle(indices)\n", " \n", " # perform crossover for random pairs\n", " for i in range(len(self.population) // 4):\n", " i_a = indices[2*i]\n", " i_b = indices[2*i+1]\n", " \n", " self.pairwise_crossover(self.population[i_a], self.population[i_b])\n", " \n", " \n", " def pairwise_crossover(self, tree_a, tree_b):\n", " # for crossover: find a random subtree in both trees, and switch them\n", " \n", " # first, select one random mix node from both\n", " a_nodes = tree_a.root().traverse()\n", " b_nodes = tree_b.root().traverse()\n", " \n", " a_mix_nodes = []\n", " b_mix_nodes = []\n", " \n", " for n in a_nodes:\n", " if type(n) == MixNode:\n", " a_mix_nodes.append(n)\n", " \n", " for n in b_nodes:\n", " if type(n) == MixNode:\n", " b_mix_nodes.append(n)\n", " \n", " a_mix_node = np.random.choice(a_mix_nodes)\n", " b_mix_node = np.random.choice(b_mix_nodes)\n", " \n", " # now select one random child, we will switch the subtrees there\n", " a_child = np.random.choice(list(a_mix_node.childs()))\n", " b_child = np.random.choice(list(b_mix_node.childs()))\n", " \n", " # ...and perform the switch\n", " \n", " # manually remove references\n", " a_mix_node.remove_child(a_child)\n", " b_mix_node.remove_child(b_child)\n", " \n", " # and add child to other subtree\n", " a_mix_node.add_child(b_child)\n", " b_mix_node.add_child(a_child)\n", " \n", " \n", " \n", " def hold_best(self, n=10):\n", " scores = [tree.score() for tree in self.population]\n", " \n", " sorted_indices = np.argsort(-scores)\n", " \n", " self.population = np.array(self.population)[sorted_indices[:n]].tolist()\n", " \n", " def run(self, n=50):\n", " avg_scores = []\n", " for i in tqdm(range(n), desc=\"run evolutionary cycles\"):\n", " self.mutate()\n", "\n", " self.crossover()\n", " \n", " self.pairwise_competition()\n", " #self.collect_scores()\n", " #self.hold_best(self._n)\n", " scores = [t.score() for t in self.population]\n", " avg_scores.append(scores)\n", " return avg_scores\n", " \n", " \n", " def plot_population(self, n_best=10):\n", " scores = [tree.score() for tree in self.population]\n", " \n", " ii = np.argsort(-np.array(scores))[:n_best]\n", "\n", " for i in ii:\n", " self.population[i].root().simplify()\n", " display(self.population[i].root().dot())\n", " display(Markdown(f\"**Recipe Score**: {scores[i]}\"))\n", " display(self.population[i].root().to_instruction().to_markdown())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run Evolutionary Algorithm" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "cacb7928098b4fa19283859b2f3adccf", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(FloatProgress(value=0.0, description='build initial population', max=50.0, style=ProgressStyle(…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "p = Population([\"noodle\"],['noodle'], min_additional=4, max_additional=13, n_population = 50, mutations=1)" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [], "source": [ "#p_ingredient_unprepared(list(p.population[0].root().childs())[0]._name) < 0.2" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4dc4a7ba7e28404b88b0224cd04f169e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(FloatProgress(value=0.0, description='run evolutionary cycles', max=25.0, style=ProgressStyle(d…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "avg = p.run(25)" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "196220\n", "\n", " \n", "boil\n", "node score: 1.0000\n", "\n", "\n", "\n", "196221\n", "\n", " \n", "mix\n", "node score: 0.6727\n", "\n", "\n", "\n", "196220->196221\n", "\n", "\n", "\n", "\n", "\n", "196224\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196224\n", "\n", "\n", "\n", "\n", "\n", "196390\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "196221->196390\n", "\n", "\n", "\n", "\n", "\n", "196231\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196231\n", "\n", "\n", "\n", "\n", "\n", "196230\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196230\n", "\n", "\n", "\n", "\n", "\n", "196229\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196229\n", "\n", "\n", "\n", "\n", "\n", "196233\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196233\n", "\n", "\n", "\n", "\n", "\n", "196228\n", "\n", " \n", "garlic clove\n", "node score:0.5000\n", "\n", "\n", "\n", "196221->196228\n", "\n", "\n", "\n", "\n", "\n", "196227\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196227\n", "\n", "\n", "\n", "\n", "\n", "196222\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "196221->196222\n", "\n", "\n", "\n", "\n", "\n", "196232\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "196221->196232\n", "\n", "\n", "\n", "\n", "\n", "196225\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "196221->196225\n", "\n", "\n", "\n", "\n", "\n", "196391\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "196390->196391\n", "\n", "\n", "\n", "\n", "\n", "196223\n", "\n", " \n", "clove garlic\n", "node score:1.0000\n", "\n", "\n", "\n", "196222->196223\n", "\n", "\n", "\n", "\n", "\n", "196226\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "196225->196226\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.5542355371900826" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * pepper\n", " * clove garlic\n", " * garlic clove\n", " * onion\n", " * noodle\n", " * water\n", " * seasoning\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | chop pepper, slice clove garlic, dice onion and mix it with seasoning, seasoning, noodle, milk, olive oil, garlic clove, salt and water. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "193844\n", "\n", " \n", "cook\n", "node score: 1.0000\n", "\n", "\n", "\n", "193845\n", "\n", " \n", "mix\n", "node score: 0.6364\n", "\n", "\n", "\n", "193844->193845\n", "\n", "\n", "\n", "\n", "\n", "193857\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193857\n", "\n", "\n", "\n", "\n", "\n", "193855\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "193845->193855\n", "\n", "\n", "\n", "\n", "\n", "193846\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193846\n", "\n", "\n", "\n", "\n", "\n", "193723\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193723\n", "\n", "\n", "\n", "\n", "\n", "193861\n", "\n", " \n", "wash\n", "node score: 1.0000\n", "\n", "\n", "\n", "193845->193861\n", "\n", "\n", "\n", "\n", "\n", "193852\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193852\n", "\n", "\n", "\n", "\n", "\n", "193860\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193860\n", "\n", "\n", "\n", "\n", "\n", "193859\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193859\n", "\n", "\n", "\n", "\n", "\n", "193849\n", "\n", " \n", "cook\n", "node score: 1.0000\n", "\n", "\n", "\n", "193845->193849\n", "\n", "\n", "\n", "\n", "\n", "193858\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193858\n", "\n", "\n", "\n", "\n", "\n", "193848\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193848\n", "\n", "\n", "\n", "\n", "\n", "193847\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "193845->193847\n", "\n", "\n", "\n", "\n", "\n", "193856\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "193855->193856\n", "\n", "\n", "\n", "\n", "\n", "193862\n", "\n", " \n", "chicken\n", "node score:1.0000\n", "\n", "\n", "\n", "193861->193862\n", "\n", "\n", "\n", "\n", "\n", "193850\n", "\n", " \n", "noodle\n", "node score:0.5000\n", "\n", "\n", "\n", "193849->193850\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.5318627450980392" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * chicken\n", " * olive oil\n", " * pepper\n", " * chicken broth\n", " * cheese\n", " * onion\n", " * ground beef\n", " * noodle\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | chop onion, wash chicken, cook noodle and mix it with salt, ground beef, milk, pepper, chicken broth, sausage, olive oil, milk and cheese. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "197738\n", "\n", " \n", "cook\n", "node score: 0.6364\n", "\n", "\n", "\n", "197739\n", "\n", " \n", "boil\n", "node score: 0.8182\n", "\n", "\n", "\n", "197738->197739\n", "\n", "\n", "\n", "\n", "\n", "197740\n", "\n", " \n", "mix\n", "node score: 0.5818\n", "\n", "\n", "\n", "197739->197740\n", "\n", "\n", "\n", "\n", "\n", "197752\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197752\n", "\n", "\n", "\n", "\n", "\n", "197746\n", "\n", " \n", "cut\n", "node score: 1.0000\n", "\n", "\n", "\n", "197740->197746\n", "\n", "\n", "\n", "\n", "\n", "197749\n", "\n", " \n", "hot water\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197749\n", "\n", "\n", "\n", "\n", "\n", "197745\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197745\n", "\n", "\n", "\n", "\n", "\n", "197751\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197751\n", "\n", "\n", "\n", "\n", "\n", "197748\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197748\n", "\n", "\n", "\n", "\n", "\n", "197743\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197743\n", "\n", "\n", "\n", "\n", "\n", "197750\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197750\n", "\n", "\n", "\n", "\n", "\n", "197741\n", "\n", " \n", "place\n", "node score: 1.0000\n", "\n", "\n", "\n", "197740->197741\n", "\n", "\n", "\n", "\n", "\n", "197744\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197744\n", "\n", "\n", "\n", "\n", "\n", "197849\n", "\n", " \n", "red pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "197740->197849\n", "\n", "\n", "\n", "\n", "\n", "197747\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "197746->197747\n", "\n", "\n", "\n", "\n", "\n", "197742\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "197741->197742\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.5256198347107438" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * pepper\n", " * hot water\n", " * chicken broth\n", " * noodle\n", " * water\n", " * red pepper\n", " * seasoning\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | cut pepper, place noodle and mix it with milk, hot water, salt, water, chicken broth, sausage, seasoning, olive oil and red pepper. Then boil it. |\n", "| 2 | cook the result of step 1 |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "194419\n", "\n", " \n", "boil\n", "node score: 1.0000\n", "\n", "\n", "\n", "194420\n", "\n", " \n", "mix\n", "node score: 0.6182\n", "\n", "\n", "\n", "194419->194420\n", "\n", "\n", "\n", "\n", "\n", "194432\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "194420->194432\n", "\n", "\n", "\n", "\n", "\n", "194574\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194574\n", "\n", "\n", "\n", "\n", "\n", "194421\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "194420->194421\n", "\n", "\n", "\n", "\n", "\n", "194431\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194431\n", "\n", "\n", "\n", "\n", "\n", "194425\n", "\n", " \n", "spaghetti sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194425\n", "\n", "\n", "\n", "\n", "\n", "194424\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194424\n", "\n", "\n", "\n", "\n", "\n", "194429\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194429\n", "\n", "\n", "\n", "\n", "\n", "194426\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194426\n", "\n", "\n", "\n", "\n", "\n", "194428\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194428\n", "\n", "\n", "\n", "\n", "\n", "194423\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194423\n", "\n", "\n", "\n", "\n", "\n", "194427\n", "\n", " \n", "red wine\n", "node score:1.0000\n", "\n", "\n", "\n", "194420->194427\n", "\n", "\n", "\n", "\n", "\n", "194433\n", "\n", " \n", "clove garlic\n", "node score:1.0000\n", "\n", "\n", "\n", "194432->194433\n", "\n", "\n", "\n", "\n", "\n", "194422\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "194421->194422\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.5245179063360881" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * spaghetti sauce\n", " * clove garlic\n", " * onion\n", " * noodle\n", " * water\n", " * seasoning\n", " * salt\n", " * red wine\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | slice clove garlic, dice onion and mix it with seasoning, salt, spaghetti sauce, milk, noodle, seasoning, water, olive oil and red wine. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "199522\n", "\n", " \n", "cook\n", "node score: 0.7273\n", "\n", "\n", "\n", "199523\n", "\n", " \n", "boil\n", "node score: 0.9091\n", "\n", "\n", "\n", "199522->199523\n", "\n", "\n", "\n", "\n", "\n", "199524\n", "\n", " \n", "mix\n", "node score: 0.5818\n", "\n", "\n", "\n", "199523->199524\n", "\n", "\n", "\n", "\n", "\n", "199537\n", "\n", " \n", "red pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199537\n", "\n", "\n", "\n", "\n", "\n", "199527\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199527\n", "\n", "\n", "\n", "\n", "\n", "199534\n", "\n", " \n", "place\n", "node score: 1.0000\n", "\n", "\n", "\n", "199524->199534\n", "\n", "\n", "\n", "\n", "\n", "199536\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199536\n", "\n", "\n", "\n", "\n", "\n", "199653\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "199524->199653\n", "\n", "\n", "\n", "\n", "\n", "199525\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199525\n", "\n", "\n", "\n", "\n", "\n", "199528\n", "\n", " \n", "hot water\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199528\n", "\n", "\n", "\n", "\n", "\n", "199531\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199531\n", "\n", "\n", "\n", "\n", "\n", "199533\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199533\n", "\n", "\n", "\n", "\n", "\n", "199529\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199529\n", "\n", "\n", "\n", "\n", "\n", "199530\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "199524->199530\n", "\n", "\n", "\n", "\n", "\n", "199535\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "199534->199535\n", "\n", "\n", "\n", "\n", "\n", "199654\n", "\n", " \n", "sausage\n", "node score:0.5000\n", "\n", "\n", "\n", "199653->199654\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.5140495867768595" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * pepper\n", " * hot water\n", " * chicken broth\n", " * noodle\n", " * water\n", " * red pepper\n", " * seasoning\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | place noodle, slice sausage and mix it with red pepper, pepper, olive oil, milk, hot water, chicken broth, seasoning, salt and water. Then boil it. |\n", "| 2 | cook the result of step 1 |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "199316\n", "\n", " \n", "cook\n", "node score: 0.9167\n", "\n", "\n", "\n", "199317\n", "\n", " \n", "mix\n", "node score: 0.6515\n", "\n", "\n", "\n", "199316->199317\n", "\n", "\n", "\n", "\n", "\n", "199327\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199327\n", "\n", "\n", "\n", "\n", "\n", "199319\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199319\n", "\n", "\n", "\n", "\n", "\n", "199320\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "199317->199320\n", "\n", "\n", "\n", "\n", "\n", "199333\n", "\n", " \n", "spinach\n", "node score:0.5000\n", "\n", "\n", "\n", "199317->199333\n", "\n", "\n", "\n", "\n", "\n", "198715\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->198715\n", "\n", "\n", "\n", "\n", "\n", "199322\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199322\n", "\n", "\n", "\n", "\n", "\n", "199328\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "199317->199328\n", "\n", "\n", "\n", "\n", "\n", "199330\n", "\n", " \n", "cook\n", "node score: 0.0000\n", "\n", "\n", "\n", "199317->199330\n", "\n", "\n", "\n", "\n", "\n", "199323\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199323\n", "\n", "\n", "\n", "\n", "\n", "199318\n", "\n", " \n", "spaghetti sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199318\n", "\n", "\n", "\n", "\n", "\n", "199324\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199324\n", "\n", "\n", "\n", "\n", "\n", "199325\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "199317->199325\n", "\n", "\n", "\n", "\n", "\n", "199321\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "199320->199321\n", "\n", "\n", "\n", "\n", "\n", "199329\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "199328->199329\n", "\n", "\n", "\n", "\n", "\n", "199331\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "199330->199331\n", "\n", "\n", "\n", "\n", "\n", "199332\n", "\n", " \n", "noodle\n", "node score:0.6667\n", "\n", "\n", "\n", "199331->199332\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.5004501028806584" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * milk\n", " * olive oil\n", " * spaghetti sauce\n", " * pepper\n", " * cheese\n", " * onion\n", " * ground beef\n", " * noodle\n", " * spinach\n", " * salt\n", " * chicken broth\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | heat and cook noodle |\n", "| 2 | chop onion, chop pepper and mix it with salt, olive oil, spinach, chicken broth, ground beef, chicken broth, spaghetti sauce, cheese and milk and mix it together with the results of step 1. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "195583\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "195584\n", "\n", " \n", "mix\n", "node score: 0.5897\n", "\n", "\n", "\n", "195583->195584\n", "\n", "\n", "\n", "\n", "\n", "195601\n", "\n", " \n", "mushroom soup\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195601\n", "\n", "\n", "\n", "\n", "\n", "195595\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "195584->195595\n", "\n", "\n", "\n", "\n", "\n", "195590\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195590\n", "\n", "\n", "\n", "\n", "\n", "195585\n", "\n", " \n", "grate\n", "node score: 1.0000\n", "\n", "\n", "\n", "195584->195585\n", "\n", "\n", "\n", "\n", "\n", "195600\n", "\n", " \n", "red pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195600\n", "\n", "\n", "\n", "\n", "\n", "195808\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195808\n", "\n", "\n", "\n", "\n", "\n", "195589\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195589\n", "\n", "\n", "\n", "\n", "\n", "195599\n", "\n", " \n", "shrimp\n", "node score:0.5000\n", "\n", "\n", "\n", "195584->195599\n", "\n", "\n", "\n", "\n", "\n", "195587\n", "\n", " \n", "soy sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195587\n", "\n", "\n", "\n", "\n", "\n", "195594\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195594\n", "\n", "\n", "\n", "\n", "\n", "195598\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195598\n", "\n", "\n", "\n", "\n", "\n", "195597\n", "\n", " \n", "basil\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195597\n", "\n", "\n", "\n", "\n", "\n", "195588\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "195584->195588\n", "\n", "\n", "\n", "\n", "\n", "195596\n", "\n", " \n", "parsley\n", "node score:1.0000\n", "\n", "\n", "\n", "195595->195596\n", "\n", "\n", "\n", "\n", "\n", "195586\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "195585->195586\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.49634528367560043" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * soy sauce\n", " * ground beef\n", " * noodle\n", " * carrot\n", " * basil\n", " * sausage\n", " * red pepper\n", " * salt\n", " * mushroom soup\n", " * chicken broth\n", " * shrimp\n", " * parsley\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | chop parsley, grate carrot and mix it with mushroom soup, chicken broth, red pepper, ground beef, ground beef, shrimp, soy sauce, salt, sausage, basil and noodle. Then heat it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "198830\n", "\n", " \n", "boil\n", "node score: 1.0000\n", "\n", "\n", "\n", "198831\n", "\n", " \n", "mix\n", "node score: 0.6727\n", "\n", "\n", "\n", "198830->198831\n", "\n", "\n", "\n", "\n", "\n", "198834\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198834\n", "\n", "\n", "\n", "\n", "\n", "198832\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198832\n", "\n", "\n", "\n", "\n", "\n", "198835\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198835\n", "\n", "\n", "\n", "\n", "\n", "198842\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198842\n", "\n", "\n", "\n", "\n", "\n", "198841\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198841\n", "\n", "\n", "\n", "\n", "\n", "198843\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198843\n", "\n", "\n", "\n", "\n", "\n", "199089\n", "\n", " \n", "onion\n", "node score:0.5000\n", "\n", "\n", "\n", "198831->199089\n", "\n", "\n", "\n", "\n", "\n", "198837\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "198831->198837\n", "\n", "\n", "\n", "\n", "\n", "198839\n", "\n", " \n", "peel\n", "node score: 1.0000\n", "\n", "\n", "\n", "198831->198839\n", "\n", "\n", "\n", "\n", "\n", "198844\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198844\n", "\n", "\n", "\n", "\n", "\n", "198836\n", "\n", " \n", "dijon mustard\n", "node score:1.0000\n", "\n", "\n", "\n", "198831->198836\n", "\n", "\n", "\n", "\n", "\n", "198838\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "198837->198838\n", "\n", "\n", "\n", "\n", "\n", "198840\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "198839->198840\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.49537190082644633" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * dijon mustard\n", " * olive oil\n", " * onion\n", " * noodle\n", " * water\n", " * carrot\n", " * seasoning\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | dice onion, peel carrot and mix it with milk, salt, water, olive oil, milk, noodle, onion, seasoning and dijon mustard. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "193546\n", "\n", " \n", "cook\n", "node score: 1.0000\n", "\n", "\n", "\n", "193547\n", "\n", " \n", "mix\n", "node score: 0.5303\n", "\n", "\n", "\n", "193546->193547\n", "\n", "\n", "\n", "\n", "\n", "193555\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193555\n", "\n", "\n", "\n", "\n", "\n", "193563\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193563\n", "\n", "\n", "\n", "\n", "\n", "193564\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193564\n", "\n", "\n", "\n", "\n", "\n", "193551\n", "\n", " \n", "cook\n", "node score: 1.0000\n", "\n", "\n", "\n", "193547->193551\n", "\n", "\n", "\n", "\n", "\n", "193561\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "193547->193561\n", "\n", "\n", "\n", "\n", "\n", "193553\n", "\n", " \n", "cut\n", "node score: 1.0000\n", "\n", "\n", "\n", "193547->193553\n", "\n", "\n", "\n", "\n", "\n", "193559\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "193547->193559\n", "\n", "\n", "\n", "\n", "\n", "193007\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193007\n", "\n", "\n", "\n", "\n", "\n", "193558\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193558\n", "\n", "\n", "\n", "\n", "\n", "193550\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193550\n", "\n", "\n", "\n", "\n", "\n", "193565\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "193547->193565\n", "\n", "\n", "\n", "\n", "\n", "193548\n", "\n", " \n", "wash\n", "node score: 1.0000\n", "\n", "\n", "\n", "193547->193548\n", "\n", "\n", "\n", "\n", "\n", "193552\n", "\n", " \n", "noodle\n", "node score:0.5000\n", "\n", "\n", "\n", "193551->193552\n", "\n", "\n", "\n", "\n", "\n", "193562\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "193561->193562\n", "\n", "\n", "\n", "\n", "\n", "193554\n", "\n", " \n", "broccoli\n", "node score:1.0000\n", "\n", "\n", "\n", "193553->193554\n", "\n", "\n", "\n", "\n", "\n", "193560\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "193559->193560\n", "\n", "\n", "\n", "\n", "\n", "193549\n", "\n", " \n", "chicken\n", "node score:1.0000\n", "\n", "\n", "\n", "193548->193549\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.4884370015948963" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * chicken\n", " * olive oil\n", " * pepper\n", " * chicken broth\n", " * cheese\n", " * onion\n", " * noodle\n", " * ground beef\n", " * broccoli\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | cook noodle, chop pepper, cut broccoli, chop onion, wash chicken and mix it with ground beef, cheese, milk, salt, olive oil, sausage and chicken broth. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "198169\n", "\n", " \n", "cook\n", "node score: 1.0000\n", "\n", "\n", "\n", "198170\n", "\n", " \n", "mix\n", "node score: 0.6545\n", "\n", "\n", "\n", "198169->198170\n", "\n", "\n", "\n", "\n", "\n", "198178\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "198170->198178\n", "\n", "\n", "\n", "\n", "\n", "198181\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198181\n", "\n", "\n", "\n", "\n", "\n", "198183\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198183\n", "\n", "\n", "\n", "\n", "\n", "198182\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198182\n", "\n", "\n", "\n", "\n", "\n", "197723\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->197723\n", "\n", "\n", "\n", "\n", "\n", "198172\n", "\n", " \n", "onion\n", "node score:0.5000\n", "\n", "\n", "\n", "198170->198172\n", "\n", "\n", "\n", "\n", "\n", "198174\n", "\n", " \n", "peel\n", "node score: 1.0000\n", "\n", "\n", "\n", "198170->198174\n", "\n", "\n", "\n", "\n", "\n", "198176\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198176\n", "\n", "\n", "\n", "\n", "\n", "198180\n", "\n", " \n", "tomato sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198180\n", "\n", "\n", "\n", "\n", "\n", "198177\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198177\n", "\n", "\n", "\n", "\n", "\n", "198173\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "198170->198173\n", "\n", "\n", "\n", "\n", "\n", "198179\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "198178->198179\n", "\n", "\n", "\n", "\n", "\n", "198175\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "198174->198175\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.4819834710743802" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * onion\n", " * noodle\n", " * ground beef\n", " * carrot\n", " * water\n", " * seasoning\n", " * sausage\n", " * tomato sauce\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | heat olive oil, peel carrot and mix it with olive oil, sausage, noodle, seasoning, onion, ground beef, tomato sauce, water and seasoning. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "183823\n", "\n", " \n", "boil\n", "node score: 1.0000\n", "\n", "\n", "\n", "183824\n", "\n", " \n", "mix\n", "node score: 0.5818\n", "\n", "\n", "\n", "183823->183824\n", "\n", "\n", "\n", "\n", "\n", "183828\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183828\n", "\n", "\n", "\n", "\n", "\n", "183831\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183831\n", "\n", "\n", "\n", "\n", "\n", "183840\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "183824->183840\n", "\n", "\n", "\n", "\n", "\n", "183832\n", "\n", " \n", "peel\n", "node score: 1.0000\n", "\n", "\n", "\n", "183824->183832\n", "\n", "\n", "\n", "\n", "\n", "183835\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183835\n", "\n", "\n", "\n", "\n", "\n", "183830\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183830\n", "\n", "\n", "\n", "\n", "\n", "184253\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->184253\n", "\n", "\n", "\n", "\n", "\n", "183834\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183834\n", "\n", "\n", "\n", "\n", "\n", "183836\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183836\n", "\n", "\n", "\n", "\n", "\n", "183825\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "183824->183825\n", "\n", "\n", "\n", "\n", "\n", "183826\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "183824->183826\n", "\n", "\n", "\n", "\n", "\n", "183829\n", "\n", " \n", "sausage\n", "node score:0.5000\n", "\n", "\n", "\n", "183840->183829\n", "\n", "\n", "\n", "\n", "\n", "183833\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "183832->183833\n", "\n", "\n", "\n", "\n", "\n", "183827\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "183826->183827\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.47933884297520657" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * cheese\n", " * onion\n", " * noodle\n", " * carrot\n", " * water\n", " * seasoning\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | slice sausage, peel carrot, dice onion and mix it with milk, seasoning, milk, water, cheese, salt, olive oil and noodle. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "192482\n", "\n", " \n", "boil\n", "node score: 0.9091\n", "\n", "\n", "\n", "192483\n", "\n", " \n", "mix\n", "node score: 0.5455\n", "\n", "\n", "\n", "192482->192483\n", "\n", "\n", "\n", "\n", "\n", "192484\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192484\n", "\n", "\n", "\n", "\n", "\n", "192493\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192493\n", "\n", "\n", "\n", "\n", "\n", "192488\n", "\n", " \n", "pour\n", "node score: 1.0000\n", "\n", "\n", "\n", "192483->192488\n", "\n", "\n", "\n", "\n", "\n", "192492\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192492\n", "\n", "\n", "\n", "\n", "\n", "192496\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "192483->192496\n", "\n", "\n", "\n", "\n", "\n", "192494\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192494\n", "\n", "\n", "\n", "\n", "\n", "192318\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192318\n", "\n", "\n", "\n", "\n", "\n", "192485\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192485\n", "\n", "\n", "\n", "\n", "\n", "192491\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192491\n", "\n", "\n", "\n", "\n", "\n", "192486\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "192483->192486\n", "\n", "\n", "\n", "\n", "\n", "192495\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "192483->192495\n", "\n", "\n", "\n", "\n", "\n", "192489\n", "\n", " \n", "carrot\n", "node score:0.5000\n", "\n", "\n", "\n", "192488->192489\n", "\n", "\n", "\n", "\n", "\n", "192497\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "192496->192497\n", "\n", "\n", "\n", "\n", "\n", "192487\n", "\n", " \n", "sausage\n", "node score:0.5000\n", "\n", "\n", "\n", "192486->192487\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.47417355371900827" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * cheese\n", " * onion\n", " * ground beef\n", " * noodle\n", " * carrot\n", " * water\n", " * seasoning\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | pour carrot, dice onion, slice sausage and mix it with milk, salt, cheese, olive oil, ground beef, seasoning, water and noodle. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "198151\n", "\n", " \n", "boil\n", "node score: 0.9091\n", "\n", "\n", "\n", "198152\n", "\n", " \n", "mix\n", "node score: 0.6000\n", "\n", "\n", "\n", "198151->198152\n", "\n", "\n", "\n", "\n", "\n", "198155\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198155\n", "\n", "\n", "\n", "\n", "\n", "198154\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198154\n", "\n", "\n", "\n", "\n", "\n", "198158\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198158\n", "\n", "\n", "\n", "\n", "\n", "198160\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "198152->198160\n", "\n", "\n", "\n", "\n", "\n", "198156\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "198152->198156\n", "\n", "\n", "\n", "\n", "\n", "198162\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198162\n", "\n", "\n", "\n", "\n", "\n", "197993\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->197993\n", "\n", "\n", "\n", "\n", "\n", "198159\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198159\n", "\n", "\n", "\n", "\n", "\n", "198164\n", "\n", " \n", "seed\n", "node score:0.5000\n", "\n", "\n", "\n", "198152->198164\n", "\n", "\n", "\n", "\n", "\n", "198153\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198153\n", "\n", "\n", "\n", "\n", "\n", "198163\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "198152->198163\n", "\n", "\n", "\n", "\n", "\n", "198161\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "198160->198161\n", "\n", "\n", "\n", "\n", "\n", "198157\n", "\n", " \n", "sausage\n", "node score:0.5000\n", "\n", "\n", "\n", "198156->198157\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.46942148760330576" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * pepper\n", " * cheese\n", " * noodle\n", " * water\n", " * seasoning\n", " * sausage\n", " * salt\n", " * seed\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | chop pepper, slice sausage and mix it with noodle, milk, seasoning, cheese, cheese, water, seed, olive oil and salt. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "195476\n", "\n", " \n", "boil\n", "node score: 0.9091\n", "\n", "\n", "\n", "195477\n", "\n", " \n", "mix\n", "node score: 0.5273\n", "\n", "\n", "\n", "195476->195477\n", "\n", "\n", "\n", "\n", "\n", "195488\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195488\n", "\n", "\n", "\n", "\n", "\n", "195478\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195478\n", "\n", "\n", "\n", "\n", "\n", "195489\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195489\n", "\n", "\n", "\n", "\n", "\n", "195480\n", "\n", " \n", "slice\n", "node score: 1.0000\n", "\n", "\n", "\n", "195477->195480\n", "\n", "\n", "\n", "\n", "\n", "195479\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195479\n", "\n", "\n", "\n", "\n", "\n", "195485\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195485\n", "\n", "\n", "\n", "\n", "\n", "195431\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "195477->195431\n", "\n", "\n", "\n", "\n", "\n", "195486\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195486\n", "\n", "\n", "\n", "\n", "\n", "195487\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "195477->195487\n", "\n", "\n", "\n", "\n", "\n", "195484\n", "\n", " \n", "seed\n", "node score:0.5000\n", "\n", "\n", "\n", "195477->195484\n", "\n", "\n", "\n", "\n", "\n", "195482\n", "\n", " \n", "peel\n", "node score: 1.0000\n", "\n", "\n", "\n", "195477->195482\n", "\n", "\n", "\n", "\n", "\n", "195481\n", "\n", " \n", "sausage\n", "node score:0.5000\n", "\n", "\n", "\n", "195480->195481\n", "\n", "\n", "\n", "\n", "\n", "195432\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "195431->195432\n", "\n", "\n", "\n", "\n", "\n", "195483\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "195482->195483\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.4583677685950413" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * pepper\n", " * cheese\n", " * noodle\n", " * water\n", " * carrot\n", " * seasoning\n", " * sausage\n", " * salt\n", " * seed\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | slice sausage, chop pepper, peel carrot and mix it with olive oil, milk, noodle, seasoning, water, cheese, salt and seed. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "192796\n", "\n", " \n", "cook\n", "node score: 0.9167\n", "\n", "\n", "\n", "192797\n", "\n", " \n", "mix\n", "node score: 0.5758\n", "\n", "\n", "\n", "192796->192797\n", "\n", "\n", "\n", "\n", "\n", "192813\n", "\n", " \n", "spaghetti sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192813\n", "\n", "\n", "\n", "\n", "\n", "192809\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192809\n", "\n", "\n", "\n", "\n", "\n", "192810\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "192797->192810\n", "\n", "\n", "\n", "\n", "\n", "192812\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192812\n", "\n", "\n", "\n", "\n", "\n", "192805\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192805\n", "\n", "\n", "\n", "\n", "\n", "192801\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192801\n", "\n", "\n", "\n", "\n", "\n", "192804\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192804\n", "\n", "\n", "\n", "\n", "\n", "192808\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192808\n", "\n", "\n", "\n", "\n", "\n", "193387\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->193387\n", "\n", "\n", "\n", "\n", "\n", "192806\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "192797->192806\n", "\n", "\n", "\n", "\n", "\n", "192798\n", "\n", " \n", "cook\n", "node score: 0.0000\n", "\n", "\n", "\n", "192797->192798\n", "\n", "\n", "\n", "\n", "\n", "192800\n", "\n", " \n", "spaghetti sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "192797->192800\n", "\n", "\n", "\n", "\n", "\n", "192811\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "192810->192811\n", "\n", "\n", "\n", "\n", "\n", "192807\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "192806->192807\n", "\n", "\n", "\n", "\n", "\n", "192815\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "192798->192815\n", "\n", "\n", "\n", "\n", "\n", "192799\n", "\n", " \n", "noodle\n", "node score:0.6667\n", "\n", "\n", "\n", "192815->192799\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.4569187242798354" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * milk\n", " * olive oil\n", " * spaghetti sauce\n", " * pepper\n", " * cheese\n", " * onion\n", " * ground beef\n", " * noodle\n", " * sausage\n", " * salt\n", " * chicken broth\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | heat and cook noodle |\n", "| 2 | chop onion, chop pepper and mix it with spaghetti sauce, olive oil, ground beef, chicken broth, cheese, milk, sausage, salt and spaghetti sauce and mix it together with the results of step 1. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "199985\n", "\n", " \n", "cook\n", "node score: 0.5455\n", "\n", "\n", "\n", "199986\n", "\n", " \n", "boil\n", "node score: 0.9091\n", "\n", "\n", "\n", "199985->199986\n", "\n", "\n", "\n", "\n", "\n", "199987\n", "\n", " \n", "mix\n", "node score: 0.5636\n", "\n", "\n", "\n", "199986->199987\n", "\n", "\n", "\n", "\n", "\n", "199988\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "199987->199988\n", "\n", "\n", "\n", "\n", "\n", "199990\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->199990\n", "\n", "\n", "\n", "\n", "\n", "199996\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->199996\n", "\n", "\n", "\n", "\n", "\n", "199991\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->199991\n", "\n", "\n", "\n", "\n", "\n", "200001\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->200001\n", "\n", "\n", "\n", "\n", "\n", "199998\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "199987->199998\n", "\n", "\n", "\n", "\n", "\n", "199992\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->199992\n", "\n", "\n", "\n", "\n", "\n", "200002\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->200002\n", "\n", "\n", "\n", "\n", "\n", "200000\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->200000\n", "\n", "\n", "\n", "\n", "\n", "199798\n", "\n", " \n", "spaghetti sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "199987->199798\n", "\n", "\n", "\n", "\n", "\n", "199993\n", "\n", " \n", "place\n", "node score: 0.0000\n", "\n", "\n", "\n", "199987->199993\n", "\n", "\n", "\n", "\n", "\n", "199989\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "199988->199989\n", "\n", "\n", "\n", "\n", "\n", "199999\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "199998->199999\n", "\n", "\n", "\n", "\n", "\n", "199994\n", "\n", " \n", "fry\n", "node score: 0.0000\n", "\n", "\n", "\n", "199993->199994\n", "\n", "\n", "\n", "\n", "\n", "199995\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "199994->199995\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.45261707988980715" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * spaghetti sauce\n", " * pepper\n", " * onion\n", " * ground beef\n", " * noodle\n", " * water\n", " * seasoning\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | fry and place noodle |\n", "| 2 | heat pepper, dice onion and mix it with olive oil, sausage, milk, water, salt, ground beef, seasoning and spaghetti sauce and mix it together with the results of step 1. Then boil it. |\n", "| 3 | cook the result of step 2 |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "197446\n", "\n", " \n", "boil\n", "node score: 0.9091\n", "\n", "\n", "\n", "197447\n", "\n", " \n", "mix\n", "node score: 0.6000\n", "\n", "\n", "\n", "197446->197447\n", "\n", "\n", "\n", "\n", "\n", "197451\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197451\n", "\n", "\n", "\n", "\n", "\n", "197460\n", "\n", " \n", "onion\n", "node score:0.5000\n", "\n", "\n", "\n", "197447->197460\n", "\n", "\n", "\n", "\n", "\n", "197450\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197450\n", "\n", "\n", "\n", "\n", "\n", "197459\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197459\n", "\n", "\n", "\n", "\n", "\n", "197457\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "197447->197457\n", "\n", "\n", "\n", "\n", "\n", "197449\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197449\n", "\n", "\n", "\n", "\n", "\n", "197456\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197456\n", "\n", "\n", "\n", "\n", "\n", "197448\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197448\n", "\n", "\n", "\n", "\n", "\n", "197454\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197454\n", "\n", "\n", "\n", "\n", "\n", "197328\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "197447->197328\n", "\n", "\n", "\n", "\n", "\n", "197452\n", "\n", " \n", "peel\n", "node score: 0.0000\n", "\n", "\n", "\n", "197447->197452\n", "\n", "\n", "\n", "\n", "\n", "197458\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "197457->197458\n", "\n", "\n", "\n", "\n", "\n", "197453\n", "\n", " \n", "cherry tomato\n", "node score:1.0000\n", "\n", "\n", "\n", "197452->197453\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.45123966942148763" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * pepper\n", " * onion\n", " * noodle\n", " * water\n", " * cherry tomato\n", " * seasoning\n", " * sausage\n", " * salt\n", " * milk\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | chop pepper, peel cherry tomato and mix it with sausage, onion, olive oil, noodle, milk, water, seasoning, salt and olive oil. Then boil it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "199966\n", "\n", " \n", "cook\n", "node score: 0.9167\n", "\n", "\n", "\n", "199967\n", "\n", " \n", "mix\n", "node score: 0.5303\n", "\n", "\n", "\n", "199966->199967\n", "\n", "\n", "\n", "\n", "\n", "199969\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199969\n", "\n", "\n", "\n", "\n", "\n", "199973\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199973\n", "\n", "\n", "\n", "\n", "\n", "199978\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "199967->199978\n", "\n", "\n", "\n", "\n", "\n", "199639\n", "\n", " \n", "dice\n", "node score: 1.0000\n", "\n", "\n", "\n", "199967->199639\n", "\n", "\n", "\n", "\n", "\n", "199968\n", "\n", " \n", "spaghetti sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199968\n", "\n", "\n", "\n", "\n", "\n", "199980\n", "\n", " \n", "cook\n", "node score: 0.0000\n", "\n", "\n", "\n", "199967->199980\n", "\n", "\n", "\n", "\n", "\n", "199974\n", "\n", " \n", "cheese\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199974\n", "\n", "\n", "\n", "\n", "\n", "199976\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199976\n", "\n", "\n", "\n", "\n", "\n", "199977\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199977\n", "\n", "\n", "\n", "\n", "\n", "199970\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "199967->199970\n", "\n", "\n", "\n", "\n", "\n", "199975\n", "\n", " \n", "milk\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199975\n", "\n", "\n", "\n", "\n", "\n", "199972\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "199967->199972\n", "\n", "\n", "\n", "\n", "\n", "199979\n", "\n", " \n", "pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "199978->199979\n", "\n", "\n", "\n", "\n", "\n", "199640\n", "\n", " \n", "onion\n", "node score:1.0000\n", "\n", "\n", "\n", "199639->199640\n", "\n", "\n", "\n", "\n", "\n", "199981\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "199980->199981\n", "\n", "\n", "\n", "\n", "\n", "199982\n", "\n", " \n", "noodle\n", "node score:0.6667\n", "\n", "\n", "\n", "199981->199982\n", "\n", "\n", "\n", "\n", "\n", "199971\n", "\n", " \n", "tarragon\n", "node score:0.5000\n", "\n", "\n", "\n", "199970->199971\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.4488968633705475" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * milk\n", " * olive oil\n", " * spaghetti sauce\n", " * pepper\n", " * tarragon\n", " * cheese\n", " * onion\n", " * noodle\n", " * ground beef\n", " * sausage\n", " * salt\n", " * chicken broth\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | heat and cook noodle |\n", "| 2 | chop pepper, dice onion, chop tarragon and mix it with olive oil, chicken broth, spaghetti sauce, cheese, sausage, salt, milk and ground beef and mix it together with the results of step 1. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "192203\n", "\n", " \n", "heat\n", "node score: 0.9231\n", "\n", "\n", "\n", "192204\n", "\n", " \n", "mix\n", "node score: 0.4872\n", "\n", "\n", "\n", "192203->192204\n", "\n", "\n", "\n", "\n", "\n", "192207\n", "\n", " \n", "grate\n", "node score: 1.0000\n", "\n", "\n", "\n", "192204->192207\n", "\n", "\n", "\n", "\n", "\n", "192211\n", "\n", " \n", "soy sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192211\n", "\n", "\n", "\n", "\n", "\n", "192220\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192220\n", "\n", "\n", "\n", "\n", "\n", "192215\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192215\n", "\n", "\n", "\n", "\n", "\n", "192216\n", "\n", " \n", "chicken broth\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192216\n", "\n", "\n", "\n", "\n", "\n", "192222\n", "\n", " \n", "cool\n", "node score: 1.0000\n", "\n", "\n", "\n", "192204->192222\n", "\n", "\n", "\n", "\n", "\n", "192144\n", "\n", " \n", "salt\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192144\n", "\n", "\n", "\n", "\n", "\n", "192209\n", "\n", " \n", "chop\n", "node score: 1.0000\n", "\n", "\n", "\n", "192204->192209\n", "\n", "\n", "\n", "\n", "\n", "192217\n", "\n", " \n", "basil\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192217\n", "\n", "\n", "\n", "\n", "\n", "192219\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192219\n", "\n", "\n", "\n", "\n", "\n", "192205\n", "\n", " \n", "shrimp\n", "node score:0.5000\n", "\n", "\n", "\n", "192204->192205\n", "\n", "\n", "\n", "\n", "\n", "192218\n", "\n", " \n", "red pepper\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192218\n", "\n", "\n", "\n", "\n", "\n", "192214\n", "\n", " \n", "mushroom soup\n", "node score:1.0000\n", "\n", "\n", "\n", "192204->192214\n", "\n", "\n", "\n", "\n", "\n", "192208\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "192207->192208\n", "\n", "\n", "\n", "\n", "\n", "192212\n", "\n", " \n", "peel\n", "node score: 1.0000\n", "\n", "\n", "\n", "192222->192212\n", "\n", "\n", "\n", "\n", "\n", "192213\n", "\n", " \n", "garlic clove\n", "node score:1.0000\n", "\n", "\n", "\n", "192212->192213\n", "\n", "\n", "\n", "\n", "\n", "192210\n", "\n", " \n", "parsley\n", "node score:1.0000\n", "\n", "\n", "\n", "192209->192210\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.4467455621301775" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * soy sauce\n", " * garlic clove\n", " * ground beef\n", " * noodle\n", " * carrot\n", " * basil\n", " * red pepper\n", " * sausage\n", " * salt\n", " * mushroom soup\n", " * chicken broth\n", " * shrimp\n", " * parsley\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | peel and cool garlic clove |\n", "| 2 | grate carrot, chop parsley and mix it with soy sauce, noodle, ground beef, chicken broth, salt, basil, sausage, shrimp, red pepper and mushroom soup and mix it together with the results of step 1. Then heat it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "197023\n", "\n", " \n", "cook\n", "node score: 1.0000\n", "\n", "\n", "\n", "197024\n", "\n", " \n", "mix\n", "node score: 0.5455\n", "\n", "\n", "\n", "197023->197024\n", "\n", "\n", "\n", "\n", "\n", "197032\n", "\n", " \n", "apple cider\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197032\n", "\n", "\n", "\n", "\n", "\n", "197030\n", "\n", " \n", "onion\n", "node score:0.5000\n", "\n", "\n", "\n", "197024->197030\n", "\n", "\n", "\n", "\n", "\n", "197031\n", "\n", " \n", "seasoning\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197031\n", "\n", "\n", "\n", "\n", "\n", "197034\n", "\n", " \n", "peel\n", "node score: 1.0000\n", "\n", "\n", "\n", "197024->197034\n", "\n", "\n", "\n", "\n", "\n", "197033\n", "\n", " \n", "ground beef\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197033\n", "\n", "\n", "\n", "\n", "\n", "197071\n", "\n", " \n", "water\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197071\n", "\n", "\n", "\n", "\n", "\n", "197028\n", "\n", " \n", "heat\n", "node score: 1.0000\n", "\n", "\n", "\n", "197024->197028\n", "\n", "\n", "\n", "\n", "\n", "197026\n", "\n", " \n", "tomato sauce\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197026\n", "\n", "\n", "\n", "\n", "\n", "197027\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197027\n", "\n", "\n", "\n", "\n", "\n", "197038\n", "\n", " \n", "noodle\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197038\n", "\n", "\n", "\n", "\n", "\n", "197025\n", "\n", " \n", "sausage\n", "node score:1.0000\n", "\n", "\n", "\n", "197024->197025\n", "\n", "\n", "\n", "\n", "\n", "197035\n", "\n", " \n", "carrot\n", "node score:1.0000\n", "\n", "\n", "\n", "197034->197035\n", "\n", "\n", "\n", "\n", "\n", "197029\n", "\n", " \n", "olive oil\n", "node score:1.0000\n", "\n", "\n", "\n", "197028->197029\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Recipe Score**: 0.44628099173553715" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "**Ingredients**:\n", " * olive oil\n", " * onion\n", " * ground beef\n", " * noodle\n", " * carrot\n", " * water\n", " * apple cider\n", " * seasoning\n", " * sausage\n", " * tomato sauce\n", "\n", "\n", "**Instructions**:\n", "\n", "| Step | Instruction |\n", "| ----:|:----------- |\n", "| 1 | peel carrot, heat olive oil and mix it with apple cider, onion, seasoning, ground beef, water, tomato sauce, olive oil, noodle and sausage. Then cook it. |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "p.plot_population(n_best=20)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "file_extension": ".py", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.5" }, "mimetype": "text/x-python", "name": "python", "npconvert_exporter": "python", "pygments_lexer": "ipython3", "version": 3 }, "nbformat": 4, "nbformat_minor": 4 }