{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "u5so2A-18pH9" }, "source": [ "## 1 - Regresion Lineal\n", "\n", "Como vimos en el curso, la regresion lineal es una tecnica de **modelado predictivo** que encuentra relaciones entre variables independientes $x_i$, que pueden ser *categoricas* (e.g. \"Bueno\", \"Intermedio\", \"Malo\") o *continuas* (24, 3.14, etc), y predice una **respuesta $y$ continua**.\n", "\n", "Las tecnicas de regresion son ampliamente usadas para prediccion y modelado de series temporales, y un ejemplo es la prediccion del progreso de una enfermedad.\n", "\n", "### Diabetes dataset\n", "\n", "Esta base de datos contiene registros individuales de n = 442 pacientes con diabetes, así como la respuesta de interés: una **medida cuantitativa de la progresión de la enfermedad** un año después del inicio. El registro consiste en **diez mediciones características**: edad, sexo, índice de masa corporal, presión arterial promedio y seis mediciones de suero sanguíneo. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "O2b8gVz7y6X0" }, "outputs": [], "source": [ "# Como siempre, comenzamos importando los paquetes necesarios\n", "\n", "import numpy as np # paquete con funcionalidades matemáticas\n", "import pandas as pandas # paquete que permite manipular datos con formato de tabla\n", "from pandas import plotting as pandas_plot # funciones para graficar datos de tablas\n", "import matplotlib.pyplot as plt # funciones generales para graficar\n", "from sklearn.model_selection import train_test_split # separación de datos en entrenamiento y validación\n", "from sklearn.linear_model import LinearRegression,Ridge,Lasso # modelos para calcular regresión lineal\n", "from sklearn.metrics import mean_squared_error, r2_score # funciones para medir rendimiento de la regresión\n", "import seaborn as sns" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Cargar set de datos\n", "from sklearn.datasets import load_diabetes\n", "\n", "dataset = load_diabetes() \n", "print(dataset.keys())\n", "print('Features:', dataset.feature_names)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nZYebPLL8VO4" }, "outputs": [], "source": [ "# Como con Iris, podemos imprimir informacion sobre el dataset,\n", "# incluyendo cuales son las 10 caracteristicas\n", "print('Descripción:\\n',dataset['DESCR'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "vafz-11c5eyj" }, "outputs": [], "source": [ "X, y = dataset.data, dataset.target\n", "n,m = X.shape\n", "# Imprimimos informacion sobre el dataset\n", "print(f\"datos: {n} muestras de dimensión {m} cada una.\")\n", "print(dataset.keys())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "h3Y8PWVm5wRg" }, "outputs": [], "source": [ "from sklearn.preprocessing import StandardScaler\n", "\n", "# Obtenemos los datos para entrenar\n", "caracteristicas = dataset['feature_names']\n", "muestras = dataset['data']\n", "etiquetas = dataset['target']\n", "\n", "# Separamos el dataset en un conjunto de entrenamiento y otro de testeo\n", "Xtrain, Xtest, ytrain, ytest = train_test_split(muestras, etiquetas, random_state=42)\n", "\n", "standarize = True # Estandarizar o no los datos\n", "\n", "if standarize:\n", " scaler = StandardScaler()\n", " Xtrain = scaler.fit_transform(Xtrain) # Estandarizar con datos train\n", " Xtest = scaler.transform(Xtest) # Aplicar estandarización a datos test" ] }, { "cell_type": "markdown", "metadata": { "id": "r9x5fOga9PLm" }, "source": [ "Otra forma de visualizar un set de datos con muchas variables es usando una matriz de correlación, donde cada cuadrado muestra la correlación entre dos variables. Abajo tiene el código para imprimir una matriz de correlación, para el Diabetes dataset, incluyendo la variable que queremos predecir, el progreso de la enfermedad." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "s2j65iOZ8w_1" }, "outputs": [], "source": [ "# llevamos el dataset a un dataframe de pandas\n", "data_view = pandas.DataFrame(Xtrain, columns=dataset.feature_names)\n", "# agregamos el valor del progreso de diabetes, que es nuestro target\n", "data_view['disease_prog'] = ytrain\n", "\n", "# calculamos la matriz de correlacion con .corr()\n", "# .round(2) redondea a dos cifras significativas\n", "matriz_correlacion = data_view.corr().round(2)\n", "# annot = True imprime los valores adentro de las celdas\n", "plt.figure(figsize=(10,10))\n", "sns.heatmap(data=matriz_correlacion, annot=True, cmap=\"RdBu\")" ] }, { "cell_type": "markdown", "metadata": { "id": "7tZ44Hs7pzqO" }, "source": [ "Analizando la matriz de correlación, ¿qué características piensa pueden ser útiles para predecir la progresión? ¿Porqué? ¿Da lo mismo una correlación muy positiva que una muy negativa?" ] }, { "cell_type": "markdown", "metadata": { "id": "lJa9GxvAqtRa" }, "source": [ "*Puede insertar su respuesta aquí:*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se propone una manera de visualizacion de los datos:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "c8aGNXU7-zHh" }, "outputs": [], "source": [ "# Seleccione las variables que quiera usar para ajustar el modelo\n", "# Recuerde que las variables posibles son:\n", "# ['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']\n", "#\n", "variablesUsadas = ['age', 's5']\n", "\n", "\n", "# Extraemos los índices de las columnas que corresponden a esos nombres, usando list comprehensions\n", "indicesUsados = [i for i, val in enumerate(caracteristicas) if val in variablesUsadas]\n", "\n", "# Con los índices, armamos Xtrain y Xtest incompletos, con sólo las columnas especificadas\n", "Xtrain_inc = Xtrain[:,indicesUsados]\n", "Xtest_inc = Xtest[:,indicesUsados]\n", "#\n", "# Y graficamos un scatter plot de las variables a utilizar\n", "plt.figure(figsize=(20, 5))\n", "for i, col in enumerate(indicesUsados):\n", " plt.subplot(1, len(indicesUsados) , i+1)\n", " x = Xtrain[:,col]\n", " y = ytrain\n", " plt.scatter(x, y, marker='o')\n", " plt.title(caracteristicas[col])\n", " plt.xlabel(caracteristicas[col])\n", " plt.ylabel('disease_prog')" ] }, { "cell_type": "markdown", "metadata": { "id": "UrVmSSRwqnhk" }, "source": [ "Luego de haber observado un poco los datos con los que vamos a trabajar, procedemos a entrenar un modelo de la misma manera que en los otros notebooks.\n", "\n", "Aquí se utilizará como métrica de desempeño el [coeficiente de determinación](https://es.wikipedia.org/wiki/Coeficiente_de_determinaci%C3%B3n) $R^2$ [implementado por sklearn](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.r2_score.html)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "JvaXvvoXGk95" }, "outputs": [], "source": [ "# Entrenamos el modelo con las variables seleccionadas y medimos el rendimiento\n", "#\n", "# Primero definimos nuestro modelo de regresión lineal\n", "lr_inc = LinearRegression()\n", "#\n", "# Luego lo ajustamos a los las columnas seleccionadas (note que usamos Xtrain_inc en lugar de Xtrain)\n", "lr_inc.fit(Xtrain_inc, ytrain)\n", "#\n", "# Y finalmente, obtenemos las métricas de evaluación para el set de entrenamiento y de testeo y las imprimimos:\n", "#\n", "# evaluacion modelo sobre los datos de entrenamiento\n", "ytrain_predict = lr_inc.predict(Xtrain_inc)\n", "r2_train = r2_score(ytrain, ytrain_predict)\n", "# evaluacion del modelo sobre los datos de testeo\n", "ytest_predict = lr_inc.predict(Xtest_inc)\n", "r2_test = r2_score(ytest, ytest_predict)\n", "#\n", "print( f\"R2 en training set es {r2_train:5.3f}, y en el test set es de {r2_test:6.3f}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "m4l2x1iGuDtQ" }, "source": [ "El seleccionar qué variables son relevantes según nuestras expectativas, en lugar de usar todos los datos disponibles, puede ser una forma de prevenir el overfitting. Veamos que pasa si ajustamos la regresión lineal usando todas las variables, en lugar de las seleccionadas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "x2KsREovJXbW" }, "outputs": [], "source": [ "# Ajustamos una regresión a todas las columnas\n", "\n", "# Primero definimos nuestro modelo\n", "lr = LinearRegression()\n", "\n", "# Luego lo ajustamos a todos los datos\n", "Xtrain_inc = Xtrain\n", "Xtest_inc = Xtest\n", "\n", "lr.fit(Xtrain, ytrain)\n", "\n", "# Obtenemos las métricas de evaluación para el set de entrenamiento y de testeo y las imprimimos:\n", "# evaluacion modelo sobre los datos de entrenamiento\n", "ytrain_predict = lr.predict(Xtrain)\n", "r2_train = r2_score(ytrain, ytrain_predict)\n", "# evaluacion del modelo sobre los datos de testeo\n", "ytest_predict = lr.predict(Xtest) \n", "r2_test = r2_score(ytest, ytest_predict) \n", "#\n", "print( f\"Usando todas las columnas, R2 en training set es {r2_train:5.3f}, y en el test set es de {r2_test:6.3f}\" )" ] }, { "cell_type": "markdown", "metadata": { "id": "a0dJab73u2-R" }, "source": [ "¿Cómo cambia el rendimiento entre usar sólo las columnas seleccionadas o usarlas todas? ¿Qué concluye? ¿Piensa que este resultado podría cambiar si tuvieramos muchos menos datos?" ] }, { "cell_type": "markdown", "metadata": { "id": "0g678vzqvHNV" }, "source": [ "*Puede insertar su respuesta aquí:*" ] }, { "cell_type": "markdown", "metadata": { "id": "jpp8cMgM7qWY" }, "source": [ "Una forma más \"automática\" de elegir qué variables son relevantes para la regresión es mediante el uso de regularización. Intente mejorar el rendimiento del modelo aplicando una regresión de Ridge, y otra regreson de Lasso." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "4fKLhV7jyLfb" }, "outputs": [], "source": [ "# Primero defina el modelo de Ridge\n", "# al final donde se muestra la regularización. Note que debe elegir el valor\n", "# del parámetro de regularización.\n", "#\n", "modeloRidge = Ridge(alpha=100) \n", "#\n", "# Luego ajuste el modelo definido a los datos de todas las columnas\n", "modeloRidge.fit(Xtrain, ytrain) \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Ahora haga lo mismo pero para un modelo tipo Lasso\n", "modeloLasso = Lasso(alpha=1)\n", "modeloLasso.fit(Xtrain, ytrain)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9RUQYIxt2u96" }, "outputs": [], "source": [ "# Evaluamos el rendimiento de los modelos\n", "\n", "# Evaluación Ridge:\n", "ytrain_predict_ridge = modeloRidge.predict(Xtrain)\n", "r2_train_ridge = r2_score(ytrain, ytrain_predict_ridge)\n", "\n", "# evaluacion del modelo sobre los datos de testeo\n", "ytest_predict_ridge = modeloRidge.predict(Xtest)\n", "r2_test_ridge = r2_score(ytest, ytest_predict_ridge)\n", "\n", "# Evaluación LASSO\n", "ytrain_predict_lasso = modeloLasso.predict(Xtrain)\n", "r2_train_lasso = r2_score(ytrain, ytrain_predict_lasso)\n", "# evaluacion del modelo sobre los datos de testeo\n", "ytest_predict_lasso = modeloLasso.predict(Xtest)\n", "r2_test_lasso = r2_score(ytest, ytest_predict_lasso)\n", "\n", "# Finalmente, imprimimos el rendimiento de los modelos\n", "#\n", "print( f\"El R2 del modelo Ridge en training set es de {r2_train_ridge:5.3f}, y en el test set es de {r2_test_ridge:6.3f}\" )\n", "print( f\"El R2 del modelo LASSO en training set es de {r2_train_lasso:5.3f}, y en el test set es de {r2_test_lasso:6.3f}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "WK2qwoHo7CDf" }, "source": [ "¿Qué cambios observó en el rendimiento de las predicciones al usar regularización? Discuta brevemente (si puede, mencione la relación entre cantidad de datos y cantidad de variables en este problema)" ] }, { "cell_type": "markdown", "metadata": { "id": "nXUdlald-RIt" }, "source": [ "### Interpretabilidad" ] }, { "cell_type": "markdown", "metadata": { "id": "eSvyyoPG714_" }, "source": [ "A veces, uno de los principales objetivos de entrenar un modelo es ver qué variables son más importantes para el mismo. Esto ya lo hicimos \"a ojo\" mirando la matriz de correlación más arriba.\n", "\n", "Extraiga los coeficientes de los 3 modelos que entrenamos con todas las variables más arriba, para graficar los valores que tienen en el modelo." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "t7DvyBcHLVnR" }, "outputs": [], "source": [ "coefs_regresionLineal = lr.coef_### COEFICIENTES DE LA REGRESION SIN PENALIZACION\n", "coefs_regresionRidge = modeloRidge.coef_ ### COEFICIENTES DE LA REGRESION CON PENALIZACION RIDGE\n", "coefs_regresionLasso = modeloLasso.coef_### COEFICIENTES DE LA REGRESION CON PENALIZACION LASSO\n", "\n", "# Extraemos los nombres de las variables para identificarlas\n", "nombresVariables = dataset.feature_names\n", "N = len(nombresVariables)\n", "\n", "# Graficamos los coeficientes de la regresion sin penalizacion\n", "plt.figure(figsize=(8,10))\n", "plt.subplot(3,1,1)\n", "plt.plot(coefs_regresionLineal.T,'o')\n", "plt.title('Regresion lineal sin penalizacion')\n", "plt.grid(True)\n", "axis = plt.xticks(ticks=np.arange(N), labels=nombresVariables)\n", "\n", "# Graficamos los coeficientes de la regresion con penalizacion RIDGE\n", "plt.subplot(3,1,2)\n", "grafico = plt.plot(coefs_regresionRidge.T,'o')\n", "plt.title('Regresion lineal con penalizacion Ridge')\n", "inactivos = np.flatnonzero(coefs_regresionRidge == 0)\n", "plt.grid(True)\n", "axis = plt.xticks(ticks=np.arange(N), labels=nombresVariables)\n", "\n", "# Graficamos los coeficientes de la regresion con penalizacion\n", "plt.subplot(3,1,3)\n", "inactivos = np.flatnonzero(coefs_regresionLasso == 0)\n", "grafico = plt.plot(coefs_regresionLasso.T,'o')\n", "plt.plot(inactivos,np.zeros(len(inactivos)),'o',color='gray', label='Coeficientes inactivos')\n", "plt.title('Regresion lineal con penalizacion Lasso')\n", "plt.grid(True)\n", "plt.legend()\n", "axis = plt.xticks(ticks=np.arange(N), labels=nombresVariables)" ] }, { "cell_type": "markdown", "metadata": { "id": "HyTqfiANbYWs" }, "source": [ "Compare los coeficientes devueltos por los modelos entre ellos, y comparelos con los que usted eligió al principio. ¿Se ajustan los coeficientes devueltos por los modelos con lo que esperaría a partir de la matriz de correlación? Más arriba usted tuvo que elegir el parámetro de regularización de los modelos (alpha). ¿Cómo cree que cambiarían los resultados según se cambie el alpha? (si quiere pruebe cambiando los parámetros y volviendo a correr el código)." ] }, { "cell_type": "markdown", "metadata": { "id": "jFqgWVKcccbM" }, "source": [ "*Puede insertar sus respuestas aquí:*" ] }, { "cell_type": "markdown", "metadata": { "id": "bvfv0-ZZdUwL" }, "source": [ "**INTENTE COMPLETAR LA PREGUNTA DE ARRIBA ANTES DE PASAR A LA PRÓXIMA**\n", "\n", "En el código que corrimos arriba, entrenando los modelos y analizando los coeficientes, se usó un paso importante: **normalización de los datos**\n", "\n", "Este paso puede afectar mucho los coeficientes y la interpretabilidad del modelo. Hipotetice sobre el efecto que puede tener el **no** normalizar los datos sobre los coeficientes del modelo (piense en la escala de las diferentes variables que usamos para entrenar el modelo).\n", "\n", "Compruebe su hipótesis cambiando la variable `standarize = False` en las primeras celdas." ] }, { "cell_type": "markdown", "metadata": { "id": "n9ZNK4hiiNBL" }, "source": [ "*Puede insertar sus respuestas aquí:*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2 - Gradiente descendiente\n", "\n", "Veremos cómo también se puede resolver un problema de regresión lineal de manera no exacta (sin las ecuaciones normales), aprovechando que se trata de un modelo lineal." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Resolver un problema de regresión lineal usando la forma cerrada (ecuaciones normales)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.preprocessing import add_dummy_feature\n", "\n", "\n", "np.random.seed(42) # para volver a reproducir el mismo código\n", "m = 100 # cantidad de datos\n", "X = 2 * np.random.rand(m, 1) # datos\n", "y = 4 + 3 * X + np.random.randn(m, 1) # valores\n", "\n", "plt.figure(figsize=(6, 4))\n", "plt.plot(X, y, \"b.\")\n", "plt.xlabel(\"$x_1$\")\n", "plt.ylabel(\"$y$\", rotation=0)\n", "plt.axis([0, 2, 0, 15])\n", "plt.grid()\n", "plt.show()\n", "\n", "X_b = add_dummy_feature(X) # agregado de coordenadas homogéneas x0 = 1\n", "theta_best = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y\n", "\n", "print('Mejor ajuste:\\n', theta_best)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Comprobar que es la misma solución que LinearRegression de sklearn\n", "lin_reg = LinearRegression()\n", "lin_reg.fit(X, y)\n", "lin_reg.intercept_, lin_reg.coef_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Gradiente descendiente por lote (BGD)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "eta = 0.1 # learning rate\n", "n_epochs = 1000\n", "m = len(X_b)\n", "\n", "np.random.seed(42)\n", "theta = np.random.randn(2, 1) # inicializar los parámetros del modelo de manera aleatoria\n", "\n", "# Historial de los parámetros para BGD\n", "theta_path_bgd = []\n", "\n", "for epoch in range(n_epochs):\n", " gradients = 2 / m * X_b.T @ (X_b @ theta - y)\n", " theta = theta - eta * gradients\n", " theta_path_bgd.append(theta)\n", "\n", "print('Solución encontrada con GD:\\n', theta, '\\n')\n", "\n", "print('Mejor ajuste:\\n', theta_best)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Gradiente descendente estocástico (SGD)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n_epochs = 50\n", "t0, t1 = 5, 50 # hiperparámetros para reducción de learning rate\n", "\n", "def learning_schedule(t):\n", " return t0 / (t + t1)\n", "\n", "np.random.seed(42)\n", "theta = np.random.randn(2, 1) # inicialización aleatoria\n", "\n", "# Historial de los parámetros para SGD\n", "theta_path_sgd = []\n", "\n", "for epoch in range(n_epochs):\n", " for iteration in range(m):\n", " random_index = np.random.randint(m)\n", " xi = X_b[random_index : random_index + 1]\n", " yi = y[random_index : random_index + 1]\n", " gradients = 2 * xi.T @ (xi @ theta - yi)\n", " eta = learning_schedule(epoch * m + iteration)\n", " theta = theta - eta * gradients\n", " theta_path_sgd.append(theta) \n", "\n", "print('Solución encontrada con SGD:\\n', theta, '\\n')\n", "\n", "print('Mejor ajuste:\\n', theta_best)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Verificar que de parecido a `SGDRegressor`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.linear_model import SGDRegressor\n", "\n", "sgd_reg = SGDRegressor(max_iter=1000, tol=1e-5, penalty=None, eta0=0.01,\n", " n_iter_no_change=100, random_state=42)\n", "sgd_reg.fit(X, y.ravel()) # se usa ravel() porque fit() espera arrays en 1D\n", "\n", "sgd_reg.intercept_, sgd_reg.coef_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Gradiente descendiente por mini-batch" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n_epochs = 50\n", "minibatch_size = 20\n", "n_batches_per_epoch = int(np.ceil(m / minibatch_size))\n", "\n", "np.random.seed(42)\n", "theta = np.random.randn(2, 1) # inicialización aleatoria\n", "\n", "t0, t1 = 200, 1000 \n", "\n", "def learning_schedule(t):\n", " return t0 / (t + t1)\n", "\n", "# Historial de los parámetros para mini-batch GD\n", "theta_path_mgd = []\n", "\n", "for epoch in range(n_epochs):\n", " shuffled_indices = np.random.permutation(m)\n", " X_b_shuffled = X_b[shuffled_indices]\n", " y_shuffled = y[shuffled_indices]\n", " for iteration in range(0, n_batches_per_epoch):\n", " idx = iteration * minibatch_size\n", " xi = X_b_shuffled[idx : idx + minibatch_size]\n", " yi = y_shuffled[idx : idx + minibatch_size]\n", " gradients = 2 / minibatch_size * xi.T @ (xi @ theta - yi)\n", " eta = learning_schedule(iteration)\n", " theta = theta - eta * gradients\n", " theta_path_mgd.append(theta)\n", "\n", "print('Solución encontrada con mini-batch GD:\\n', theta)\n", "\n", "print('Mejor ajuste:\\n', theta_best)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visualizar la evolución de cada método de resolución" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "theta_path_bgd = np.array(theta_path_bgd)\n", "theta_path_sgd = np.array(theta_path_sgd)\n", "theta_path_mgd = np.array(theta_path_mgd)\n", "\n", "plt.figure(figsize=(7, 4))\n", "plt.plot(theta_path_sgd[:, 0], theta_path_sgd[:, 1], \"m-s\", linewidth=1,\n", " label=\"Stochastic\")\n", "plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1], \"g-+\", linewidth=2,\n", " label=\"Mini-batch\")\n", "plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1], \"b-o\", linewidth=3,\n", " label=\"Batch\")\n", "\n", "plt.plot(theta_best[0], theta_best[1], 'Xr', markersize=15, label='Solución Cerrada')\n", "\n", "plt.legend(loc=\"upper left\")\n", "plt.xlabel(r\"$\\theta_0$\")\n", "plt.ylabel(r\"$\\theta_1$ \", rotation=0)\n", "plt.axis([2.6, 4.6, 2.3, 3.4])\n", "plt.grid()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notar que los tres métodos vistos convergen a una misma región, logrando terminar cerca de la solución que minimiza el error cuadrático medio.\n", "\n", "**PREGUNTA:** \n", "\n", "¿Se debe a los datos, al error o al modelo elegido? ¿Por qué?\n", "\n", "_Respuesta:_" ] } ], "metadata": { "colab": { "provenance": [ { "file_id": "1bQRKBrXKfaYhxB_eu3BK1wzKvzqTjUAl", "timestamp": 1627221620835 } ] }, "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.9.13" } }, "nbformat": 4, "nbformat_minor": 1 }