pacman::p_load(tidyverse, tidymodels, ISLR, janitor, inspectdf, GGally, kknn ) TALLER
DATOS
El conjunto de datos principales está relacionado con el registro histórico de dos años correspondiente a los años 2011 y 2012 del sistema Capital Bikeshare, Washington D.C., EE. UU., que está disponible públicamente en http://capitalbikeshare.com/system-data. Los datos fueron agregados cada dos horas y cada día y, a continuación se añadió la información meteorológica y estacional correspondiente. La información meteorológica se extrajo de http://www.freemeteo.com
url <- "https://archive.ics.uci.edu/static/public/275/bike+sharing+dataset.zip"
download.file(url, destfile = "bike_sharing_dataset.zip")
unzip("bike_sharing_dataset.zip")
datos <- read.csv("day.csv")Análisis Exploratorio de los datos
inspect_types(datos)# A tibble: 3 × 4
type cnt pcnt col_name
<chr> <int> <dbl> <named list>
1 integer 11 68.8 <chr [11]>
2 numeric 4 25 <chr [4]>
3 character 1 6.25 <chr [1]>
var_cat<- inspect_cat(datos)
names(datos) [1] "instant" "dteday" "season" "yr" "mnth"
[6] "holiday" "weekday" "workingday" "weathersit" "temp"
[11] "atemp" "hum" "windspeed" "casual" "registered"
[16] "cnt"
inspect_types(datos)# A tibble: 3 × 4
type cnt pcnt col_name
<chr> <int> <dbl> <named list>
1 integer 11 68.8 <chr [11]>
2 numeric 4 25 <chr [4]>
3 character 1 6.25 <chr [1]>
str(datos)'data.frame': 731 obs. of 16 variables:
$ instant : int 1 2 3 4 5 6 7 8 9 10 ...
$ dteday : chr "2011-01-01" "2011-01-02" "2011-01-03" "2011-01-04" ...
$ season : int 1 1 1 1 1 1 1 1 1 1 ...
$ yr : int 0 0 0 0 0 0 0 0 0 0 ...
$ mnth : int 1 1 1 1 1 1 1 1 1 1 ...
$ holiday : int 0 0 0 0 0 0 0 0 0 0 ...
$ weekday : int 6 0 1 2 3 4 5 6 0 1 ...
$ workingday: int 0 0 1 1 1 1 1 0 0 1 ...
$ weathersit: int 2 2 1 1 1 1 2 2 1 1 ...
$ temp : num 0.344 0.363 0.196 0.2 0.227 ...
$ atemp : num 0.364 0.354 0.189 0.212 0.229 ...
$ hum : num 0.806 0.696 0.437 0.59 0.437 ...
$ windspeed : num 0.16 0.249 0.248 0.16 0.187 ...
$ casual : int 331 131 120 108 82 88 148 68 54 41 ...
$ registered: int 654 670 1229 1454 1518 1518 1362 891 768 1280 ...
$ cnt : int 985 801 1349 1562 1600 1606 1510 959 822 1321 ...
ggpairs(datos[, c("atemp", "hum", "windspeed", "cnt")])Seleccionar variables predictoras y variable a predecir
x <- c("atemp", "hum", "windspeed")
y <- "cnt"
data <- datos[, c(x,y)]Partición de datos
set.seed(100)
particion<- initial_split(datos, prop = 0.8)
dato_entre<- training(particion)
dato_test<- testing(particion)Definición Genérica del Modelo
Usaremos la función tune() para definir el hiperparámetro que vamos ajustar para el algoritmo KNN
knn_spec<- nearest_neighbor() |>
set_engine("kknn") |>
set_args(neighbors= tune()) |>
set_mode("regression")Creación de la receta
rec_spec <- recipe(cnt ~ atemp + hum + windspeed, data = data) |>
step_normalize(all_numeric_predictors())Definición del Flujo de Trabajo
cv_ft <- workflow() |>
add_recipe(rec_spec) |>
add_model(knn_spec)Definición de objeto de validación cruzada
set.seed(100)
obj_rem <- vfold_cv(dato_entre, v = 10)Creación del objeto Grilla
Se crea el objeto para busqueda del hiperparámetro
vecinos <- tibble(neighbors = seq(1, 10))Afinar el hiperparámetro
tune_res<- tune_grid(
object = cv_ft,
resamples = obj_rem,
grid = vecinos)Revisión gráfica del ajuste del hiperparámetro
autoplot(tune_res)Visualización de los mejores valores
show_best(tune_res, metric = "rmse")# A tibble: 5 × 7
neighbors .metric .estimator mean n std_err .config
<int> <chr> <chr> <dbl> <int> <dbl> <chr>
1 10 rmse standard 1356. 10 13.9 Preprocessor1_Model10
2 9 rmse standard 1366. 10 13.1 Preprocessor1_Model09
3 8 rmse standard 1378. 10 12.6 Preprocessor1_Model08
4 7 rmse standard 1392. 10 13.0 Preprocessor1_Model07
5 6 rmse standard 1409. 10 15.0 Preprocessor1_Model06
Selección del mejor hiperparámetro
mejor_hip <- select_by_one_std_err(tune_res, neighbors, metric = "rmse")
mejor_hip# A tibble: 1 × 9
neighbors .metric .estimator mean n std_err .config .best .bound
<int> <chr> <chr> <dbl> <int> <dbl> <chr> <dbl> <dbl>
1 9 rmse standard 1366. 10 13.1 Preprocessor1_M… 1356. 1370.
Actualización del Flujo de Trabajo
final_ft <- finalize_workflow(cv_ft, mejor_hip)
final_ft══ Workflow ════════════════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: nearest_neighbor()
── Preprocessor ────────────────────────────────────────────────────────────────
1 Recipe Step
• step_normalize()
── Model ───────────────────────────────────────────────────────────────────────
K-Nearest Neighbor Model Specification (regression)
Main Arguments:
neighbors = 9
Computational engine: kknn
Ajustar el modelo con datos del entrenamiento
final_fit <- fit(final_ft, dato_entre)
final_fit══ Workflow [trained] ══════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: nearest_neighbor()
── Preprocessor ────────────────────────────────────────────────────────────────
1 Recipe Step
• step_normalize()
── Model ───────────────────────────────────────────────────────────────────────
Call:
kknn::train.kknn(formula = ..y ~ ., data = data, ks = min_rows(9L, data, 5))
Type of response variable: continuous
minimal mean absolute error: 1112.761
Minimal mean squared error: 1849353
Best kernel: optimal
Best k: 9
Análisis del rendimiento con los datos de prueba
fit_test <- augment(final_fit, new_data = dato_test)
fit_test# A tibble: 147 × 18
.pred .resid instant dteday season yr mnth holiday weekday workingday
<dbl> <dbl> <int> <chr> <int> <int> <int> <int> <int> <int>
1 3049. -1449. 5 2011-01-05 1 0 1 0 3 1
2 1700. -700. 17 2011-01-17 1 0 1 1 1 0
3 3446. -1519. 20 2011-01-20 1 0 1 0 4 1
4 1643. -545. 29 2011-01-29 1 0 1 0 6 0
5 1757. -231. 33 2011-02-02 1 0 2 0 3 1
6 3499. -2027. 43 2011-02-12 1 0 2 0 6 0
7 5275. -2348. 49 2011-02-18 1 0 2 0 5 1
8 3248. -1436. 51 2011-02-20 1 0 2 0 0 0
9 3757. -2650. 52 2011-02-21 1 0 2 1 1 0
10 3922. -1953. 57 2011-02-26 1 0 2 0 6 0
# ℹ 137 more rows
# ℹ 8 more variables: weathersit <int>, temp <dbl>, atemp <dbl>, hum <dbl>,
# windspeed <dbl>, casual <int>, registered <int>, cnt <int>
Visualización del rendimiento
fit_test |>
metrics(truth = cnt, estimate = .pred)# A tibble: 3 × 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 rmse standard 1313.
2 rsq standard 0.530
3 mae standard 1071.
Gráfico de predicción vs. valores reales
ggplot(data = fit_test, aes(x = .pred, y = cnt)) +
geom_point() +
geom_abline(intercept = 0, slope = 1, color = "red") +
labs(x = "Predicción", y = "Valor real", title = "Predicción vs. Valores reales")