Evidencia 1: Estadística multivariante

Importación de librerías

library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
library(ggplot2)
library(lattice)
library(rpart)
library(rpart.plot)
library(party)
## Loading required package: grid
## Loading required package: mvtnorm
## Loading required package: modeltools
## Loading required package: stats4
## Loading required package: strucchange
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: sandwich
library(gmodels)
library(grid)
library(mvtnorm)
library(modeltools)
library(stats4)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:party':
## 
##     where
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(strucchange)
library(zoo)
library(readr)
library(ggplot2)

Limpieza de base de datos

Se carga base de datos y se realia transformación de tipos de datos

bd <- read.csv("Datos bienes y raices CDMXF (1).csv", stringsAsFactors = TRUE)
bd$Estacionamiento <- as.numeric(bd$Estacionamiento)
bd$Precio <- as.numeric(bd$Precio)

Se eliminan duplicados

bd <- unique(bd)
dim(bd) #5 registros duplicados
## [1] 653  23

Se elimina outliers por medio del rango intercuartil de la variable precio y eliminación de nulos

conteorango <- sum(bd$Precio >= 0 & bd$Precio < 100, na.rm = TRUE)
conteorango
## [1] 1
bd$Precio <- replace(bd$Precio, bd$Precio >= 0 & bd$Precio < 100, NA)

bd$Precio[is.na(bd$Precio)] <- median(bd$Precio, na.rm = TRUE)

#Eliminar valores extremos adicionales usando el rango intercuartil
q1 <- quantile(bd$Precio, 0.25, na.rm=TRUE)
q3 <- quantile(bd$Precio, 0.75, na.rm=TRUE)
rangointq <- q3 - q1

limite_inferior <- q1 - 1.5 * rangointq
limite_superior <- q3 + 1.5 * rangointq

bd <- subset(bd, Precio >= limite_inferior & Precio <= limite_superior)
summary(bd$Precio)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   116.0   823.8  1728.0  2993.1  4250.0 12500.0

Se reemplazan variantes de valores para solamente tener “Si” y “No”

# Cambiar los valores
bd$Cocina_equip <- gsub("Sí|Si ", "Si", bd$Cocina_equip)
bd$Gimnasio <- gsub("Sí|Si ", "Si", bd$Gimnasio)
bd$Amueblado <- gsub("Sí|Si ", "Si", bd$Amueblado)
bd$Alberca <- gsub("Sí|Si ", "Si", bd$Alberca)
bd$Alberca <- gsub("si|si ", "Si", bd$Alberca)
bd$Terraza <- gsub("Sí|Si ", "Si", bd$Terraza)
bd$Elevador <- gsub("Sí|Si ", "Si", bd$Elevador)
bd$Elevador <- gsub("si|si  ", "Si", bd$Elevador)

bd$Cocina_equip <- gsub("No ", "No", bd$Cocina_equip)
bd$Gimnasio <- gsub("No ", "No", bd$Gimnasio)
bd$Amueblado <- gsub("No ", "No", bd$Amueblado)
bd$Alberca <- gsub("No ", "No", bd$Alberca)
bd$Terraza <- gsub("No ", "No", bd$Terraza)
bd$Elevador <- gsub("No ", "No", bd$Elevador)

unique(bd$Gimnasio)
## [1] "Si" "No"

Se convierten los datos a factores

#Conversión a factores
for (i in colnames(bd)) {
  if (is.character(bd[[i]])) {
    bd[[i]] <- as.factor(bd[[i]])
  }
}

