Objetivo

Construir un modelo basado en árboles de regresión y realizar predicciones

Descripción

Con los datos de precios de casas aplicar un modelo de árboles de regresión y realizar predicciones

Fundamento teórico

Los árboles de regresión/clasificación tienen como objetivo predecir la variable respuesta Y en función de covariables. (Hernández, 2020)

Los árboles de regresión permiten al igual que otros modelos de regresión predecir una variable dependiente Y en relación varias variables independentes Xs.

Proceso

Cargar librerías

library(rpart)      # Arboles
## Warning: package 'rpart' was built under R version 4.0.3
library(rpart.plot) # Visualizar y represenar árboles
## Warning: package 'rpart.plot' was built under R version 4.0.3
library(caret)      # Para llevar a cabo particiones de conjuntos de datos en caso de...
## Warning: package 'caret' was built under R version 4.0.3
## Loading required package: lattice
## Loading required package: ggplot2
library(dplyr)      # Para select, filter, mutate, arange ....
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(readr)      # Para leer datos
library(ggplot2)    # Para grafica mas vistosas
library(reshape)    # Para renombrar columnas
## Warning: package 'reshape' was built under R version 4.0.3
## 
## Attaching package: 'reshape'
## The following object is masked from 'package:dplyr':
## 
##     rename
library(knitr)

options(scipen = 999) # Notación normal para que no salga notación científica

Cargar datos

datos <- read.csv('C:/Users/Blue/Documents/casas.csv', encoding = "UTF-8")

Limpiar datos

Quitar columnas que no se necesitan Poner banio al nombre de la variable Poner 0 los NA en todas las variables porque no tiene estacionamiento

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 = "Los datos")
Los datos
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

Conjunto de entrenamiento y conjunto de validación 70%, 30%

set.seed(2020)
entrena <- createDataPartition(y = datos$precio, p = 0.7, list = FALSE, times = 1)

# Datos entrenamiento
datos.entrenamiento <- datos[entrena, ]  # [renglones, columna]

# Datos validación
datos.validacion <- datos[-entrena, ]

kable(head(datos.entrenamiento, 10), caption = "Datos de entrenamiento  (primeros diez)", row.names = 1:nrow(datos.entrenamiento))
## Warning in if (is.na(row.names)) row.names = has_rownames(x): la condición tiene
## longitud > 1 y sólo el primer elemento será usado
## Warning in if (row.names) {: la condición tiene longitud > 1 y sólo el primer
## elemento será usado
Datos de entrenamiento (primeros diez)
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(datos.validacion, 10), caption = "Datos de validación  (primeros diez)", row.names = 1:nrow(datos.entrenamiento))
## Warning in if (is.na(row.names)) row.names = has_rownames(x): la condición tiene
## longitud > 1 y sólo el primer elemento será usado
## Warning in if (row.names) {: la condición tiene longitud > 1 y sólo el primer
## elemento será usado
Datos de validación (primeros diez)
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

Generar el modelo de árbol de regresión

El comando para generar un modelo de árbol de decisión, usando la librería rpart La función lleva el mismo nombre

set.seed(2020) # Semilla

modelo <- rpart(formula = precio  ~ ., data = datos.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 *

Visualizar el árbol de regresión

Dibujar el árbol mediante la función prp()

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

Predecir con datos de validación

prediccion <- predict(object = modelo, newdata =  datos.validacion)

prediccion
##         1         6         9        13        16        23        25        32 
## 1596714.3  603043.3  603043.3 1596714.3 1031363.6  603043.3 1596714.3 1031363.6 
##        34        35        45        49        51 
##  603043.3  603043.3 1596714.3 1031363.6 1596714.3

Ver los datos de la predicción en un tabla

predicciones <- data.frame(datos.validacion, prediccion)

kable(predicciones)
precio estacionamientos recamaras banio construccion terreno prediccion
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

Predecir con nuevo registro y nuevos valores

estacionamientos <- 2
recamaras <- 3
banio <- 2
construccion <- 250
terreno = 201

nuevos.datos <- data.frame(estacionamientos=estacionamientos,recamaras=recamaras, banio=banio, construccion=construccion,terreno=terreno)

prediccion <- predict(object = modelo, 
                      newdata = nuevos.datos)
                      
                      

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

Interpretacion

De acuerdo al caso de casas de durango en el cual se busca predecir el costo de la casa en base a varios aspectos como numero de estacionamientos, recamaras, contruccion y terreno, se utilizo ahora el modelo de arboles de decision.

Los resultados que nos arrojo el arbol de decision son que si la construccion de la casa es menor a 205.5 tendra un precio de $991,950.7, si la construccion es menor a 152.55 tendra un precio de $807,892.2. En cambio si la contruccion es mayor a 250.5 tendra un precio de $3,749,750.

Por ultimo se realizo una prediccion de una casa con los siguientes atributos estacionamientos 2, recamaras 3, construccion 250, terreno 201. La estimacion del precio al aplicar el modelo dio un total de $3,749,750 que si lo comparamos con el modelo de regresion multiple anteriormente es bastante similar.

Referencias bibliograficas

Hernández, F. (2020). Modelos predictivos. https://fhernanb.github.io/libro_mod_pred/

Pizarro, R. (2020). Arboles de regresion para predecir el precio de casas en melbourne. https://rpubs.com/rpizarro/581253