{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Objective functions can optionally take in step, budget, and generations.\n", "\n", "step - The same objective function will be run for #evaluation_early_stop_steps, the current step will be passed into the function as an interger. (This is useful for getting a single fold of cross validation for example).\n", "\n", "budget - A parameter that varies over the course of the generations. Gets passed into the objective function as a float between 0 and 1. If the budget of the previous evaluation is less than the current budget, it will get re-evaluated. Useful for using smaller datasets earlier in training.\n", "\n", "generations - an int corresponding to the current generation number.\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b45777d6dffe4af3892ecc716ce12a64", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Generation: 0%| | 0/100 [00:00 1:\n", " self.subsets.update(random.sample(not_included, k=min(self.k, len(not_included))))\n", " return True\n", " else:\n", " return False\n", "\n", " def _mutate_remove(self,):\n", " if len(self.subsets) > 1:\n", " self.subsets = self.subsets - set(random.sample(list(self.subsets), k=min(self.k, len(self.subsets)-1) ))\n", "\n", " def _crossover_swap(self, ss2):\n", " diffs = self.subsets.symmetric_difference(ss2.subsets)\n", "\n", " if len(diffs) == 0:\n", " return False\n", " for v in diffs:\n", " self.subsets.discard(v)\n", " ss2.subsets.discard(v)\n", " random.choice([self.subsets, ss2.subsets]).add(v)\n", " \n", " return True\n", "\n", " def unique_id(self):\n", " return str(tuple(sorted(self.subsets)))\n", "\n", "def individual_generator():\n", " while True:\n", " yield SubsetSelector(values=np.arange(len(values)))\n", "\n", "\n", "values = np.random.randint(200,size=100)\n", "weights = np.random.random(200)*10\n", "max_weight = 50\n", "\n", "def simple_objective(ind, **kwargs):\n", " subset = np.array(list(ind.subsets))\n", " if len(subset) == 0:\n", " return 0, 0\n", "\n", " total_weight = np.sum(weights[subset])\n", " total_value = np.sum(values[subset])\n", "\n", " if total_weight > max_weight:\n", " total_value = 0\n", "\n", " return total_value, total_weight\n", "\n", "objective_names = [\"Value\", \"Weight\"]\n", "objective_function_weights = [1,-1]\n", "\n", "\n", "\n", "evolver = tpot2.BaseEvolver( individual_generator=individual_generator(), \n", " objective_functions=[simple_objective],\n", " objective_function_weights = objective_function_weights,\n", " bigger_is_better = True,\n", " population_size= 100,\n", " objective_names = objective_names,\n", " generations= 100,\n", " n_jobs=1,\n", " verbose = 1,\n", "\n", ")\n", "\n", "evolver.optimize()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "best subset {0, 1, 8, 12, 16, 17, 27, 33, 39, 40, 49, 60, 61, 62, 63, 68, 71, 72, 75, 80, 83, 88, 93, 94}\n", "Best value 3303.0, weight 49.904270360434694\n", "\n", "All results\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Selected IndexValueWeightParentsVariation_FunctionIndividualGeneration
0(12,)111.02.311217NaNNaN<__main__.SubsetSelector object at 0x7f8f6ab1b...0.0
1(4,)53.09.250839NaNNaN<__main__.SubsetSelector object at 0x7f8f679b8...0.0
2(49,)142.01.245016NaNNaN<__main__.SubsetSelector object at 0x7f8f6ab1a...0.0
3(41,)165.06.678665NaNNaN<__main__.SubsetSelector object at 0x7f8f6ab1a...0.0
4(52,)149.04.166724NaNNaN<__main__.SubsetSelector object at 0x7f8f6ab1a...0.0
........................
9995(0, 1, 8, 12, 16, 17, 27, 33, 39, 40, 48, 49, ...0.056.274519((0, 1, 8, 12, 16, 17, 27, 33, 39, 40, 49, 60,...mutate<__main__.SubsetSelector object at 0x7f8f67c93...99.0
9996(8, 27, 30, 33, 65, 80, 83, 94)871.011.654615((8, 27, 30, 33, 80, 83, 94),)mutate<__main__.SubsetSelector object at 0x7f8f67c93...99.0
9997(27, 48, 60, 80, 83, 94)764.010.725417((27, 33, 60, 80, 83, 94),)mutate<__main__.SubsetSelector object at 0x7f8f67c93...99.0
9998(8, 27, 30, 33, 58, 65, 80, 83, 94)924.020.673691((8, 27, 30, 33, 80, 83, 94),)mutate<__main__.SubsetSelector object at 0x7f8f67c93...99.0
9999(8, 17, 27, 29, 33, 68, 72, 80, 97)1098.010.477494((8, 17, 27, 29, 33, 68, 72, 80),)mutate<__main__.SubsetSelector object at 0x7f8f67c93...99.0
\n", "

10000 rows × 7 columns

\n", "
" ], "text/plain": [ " Selected Index Value Weight \\\n", "0 (12,) 111.0 2.311217 \n", "1 (4,) 53.0 9.250839 \n", "2 (49,) 142.0 1.245016 \n", "3 (41,) 165.0 6.678665 \n", "4 (52,) 149.0 4.166724 \n", "... ... ... ... \n", "9995 (0, 1, 8, 12, 16, 17, 27, 33, 39, 40, 48, 49, ... 0.0 56.274519 \n", "9996 (8, 27, 30, 33, 65, 80, 83, 94) 871.0 11.654615 \n", "9997 (27, 48, 60, 80, 83, 94) 764.0 10.725417 \n", "9998 (8, 27, 30, 33, 58, 65, 80, 83, 94) 924.0 20.673691 \n", "9999 (8, 17, 27, 29, 33, 68, 72, 80, 97) 1098.0 10.477494 \n", "\n", " Parents Variation_Function \\\n", "0 NaN NaN \n", "1 NaN NaN \n", "2 NaN NaN \n", "3 NaN NaN \n", "4 NaN NaN \n", "... ... ... \n", "9995 ((0, 1, 8, 12, 16, 17, 27, 33, 39, 40, 49, 60,... mutate \n", "9996 ((8, 27, 30, 33, 80, 83, 94),) mutate \n", "9997 ((27, 33, 60, 80, 83, 94),) mutate \n", "9998 ((8, 27, 30, 33, 80, 83, 94),) mutate \n", "9999 ((8, 17, 27, 29, 33, 68, 72, 80),) mutate \n", "\n", " Individual Generation \n", "0 <__main__.SubsetSelector object at 0x7f8f6ab1b... 0.0 \n", "1 <__main__.SubsetSelector object at 0x7f8f679b8... 0.0 \n", "2 <__main__.SubsetSelector object at 0x7f8f6ab1a... 0.0 \n", "3 <__main__.SubsetSelector object at 0x7f8f6ab1a... 0.0 \n", "4 <__main__.SubsetSelector object at 0x7f8f6ab1a... 0.0 \n", "... ... ... \n", "9995 <__main__.SubsetSelector object at 0x7f8f67c93... 99.0 \n", "9996 <__main__.SubsetSelector object at 0x7f8f67c93... 99.0 \n", "9997 <__main__.SubsetSelector object at 0x7f8f67c93... 99.0 \n", "9998 <__main__.SubsetSelector object at 0x7f8f67c93... 99.0 \n", "9999 <__main__.SubsetSelector object at 0x7f8f67c93... 99.0 \n", "\n", "[10000 rows x 7 columns]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "final_population_results = evolver.population.evaluated_individuals\n", "final_population_results.reset_index(inplace=True)\n", "final_population_results = final_population_results.rename(columns = {'index':'Selected Index'})\n", "\n", "best_idx = final_population_results[\"Value\"].idxmax()\n", "best_individual = final_population_results.loc[best_idx]['Individual']\n", "print(\"best subset\", best_individual.subsets)\n", "print(\"Best value {0}, weight {1}\".format(final_population_results.loc[best_idx, \"Value\"],final_population_results.loc[best_idx, \"Weight\"]))\n", "print()\n", "\n", "print(\"All results\")\n", "final_population_results" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from scipy.stats import binned_statistic_2d\n", "\n", "y = final_population_results[\"Value\"]\n", "x = final_population_results[\"Weight\"]\n", "c = final_population_results[\"Generation\"]\n", "\n", "x_bins = np.linspace(0, 100, 100)\n", "y_bins = np.linspace(0, 3000, 100)\n", "\n", "ret = binned_statistic_2d(x, y, c, statistic=np.mean, bins=[x_bins, y_bins])\n", "\n", "fig, ax1 = plt.subplots(1, 1, figsize=(12, 4))\n", "\n", "im = ax1.imshow(ret.statistic.T, origin='lower', extent=(0,100,0,3000), vmin=0, vmax=100, aspect=.03)\n", "ax1.set_xlabel(\"Weight\")\n", "ax1.set_ylabel(\"Value\")\n", "ax1.set_title(\"Binned Average Generation\")\n", "\n", "cbar = fig.colorbar(im,)\n", "cbar.set_label('Generation')\n", "plt.tight_layout()" ] } ], "metadata": { "kernelspec": { "display_name": "tpot_dev", "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.10.10" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "7fe1fe9ef32cd5efd76326a08046147513534f0dd2318301a1a96ae9071c1c4e" } } }, "nbformat": 4, "nbformat_minor": 2 }