# Visualizar los datos
summary(bd)
##                 Alcaldia                         Colonia          X1       
##  Iztapalapa         : 92   Santa Fe                  : 22   Min.   :0.350  
##  Tlahuac            : 80   San Angel                 : 13   1st Qu.:1.020  
##  Alvaro Obregon     : 79   San Jer\xf3nimo L\xedndice: 11   Median :1.400  
##  Gustavo A. Madero  : 79   Lomas Estrella            : 10   Mean   :1.383  
##  Coyoacan           : 45   Miguel Hidalgo            : 10   3rd Qu.:1.550  
##  Venustiano Carranza: 33   Tepalcates                :  9   Max.   :2.800  
##  (Other)            :192   (Other)                   :525                  
##        X2              X3              X4              X5       
##  Min.   :3.810   Min.   :31.70   Min.   : 6.07   Min.   :18.46  
##  1st Qu.:4.980   1st Qu.:40.21   1st Qu.:16.35   1st Qu.:24.42  
##  Median :5.620   Median :42.85   Median :18.21   Median :26.78  
##  Mean   :5.355   Mean   :42.56   Mean   :17.46   Mean   :26.61  
##  3rd Qu.:5.680   3rd Qu.:46.56   3rd Qu.:20.05   3rd Qu.:28.25  
##  Max.   :6.780   Max.   :51.23   Max.   :23.46   Max.   :32.20  
##                                                                 
##        X6              X7               X8                X9        
##  Min.   :0.480   Min.   : 0.030   Min.   :0.02000   Min.   : 3.170  
##  1st Qu.:2.280   1st Qu.: 0.280   1st Qu.:0.03000   1st Qu.: 6.980  
##  Median :3.190   Median : 0.300   Median :0.05000   Median : 8.250  
##  Mean   :3.476   Mean   : 1.077   Mean   :0.08055   Mean   : 7.997  
##  3rd Qu.:4.540   3rd Qu.: 0.710   3rd Qu.:0.10000   3rd Qu.: 9.560  
##  Max.   :8.530   Max.   :10.210   Max.   :0.23000   Max.   :13.060  
##                                                                     
##       X10        Cocina_equip Gimnasio Amueblado Alberca  Terraza  Elevador
##  Min.   :15.15   No: 61       No:453   No:587    No:520   No:335   No:292  
##  1st Qu.:36.60   Si:539       Si:147   Si: 13    Si: 80   Si:265   Si:308  
##  Median :43.86                                                             
##  Mean   :41.04                                                             
##  3rd Qu.:50.08                                                             
##  Max.   :63.97                                                             
##                                                                            
##  m2_construido        Banos         Recamaras     Estacionamiento
##  Min.   : 34.00   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.: 57.00   1st Qu.:1.000   1st Qu.:2.000   1st Qu.:2.000  
##  Median : 70.00   Median :1.000   Median :2.000   Median :2.000  
##  Mean   : 88.24   Mean   :1.562   Mean   :2.262   Mean   :2.297  
##  3rd Qu.:100.25   3rd Qu.:2.000   3rd Qu.:3.000   3rd Qu.:3.000  
##  Max.   :450.00   Max.   :5.000   Max.   :5.000   Max.   :7.000  
##                                                                  
##      Precio       
##  Min.   :  116.0  
##  1st Qu.:  823.8  
##  Median : 1728.0  
##  Mean   : 2993.1  
##  3rd Qu.: 4250.0  
##  Max.   :12500.0  
## 

Observaciones:

Significado de cada una de las X

##Clusterizacion##

Se seleccionan variables X

# Seleccionar solo las variables numéricas
datos_clusters <- bd[sapply(bd, is.numeric)]

Se excluyen variables categóricas

columnas_a_excluir <- c("Precio", "m2_construido", "Banos", "Recamaras", "Estacionamiento")

Se genera merge

datos_clusters <- datos_clusters[, !names(datos_clusters) %in% columnas_a_excluir]

Se escala la bd anterior

Se genera método de k-means y su gráfica

set.seed(123)
wcss <- vector()
max_k <- 10 #se puede modificar
for (k in 1:max_k) {
  kmeans_model <- kmeans(dfc_scaled, centers = k, nstart = 25)
  wcss[k] <- kmeans_model$tot.withinss
}

# Graficar el método del codo
par(mar = c(4, 4, 1, 1))
plot(1:max_k, wcss, type = "b", xlab = "Numero de Clusters", ylab = "WCSS", main = "Metodo del Codo", pch = 19, frame = FALSE)

Se realiza análisis de conglomerados k-means con 5 grupos/clusters

k <- 5

indices_centroides_iniciales <- sample(1:nrow(dfc_scaled),k)
centroides_iniciales <- dfc_scaled[indices_centroides_iniciales, ]

