{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "```{admonition} Information\n", "__Section__: Attributes selection \n", "__Goal__: Understand which attributes can be useful, useless or even prejudicial for prediction. \n", "__Time needed__: 20 min \n", "__Prerequisites__: AIS data, basics about machine learning\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Attributes selection" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For this section, we will see how the selection of the predictive attributes can lead to very different results in the prediction.\n", "\n", "Again, you are asked to build a model to predict the width of a ship. You can use any numerical attribute in the dataset. The static dataset is used here." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%run 1-functions.ipynb # this line runs the other functions we will use later on the page\n", "\n", "import pandas as pd\n", "\n", "static_data = pd.read_csv('./static_data.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The attributes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, let's have a look at the list of the numerical attributes we can use in the dataset." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{toggle} Advanced level\n", "We use the function [select_dtypes()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.select_dtypes.html) and the type ``np.number`` from the [numpy](https://docs.scipy.org/doc/numpy/reference/) library, which allows us to select all columns that are numerical.\n", "```" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "tags": [ "hide-input" ] }, "outputs": [ { "data": { "text/plain": [ "Index(['TripID', 'MMSI', 'MeanSOG', 'VesselType', 'Length', 'Width', 'Draft',\n", " 'Cargo', 'DepLat', 'DepLon', 'ArrLat', 'ArrLon'],\n", " dtype='object')" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "static_data.select_dtypes([np.number]).columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we will build a model to predict the ``Width`` attribute, from a combination of these attributes. Change the value of the variable ``x`` as much as possible, adding more or less of the numerical attributes, and compare the results in the prediction.\n", "\n", "Try to find the combination of attributes that gives the best performance, and the one that gives the worst performance." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "hide-input", "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MAE: 4.929193421052632\n" ] } ], "source": [ "from sklearn.metrics import mean_absolute_error\n", "\n", "x = ['Length', 'TripID', 'MMSI']\n", "y = ['Width']\n", "\n", "predictions, ytest = knn_regression(static_data, x, y)\n", "print('MAE: ' + str(mean_absolute_error(predictions, ytest)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Beginner version:__\n", "Use the following widget and add or remove attributes to the predictive model. The first attribute is necessary, the other ones are optional. Try to find out which model gives the best prediction, and which one gives the worst." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "tags": [ "hide-input" ] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8938a035fbb949748119f6d7ca0778ec", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(Dropdown(description='x = [Att 1:', options=('TripID', 'MMSI', 'MeanSOG', 'VesselType', …" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# For beginner version: cell to hide\n", "\n", "import numpy as np\n", "from sklearn.metrics import mean_absolute_error\n", "import ipywidgets as widgets\n", "from ipywidgets import interact\n", "\n", "attributes = []\n", "attributes.append('')\n", "for att in static_data.select_dtypes([np.number]).columns:\n", " attributes.append(att)\n", "\n", "def mae_pred(att1, att2, att3, att4, att5):\n", " \n", " x = []\n", " for att in [att1, att2, att3, att4, att5]:\n", " if att != '':\n", " x.append(att) \n", " y = ['Width']\n", "\n", " predictions, ytest = knn_regression(static_data, x, y)\n", " print('MAE: ' + str(mean_absolute_error(predictions, ytest)))\n", "\n", "interact(mae_pred,\n", " att1 = widgets.Dropdown(options = static_data.select_dtypes([np.number]).columns,\n", " value = static_data.select_dtypes([np.number]).columns[0],\n", " description = 'x = [Att 1:',\n", " disabled = False,),\n", " att2 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 2 (opt):',\n", " disabled = False,),\n", " att3 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 3 (opt):',\n", " disabled = False,),\n", " att4 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 4 (opt):',\n", " disabled = False,),\n", " att5 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 5 (opt)]:',\n", " disabled = False,))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Compare the performances" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can plot the predictions made according to the value of ``x``, to better gauge the performance of the model built:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "tags": [ "hide-input", "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MAE: 4.929193421052632\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "from sklearn.metrics import mean_absolute_error\n", "\n", "x = ['Length', 'TripID', 'MMSI']\n", "y = ['Width']\n", "\n", "predictions, ytest = knn_regression(static_data, x, y)\n", "print('MAE: ' + str(mean_absolute_error(predictions, ytest)))\n", "\n", "plt.figure(figsize = (12, 8))\n", "pred = []\n", "for element in predictions:\n", " pred.append(element[0])\n", "plt.plot(pred, ytest, 'x')\n", " \n", "x = np.linspace(0, 50, 50)\n", "plt.plot(x, x, color = 'black')\n", " \n", "plt.xlabel('Prediction')\n", "plt.ylabel('True label')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "tags": [ "hide-input" ] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6293fc0554d84887ba7bdc2701c9c9bd", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(Dropdown(description='x = [Att 1:', options=('TripID', 'MMSI', 'MeanSOG', 'VesselType', …" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# For beginner version: cell to hide\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from sklearn.metrics import mean_absolute_error\n", "import ipywidgets as widgets\n", "from ipywidgets import interact\n", "\n", "attributes = []\n", "attributes.append('')\n", "for att in static_data.select_dtypes([np.number]).columns:\n", " attributes.append(att)\n", "\n", "def plot_pred(att1, att2, att3, att4, att5):\n", " \n", " plt.figure(figsize = (12, 8))\n", " \n", " x = []\n", " title = 'Prediction of Width from '\n", " for att in [att1, att2, att3, att4, att5]:\n", " if att != '':\n", " x.append(att)\n", " title = title + str(att) + ' '\n", " \n", " y = ['Width']\n", "\n", " predictions, ytest = knn_regression(static_data, x, y)\n", " print('MAE: ' + str(mean_absolute_error(predictions, ytest)))\n", " \n", " pred = []\n", " for element in predictions:\n", " pred.append(element[0])\n", " plt.plot(pred, ytest, 'x')\n", " \n", " x = np.linspace(0, 50, 50)\n", " plt.plot(x, x, color = 'black')\n", " \n", " plt.xlabel('Prediction')\n", " plt.ylabel('True label')\n", " plt.title(title)\n", "\n", "interact(plot_pred,\n", " att1 = widgets.Dropdown(options = static_data.select_dtypes([np.number]).columns,\n", " value = static_data.select_dtypes([np.number]).columns[0],\n", " description = 'x = [Att 1:',\n", " disabled = False,),\n", " att2 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 2 (opt):',\n", " disabled = False,),\n", " att3 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 3 (opt):',\n", " disabled = False,),\n", " att4 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 4 (opt):',\n", " disabled = False,),\n", " att5 = widgets.Dropdown(options = attributes,\n", " value = attributes[0],\n", " description = '+ Att 5 (opt)]:',\n", " disabled = False,))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare the following predictive models:\n", "+ only ``Length``\n", "+ ``Length`` and ``MMSI``\n", "+ only ``MMSI``\n", "+ only ``TripID``\n", "\n", "As you can imagine, the attribute ``TripID``, having been artificially created only for organisation purpose, makes no sense in predicting the width of the ship. It is no surprising that it gives the worst performance.\n", "The attribute ``Length`` is the best attribute to predict the width, which seems normal: by construction, the length and the width of a ship have to be more or less proportional. However, we see that adding the ``MMSI`` to the ``Length`` attribute pollutes the model and gives a worse performance.\n", "\n", "In fact, when we remove the ``Length`` attribute, the prediction doesn't change: the ``MMSI`` attribute takes all the lead on the ``Length`` attribute for the prediction. This last point is mainly due to the model used, the KNN model being sensitive to the scale of the attributes (and ``MMSI`` is a very high number compared to ``Length``). But the choice of the model is outside of the scope of the course." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generalization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In general, it is important to carefully consider which attributes are chosen for the prediction: more attributes means more information, but it doesn't necessarily lead to better result, as the added information can be useless or even prejudicial for the prediction.\n", "\n", "The attributes such as ``TripID``, ``MMSI`` or ``VesselTypes`` represent a code: they are not continuous variables, and as a consequence, should not be used a numerical attributes. If we used them as numerical attributes, we would give a meaning to their value (in the sense: a lower value means something different than a higher value), when in the real world, they are just codes: two close values of these attributes don't necessarily imply a close meaning, like it is the case for continuous variables, where two instances with close values for length can mean close values for width." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Quiz" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [ "hide-input" ] }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import IFrame\n", "IFrame(\"https://h5p.org/h5p/embed/761741\", \"694\", \"600\")" ] } ], "metadata": { "celltoolbar": "Edit Metadata", "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.1" }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }