You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
447 lines
18 KiB
447 lines
18 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_1-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": [],
|
|
"toc_visible": true
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
|
|
"translation_date": "2025-09-04T01:33:30+00:00",
|
|
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
|
|
"language_code": "es"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [],
|
|
"metadata": {
|
|
"id": "YJUHCXqK57yz"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Introducción a la Regresión - Lección 1\n",
|
|
"\n",
|
|
"#### Poniéndolo en perspectiva\n",
|
|
"\n",
|
|
"✅ Hay muchos tipos de métodos de regresión, y cuál elijas depende de la respuesta que estás buscando. Si quieres predecir la altura probable de una persona dada su edad, usarías `regresión lineal`, ya que estás buscando un **valor numérico**. Si estás interesado en descubrir si un tipo de cocina debería considerarse vegana o no, estás buscando una **asignación de categoría**, por lo que usarías `regresión logística`. Aprenderás más sobre la regresión logística más adelante. Piensa un poco en algunas preguntas que podrías hacerle a los datos y cuál de estos métodos sería más apropiado.\n",
|
|
"\n",
|
|
"En esta sección, trabajarás con un [pequeño conjunto de datos sobre diabetes](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Imagina que quisieras probar un tratamiento para pacientes diabéticos. Los modelos de aprendizaje automático podrían ayudarte a determinar qué pacientes responderían mejor al tratamiento, basándote en combinaciones de variables. Incluso un modelo de regresión muy básico, cuando se visualiza, podría mostrar información sobre variables que te ayudarían a organizar tus ensayos clínicos teóricos.\n",
|
|
"\n",
|
|
"Dicho esto, ¡vamos a comenzar con esta tarea!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/encouRage.jpg\"\n",
|
|
" width=\"630\"/>\n",
|
|
" <figcaption>Obra de @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"<!--<br>Obra de @allison_horst-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "LWNNzfqd6feZ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 1. Cargando nuestro conjunto de herramientas\n",
|
|
"\n",
|
|
"Para esta tarea, necesitaremos los siguientes paquetes:\n",
|
|
"\n",
|
|
"- `tidyverse`: El [tidyverse](https://www.tidyverse.org/) es una [colección de paquetes de R](https://www.tidyverse.org/packages) diseñada para hacer la ciencia de datos más rápida, fácil y divertida.\n",
|
|
"\n",
|
|
"- `tidymodels`: El marco de trabajo [tidymodels](https://www.tidymodels.org/) es una [colección de paquetes](https://www.tidymodels.org/packages/) para modelado y aprendizaje automático.\n",
|
|
"\n",
|
|
"Puedes instalarlos con el siguiente comando:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
|
|
"\n",
|
|
"El script a continuación verifica si tienes los paquetes necesarios para completar este módulo y los instala por ti en caso de que falte alguno.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "FIo2YhO26wI9"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
|
|
"pacman::p_load(tidyverse, tidymodels)"
|
|
],
|
|
"outputs": [
|
|
{
|
|
"output_type": "stream",
|
|
"name": "stderr",
|
|
"text": [
|
|
"Loading required package: pacman\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"id": "cIA9fz9v7Dss",
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Ahora, carguemos estos paquetes increíbles y hagámoslos disponibles en nuestra sesión actual de R. (Esto es solo para ilustración, `pacman::p_load()` ya lo hizo por ti)\n"
|
|
],
|
|
"metadata": {
|
|
"id": "gpO_P_6f9WUG"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# load the core Tidyverse packages\r\n",
|
|
"library(tidyverse)\r\n",
|
|
"\r\n",
|
|
"# load the core Tidymodels packages\r\n",
|
|
"library(tidymodels)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "NLMycgG-9ezO"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 2. El conjunto de datos de diabetes\n",
|
|
"\n",
|
|
"En este ejercicio, pondremos en práctica nuestras habilidades de regresión haciendo predicciones sobre un conjunto de datos de diabetes. El [conjunto de datos de diabetes](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) incluye `442 muestras` de datos relacionados con la diabetes, con 10 variables predictoras: `edad`, `sexo`, `índice de masa corporal`, `presión arterial promedio` y `seis mediciones de suero sanguíneo`, así como una variable de resultado `y`: una medida cuantitativa de la progresión de la enfermedad un año después del punto de referencia.\n",
|
|
"\n",
|
|
"|Número de observaciones|442|\n",
|
|
"|-----------------------|:---|\n",
|
|
"|Número de predictores|Las primeras 10 columnas son numéricas predictivas|\n",
|
|
"|Resultado/Objetivo|La columna 11 es una medida cuantitativa de la progresión de la enfermedad un año después del punto de referencia|\n",
|
|
"|Información de los predictores|- edad en años\n",
|
|
"||- sexo\n",
|
|
"||- bmi índice de masa corporal\n",
|
|
"||- bp presión arterial promedio\n",
|
|
"||- s1 tc, colesterol total en suero\n",
|
|
"||- s2 ldl, lipoproteínas de baja densidad\n",
|
|
"||- s3 hdl, lipoproteínas de alta densidad\n",
|
|
"||- s4 tch, colesterol total / HDL\n",
|
|
"||- s5 ltg, posiblemente logaritmo del nivel de triglicéridos en suero\n",
|
|
"||- s6 glu, nivel de azúcar en sangre|\n",
|
|
"\n",
|
|
"> 🎓 Recuerda, esto es aprendizaje supervisado, y necesitamos un objetivo llamado 'y'.\n",
|
|
"\n",
|
|
"Antes de poder manipular datos con R, necesitas importar los datos a la memoria de R o establecer una conexión con los datos para que R pueda acceder a ellos de forma remota.\n",
|
|
"\n",
|
|
"> El paquete [readr](https://readr.tidyverse.org/), que forma parte de Tidyverse, proporciona una forma rápida y amigable de leer datos rectangulares en R.\n",
|
|
"\n",
|
|
"Ahora, carguemos el conjunto de datos de diabetes proporcionado en esta URL fuente: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
|
|
"\n",
|
|
"Además, realizaremos una verificación básica de nuestros datos usando `glimpse()` y mostraremos las primeras 5 filas usando `slice()`.\n",
|
|
"\n",
|
|
"Antes de continuar, también introduzcamos algo que encontrarás con frecuencia en el código de R 🥁🥁: el operador pipe `%>%`\n",
|
|
"\n",
|
|
"El operador pipe (`%>%`) realiza operaciones en secuencia lógica pasando un objeto hacia adelante dentro de una función o expresión de llamada. Puedes pensar en el operador pipe como si dijera \"y luego\" en tu código.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "KM6iXLH996Cl"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Import the data set\r\n",
|
|
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Get a glimpse and dimensions of the data\r\n",
|
|
"glimpse(diabetes)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Select the first 5 rows of the data\r\n",
|
|
"diabetes %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "Z1geAMhM-bSP"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"`glimpse()` nos muestra que estos datos tienen 442 filas y 11 columnas, y todas las columnas son del tipo de dato `double`.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"> glimpse() y slice() son funciones de [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, que forma parte de Tidyverse, es una gramática para la manipulación de datos que proporciona un conjunto consistente de verbos que te ayudan a resolver los desafíos más comunes en la manipulación de datos.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"Ahora que tenemos los datos, vamos a centrarnos en una característica (`bmi`) como objetivo para este ejercicio. Esto requerirá que seleccionemos las columnas deseadas. Entonces, ¿cómo hacemos esto?\n",
|
|
"\n",
|
|
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) nos permite *seleccionar* (y opcionalmente renombrar) columnas en un marco de datos.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "UwjVT1Hz-c3Z"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Select predictor feature `bmi` and outcome `y`\r\n",
|
|
"diabetes_select <- diabetes %>% \r\n",
|
|
" select(c(bmi, y))\r\n",
|
|
"\r\n",
|
|
"# Print the first 5 rows\r\n",
|
|
"diabetes_select %>% \r\n",
|
|
" slice(1:10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "RDY1oAKI-m80"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 3. Datos de entrenamiento y prueba\n",
|
|
"\n",
|
|
"Es una práctica común en el aprendizaje supervisado *dividir* los datos en dos subconjuntos: un conjunto (generalmente más grande) para entrenar el modelo, y un conjunto más pequeño de \"reserva\" para evaluar cómo se desempeñó el modelo.\n",
|
|
"\n",
|
|
"Ahora que tenemos los datos listos, podemos ver si una máquina puede ayudar a determinar una división lógica entre los números de este conjunto de datos. Podemos usar el paquete [rsample](https://tidymodels.github.io/rsample/), que forma parte del marco Tidymodels, para crear un objeto que contenga la información sobre *cómo* dividir los datos, y luego dos funciones adicionales de rsample para extraer los conjuntos de entrenamiento y prueba creados:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "SDk668xK-tc3"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"set.seed(2056)\r\n",
|
|
"# Split 67% of the data for training and the rest for tesing\r\n",
|
|
"diabetes_split <- diabetes_select %>% \r\n",
|
|
" initial_split(prop = 0.67)\r\n",
|
|
"\r\n",
|
|
"# Extract the resulting train and test sets\r\n",
|
|
"diabetes_train <- training(diabetes_split)\r\n",
|
|
"diabetes_test <- testing(diabetes_split)\r\n",
|
|
"\r\n",
|
|
"# Print the first 3 rows of the training set\r\n",
|
|
"diabetes_train %>% \r\n",
|
|
" slice(1:10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "EqtHx129-1h-"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 4. Entrenar un modelo de regresión lineal con Tidymodels\n",
|
|
"\n",
|
|
"¡Ahora estamos listos para entrenar nuestro modelo!\n",
|
|
"\n",
|
|
"En Tidymodels, se especifican los modelos utilizando `parsnip()` definiendo tres conceptos:\n",
|
|
"\n",
|
|
"- El **tipo** de modelo diferencia entre modelos como la regresión lineal, la regresión logística, los modelos de árboles de decisión, entre otros.\n",
|
|
"\n",
|
|
"- El **modo** del modelo incluye opciones comunes como regresión y clasificación; algunos tipos de modelos admiten cualquiera de estos modos, mientras que otros solo tienen un modo disponible.\n",
|
|
"\n",
|
|
"- El **motor** del modelo es la herramienta computacional que se utilizará para ajustar el modelo. A menudo, estos son paquetes de R, como **`\"lm\"`** o **`\"ranger\"`**.\n",
|
|
"\n",
|
|
"Esta información del modelo se captura en una especificación de modelo, ¡así que vamos a construir una!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "sBOS-XhB-6v7"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Build a linear model specification\r\n",
|
|
"lm_spec <- \r\n",
|
|
" # Type\r\n",
|
|
" linear_reg() %>% \r\n",
|
|
" # Engine\r\n",
|
|
" set_engine(\"lm\") %>% \r\n",
|
|
" # Mode\r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print the model specification\r\n",
|
|
"lm_spec"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "20OwEw20--t3"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Después de que un modelo ha sido *especificado*, el modelo puede ser `estimado` o `entrenado` utilizando la función [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), generalmente usando una fórmula y algunos datos.\n",
|
|
"\n",
|
|
"`y ~ .` significa que ajustaremos `y` como la cantidad/objetivo predicho, explicado por todos los predictores/características, es decir, `.` (en este caso, solo tenemos un predictor: `bmi`).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "_oDHs89k_CJj"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Build a linear model specification\r\n",
|
|
"lm_spec <- linear_reg() %>% \r\n",
|
|
" set_engine(\"lm\") %>%\r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Train a linear regression model\r\n",
|
|
"lm_mod <- lm_spec %>% \r\n",
|
|
" fit(y ~ ., data = diabetes_train)\r\n",
|
|
"\r\n",
|
|
"# Print the model\r\n",
|
|
"lm_mod"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "YlsHqd-q_GJQ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"A partir del resultado del modelo, podemos observar los coeficientes aprendidos durante el entrenamiento. Representan los coeficientes de la línea de mejor ajuste que nos proporciona el menor error global entre la variable real y la predicha.\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"## 5. Realizar predicciones en el conjunto de prueba\n",
|
|
"\n",
|
|
"Ahora que hemos entrenado un modelo, podemos usarlo para predecir la progresión de la enfermedad y para el conjunto de datos de prueba utilizando [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Esto se utilizará para trazar la línea entre los grupos de datos.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "kGZ22RQj_Olu"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make predictions for the test set\r\n",
|
|
"predictions <- lm_mod %>% \r\n",
|
|
" predict(new_data = diabetes_test)\r\n",
|
|
"\r\n",
|
|
"# Print out some of the predictions\r\n",
|
|
"predictions %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "nXHbY7M2_aao"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"¡Qué emoción! 💃🕺 ¡Acabamos de entrenar un modelo y lo usamos para hacer predicciones!\n",
|
|
"\n",
|
|
"Al hacer predicciones, la convención de tidymodels es siempre generar un tibble/data frame de resultados con nombres de columnas estandarizados. Esto facilita combinar los datos originales con las predicciones en un formato útil para operaciones posteriores, como la creación de gráficos.\n",
|
|
"\n",
|
|
"`dplyr::bind_cols()` une de manera eficiente múltiples data frames por columna.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "R_JstwUY_bIs"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Combine the predictions and the original test set\r\n",
|
|
"results <- diabetes_test %>% \r\n",
|
|
" bind_cols(predictions)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"results %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "RybsMJR7_iI8"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 6. Graficar los resultados del modelo\n",
|
|
"\n",
|
|
"Ahora es momento de verlo de forma visual 📈. Crearemos un diagrama de dispersión con todos los valores de `y` y `bmi` del conjunto de prueba, y luego utilizaremos las predicciones para dibujar una línea en el lugar más adecuado, entre los agrupamientos de datos del modelo.\n",
|
|
"\n",
|
|
"R tiene varios sistemas para crear gráficos, pero `ggplot2` es uno de los más elegantes y versátiles. Esto te permite componer gráficos **combinando componentes independientes**.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "XJbYbMZW_n_s"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Set a theme for the plot\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"# Create a scatter plot\r\n",
|
|
"results %>% \r\n",
|
|
" ggplot(aes(x = bmi)) +\r\n",
|
|
" # Add a scatter plot\r\n",
|
|
" geom_point(aes(y = y), size = 1.6) +\r\n",
|
|
" # Add a line plot\r\n",
|
|
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "R9tYp3VW_sTn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"✅ Piensa un poco en lo que está sucediendo aquí. Una línea recta atraviesa muchos pequeños puntos de datos, pero ¿qué está haciendo exactamente? ¿Puedes ver cómo deberías poder usar esta línea para predecir dónde debería encajar un nuevo punto de datos no visto en relación con el eje y del gráfico? Intenta expresar en palabras el uso práctico de este modelo.\n",
|
|
"\n",
|
|
"¡Felicidades, construiste tu primer modelo de regresión lineal, creaste una predicción con él y la mostraste en un gráfico!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "zrPtHIxx_tNI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Descargo de responsabilidad**: \nEste documento ha sido traducido utilizando el servicio de traducción automática [Co-op Translator](https://github.com/Azure/co-op-translator). Si bien nos esforzamos por lograr precisión, tenga en cuenta que las traducciones automáticas pueden contener errores o imprecisiones. El documento original en su idioma nativo debe considerarse como la fuente autorizada. Para información crítica, se recomienda una traducción profesional realizada por humanos. No nos hacemos responsables de malentendidos o interpretaciones erróneas que puedan surgir del uso de esta traducción.\n"
|
|
]
|
|
}
|
|
]
|
|
} |