resultado_kmeans <- kmeans(dfc_scaled, centers = centroides_iniciales)
print(resultado_kmeans)
## K-means clustering with 5 clusters of sizes 205, 91, 132, 90, 82
## 
## Cluster means:
##            X1         X2         X3          X4         X5         X6
## 1 -0.01229747 -0.1670383 -0.2039899  0.09587836 -0.4141441 -0.1649009
## 2  0.64762161 -1.3830533  0.9327452  0.73317336  0.1590626  1.2306895
## 3  1.16542516  0.1099135  1.0324527  1.01598968  1.4941049  0.9152052
## 4 -0.87491379  1.4820834 -0.1918941 -0.64352157 -0.3583660 -0.9416883
## 5 -1.60373738  0.1488367 -1.9765264 -1.98253094 -1.1529764 -1.3932097
##           X7         X8          X9        X10
## 1 -0.1503282 -0.5822788 -0.06552285 -0.1250894
## 2  0.2532510  0.6063286  1.04756593  1.2348923
## 3  0.6274710  1.5423629  0.68370493  0.8541518
## 4 -0.4007392 -0.7049406 -0.32094289 -0.5444220
## 5 -0.4754661 -0.9262925 -1.74707933 -1.8351457
## 
## Clustering vector:
##   1   2   4   5   6   8   9  10  11  12  13  14  15  17  18  19  20  21  22  23 
##   3   2   2   2   2   1   3   4   3   1   1   3   5   1   5   4   4   5   3   4 
##  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  42  43  44  45 
##   1   3   4   4   3   3   1   2   2   1   1   2   1   1   2   1   3   1   1   1 
##  46  47  49  50  51  53  54  55  56  57  58  61  62  63  64  65  66  67  68  69 
##   1   1   4   3   3   1   5   1   2   5   5   3   2   1   2   5   3   1   3   1 
##  70  71  72  73  74  75  76  77  78  82  83  84  85  86  87  88  89  90  91  92 
##   1   3   4   1   1   1   1   4   2   3   1   1   3   5   4   1   2   1   1   3 
##  94  96  97  98  99 100 101 102 103 104 105 106 107 108 110 111 112 113 115 116 
##   4   1   3   3   1   5   3   5   3   1   1   3   4   5   3   3   1   4   5   1 
## 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 
##   3   1   2   1   1   1   2   1   3   1   3   3   4   1   4   4   2   5   5   5 
## 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 
##   3   2   4   5   1   3   5   2   3   1   1   4   1   4   3   1   1   3   2   2 
## 157 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 
##   5   4   2   4   5   3   1   1   3   1   3   2   1   3   1   2   4   1   4   4 
## 178 179 180 181 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 
##   2   1   2   5   1   2   1   3   2   1   2   1   1   3   1   3   4   3   1   1 
## 199 200 201 202 203 204 207 208 209 210 212 213 214 216 217 218 219 221 222 223 
##   3   1   5   3   1   2   2   1   1   4   1   4   1   1   4   2   4   1   1   2 
## 224 225 226 227 228 229 230 231 232 233 234 235 237 238 239 240 241 242 243 244 
##   3   5   5   4   5   4   3   1   3   1   1   2   5   1   4   1   1   1   1   2 
## 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 262 263 264 265 
##   4   3   1   2   2   3   2   1   1   3   2   2   3   5   1   3   1   2   1   4 
## 266 267 268 270 271 272 273 274 275 276 277 278 279 280 281 283 284 285 286 287 
##   1   1   1   4   1   1   5   1   1   1   4   1   5   5   2   3   2   1   1   3 
## 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 
##   5   5   3   1   5   2   4   4   5   3   2   2   3   1   4   4   4   3   5   1 
## 308 309 310 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 
##   3   3   2   3   5   2   1   1   5   3   3   1   4   1   3   1   3   1   1   3 
## 329 330 332 333 334 335 336 337 338 339 340 341 342 343 345 346 347 348 349 350 
##   4   1   1   1   4   1   2   1   5   4   4   5   5   4   2   5   2   4   2   3 
## 351 352 353 354 355 356 358 359 360 361 362 363 364 365 366 367 368 369 370 371 
##   1   1   1   1   5   2   3   1   3   4   2   4   2   2   2   1   1   4   4   3 
## 372 373 374 375 377 378 379 380 381 382 383 384 385 386 387 388 389 390 393 394 
##   4   1   5   4   5   3   3   3   5   5   1   2   1   3   5   1   2   1   1   1 
## 395 396 397 398 399 400 401 402 403 404 405 407 408 409 410 411 413 414 415 416 
##   3   4   4   2   3   2   4   4   1   1   5   1   1   4   3   3   3   3   3   1 
## 417 418 419 420 421 422 424 425 426 427 428 429 431 432 433 434 435 436 437 438 
##   1   5   3   2   4   4   5   3   3   3   5   3   3   5   3   5   4   3   1   1 
## 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 
##   4   1   3   1   5   1   1   2   3   3   4   3   5   2   4   4   1   4   1   3 
## 459 460 461 462 463 464 465 466 467 469 470 471 472 473 474 475 476 477 478 479 
##   1   5   3   4   3   1   1   4   3   1   1   3   1   3   1   1   2   3   4   5 
## 480 481 482 483 484 485 486 487 488 489 491 492 493 495 496 497 498 499 500 502 
##   2   2   1   5   1   1   3   1   3   1   5   5   3   2   5   1   2   2   1   2 
## 503 504 505 506 507 509 510 511 512 513 514 515 516 517 518 519 520 522 523 525 
##   5   1   2   3   1   1   1   4   1   3   5   3   5   2   2   5   1   3   3   1 
## 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 
##   4   3   1   4   5   3   4   2   4   4   2   3   4   1   2   3   2   4   1   3 
## 546 547 548 549 551 552 553 556 557 558 559 560 561 562 563 564 565 566 569 570 
##   1   4   2   2   3   1   1   1   5   1   1   5   2   1   4   5   1   2   1   5 
## 571 572 574 575 576 577 578 579 580 581 582 583 584 586 587 588 589 590 591 592 
##   3   1   2   1   1   1   1   3   3   3   1   5   3   2   5   4   5   1   2   5 
## 593 594 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 
##   4   1   3   5   1   1   1   1   3   1   1   1   2   3   3   5   1   1   3   4 
## 615 616 617 618 620 621 622 624 625 626 627 628 629 630 631 632 634 635 636 637 
##   5   1   5   5   1   2   1   2   3   3   2   1   1   1   1   1   2   1   2   5 
## 638 639 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 
##   2   4   3   4   3   5   4   1   4   4   4   1   3   3   1   5   5   3   3   4 
## 
## Within cluster sum of squares by cluster:
## [1] 348.5061 299.1237 489.8702 153.6554 185.7432
##  (between_SS / total_SS =  75.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
bd$Cluster <- resultado_kmeans$cluster

