Objetivo:

Construir un modelo con árboles de regresión y realizar predicciones con el mismo.

Descripción:

Aplicar el modelo de árboles de regresión en el conjunto de datos de precios de casas en Durango.

Proceso

1. Cargar librerías

library(rpart)
library(rpart.plot)
library(caret)
library(dplyr)
library(readr)
library(ggplot2)
library(reshape)
library(knitr)

options(scipen = 999)

2. Cargar datos

datos <- read.csv("https://raw.githubusercontent.com/rpizarrog/FundamentosMachineLearning/master/datos/datos%20precios%20de%20casas.csv", encoding = "UTF-8")

3. Limpiar datos

datos <- datos[,c(1,2,3,4,7,8)]
names(datos)[4] <- c('banio')
datos <- mutate(datos, estacionamientos = ifelse(is.na(estacionamientos), 0, estacionamientos))
datos <- mutate(datos, construccion = ifelse(is.na(construccion), mean(construccion, na.rm = TRUE), construccion))

kable(head(datos), caption = "Registros")
Registros
precio estacionamientos recamaras banio construccion terreno
1780000 2 3 2 169 126
650000 1 3 1 90 90
590000 2 2 2 63 90
1300000 2 3 2 130 120
1000000 2 2 1 110 160
465000 2 3 1 53 89

4. División datos (entrenamiento/validación)

set.seed(2020)

para_entrenar <- createDataPartition(y = datos$precio, p = 0.7, list = FALSE, times = 1)

conjunto_entrenamiento <- datos[para_entrenar, ]
conjunto_validacion <- datos[-para_entrenar, ]

kable(head(conjunto_entrenamiento, 10), caption = "Datos de entrenamiento (primeros diez registros)", row.names = 1:row(conjunto_entrenamiento))
Datos de entrenamiento (primeros diez registros)
precio estacionamientos recamaras banio construccion terreno
2 650000 1 3 1 90.0000 90
3 590000 2 2 2 63.0000 90
4 1300000 2 3 2 130.0000 120
5 1000000 2 2 1 110.0000 160
7 780000 2 1 1 84.0000 90
8 464520 0 2 1 47.0000 98
10 580000 0 3 1 65.0000 103
11 1550000 2 3 2 155.0000 126
12 640000 0 2 1 151.1156 90
14 480000 0 2 1 53.0000 90
kable(head(conjunto_validacion, 10), caption = "Datos de validación (primeros diez registros)", row.names = 1:row(conjunto_validacion))
Datos de validación (primeros diez registros)
precio estacionamientos recamaras banio construccion terreno
1 1780000 2 3 2.0 169.00 126
6 465000 2 3 1.0 53.00 89
9 660000 0 3 1.0 73.00 112
13 2350000 2 3 2.5 194.56 203
16 1000000 2 3 2.0 110.00 120
23 660000 0 3 1.0 73.00 112
25 1750000 1 3 2.0 154.00 130
32 2100000 0 4 2.0 151.00 151
34 640000 1 2 1.0 60.00 90
35 462000 1 2 1.0 47.00 90

5. Generar modelo

set.seed(2020)

modelo <- rpart(formula = precio ~ ., data = conjunto_entrenamiento)

modelo
n= 38 

node), split, n, deviance, yval
      * denotes terminal node

1) root 38 81930710000000 1572540.0  
  2) construccion< 205.5 30  6480123000000  991950.7  
    4) construccion< 152.5578 23  1930233000000  807892.2  
      8) construccion< 96.5 12   116237700000  603043.3 *
      9) construccion>=96.5 11   761104500000 1031364.0 *
    5) construccion>=152.5578 7  1210533000000 1596714.0 *
  3) construccion>=205.5 8 27416120000000 3749750.0 *

6. Visualizar modelo

prp(modelo, type = 2, nn = TRUE, fallen.leaves = TRUE, faclen = 4, varlen =8, shadow.col = "gray")

7. Predecir con datos de validación

predicciones <- predict(object = modelo, newdata = conjunto_validacion)

predicciones_df <- data.frame(conjunto_validacion, predicciones)

kable(predicciones_df)
precio estacionamientos recamaras banio construccion terreno predicciones
1 1780000 2 3 2.0 169.00 126 1596714.3
6 465000 2 3 1.0 53.00 89 603043.3
9 660000 0 3 1.0 73.00 112 603043.3
13 2350000 2 3 2.5 194.56 203 1596714.3
16 1000000 2 3 2.0 110.00 120 1031363.6
23 660000 0 3 1.0 73.00 112 603043.3
25 1750000 1 3 2.0 154.00 130 1596714.3
32 2100000 0 4 2.0 151.00 151 1031363.6
34 640000 1 2 1.0 60.00 90 603043.3
35 462000 1 2 1.0 47.00 90 603043.3
45 960000 1 3 2.0 162.00 90 1596714.3
49 1200000 1 3 1.5 115.00 112 1031363.6
51 3450000 2 3 2.0 200.00 280 1596714.3

8. Predecir con nuevos valores

estacionamiento <- 3
recamara <- 4
bano <- 3
const <- 250
trrn <- 203

nuevos_datos <- data.frame(estacionamientos = estacionamiento, recamaras = recamara, banio = bano, construccion = const, terreno = trrn)

nueva_prediccion <- predict(object = modelo, newdata = nuevos_datos)

paste("El valor del precio predicho es de:", round(nueva_prediccion, 2))
[1] "El valor del precio predicho es de: 3749750"

9. Comparar modelo actual con modelo de regresión múltiple

Si comparamos las tablas donde tenemos las predicciones, el modelo con árboles de regresión es bastante aproximado a valores bajos en casas, mientras que en valores altos suele quedar ligeramente bajo el precio real o exageradamente por arriba de la realidad. En cuanto al modelo con regresión lineal múltiple observamos que es el caso contrario, para los precios altos en las casas es preciso con diferencias en pesos no tan significativas, pero para valores bajos suele quedar muy por debajo del precio real la gran parte de los registros.

10. Interpretar el caso

Como se mencionó en el punto anterior, este modelo predice muy bien los valores bajos e intermedios de las casas, en el precio más alto del conjunto de datos se quedo bastante por debajo del precio real de la casa, en cuanto a la variable que determina mejor el precio es la de construcción con un valor menor a 206 metros siendo los precios más altos, seguido de un valor menor a 153 metros con valores intermedios y para los precios más bajos corresponde una construcción menor a los 97 metros. Estos valores determinaron los nodos finales de nuestro árbol de regresión.