Alan Aaron Marinez Castillo

10/03/2020

Árboles de regresión para predecir el precio de casas en Melbourne

Las librerías
# Arboles de regresion de prediccion de casas

# install.packages("rpart", "rpart.plot", "caret") 
library(rpart)      # Arboles
library(rpart.plot) # Visualizar y represenar árboles
library(caret)      # Para llevar a cabo particiones de conjuntos de datos en caso de...
library(dplyr)      # Para select, filter, mutate, arange ....
library(readr)      # Para leer datos
library(ggplot2)    # Para grafica mas vistosas
library(reshape)    # Para renombrar columnas
Los datos
ruta="C:/Users/AlanA/Desktop/8vo/Analisis Datos/datos"
setwd(ruta)
datos <- read.csv("datos.csv")
head(datos)
##       Suburb          Address Rooms Type   Price Method SellerG      Date
## 1 Abbotsford     85 Turner St     2    h 1480000      S  Biggin 3/12/2016
## 2 Abbotsford  25 Bloomburg St     2    h 1035000      S  Biggin 4/02/2016
## 3 Abbotsford     5 Charles St     3    h 1465000     SP  Biggin 4/03/2017
## 4 Abbotsford 40 Federation La     3    h  850000     PI  Biggin 4/03/2017
## 5 Abbotsford      55a Park St     4    h 1600000     VB  Nelson 4/06/2016
## 6 Abbotsford   129 Charles St     2    h  941000      S  Jellis 7/05/2016
##   Distance Postcode Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 1      2.5     3067        2        1   1      202           NA        NA
## 2      2.5     3067        2        1   0      156           79      1900
## 3      2.5     3067        3        2   0      134          150      1900
## 4      2.5     3067        3        2   1       94           NA        NA
## 5      2.5     3067        3        1   2      120          142      2014
## 6      2.5     3067        2        1   0      181           NA        NA
##   CouncilArea Lattitude Longtitude            Regionname Propertycount
## 1       Yarra  -37.7996   144.9984 Northern Metropolitan          4019
## 2       Yarra  -37.8079   144.9934 Northern Metropolitan          4019
## 3       Yarra  -37.8093   144.9944 Northern Metropolitan          4019
## 4       Yarra  -37.7969   144.9969 Northern Metropolitan          4019
## 5       Yarra  -37.8072   144.9941 Northern Metropolitan          4019
## 6       Yarra  -37.8041   144.9953 Northern Metropolitan          4019

Elegimos sólo las variables numéricas

  • Un conjunto de datos únicamente con las variables numéricas del conjunto de datos original
datos.Num <- select(datos, Price, Rooms, Distance, Bedroom2, Bathroom, Car, Landsize, BuildingArea, YearBuilt, Propertycount) 
head(datos.Num)
##     Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 1 1480000     2      2.5        2        1   1      202           NA        NA
## 2 1035000     2      2.5        2        1   0      156           79      1900
## 3 1465000     3      2.5        3        2   0      134          150      1900
## 4  850000     3      2.5        3        2   1       94           NA        NA
## 5 1600000     4      2.5        3        1   2      120          142      2014
## 6  941000     2      2.5        2        1   0      181           NA        NA
##   Propertycount
## 1          4019
## 2          4019
## 3          4019
## 4          4019
## 5          4019
## 6          4019

Depurar, limpiar los datos

  • Hay algunos NA que pueden afectar al modelo?
  • Las varraiables Car, BuildingArea y YearBuilding tienen NA summary()
  • Primero encontrar los registros y columnas que tienen NA
  • Actualizar conforme a su mediana, ¿porqué?, decisión del analista, y la finalidad es que no afecten al modelo, que mejor que tengan un valor (la mediana) a que no tengan nada
mediana.BA <- median(datos.Num$BuildingArea, na.rm = TRUE) # summary(datos.Num$BuildingArea)[3], como otra alternativa
mediana.YB <- median(datos.Num$YearBuilt, na.rm = TRUE)    # summary(datos.Num$YearBuilt)[3], , como otra alternativa
mediana.C <- median(datos.Num$Car, na.rm = TRUE)    # summary(datos.Num$Car)[3], , como otra alternativa

Actualizar mutate() los NA por la medianas

  • Las vaiables que tienen NAs
