{ "cells": [ { "cell_type": "markdown", "id": "34e40f04473a10fa", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "# UD05 · Notebook 4 — Reglas sobre datos: el Titanic\n", "\n", "En este ejercicio, utilizaremos los datos Titanic para predecir si un pasajero sobrevivió o no al naufragio.\n", "Veremos diferentes formas de hacerlo; con varios grados de automatismo." ] }, { "cell_type": "markdown", "id": "ec69289f113fc6a9", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "## Human Learn\n", "\n", "Human Learn es una librería que nos permite combinar el aprendizaje automático con el conocimiento humano de una manera simple." ] }, { "cell_type": "code", "execution_count": 1, "id": "64bef4a435fdd146", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:17:49.199438Z", "start_time": "2024-01-08T15:17:49.071191Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Cargamos las librerías y los datos" ] }, { "cell_type": "code", "execution_count": 2, "id": "614e3f256ed002c5", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:03.913737Z", "start_time": "2024-01-08T15:17:49.214884Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting git+https://github.com/koaning/human-learn.git\n", " Cloning https://github.com/koaning/human-learn.git to /tmp/pip-req-build-chdvtz20\n", " Running command git clone --filter=blob:none --quiet https://github.com/koaning/human-learn.git /tmp/pip-req-build-chdvtz20\n", " Resolved https://github.com/koaning/human-learn.git to commit ab961c200829a3270084fb1345eeea60623fa89d\n", " Installing build dependencies ... \u001b[?25ldone\n", "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", "\u001b[?25hCollecting scikit-learn>=0.23.2 (from human-learn==0.3.5)\n", " Downloading scikit_learn-1.7.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (11 kB)\n", "Collecting pandas>=0.23.4 (from human-learn==0.3.5)\n", " Downloading pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.metadata (91 kB)\n", "Collecting clumper<0.3.0,>=0.2.5 (from human-learn==0.3.5)\n", " Downloading clumper-0.2.15-py2.py3-none-any.whl.metadata (1.2 kB)\n", "Collecting Shapely>=1.7.1 (from human-learn==0.3.5)\n", " Downloading shapely-2.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (6.8 kB)\n", "Collecting bokeh<3.0.0,>=2.2.1 (from human-learn==0.3.5)\n", " Downloading bokeh-2.4.3-py3-none-any.whl.metadata (14 kB)\n", "Requirement already satisfied: Jinja2>=2.9 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (3.1.6)\n", "Requirement already satisfied: numpy>=1.11.3 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (1.23.5)\n", "Requirement already satisfied: packaging>=16.8 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (25.0)\n", "Requirement already satisfied: pillow>=7.1.0 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (12.0.0)\n", "Requirement already satisfied: PyYAML>=3.10 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (6.0.3)\n", "Requirement already satisfied: tornado>=5.1 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (6.5.2)\n", "Requirement already satisfied: typing-extensions>=3.10.0 in /usr/local/lib/python3.10/site-packages (from bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (4.15.0)\n", "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/site-packages (from Jinja2>=2.9->bokeh<3.0.0,>=2.2.1->human-learn==0.3.5) (3.0.3)\n", "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/site-packages (from pandas>=0.23.4->human-learn==0.3.5) (2.9.0.post0)\n", "Collecting pytz>=2020.1 (from pandas>=0.23.4->human-learn==0.3.5)\n", " Downloading pytz-2025.2-py2.py3-none-any.whl.metadata (22 kB)\n", "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/site-packages (from pandas>=0.23.4->human-learn==0.3.5) (2025.2)\n", "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/site-packages (from python-dateutil>=2.8.2->pandas>=0.23.4->human-learn==0.3.5) (1.17.0)\n", "Requirement already satisfied: scipy>=1.8.0 in /usr/local/lib/python3.10/site-packages (from scikit-learn>=0.23.2->human-learn==0.3.5) (1.15.3)\n", "Collecting joblib>=1.2.0 (from scikit-learn>=0.23.2->human-learn==0.3.5)\n", " Downloading joblib-1.5.2-py3-none-any.whl.metadata (5.6 kB)\n", "Collecting threadpoolctl>=3.1.0 (from scikit-learn>=0.23.2->human-learn==0.3.5)\n", " Downloading threadpoolctl-3.6.0-py3-none-any.whl.metadata (13 kB)\n", "Downloading bokeh-2.4.3-py3-none-any.whl (18.5 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m18.5/18.5 MB\u001b[0m \u001b[31m28.4 MB/s\u001b[0m \u001b[33m0:00:00\u001b[0mm0:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading clumper-0.2.15-py2.py3-none-any.whl (18 kB)\n", "Downloading pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (12.8 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m12.8/12.8 MB\u001b[0m \u001b[31m23.6 MB/s\u001b[0m \u001b[33m0:00:00\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading pytz-2025.2-py2.py3-none-any.whl (509 kB)\n", "Downloading scikit_learn-1.7.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (9.7 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m9.7/9.7 MB\u001b[0m \u001b[31m30.8 MB/s\u001b[0m \u001b[33m0:00:00\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading joblib-1.5.2-py3-none-any.whl (308 kB)\n", "Downloading shapely-2.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (3.1 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m32.4 MB/s\u001b[0m \u001b[33m0:00:00\u001b[0m\n", "\u001b[?25hDownloading threadpoolctl-3.6.0-py3-none-any.whl (18 kB)\n", "Building wheels for collected packages: human-learn\n", " Building wheel for human-learn (pyproject.toml) ... \u001b[?25ldone\n", "\u001b[?25h Created wheel for human-learn: filename=human_learn-0.3.5-py3-none-any.whl size=116523 sha256=383b213712406de6e8251e28373991ba0eddfa6db407a4256a53af613a014cc6\n", " Stored in directory: /tmp/pip-ephem-wheel-cache-t7brfw2y/wheels/84/81/6b/a9c7f40f0c7d485c35c319703ee16c9a3b0ae88f5bd49d8248\n", "Successfully built human-learn\n", "Installing collected packages: pytz, clumper, threadpoolctl, Shapely, joblib, scikit-learn, pandas, bokeh, human-learn\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m9/9\u001b[0m [human-learn]\u001b[0m [bokeh]]learn]]\n", "\u001b[1A\u001b[2KSuccessfully installed Shapely-2.1.2 bokeh-2.4.3 clumper-0.2.15 human-learn-0.3.5 joblib-1.5.2 pandas-2.3.3 pytz-2025.2 scikit-learn-1.7.2 threadpoolctl-3.6.0\n", "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\u001b[0m\u001b[33m\n", "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "# Instalamos la librería\n", "%pip install git+https://github.com/koaning/human-learn.git" ] }, { "cell_type": "code", "execution_count": 3, "id": "2dac3db4d659ca1f", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:05.182641Z", "start_time": "2024-01-08T15:18:03.922465Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Cargamos el Dataset\n", "from hulearn.datasets import load_titanic" ] }, { "cell_type": "code", "execution_count": 4, "id": "5bd4f161fba434c", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:05.249102Z", "start_time": "2024-01-08T15:18:05.190452Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
survivedpclassnamesexagefaresibspparch
003Braund, Mr. Owen Harrismale22.07.250010
111Cumings, Mrs. John Bradley (Florence Briggs Th...female38.071.283310
213Heikkinen, Miss. Lainafemale26.07.925000
311Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.053.100010
403Allen, Mr. William Henrymale35.08.050000
...........................
70903Rice, Mrs. William (Margaret Norton)female39.029.125005
71002Montvila, Rev. Juozasmale27.013.000000
71111Graham, Miss. Margaret Edithfemale19.030.000000
71211Behr, Mr. Karl Howellmale26.030.000000
71303Dooley, Mr. Patrickmale32.07.750000
\n", "

714 rows × 8 columns

\n", "
" ], "text/plain": [ " survived pclass name \\\n", "0 0 3 Braund, Mr. Owen Harris \n", "1 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... \n", "2 1 3 Heikkinen, Miss. Laina \n", "3 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) \n", "4 0 3 Allen, Mr. William Henry \n", ".. ... ... ... \n", "709 0 3 Rice, Mrs. William (Margaret Norton) \n", "710 0 2 Montvila, Rev. Juozas \n", "711 1 1 Graham, Miss. Margaret Edith \n", "712 1 1 Behr, Mr. Karl Howell \n", "713 0 3 Dooley, Mr. Patrick \n", "\n", " sex age fare sibsp parch \n", "0 male 22.0 7.2500 1 0 \n", "1 female 38.0 71.2833 1 0 \n", "2 female 26.0 7.9250 0 0 \n", "3 female 35.0 53.1000 1 0 \n", "4 male 35.0 8.0500 0 0 \n", ".. ... ... ... ... ... \n", "709 female 39.0 29.1250 0 5 \n", "710 male 27.0 13.0000 0 0 \n", "711 female 19.0 30.0000 0 0 \n", "712 male 26.0 30.0000 0 0 \n", "713 male 32.0 7.7500 0 0 \n", "\n", "[714 rows x 8 columns]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = load_titanic(as_frame=True)\n", "df" ] }, { "cell_type": "code", "execution_count": 5, "id": "66db6720acc24205", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:07.349465Z", "start_time": "2024-01-08T15:18:05.250047Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "from sklearn.model_selection import train_test_split\n", "\n", "# Preparamos los datos: separamos las variables explicativas de la variable de destino y creamos los conjuntos de entrenamiento y test\n", "X_train, X_test, y_train, y_test = train_test_split(\n", " df.drop(['name', 'survived'], axis=1), df['survived'], test_size=0.25, random_state=42)" ] }, { "cell_type": "markdown", "id": "1f1dbffad43c9454", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### Clasificación con una función\n", "\n", "En este primer ejemplo, utilizaremos una función para clasificar a los pasajeros. Es una función muy simple que clasifica a los pasajeros en función del precio del billete. El enfoque es que los pasajeros que más pagaban tenían más probabilidades de sobrevivir." ] }, { "cell_type": "code", "execution_count": 6, "id": "c093e50ea67fe78d", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:07.421935Z", "start_time": "2024-01-08T15:18:07.352723Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# FunctionClassifier nos permite crear un clasificador a partir de una función\n", "from hulearn.classification import FunctionClassifier" ] }, { "cell_type": "code", "execution_count": 7, "id": "86a28d1169e69845", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:07.465186Z", "start_time": "2024-01-08T15:18:07.426983Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/html": [ "
FunctionClassifier(func=<function classificador_preu_bitllet at 0x7f22d9fd49d0>)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "FunctionClassifier(func=)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Usaremos el FunctionClassifier Para crear un clasificador que use el precio del boleto para predecir si un pasajero sobrevivió o no\n", "\n", "def classificador_preu_bitllet(df, preu_minim=20):\n", " \"\"\"\n", " Clasificar a los pasajeros según el precio del billete\n", " El enfoque es que los pasajeros que más pagaban tenían más probabilidades de sobrevivir.\n", " El valor predeterminado es 20 pero podemos cambiarlo\n", " \"\"\"\n", " return (df['fare'] > preu_minim).astype(int)\n", "\n", "\n", "model = FunctionClassifier(classificador_preu_bitllet)\n", "\n", "# Preparem el classificador\n", "model.fit(X_train, y_train)" ] }, { "cell_type": "markdown", "id": "984bf10e4fecf755", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### Evaluamos el clasificador" ] }, { "cell_type": "code", "execution_count": 8, "id": "67b13f6674f19d79", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:07.541807Z", "start_time": "2024-01-08T15:18:07.455471Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 0.73 0.69 0.71 107\n", " 1 0.57 0.61 0.59 72\n", "\n", " accuracy 0.66 179\n", " macro avg 0.65 0.65 0.65 179\n", "weighted avg 0.66 0.66 0.66 179\n", "\n" ] } ], "source": [ "from sklearn.metrics import classification_report\n", "\n", "print(classification_report(y_test, model.predict(X_test)))" ] }, { "cell_type": "markdown", "id": "108415d7eecd00b5", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "El rendimiento del clasificador es bastante malo. Seguramente el precio del boleto no es una buena variable para predecir si un pasajero sobrevivió o no. Aun así, intentaremos mejorar su rendimiento de refinación el parámetro de precio_minim.\n", "\n", "Usaremos GridSearchCV para encontrar el mejor valor para Price_Minim. GridSearchCV nos permite hacer una búsqueda de cuadrícula para encontrar los mejores parámetros, la puntuación será dada por la exactitud (Accuracy), la precisión (Precision) y la sensibilidad (Recall).\n", "\n", "- **Accuracy**: ¿Cuántas predicciones son correctas?\n", "- **Precision**: ¿Cuántas predicciones positivas son correctas?\n", "- **Recall**: ¿Cuántas predicciones positivas son correctas de todos los aspectos positivos?" ] }, { "cell_type": "code", "execution_count": 9, "id": "c52b1eab0c9699a5", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:08.323493Z", "start_time": "2024-01-08T15:18:07.517718Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 0.66 0.93 0.77 107\n", " 1 0.74 0.28 0.40 72\n", "\n", " accuracy 0.67 179\n", " macro avg 0.70 0.61 0.59 179\n", "weighted avg 0.69 0.67 0.62 179\n", "\n" ] } ], "source": [ "import numpy as np\n", "from sklearn.metrics import make_scorer, accuracy_score, precision_score, recall_score\n", "from sklearn.model_selection import GridSearchCV\n", "\n", "# Creamos un clasificador con un precio mínimo de 20\n", "mod = FunctionClassifier(classificador_preu_bitllet, preu_minim=20)\n", "\n", "# El objeto GridSearchCV nos permite hacer una búsqueda de cuadrícula para encontrar los mejores parámetros.\n", "# En este caso buscaremos el mejor precio mínimo para clasificar a los pasajeros\n", "grid = GridSearchCV(mod,\n", " cv=2,\n", " param_grid={'preu_minim': np.linspace(0, 100, 30)},\n", " scoring={'accuracy': make_scorer(accuracy_score),\n", " 'precision': make_scorer(precision_score),\n", " 'recall': make_scorer(recall_score)},\n", " refit='accuracy')\n", "grid.fit(X_train, y_train)\n", "\n", "print(classification_report(y_test, grid.predict(X_test)))" ] }, { "cell_type": "code", "execution_count": 10, "id": "589c41ab3121d4f7", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:08.393213Z", "start_time": "2024-01-08T15:18:08.312134Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/plain": [ "{'preu_minim': 48.275862068965516}" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Podemos ver cuál era el mejor precio mínimo\n", "grid.best_params_" ] }, { "cell_type": "markdown", "id": "6f547d25473021c", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### Exploración interactiva\n", "\n", "Ahora que hemos visto que el precio del boleto no es una buena variable para predecir si un pasajero sobrevivió o no, podemos explorar los datos para encontrar una mejor variable.\n", "\n", "Para hacer esto, utilizaremos la función Interactivecharts.Esta función nos permitirá explorar los datos de manera interactiva.En este caso, utilizaremos la función Parallel_Coordinates para ver cómo se distribuyen los datos en función de las variables explicativas." ] }, { "cell_type": "code", "execution_count": 11, "id": "a077f1c80f36068a", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:08.923285Z", "start_time": "2024-01-08T15:18:08.350618Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", " \n", "
\n" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from hulearn.experimental.interactive import parallel_coordinates\n", "\n", "parallel_coordinates(df, label=\"survived\", height=200)" ] }, { "cell_type": "markdown", "id": "e688464b6b92da50", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "Basado en la hipótesis de que las mujeres y los niños tenían más probabilidades de sobrevivir, podemos explorar datos para ver si es cierto y parece que sí (teniendo en cuenta las diferencias de clase social): si solo dejamos mujeres y niños en primera y segunda clase, la mayoría sobrevivió.\n", "\n", "Entonces podemos crear un clasificador que use el sexo, la edad y la clase del pasajero para predecir si sobrevivió o no." ] }, { "cell_type": "code", "execution_count": 12, "id": "85c6243fc0a6391a", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:08.930742Z", "start_time": "2024-01-08T15:18:08.922527Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/plain": [ "0.8212290502793296" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def classificador_edat_sexe_classe(df, edat=12):\n", " \"\"\"\n", " Clasificar a los pasajeros según el sexo, la edad y la clase de pasajeros\n", " El enfoque es que las mujeres y los niños tenían más probabilidades de sobrevivir\n", " \"\"\"\n", " regla_dones = (df['pclass'] < 3.0) & (df['sex'] == \"female\")\n", " regla_nens = (df['pclass'] < 3.0) & (df['age'] <= edat)\n", " return regla_dones | regla_nens\n", "\n", "\n", "mod = FunctionClassifier(classificador_edat_sexe_classe)\n", "mod.fit(X_train, y_train)\n", "mod.score(X_test, y_test)" ] }, { "cell_type": "code", "execution_count": 13, "id": "a826cdf8de70564b", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:10.508277Z", "start_time": "2024-01-08T15:18:08.941670Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'edat': 3.0612244897959187}\n", "649 False\n", "360 False\n", "518 False\n", "248 True\n", "344 False\n", " ... \n", "71 False\n", "106 False\n", "270 True\n", "435 False\n", "102 False\n", "Length: 535, dtype: bool\n", " precision recall f1-score support\n", "\n", " 0 0.76 0.97 0.86 107\n", " 1 0.93 0.56 0.70 72\n", "\n", " accuracy 0.80 179\n", " macro avg 0.85 0.76 0.78 179\n", "weighted avg 0.83 0.80 0.79 179\n", "\n" ] } ], "source": [ "grid = GridSearchCV(mod,\n", " cv=2,\n", " param_grid={'edat': np.linspace(0, 50, 50)},\n", " scoring={'accuracy': make_scorer(accuracy_score),\n", " 'precision': make_scorer(precision_score),\n", " 'recall': make_scorer(recall_score)},\n", " refit='accuracy')\n", "grid.fit(X_train, y_train)\n", "\n", "print(grid.best_params_)\n", "predict = grid.predict(X_train)\n", "\n", "print(predict)\n", "print(classification_report(y_test, grid.predict(X_test)))" ] }, { "cell_type": "markdown", "id": "dd396aace21094b9", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "Los números son lo mucho mejores que los anteriores. Por lo tanto, podemos usar este clasificador para hacer predicciones en nuevos pasajeros." ] }, { "cell_type": "markdown", "id": "644b4776983453ff", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "## FIGS\n", "\n", "FIGS Es una librería que nos permite crear reglas para clasificar los datos.En este caso, utilizaremos los datos Titanic para crear reglas que nos permitan predecir si un pasajero sobrevivió o no." ] }, { "cell_type": "code", "execution_count": 14, "id": "d80fc18bfa3eb3ad", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:15.756337Z", "start_time": "2024-01-08T15:18:10.503242Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting imodels\n", " Downloading imodels-2.0.3-py3-none-any.whl.metadata (29 kB)\n", "Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/site-packages (from imodels) (3.10.7)\n", "Collecting mlxtend (from imodels)\n", " Downloading mlxtend-0.23.4-py3-none-any.whl.metadata (7.3 kB)\n", "Requirement already satisfied: numpy in /usr/local/lib/python3.10/site-packages (from imodels) (1.23.5)\n", "Requirement already satisfied: pandas in /usr/local/lib/python3.10/site-packages (from imodels) (2.3.3)\n", "Requirement already satisfied: requests in /usr/local/lib/python3.10/site-packages (from imodels) (2.32.5)\n", "Requirement already satisfied: scipy in /usr/local/lib/python3.10/site-packages (from imodels) (1.15.3)\n", "Requirement already satisfied: scikit-learn in /usr/local/lib/python3.10/site-packages (from imodels) (1.7.2)\n", "Collecting tqdm (from imodels)\n", " Downloading tqdm-4.67.1-py3-none-any.whl.metadata (57 kB)\n", "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (1.3.2)\n", "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (0.12.1)\n", "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (4.60.1)\n", "Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (1.4.9)\n", "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (25.0)\n", "Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (12.0.0)\n", "Requirement already satisfied: pyparsing>=3 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (3.2.5)\n", "Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/site-packages (from matplotlib->imodels) (2.9.0.post0)\n", "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib->imodels) (1.17.0)\n", "Requirement already satisfied: joblib>=0.13.2 in /usr/local/lib/python3.10/site-packages (from mlxtend->imodels) (1.5.2)\n", "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/site-packages (from pandas->imodels) (2025.2)\n", "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/site-packages (from pandas->imodels) (2025.2)\n", "Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.10/site-packages (from scikit-learn->imodels) (3.6.0)\n", "Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.10/site-packages (from requests->imodels) (3.4.4)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/site-packages (from requests->imodels) (3.11)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/site-packages (from requests->imodels) (2.5.0)\n", "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/site-packages (from requests->imodels) (2025.11.12)\n", "Downloading imodels-2.0.3-py3-none-any.whl (274 kB)\n", "Downloading mlxtend-0.23.4-py3-none-any.whl (1.4 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m17.9 MB/s\u001b[0m \u001b[33m0:00:00\u001b[0m\n", "\u001b[?25hDownloading tqdm-4.67.1-py3-none-any.whl (78 kB)\n", "Installing collected packages: tqdm, mlxtend, imodels\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3/3\u001b[0m [imodels]m2/3\u001b[0m [imodels]\n", "\u001b[1A\u001b[2KSuccessfully installed imodels-2.0.3 mlxtend-0.23.4 tqdm-4.67.1\n", "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\u001b[0m\u001b[33m\n", "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "# Instalamos la librería\n", "%pip install imodels" ] }, { "cell_type": "code", "execution_count": 15, "id": "de740ee4c575fdc9", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:17.007541Z", "start_time": "2024-01-08T15:18:15.762238Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Cargamos la librería\n", "from imodels import FIGSClassifier" ] }, { "cell_type": "code", "execution_count": 16, "id": "d080536d129ef89b", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:17.057589Z", "start_time": "2024-01-08T15:18:17.015147Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_384/94841749.py:3: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", " X_skope['sex'] = X_skope['sex'].replace(['female', 'male'], [0, 1])\n" ] } ], "source": [ "# Preparamos los datos\n", "X_skope = df.drop(columns=['name', 'sibsp'])\n", "X_skope['sex'] = X_skope['sex'].replace(['female', 'male'], [0, 1])\n", "\n", "X_train, X_test, y_train, y_test = train_test_split(\n", " X_skope.drop(['survived'], axis=1), X_skope['survived'], test_size=0.25, random_state=42)" ] }, { "cell_type": "code", "execution_count": 17, "id": "57a655d7ac877efa", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:17.110449Z", "start_time": "2024-01-08T15:18:17.048375Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/html": [ "
> ------------------------------\n",
       "> FIGS-Fast Interpretable Greedy-Tree Sums:\n",
       "> \tPredictions are made by summing the "Val" reached by traversing each tree.\n",
       "> \tFor classifiers, a softmax function is then applied to the sum.\n",
       "> ------------------------------\n",
       "sex <= 0.500 (Tree #0 root)\n",
       "\tpclass <= 2.500 (split)\n",
       "\t\tVal: 0.051 0.949 (leaf)\n",
       "\t\tVal: 0.506 0.494 (leaf)\n",
       "\tpclass <= 1.500 (split)\n",
       "\t\tVal: 0.608 0.392 (leaf)\n",
       "\t\tVal: 0.856 0.144 (leaf)\n",
       "\n",
       "\t+\n",
       "age <= 1.500 (Tree #1 root)\n",
       "\tVal: -0.631 0.631 (leaf)\n",
       "\tVal: 0.016 -0.016 (leaf)\n",
       "
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "FIGSClassifier(max_rules=4)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creamos el clasificador\n", "clf = FIGSClassifier(max_rules=4)\n", "# Entrenamos el clasificador\n", "clf.fit(X_train, y_train)" ] }, { "cell_type": "code", "execution_count": 18, "id": "d328fd73de9e804", "metadata": { "ExecuteTime": { "end_time": "2024-01-08T15:18:17.151056Z", "start_time": "2024-01-08T15:18:17.119888Z" }, "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 0.76 0.96 0.85 107\n", " 1 0.91 0.54 0.68 72\n", "\n", " accuracy 0.79 179\n", " macro avg 0.83 0.75 0.76 179\n", "weighted avg 0.82 0.79 0.78 179\n", "\n" ] } ], "source": [ "# Podem veure el rendiment del classificador\n", "print(classification_report(y_test, clf.predict(X_test)))" ] }, { "cell_type": "markdown", "id": "d21ca1f154042daa", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "Podemos ver que las reglas creadas por el clasificador tienen un rendimiento similar al clasificador que hemos creado con Human Learn y los conceptos que hemos creado con Human Learn son más fáciles de interpretar y podemos continuar agregando reglas para mejorar el rendimiento del clasificador (por ejemplo, podríamos incorporar la variable `fare`(tarifa))." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.19" } }, "nbformat": 4, "nbformat_minor": 5 }