Saltar a contenido

Machine learning con R

En este documento veremos algún ejemplo de desarrollo de modelos de machine learning con R, basándonos en etapas previas de pre-procesamiento y EDA, que hemos visto en los apartados anteriores.

1. Preparando el modelo

Para empezar vamos a crear un modelo de regresión lineal múltiple que prediga el precio de un diamante (del dataset diamonds que tenemos pre-cargado con ggplot2) en base a ciertas características: peso, tipo de corte, claridad...

Comenzaremos cargando las librerías necesarias y el dataset:

library(ggplot2)
library(dplyr)
library(caTools)  # Para dividir en entrenamiento y test
library(corrr)    # Para establecer correlaciones entre datos

# Carga de datos
datos <- diamonds

1.1. Codificación de variables categóricas

Como primer paso vamos a codificar de forma numérica las variables categóricas del dataset: tipo de corte (cut), color y claridad. Como hay una gradación en sus valores (es decir, hay valores peores o mejores que otros) les asignaremos una codificación numérica de 1 en adelante:

datos$cut <- factor(datos$cut,
              levels=c("Fair", "Good", "Very Good", "Premium", "Ideal"),
              labels=1:5)
datos$cut <- as.numeric(datos$cut)

datos$color <- factor(datos$color,
              levels=LETTERS[4:10],
              labels=1:7)
datos$color <- as.numeric(datos$color)

datos$clarity <- factor(datos$clarity,
              levels=c("I1", "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"),
              labels=1:8)
datos$clarity <- as.numeric(datos$clarity)

1.2. Análisis de correlación de datos

Ahora que todas las variables son numéricas podemos establecer un análisis de correlación, para ver qué parámetros influyen más en el precio final del diamante. Usaremos para ello la función correlate del paquete corrr que hemos importado antes (y que tendremos que instalar en el sistema si no lo tenemos aún):

datos %>% 
  correlate() %>%
  focus(price)

# Representación gráfica
datos %>% 
  correlate() %>%
  network_plot()   # Función de corrr

Obtendremos un resultado como éste:

  term      price
  <chr>     <dbl>
1 carat    0.922 
2 cut     -0.0535
3 color    0.173 
4 clarity -0.147 
5 depth   -0.0106
6 table    0.127 
7 x        0.884 
8 y        0.865 
9 z        0.861 

1.3. Selección de columnas y división de datos

Como podemos observar, los parámetros más relacionados con el precio final del diamante son su peso (carat) y sus dimensiones x, y y z. Así que seleccionamos sólo estas columnas:

datos <- datos %>%
  select(carat, x, y, z, price)

# Dividimos en conjunto de entrenamiento y test (usando caTools)
split <- sample.split(datos$price, SplitRatio=0.8)
train <- subset(datos, split==TRUE)
test <- subset(datos, split==FALSE)

2. Definición del modelo de regresión lineal

Definimos un modelo de regresión lineal con la función lm, a la que le pasamos:

  • La fórmula que queremos aplicar para obtener la regresión, es decir, cuál es la variable dependiente y cuáles son las variables independientes que tenemos que combinar
  • Los datos con que trabajar
modelo <- lm(price ~ ., data=train)

La expresión price ~ . determina que la variable dependiente es la que queda a la izquierda del símbolo ~ (en este caso el precio) y el punto a la derecha indica que todas las demás columnas del conjunto de datos son variables independientes que se combinan para hallar el resultado.

2.1. Predicción de nuevos datos

Ahora vamos a predecir los precios de los diamantes del conjunto de test:

pred = predict(modelo, newdata = test)

Finalmente, podemos enlazar estos resultados al conjunto de test como una columna más, y ver/contrastar los resultados:

resultados <- test %>%
  mutate(price_pred = pred)
View(resultados)

Tendremos un resultado como éste (puede variar en cada ejecución, dependiendo de las muestras tomadas para entrenamiento y test):

carat x y z price price_pred <dbl> <dbl> <dbl> <dbl> <int> <dbl> 1 0.3 4.23 4.26 2.71 351 376. 2 0.31 4.44 4.47 2.59 353 394. 3 0.32 4.34 4.37 2.75 403 482. 4 0.32 4.36 4.38 2.79 403 446. 5 0.32 4.45 4.48 2.72 404 421. ...

Nota

Aquí tienes el ejemplo de código completo de este apartado.