head(datos.Num, 10) # Los primeros 10, se observan NAs
##      Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 1  1480000     2      2.5        2        1   1      202           NA        NA
## 2  1035000     2      2.5        2        1   0      156           79      1900
## 3  1465000     3      2.5        3        2   0      134          150      1900
## 4   850000     3      2.5        3        2   1       94           NA        NA
## 5  1600000     4      2.5        3        1   2      120          142      2014
## 6   941000     2      2.5        2        1   0      181           NA        NA
## 7  1876000     3      2.5        4        2   0      245          210      1910
## 8  1636000     2      2.5        2        1   2      256          107      1890
## 9   300000     1      2.5        1        1   1        0           NA        NA
## 10 1097000     2      2.5        3        1   2      220           75      1900
##    Propertycount
## 1           4019
## 2           4019
## 3           4019
## 4           4019
## 5           4019
## 6           4019
## 7           4019
## 8           4019
## 9           4019
## 10          4019
datos.Num<- datos.Num %>%
  mutate (BuildingArea = ifelse(is.na(BuildingArea), mediana.BA, BuildingArea))

datos.Num <- datos.Num %>%
  mutate (YearBuilt = ifelse(is.na(YearBuilt), mediana.YB, YearBuilt)) 

datos.Num <- datos.Num %>%
  mutate (Car = ifelse(is.na(Car), mediana.C, Car)) 


head(datos.Num, 10) # # Los primeros 10, YA NO se observan NAs
##      Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 1  1480000     2      2.5        2        1   1      202          126      1970
## 2  1035000     2      2.5        2        1   0      156           79      1900
## 3  1465000     3      2.5        3        2   0      134          150      1900
## 4   850000     3      2.5        3        2   1       94          126      1970
## 5  1600000     4      2.5        3        1   2      120          142      2014
## 6   941000     2      2.5        2        1   0      181          126      1970
## 7  1876000     3      2.5        4        2   0      245          210      1910
## 8  1636000     2      2.5        2        1   2      256          107      1890
## 9   300000     1      2.5        1        1   1        0          126      1970
## 10 1097000     2      2.5        3        1   2      220           75      1900
##    Propertycount
## 1           4019
## 2           4019
## 3           4019
## 4           4019
## 5           4019
## 6           4019
## 7           4019
## 8           4019
## 9           4019
## 10          4019

Crear conjuntos de entrenamiento y conjuntos de validación

  • Ya se tienen los datos limpios, sin NAs
  • Primero determinas el 70% de los registros para entrenamiento y 30% estante para validación
  • Se muestran con head y número de registros respectivamente
  • Los datos de entrenamiento representan el 70%
  • Los datos de validación representan el 30% restante
set.seed(2020) # Semilla
entrena <- createDataPartition(datos.Num$Price, p=0.7, list = FALSE)
head(entrena)
##      Resample1
## [1,]         1
## [2,]         3
## [3,]         4
## [4,]         5
## [5,]         7
## [6,]         9
# Ahora a determinar conjuntos de datos de entrenamiento y luego head()
datos.Entrena <- datos.Num[entrena,]
head(datos.Entrena)
##     Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 1 1480000     2      2.5        2        1   1      202          126      1970
## 3 1465000     3      2.5        3        2   0      134          150      1900
## 4  850000     3      2.5        3        2   1       94          126      1970
## 5 1600000     4      2.5        3        1   2      120          142      2014
## 7 1876000     3      2.5        4        2   0      245          210      1910
## 9  300000     1      2.5        1        1   1        0          126      1970
##   Propertycount
## 1          4019
## 3          4019
## 4          4019
## 5          4019
## 7          4019
## 9          4019
# y conjunto de datos de validación y luego head()
datos.Valida <- datos.Num[-entrena,]
head(datos.Valida)
##      Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 2  1035000     2      2.5        2        1   0      156           79      1900
## 6   941000     2      2.5        2        1   0      181          126      1970
## 8  1636000     2      2.5        2        1   2      256          107      1890
## 12 1350000     3      2.5        3        2   2      214          190      2005
## 13  750000     2      2.5        2        2   1        0           94      2009
## 20  890000     2      2.5        2        1   1      150           73      1985
##    Propertycount
## 2           4019
## 6           4019
## 8           4019
## 12          4019
## 13          4019
## 20          4019

Contruir el MODELO árbol

  • 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