Se crea matriz de calor para visualizar los centroides de los grupos del análisis de conglomerados k-means. Con base a eso, se determinan etiquetas de cada cluster: - cluster1 = “Zona Mixta”, - cluster2 = “Zona Economica”, - cluster3 = “Zona Marginada”, - cluster4 = “Zona Residencial”, - cluster5 = “Zona Premium”

centros <- resultado_kmeans$centers

# Transponer la matriz para que las filas representen variables y las columnas representen centros de clústeres
centros_transpuestos <- t(centros)
heatmap(centros_transpuestos, col = colorRampPalette(c("red", "green"))(20), scale = "none")

Se convierte cada cluster en variable

#Clusters a variables
cluster1 <-  bd %>% 
  filter(Cluster == 1) %>%
  select(Cocina_equip, Gimnasio, Amueblado, Alberca, Terraza, Elevador, m2_construido, Banos, Recamaras, Estacionamiento, Precio, Cluster)

cluster2 <-  bd %>% 
  filter( Cluster == 2) %>%
  select(Cocina_equip, Gimnasio, Amueblado, Alberca, Terraza, Elevador, m2_construido, Banos, Recamaras, Estacionamiento, Precio, Cluster)

cluster3 <-  bd %>% 
  filter( Cluster == 3) %>%
  select(Cocina_equip, Gimnasio, Amueblado, Alberca, Terraza, Elevador, m2_construido, Banos, Recamaras, Estacionamiento, Precio, Cluster)

cluster4 <-  bd %>% 
  filter( Cluster == 4) %>%
  select(Cocina_equip, Gimnasio, Amueblado, Alberca, Terraza, Elevador, m2_construido, Banos, Recamaras, Estacionamiento, Precio, Cluster)

cluster5 <-  bd %>% 
  filter( Cluster == 5) %>%
  select(Cocina_equip, Gimnasio, Amueblado, Alberca, Terraza, Elevador, m2_construido, Banos, Recamaras, Estacionamiento, Precio, Cluster)

##Árboles de decisión##

###Arbol 1###

Se genera arbol de decision para el cluster 1

cluster1$Cluster <- NULL

#ARBOL CLUSTER 1
set.seed(123)

# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
trainIndex1 <- createDataPartition(cluster1$Precio, p = 0.5, list = FALSE, times = 1)
train <- cluster1[trainIndex1, ]
temp <- cluster1[-trainIndex1, ]

# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
trainIndex2 <- createDataPartition(cluster1$Precio, p = 0.5, list = FALSE, times = 1)
validation <- temp[trainIndex2, ]
test <- temp[-trainIndex2, ]

# Construir el árbol de decisión
tree <- rpart(Precio ~ ., data = train, method = "anova", control = rpart.control(cp = 0.0))
rpart.plot(tree)

rpart.plot(tree,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Visualizar la curva de complejidad de costo
plotcp(tree)

Validacion Cruzada Arbol 1

Se entrena el modelo con validación cruzada y se genera árbol podado

#### Imputar valores faltantes
preproc <- preProcess(validation, method = "medianImpute")
validation_clean <- predict(preproc, cluster1)

# Definir el método de control de entrenamiento para la validación cruzada k-fold 10 pliegues o subconjuntos. El modelo se entrena 10 veces
ctrl <- trainControl(method = "cv", number = 10)

#Entrenar el modelo con validación cruzada
tree_model_cv <- train(Precio ~ ., data = validation_clean, 
                       method = "rpart", 
                       trControl = ctrl,
                       tuneLength = 10)
## Warning in nominalTrainWorkflow(x = x, y = y, wts = weights, info = trainInfo,
## : There were missing values in resampled performance measures.
# Ver los resultados
print(tree_model_cv)
## CART 
## 
## 205 samples
##  10 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 185, 184, 185, 185, 185, 183, ... 
## Resampling results across tuning parameters:
## 
##   cp           RMSE      Rsquared   MAE     
##   0.003608460  1968.573  0.7099683  1234.724
##   0.003692738  1969.835  0.7097674  1239.933
##   0.005315913  1988.867  0.7060580  1236.410
##   0.009337947  1978.756  0.7038307  1265.994
##   0.011321102  1976.867  0.7062888  1263.683
##   0.016164531  2018.379  0.6937190  1296.222
##   0.018711081  2061.550  0.6793739  1315.024
##   0.021412593  2058.870  0.6814553  1355.202
##   0.124210799  2577.552  0.5339962  1869.551
##   0.630959235  3180.049  0.4695315  2523.803
## 
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was cp = 0.00360846.
# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree <- prune(tree, cp = 0.0026)

# Visualizar el árbol podado
rpart.plot(pruned_tree)

# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree <- prune(tree, cp = 0.005)

# Visualizar el árbol podado
rpart.plot(pruned_tree)

rpart.plot(pruned_tree,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

Se realiza análisis de error y/o evaluación de modelo

# Realizar predicciones en el conjunto de prueba con el árbol podado
predictions1 <- predict(pruned_tree, newdata = test)

# Calcular e imprimir las métricas de evaluación para el modelo podado
postResample(pred = predictions1, obs = test$Precio)
##         RMSE     Rsquared          MAE 
## 1780.6426214    0.7796483 1181.8337687

###Arbol 2###

Se genera arbol de decision para el cluster 2 y su curva de complejidad

cluster2$Cluster <- NULL

#ARBOL CLUSTER 2
set.seed(123)

# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
trainIndexc2 <- createDataPartition(cluster2$Precio, p = 0.5, list = FALSE, times = 1)
train2 <- cluster2[trainIndexc2, ]
temp2 <- cluster2[-trainIndexc2, ]

# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
trainIndexc2 <- createDataPartition(cluster2$Precio, p = 0.5, list = FALSE, times = 1)
validation2 <- temp2[trainIndexc2, ]
test2 <- temp2[-trainIndexc2, ]

# Construir el árbol de decisión
tree2 <- rpart(Precio ~ ., data = train2, method = "anova", control = rpart.control(cp = 0.0))
rpart.plot(tree2)

rpart.plot(tree2,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Visualizar la curva de complejidad de costo
plotcp(tree2)

Validación Cruzada Arbol 2

Se entrena el modelo con validación cruzada y se genera árbol podado junto con análisis de error de modelo

#### Imputar valores faltantes
preproc2 <- preProcess(validation2, method = "medianImpute")
validation_clean2 <- predict(preproc2, cluster2)

# Definir el método de control de entrenamiento para la validación cruzada k-fold 10 pliegues o subconjuntos. El modelo se entrena 10 veces
ctrl2 <- trainControl(method = "cv", number = 10)

#convertir a factores
# Entrenar el modelo con validación cruzada
tree_model_cv2 <- train(Precio ~ ., data = validation_clean2, 
                       method = "rpart", 
                       trControl = ctrl,
                       tuneLength = 10)
## Warning in nominalTrainWorkflow(x = x, y = y, wts = weights, info = trainInfo,
## : There were missing values in resampled performance measures.
# Ver los resultados
print(tree_model_cv2)
## CART 
## 
## 91 samples
## 10 predictors
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 80, 82, 83, 81, 82, 81, ... 
## Resampling results across tuning parameters:
## 
##   cp          RMSE      Rsquared   MAE     
##   0.00000000  737.2043  0.1532078  509.2189
##   0.01604080  735.7325  0.1654455  504.0341
##   0.03208161  743.5254  0.1696093  514.4819
##   0.04812241  739.1747  0.1640186  504.4722
##   0.06416321  711.0589  0.1640186  493.3611
##   0.08020401  711.0589  0.1640186  493.3611
##   0.09624482  730.7579  0.1345626  510.6359
##   0.11228562  721.0586  0.1418700  514.2956
##   0.12832642  711.7599  0.1474244  507.0132
##   0.14436723  738.4366  0.0460703  525.0279
## 
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was cp = 0.08020401.
# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree2 <- prune(tree2, cp = 0.0026)

# Visualizar el árbol podado
rpart.plot(pruned_tree2)

# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree2 <- prune(tree2, cp = 0.005)

# Visualizar el árbol podado
rpart.plot(pruned_tree2)

rpart.plot(pruned_tree2,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Realizar predicciones en el conjunto de prueba con el árbol podado
predictions2 <- predict(pruned_tree2, newdata = test)

# Calcular e imprimir las métricas de evaluación para el modelo podado
postResample(pred = predictions2, obs = test2$Precio)
##      RMSE  Rsquared       MAE 
##        NA 0.1568795        NA

###Arbol 3###

Se genera arbol de decision para el cluster 3 y su curva de complejidad

cluster3$Cluster <- NULL

#ARBOL CLUSTER 3
set.seed(123)

# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
trainIndexc3 <- createDataPartition(cluster3$Precio, p = 0.5, list = FALSE, times = 1)
train3 <- cluster3[trainIndexc3, ]
temp3 <- cluster3[-trainIndexc3, ]

# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
trainIndexc3 <- createDataPartition(cluster3$Precio, p = 0.5, list = FALSE, times = 1)
validation3 <- temp3[trainIndexc3, ]
test3 <- temp3[-trainIndexc3, ]

# Construir el árbol de decisión
tree3 <- rpart(Precio ~ ., data = train3, method = "anova", control = rpart.control(cp = 0.0))
rpart.plot(tree3)

rpart.plot(tree3,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Visualizar la curva de complejidad de costo
plotcp(tree3)

Validación Cruzada Arbol 3

Se entrena el modelo con validación cruzada y se genera árbol podado junto con análisis de error de modelo

#### Imputar valores faltantes
preproc3 <- preProcess(validation3, method = "medianImpute")
validation_clean3 <- predict(preproc3, cluster3)

# Definir el método de control de entrenamiento para la validación cruzada k-fold 10 pliegues o subconjuntos. El modelo se entrena 10 veces
ctrl3 <- trainControl(method = "cv", number = 10)

#convertir a factores
# Entrenar el modelo con validación cruzada
tree_model_cv3 <- train(Precio ~ ., data = validation_clean3, 
                       method = "rpart", 
                       trControl = ctrl,
                       tuneLength = 10)
## Warning in nominalTrainWorkflow(x = x, y = y, wts = weights, info = trainInfo,
## : There were missing values in resampled performance measures.
# Ver los resultados
print(tree_model_cv3)
## CART 
## 
## 132 samples
##  10 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 119, 119, 118, 119, 119, 119, ... 
## Resampling results across tuning parameters:
## 
##   cp            RMSE       Rsquared   MAE      
##   0.0000000000   899.6444  0.7842331   594.9948
##   0.0002700762   896.7100  0.7878015   591.2929
##   0.0002936850   895.0033  0.7899250   589.9053
##   0.0003103346   895.0033  0.7899250   589.9053
##   0.0003550067   894.5138  0.7903115   588.3246
##   0.0009200305   886.7699  0.7957676   577.1581
##   0.0023527258   886.7394  0.7974596   584.4370
##   0.0127825796   898.8997  0.7859079   600.3619
##   0.0857525313   981.6731  0.7830664   672.0426
##   0.7001881662  1510.2018  0.6797223  1044.4741
## 
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was cp = 0.002352726.
# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree3 <- prune(tree3, cp = 0.0026)

# Visualizar el árbol podado
rpart.plot(pruned_tree3)

# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree3 <- prune(tree3, cp = 0.005)

# Visualizar el árbol podado
rpart.plot(pruned_tree3)

rpart.plot(pruned_tree3,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Realizar predicciones en el conjunto de prueba con el árbol podado
predictions3 <- predict(pruned_tree3, newdata = test)

# Calcular e imprimir las métricas de evaluación para el modelo podado
postResample(pred = predictions3, obs = test3$Precio)
##        RMSE    Rsquared         MAE 
##          NA 0.006732611          NA

###Arbol 4###

Se genera arbol de decision para el cluster 4 y su curva de complejidad. Cabe destacar que, no se realiza podada de árbol para obtener mayor precision en la prediccion

cluster4$Cluster <- NULL

#ARBOL CLUSTER 4
set.seed(123)

# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
trainIndexc4 <- createDataPartition(cluster4$Precio, p = 0.5, list = FALSE, times = 1)
train4 <- cluster4[trainIndexc4, ]
temp4 <- cluster4[-trainIndexc4, ]

# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
trainIndexc4 <- createDataPartition(cluster4$Precio, p = 0.5, list = FALSE, times = 1)
validation4 <- temp4[trainIndexc4, ]
test4 <- temp4[-trainIndexc4, ]

# Construir el árbol de decisión
tree4 <- rpart(Precio ~ ., data = train4, method = "anova", control = rpart.control(cp = 0.0))
rpart.plot(tree4)

rpart.plot(tree4,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Visualizar la curva de complejidad de costo
plotcp(tree4)

#ERROR
# Realizar predicciones en el conjunto de prueba con el árbol podado
predictions4 <- predict(tree4, newdata = test)

# Calcular e imprimir las métricas de evaluación para el modelo podado
postResample(pred = predictions4, obs = test4$Precio)
##       RMSE   Rsquared        MAE 
##         NA 0.06356008         NA

###Arbol 5###

Se genera arbol de decision para el cluster 5 y su curva de complejidad

cluster5$Cluster <- NULL

#ARBOL CLUSTER 5
set.seed(123)

# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
trainIndexc5 <- createDataPartition(cluster5$Precio, p = 0.5, list = FALSE, times = 1)
train5 <- cluster5[trainIndexc5, ]
temp5 <- cluster5[-trainIndexc5, ]

# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
trainIndexc5 <- createDataPartition(cluster5$Precio, p = 0.5, list = FALSE, times = 1)
validation5 <- temp5[trainIndexc5, ]
test5 <- temp5[-trainIndexc5, ]

# Construir el árbol de decisión
tree5 <- rpart(Precio ~ ., data = train5, method = "anova", control = rpart.control(cp = 0.0))
rpart.plot(tree5)

rpart.plot(tree5,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Visualizar la curva de complejidad de costo
plotcp(tree5)

Validación Cruzada Arbol 5

Se entrena el modelo con validación cruzada y se genera árbol podado junto con análisis de error de modelo

# Imputar valores faltantes
preproc5 <- preProcess(validation5, method = "medianImpute")
validation_clean5 <- predict(preproc5, cluster5)

# Definir el método de control de entrenamiento para la validación cruzada k-fold 10 pliegues o subconjuntos. El modelo se entrena 10 veces
ctrl5 <- trainControl(method = "cv", number = 10)

#convertir a factores
# Entrenar el modelo con validación cruzada
tree_model_cv5 <- train(Precio ~ ., data = validation_clean5, 
                       method = "rpart", 
                       trControl = ctrl,
                       tuneLength = 10)
## Warning in nominalTrainWorkflow(x = x, y = y, wts = weights, info = trainInfo,
## : There were missing values in resampled performance measures.
# Ver los resultados
print(tree_model_cv5)
## CART 
## 
## 82 samples
## 10 predictors
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 74, 74, 73, 74, 74, 74, ... 
## Resampling results across tuning parameters:
## 
##   cp          RMSE      Rsquared   MAE     
##   0.00000000  1999.552  0.6317392  1442.161
##   0.05291429  2098.932  0.5852149  1552.446
##   0.10582859  2388.378  0.4601879  1806.913
##   0.15874288  2545.185  0.3885035  1915.309
##   0.21165717  2545.185  0.3885035  1915.309
##   0.26457147  2545.185  0.3885035  1915.309
##   0.31748576  2545.185  0.3885035  1915.309
##   0.37040005  2545.185  0.3885035  1915.309
##   0.42331434  2545.185  0.3885035  1915.309
##   0.47622864  3022.621  0.1176967  2318.497
## 
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was cp = 0.
# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree5 <- prune(tree5, cp = 0.0026)

# Visualizar el árbol podado
rpart.plot(pruned_tree5)

# Elegir un valor de cp basado en la gráfica y podar el árbol
pruned_tree5 <- prune(tree5, cp = 0.005)

# Visualizar el árbol podado
rpart.plot(pruned_tree5)

rpart.plot(pruned_tree5,digits = 4,fallen.leaves = TRUE,type = 3,extra = 101)

# Realizar predicciones en el conjunto de prueba con el árbol podado
predictions5 <- predict(pruned_tree5, newdata = test)

# Calcular e imprimir las métricas de evaluación para el modelo podado
postResample(pred = predictions5, obs = test5$Precio)
##      RMSE  Rsquared       MAE 
##        NA 0.0402678        NA

##Predicciones##

Se agrega nueva fila a la bd con la cual se genera prediccion de precio con cada modelado y arbol de cluster

#Cargar la fila del archivo "PREDICT"
fila_prediccion1 <- read.csv("PREDICT_SP.csv")
fila_prediccion2 <- read.csv("PREDICT_SP.csv")
fila_prediccion3 <- read.csv("PREDICT_SP.csv")
fila_prediccion4 <- read.csv("PREDICT_SP.csv")
fila_prediccion5 <- read.csv("PREDICT_SP.csv")

# Realizar la predicción
prediccion1 <- predict(pruned_tree, newdata = fila_prediccion1)
prediccion2 <- predict(pruned_tree2, newdata = fila_prediccion2)
prediccion3 <- predict(pruned_tree3, newdata = fila_prediccion3)
prediccion4 <- predict(tree4, newdata = fila_prediccion4)
prediccion5 <- predict(pruned_tree5, newdata = fila_prediccion5)

# Obtener el valor del cluster
cluster1 <- as.character(prediccion1[1])
prediccion1
##        1 
## 651.3548
cluster2 <- as.character(prediccion2[1])
prediccion2
##       1 
## 1301.75
cluster3 <- as.character(prediccion3[1])
prediccion3
##        1 
## 6423.571
cluster4 <- as.character(prediccion4[1])
prediccion4
##      1 
## 5829.9
cluster5 <- as.character(prediccion5[1])
prediccion5
##        1 
## 9287.125

##Etiquetado##

Se genera datframe que muestra el etiquetado de cada cluster y su prediccion de precio segun la fila agregada

# Cambiar el nombre de los cluster
clusters <- c(
  cluster1 = "Zona Mixta",
  cluster2 = "Zona Economica",
  cluster3 = "Zona Marginada",
  cluster4 = "Zona Residencial",
  cluster5 = "Zona Premium"
)

predicciones <- c(
  prediccion1,
  prediccion2,
  prediccion3,
  prediccion4,
  prediccion5
)

df_prediccion <- data.frame(
 Predicciones = predicciones,
  Clasificacion = clusters
)

# Visualizar el DataFrame
df_prediccion
##          Predicciones    Clasificacion
## cluster1     651.3548       Zona Mixta
## cluster2    1301.7500   Zona Economica
## cluster3    6423.5714   Zona Marginada
## cluster4    5829.9000 Zona Residencial
## cluster5    9287.1250     Zona Premium