arbol <- rpart(formula = Price  ~ ., data = datos.Entrena)
arbol
## n= 9508 
## 
## node), split, n, deviance, yval
##       * denotes terminal node
## 
##  1) root 9508 3.905176e+15 1078063.0  
##    2) Rooms< 3.5 7161 1.741856e+15  931007.8  
##      4) Rooms< 2.5 3023 3.911722e+14  724213.1  
##        8) Landsize< 85.5 1214 6.222679e+13  559018.9 *
##        9) Landsize>=85.5 1809 2.735839e+14  835073.1 *
##      5) Rooms>=2.5 4138 1.126966e+15 1082081.0  
##       10) Distance>=11.9 1576 2.382967e+14  832810.4 *
##       11) Distance< 11.9 2562 7.305050e+14 1235418.0  
##         22) BuildingArea< 156.5 2230 5.283540e+14 1181265.0 *
##         23) BuildingArea>=156.5 332 1.516845e+14 1599162.0 *
##    3) Rooms>=3.5 2347 1.535971e+15 1526746.0  
##      6) Distance>=11.45 1075 2.619142e+14 1136763.0 *
##      7) Distance< 11.45 1272 9.723911e+14 1856331.0  
##       14) BuildingArea< 246.5 1025 5.968351e+14 1695057.0  
##         28) Landsize< 708.5 803 3.644950e+14 1566809.0 *
##         29) Landsize>=708.5 222 1.713594e+14 2158948.0 *
##       15) BuildingArea>=246.5 247 2.382655e+14 2525584.0 *

Visualizar el árbol de regresión

  • Vamos a verlo gráficamente rpart.
prp(arbol, type = 2, nn = TRUE, 
    fallen.leaves = TRUE, faclen = 4,
    varlen = 8,  shadow.col = "gray")

#### Ver las importancia de las variables en el modelo * ctable * LA tabla significa resultados comprensibles de los árboles con diferentes números de nodos, el promedio y la desviación STd para cada uno de los árboles con tamaño especificaco * CP Factor de complejidad el árbol * Número de divisiones en el mejor árbol * El error relativo * El XError otro error * STD La desviació estándard

arbol$cptable
##           CP nsplit rel error    xerror       xstd
## 1 0.16064529      0 1.0000000 1.0001908 0.03335304
## 2 0.07724771      1 0.8393547 0.8397732 0.02940088
## 3 0.05728747      2 0.7621070 0.7627294 0.02731604
## 4 0.04050130      3 0.7048195 0.7055469 0.02633946
## 5 0.03515605      4 0.6643182 0.6669834 0.02651936
## 6 0.01561538      5 0.6291622 0.6395277 0.02549443
## 7 0.01417645      6 0.6135468 0.6211866 0.02488627
## 8 0.01292296      7 0.5993704 0.6079174 0.02482012
## 9 0.01000000      8 0.5864474 0.5990287 0.02442405

Podar el árbol prune()

  • Más simple que el primer arbol
  • ¿Cómo elegir la poda?
  • Sumar el último valor XError = 0.5990287 + xstd = 0.02442405
  • 0.6234527 = 0.5990287 + 0.02442405
  • El primer árbol que esta por encima de dicho valor
  • El registro 7 encontrar su CP actoe de complejidad
plotcp(arbol)

  • El nodo siete es servirá para ser un buen modelo

Podar el árbol

  • Podar el árbol prune()
  • Mas simple que el primer arbol
arbol.Recortado <- prune(arbol, cp = 0.01417645)

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

#### Predicciones con el conjunto de datos de validación

summary(datos.Valida)
##      Price             Rooms          Distance        Bedroom2     
##  Min.   : 170000   Min.   :1.000   Min.   : 0.00   Min.   : 0.000  
##  1st Qu.: 649500   1st Qu.:2.000   1st Qu.: 6.20   1st Qu.: 2.000  
##  Median : 902500   Median :3.000   Median : 9.20   Median : 3.000  
##  Mean   :1070130   Mean   :2.941   Mean   :10.15   Mean   : 2.923  
##  3rd Qu.:1330000   3rd Qu.:4.000   3rd Qu.:13.00   3rd Qu.: 3.000  
##  Max.   :8000000   Max.   :8.000   Max.   :48.10   Max.   :20.000  
##     Bathroom          Car           Landsize        BuildingArea    
##  Min.   :0.000   Min.   : 0.00   Min.   :    0.0   Min.   :    0.0  
##  1st Qu.:1.000   1st Qu.: 1.00   1st Qu.:  173.0   1st Qu.:  120.0  
##  Median :1.000   Median : 2.00   Median :  435.0   Median :  126.0  
##  Mean   :1.547   Mean   : 1.61   Mean   :  508.9   Mean   :  146.2  
##  3rd Qu.:2.000   3rd Qu.: 2.00   3rd Qu.:  653.0   3rd Qu.:  130.0  
##  Max.   :8.000   Max.   :10.00   Max.   :44500.0   Max.   :44515.0  
##    YearBuilt    Propertycount  
##  Min.   :1196   Min.   :  249  
##  1st Qu.:1960   1st Qu.: 4217  
##  Median :1970   Median : 6543  
##  Mean   :1967   Mean   : 7457  
##  3rd Qu.:1972   3rd Qu.:10331  
##  Max.   :2017   Max.   :21650
prediccion.price <- predict(arbol, newdata = datos.Valida
)
# La predicción para la casa 1
datos.Valida[1,]
##     Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 2 1035000     2      2.5        2        1   0      156           79      1900
##   Propertycount
## 2          4019
prediccion.price[1]
##        2 
## 835073.1

Aqui comenzamos a cargar nuestros nuevos datos, los cuales nos permitiran realizar el modelo árbol de regresión y de regresión mútiple

Price=0
Rooms=c(3,2,4,5,2)

Distance=c(7,6,8,9,5)

Bedroom2=c(3,4,2,3,2)

Bathroom=c(2,1,3,4,3)

Car=c(3,2,3,4,5)

Landsize=c(400,450,460,480,500)

BuildingArea=c(120,130,150,180,190)

YearBuilt=c(1930,1940,1950,1960,1970)

Propertycount=c(5000,5400,5600,5800,6000)
nuevo.Dato <- data.frame(Price,Rooms, Distance, Bedroom2, Bathroom, Car, Landsize, BuildingArea, YearBuilt,
Propertycount)

colnames(nuevo.Dato) <- c("Price", "Rooms", "Distance", "Bedroom2", "Bathroom", "Car", "Landsize", "BuildingArea", "YearBuilt", "Propertycount")

nuevo.Dato
##   Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 1     0     3        7        3        2   3      400          120      1930
## 2     0     2        6        4        1   2      450          130      1940
## 3     0     4        8        2        3   3      460          150      1950
## 4     0     5        9        3        4   4      480          180      1960
## 5     0     2        5        2        3   5      500          190      1970
##   Propertycount
## 1          5000
## 2          5400
## 3          5600
## 4          5800
## 5          6000

Primero usamos el modelo de arboles.

prediccion.price <- predict(arbol, newdata = nuevo.Dato
)
# La predicción para la casa 1
datos.Valida[1,]
##     Price Rooms Distance Bedroom2 Bathroom Car Landsize BuildingArea YearBuilt
## 2 1035000     2      2.5        2        1   0      156           79      1900
##   Propertycount
## 2          4019
#Prediccion precio 1
prediccion.price[1]
##       1 
## 1181265
#Prediccion precio 2
prediccion.price[2]
##        2 
## 835073.1
#Prediccion precio 3

prediccion.price[3]
##       3 
## 1566809
#Prediccion precio 4
prediccion.price[4]
##       4 
## 1566809
#Prediccion precio 5
prediccion.price[5]
##        5 
## 835073.1

Despues lo haremos usando el modelo de regresión mútiple

modelo <- lm(Price ~ ., datos.Entrena)
modelo
## 
## Call:
## lm(formula = Price ~ ., data = datos.Entrena)
## 
## Coefficients:
##   (Intercept)          Rooms       Distance       Bedroom2       Bathroom  
##     1.031e+07      1.889e+05     -3.116e+04      3.998e+04      2.527e+05  
##           Car       Landsize   BuildingArea      YearBuilt  Propertycount  
##     6.403e+04      3.342e+00      5.647e+02     -5.159e+03     -1.143e+00
modelo <- lm(Price ~ ., datos.Valida)
modelo
## 
## Call:
## lm(formula = Price ~ ., data = datos.Valida)
## 
## Coefficients:
##   (Intercept)          Rooms       Distance       Bedroom2       Bathroom  
##     9.056e+06      2.323e+05     -3.189e+04      2.120e+04      2.502e+05  
##           Car       Landsize   BuildingArea      YearBuilt  Propertycount  
##     4.811e+04      2.836e+01     -7.488e+00     -4.511e+03     -1.789e+00
predecir1 <- predict(modelo, newdata = nuevo.Dato )
predecir1[1]
##       1 
## 1533019
predecir1[2]
##       2 
## 1011038
predecir1[3]
##       3 
## 1872586
predecir1[4]
##       4 
## 2347359
predecir1[5]
##       5 
## 1509845

Interpretaciones