#El mercado de bienes raíces en la CDMX
La Ciudad de México, como metrópolis en constante crecimiento y cambio, presenta un mercado inmobiliario dinámico y complejo. La comprensión profunda de este mercado no solo es crucial para inversionistas y desarrolladores, sino también para individuos y familias en busca de su hogar ideal. En este contexto, el análisis de datos inmobiliarios mediante técnicas avanzadas de minería de datos y aprendizaje automático, como se demostró en el código proporcionado, es fundamental. Este análisis abarcó desde la limpieza y preparación de datos hasta la aplicación de algoritmos sofisticados como K-Means para segmentación y modelos predictivos como árboles de decisión. Al investigar y aplicar estas técnicas, se ha realizado un esfuerzo significativo para extraer insights valiosos sobre precios, tendencias y patrones del mercado inmobiliario de la CDMX, con el objetivo de proporcionar una base sólida para la toma de decisiones informadas en este sector vital.
En primer lugar, se cargan las librerías necesarias para el funcionamiento del código.
library(caret)
library(rpart)
library(rpart.plot)
library(party)
library(gmodels)
library(knitr)
library(readxl)
library(readr)
library(dplyr)
library(cluster)
library(ggplot2)
library(corrplot)
Posteriormente, se carga la base de datos de los bienes y raíces de la Ciudad de México, a la cual se le denomina “df”. Así mismo, se comienza a hacer un análisis exploratorio de los datos para conocer el tipo de variables con el que se está trabajando y la estructura general de la base de datos.
#Carga
#file.choose()
<- read.csv("/Users/gabrielmedina/Downloads/Datos bienes y raices 22CDMXF.csv")
df dim(df)
## [1] 658 23
summary(df)
## Alcaldia Colonia X1 X2
## Length:658 Length:658 Min. :0.350 Min. :3.810
## Class :character Class :character 1st Qu.:0.960 1st Qu.:4.980
## Mode :character Mode :character Median :1.400 Median :5.620
## Mean :1.356 Mean :5.371
## 3rd Qu.:1.550 3rd Qu.:5.680
## Max. :2.800 Max. :6.780
## X3 X4 X5 X6
## Min. :31.70 Min. : 6.07 Min. :18.46 Min. :0.480
## 1st Qu.:40.21 1st Qu.:15.50 1st Qu.:23.74 1st Qu.:1.830
## Median :42.85 Median :18.21 Median :25.42 Median :3.190
## Mean :42.34 Mean :17.24 Mean :26.25 Mean :3.395
## 3rd Qu.:46.56 3rd Qu.:20.05 3rd Qu.:28.25 3rd Qu.:4.540
## Max. :51.23 Max. :23.46 Max. :32.20 Max. :8.530
## X7 X8 X9 X10
## Min. : 0.030 Min. :0.02000 Min. : 3.170 Min. :15.15
## 1st Qu.: 0.110 1st Qu.:0.03000 1st Qu.: 6.335 1st Qu.:35.22
## Median : 0.300 Median :0.05000 Median : 8.150 Median :39.65
## Mean : 1.022 Mean :0.07801 Mean : 7.825 Mean :40.16
## 3rd Qu.: 0.710 3rd Qu.:0.10000 3rd Qu.: 9.560 3rd Qu.:50.08
## Max. :10.210 Max. :0.23000 Max. :13.060 Max. :63.97
## Cocina_equip Gimnasio Amueblado Alberca
## Length:658 Length:658 Length:658 Length:658
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## Terraza Elevador m2_construido Banos
## Length:658 Length:658 Min. : 34.0 Min. :1.000
## Class :character Class :character 1st Qu.: 58.0 1st Qu.:1.000
## Mode :character Mode :character Median : 72.5 Median :1.000
## Mean :103.3 Mean :1.685
## 3rd Qu.:120.0 3rd Qu.:2.000
## Max. :500.0 Max. :5.000
## Recamaras Estacionamiento Precio
## Min. :1.000 Length:658 Min. : 1.0
## 1st Qu.:2.000 Class :character 1st Qu.: 861.8
## Median :2.000 Mode :character Median : 1934.0
## Mean :2.318 Mean : 4283.8
## 3rd Qu.:3.000 3rd Qu.: 5542.0
## Max. :5.000 Max. :128524.0
La base de datos contiene información sobre 658 viviendas en Ciudad de México, divididas en dos conjuntos de variables. El primero se enfoca en aspectos geográficos, como la ubicación por Alcaldía y Colonia, así como 10 variables que miden el nivel de marginación de la zona. El segundo conjunto se centra en las características de las viviendas, como instalaciones, tamaño y el precio (en miles de MXN) como variable a predecir.
Tras el análisis exploratorio de los datos, se detectaron algunas incidencias significativas. Se observaron errores ortográficos en palabras como “Si,” “Sí,” o “si,” que afectaban la coherencia de los registros. Además, se identificaron dos variables que habían sido mal interpretadas como otro tipo de variables y se corrigieron para que coincidieran con su naturaleza real. También se detectaron valores atípicos en la variable de precio, duplicados y datos faltantes, los cuales se resolvieron utilizando la mediana para no alterar la integridad de los datos.
# Limpieza de datos
$Alberca[df$Alberca == "si"] = "Si"
df$Elevador[df$Elevador == "si"] = "Si"
df
# Conversión de Variables Categóricas a Factores
$Gimnasio <- as.factor(df$Gimnasio)
df$Cocina_equip <- as.factor(df$Cocina_equip)
df$Gimnasio <- as.factor(df$Gimnasio)
df$Amueblado <- as.factor(df$Amueblado)
df$Alberca <- as.factor(df$Alberca)
df$Terraza <- as.factor(df$Terraza)
df$Elevador <- as.factor(df$Elevador)
df$Alcaldia <- as.factor(df$Alcaldia)
df$Colonia <- as.factor(df$Colonia)
df
# Eliminación de registros duplicados
<- unique(df)
df dim(df)
## [1] 653 23
# Conversión Variable Estacionamiento Numérica e Imputación de Mediana a Nulos
$Estacionamiento <- as.numeric(df$Estacionamiento) df
## Warning: NAs introduced by coercion
<- median(df$Estacionamiento, na.rm = TRUE)
mediana_estacionamiento $Estacionamiento[is.na(df$Estacionamiento)] <- mediana_estacionamiento
df
#Eliminar valores extremos adicionales a 0 usando el rango intercuartil
<- quantile(df$Precio, 0.25, na.rm=TRUE)
q1 <- quantile(df$Precio, 0.75, na.rm=TRUE)
q3 <- q3 - q1
rangointq
<- q1 - 0.17 * rangointq
limite_inferior <- q3 + 1.5 * rangointq
limite_superior
<- subset(df, Precio >= limite_inferior & Precio <= limite_superior)
df
#Revisión de Media de Variables relacionadas a la Marginación por Alcaldía
<- df %>%
Exploración select(Alcaldia,X1, X2, X3, X4, X5, X6, X7, X8, X9, X10)%>%
group_by(Alcaldia) %>%
summarise(X1mean = mean(X1), X2mean = mean(X2), X3mean = mean(X3), X4mean = mean(X4), X5mean = mean(X5), X6mean = mean(X6), X7mean = mean(X7), X8mean = mean(X8), X9mean = mean(X9), X10mean = mean(X10))
Exploración
## # A tibble: 16 × 11
## Alcaldia X1mean X2mean X3mean X4mean X5mean X6mean X7mean X8mean X9mean
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Alvaro Obregon 1.34 5.68 42.8 17.8 23.7 3.19 0.28 0.03 6.98
## 2 Azcapotzalco 0.96 5.97 39.0 15.5 20.6 1.83 0.46 0.03 7.57
## 3 Benito Juárez 0.35 6.23 31.7 6.07 20.1 0.48 0.03 0.02 3.17
## 4 Coyoacan 0.77 4.98 32.9 11.0 24.6 1.7 0.05 0.03 5.47
## 5 Cuahtemoc 0.9 6.78 42.1 12.2 26.8 1.7 0.11 0.05 6.21
## 6 Cuajimalpa 1.55 5.76 44.4 18.9 24.4 4.17 0.43 0.06 6.68
## 7 Gustavo A. Ma… 1.4 4.99 40.2 18.2 25.4 2.92 0.3 0.05 9.53
## 8 Iztacalco 1.13 4.47 41.4 17.0 27.0 2.92 0.07 0.05 7.68
## 9 Iztapalapa 1.86 5.62 47.8 21.7 32.2 4.54 0.71 0.17 9.56
## 10 La Magdalena … 1.86 5.62 47.8 21.7 32.2 4.54 0.71 0.17 9.56
## 11 Miguel Hidalgo 0.61 5.57 35.5 10.5 18.5 1.06 0.07 0.03 4.5
## 12 Milpa alta 2.8 3.81 51.2 23.5 30.3 8.53 6.47 0.23 13.1
## 13 Tlahuac 1.54 4.5 46.6 20.0 26.8 5.04 0.96 0.1 9.61
## 14 Tlalpan 1.39 4.6 40.3 16.5 27.9 3.71 3.91 0.08 6.22
## 15 Venustiano Ca… 1.02 6.37 43.6 16.4 28.2 2.28 0.06 0.04 8.15
## 16 Xochimilco 2.3 4.57 46.7 21.3 32.1 6.81 10.2 0.17 8.25
## # … with 1 more variable: X10mean <dbl>
Dentro del análisis exploratorio de los datos, es importante analizar la correlación lineal entre las variables con el fin de identificar relaciones entre las distintas variables y nuestra variable de interés, mejorar la interpretación de resultados y detectar ciertos patrones o relaciones inesperadas a considerar para la mejor construcción del modelo predictivo.
<- df %>%
numeric_cols select_if(is.numeric)
corrplot(cor(numeric_cols), type = "upper", order="hclust", addCoef.col =
"black", method = "circle", number.cex=0.5)
Se implementará el algoritmo K-Means, un método de clusterización reconocido por su eficacia y simplicidad. Este algoritmo es ideal para segmentar el conjunto de datos en grupos o ‘clusters’ basados en similitudes internas, lo que facilita la identificación de patrones y tendencias subyacentes. En particular, se aplicará K-Means para agrupar las propiedades inmobiliarias en la CDMX según variables de marginación (X1-X10).
Para lograr una clusterización efectiva de los datos de viviendas, es esencial omitir variables no relacionadas con la marginación y la variable de precio, que podría sesgar los resultados. Además, se debe normalizar las variables numéricas para una comparación equitativa utilizando la función “scales”.
#Únicamente seleccionar variables numéricas para el algoritmo
<- df %>%
numeric_cols select_if(is.numeric)
# Eliminar variable dependiente "Precio" y variables no de marginación
$Cluster <- NULL
numeric_cols$Precio <- NULL
numeric_cols$Estacionamiento <- NULL
numeric_cols$Recamaras <- NULL
numeric_cols$Banos <- NULL
numeric_cols$m2_construido <- NULL
numeric_cols
# Escalar las columnas numéricas para garantizar que las variables tengan el mismo peso
<- scale(numeric_cols)
df_scaled
# Semilla de Reproductibilidad, para garantizar que los resultados de un proceso aleatorio sean reproducibles.
set.seed(123)
Para elegir la cantidad óptima de clusters se utiliza el método del CODO.
<- numeric(15)
wss for (i in 2:15) {
<- sum(kmeans(numeric_cols, centers = i, nstart = 25)$withinss)
wss[i]
}plot(1:15, wss, type = "b", xlab = "Número de Clusters", ylab = "Suma de Cuadrados Internos")
Para elegir el número óptimo de clústers se utilizó el método del
Codo.
Como se observa en la gráfica generada por el código, el punto de inflexión, o “codo”, se encuentra en el número de cluster 4. Esto se fundamenta en el método del codo, que sugiere elegir el número de clusters en el punto donde la disminución de la suma de cuadrados internos (WSS) comienza a ralentizarse significativamente. En otras palabras, añadir más clusters más allá de este punto no mejora sustancialmente la compactación de los datos dentro de los clusters. Por lo tanto, 4 es el número óptimo de clusters para este análisis.
# Klusters = 4
<- kmeans(df_scaled, centers = 4)
kmeans_result $centers kmeans_result
## X1 X2 X3 X4 X5 X6
## 1 -0.4409913 0.98017618 -0.03902648 -0.2497081 -0.5532810 -0.5050034
## 2 -1.6019942 0.14680557 -1.97461591 -1.9804829 -1.1519415 -1.3915230
## 3 1.3032991 -0.07587472 1.09034222 1.0511366 1.4544313 1.0872793
## 4 0.1345192 -0.94534143 0.06880320 0.3025321 -0.0642621 0.2672229
## X7 X8 X9 X10
## 1 -0.378419468 -0.74895788 -0.4347685 -0.4569176
## 2 -0.475160252 -0.92504655 -1.7452433 -1.8336460
## 3 0.769839217 1.62130221 0.8332463 0.9571546
## 4 -0.009806831 -0.09912622 0.5419809 0.5083863
<- kmeans_result$centers
centros
# Transponer la matriz para que las filas representen variables y las columnas representen centros de clústeres
<- t(centros)
centros_transpuestos centros_transpuestos
## 1 2 3 4
## X1 -0.44099134 -1.6019942 1.30329909 0.134519202
## X2 0.98017618 0.1468056 -0.07587472 -0.945341430
## X3 -0.03902648 -1.9746159 1.09034222 0.068803201
## X4 -0.24970812 -1.9804829 1.05113665 0.302532147
## X5 -0.55328095 -1.1519415 1.45443130 -0.064262103
## X6 -0.50500344 -1.3915230 1.08727927 0.267222919
## X7 -0.37841947 -0.4751603 0.76983922 -0.009806831
## X8 -0.74895788 -0.9250465 1.62130221 -0.099126218
## X9 -0.43476845 -1.7452433 0.83324633 0.541980889
## X10 -0.45691758 -1.8336460 0.95715465 0.508386259
# Barplot para cada centro de clúster
<- c("red", "blue", "green")
colores barplot(centros_transpuestos, beside = TRUE, col = colores,
legend.text = rownames(centros), ylim = c(min(centros_transpuestos), max(centros_transpuestos)),
main = "Centros de Clústeres de K-means",
ylab = "Valor",
xlab = "Variables")
legend("topright", legend = paste("Clúster", 1:nrow(centros)), fill = colores)
# Añadir la columna de clusters al DataFrame original
$Cluster <- kmeans_result$cluster
dfhead(df)
## Alcaldia Colonia X1 X2 X3 X4 X5 X6
## 1 La Magdalena Contreras San Jerónimo Líndice 1.86 5.62 47.82 21.69 32.20 4.54
## 2 Tlahuac Xochicalli 1.54 4.50 46.56 20.05 26.78 5.04
## 4 Tlahuac La Turba 1.54 4.50 46.56 20.05 26.78 5.04
## 5 Tlahuac Miguel Hidalgo 1.54 4.50 46.56 20.05 26.78 5.04
## 6 Tlahuac Los Olivos 1.54 4.50 46.56 20.05 26.78 5.04
## 8 Alvaro Obregon Jardines del Pedregal 1.34 5.68 42.85 17.83 23.74 3.19
## X7 X8 X9 X10 Cocina_equip Gimnasio Amueblado Alberca Terraza Elevador
## 1 0.71 0.17 9.56 50.08 Si Si No No Si Si
## 2 0.96 0.10 9.61 52.75 Si No No No No No
## 4 0.96 0.10 9.61 52.75 No No No No No No
## 5 0.96 0.10 9.61 52.75 No No No No No No
## 6 0.96 0.10 9.61 52.75 No No No No No No
## 8 0.28 0.03 6.98 36.60 Si Si No No Si Si
## m2_construido Banos Recamaras Estacionamiento Precio Cluster
## 1 150 2.0 3 2 6500 3
## 2 51 1.0 2 1 1200 4
## 4 42 1.0 2 1 1046 4
## 5 50 1.0 2 1 1195 4
## 6 80 1.0 2 1 388 4
## 8 144 2.5 3 2 7150 1
# Conteo de Registros en Cada Cluster
<- df
dft $Cluster<- as.factor(df$Cluster)
dftsummary(dft$Cluster)
## 1 2 3 4
## 183 82 143 191
Una vez analizados los resultados de los clusters, se pueden etiquetar de la siguiente manera:
Clúster 1, denominado “Viviendas Media Residencial,” se caracteriza por exhibir en su mayoría valores bajos en las métricas de marginación. Esto sugiere que este grupo puede comprender propiedades residenciales con atributos moderadamente marginados, lo que implica un nivel intermedio de desarrollo y servicios en su ubicación.
Por otro lado, el Clúster 2, llamado “Viviendas Premium,” se distingue por mostrar los valores más bajos en todas las variables, lo que apunta a propiedades exclusivas y de alto valor. Estas viviendas probablemente se encuentran en áreas con un bajo grado de marginación social y económica, lo que las convierte en propiedades de lujo.
En contraste, el Clúster 3, conocido como “Viviendas Económicas,” exhibe valores significativamente altos en todas las métricas de marginación. Esto sugiere que estas propiedades se encuentran en áreas con altos niveles de marginación, caracterizadas por limitaciones socioeconómicas. Estas viviendas son más asequibles y dirigidas a personas con ingresos más bajos.
Finalmente, el Clúster 4, denominado “Viviendas Popular,” presenta una mezcla de valores altos y bajos en diversas métricas. Este grupo podría contener una variedad de propiedades populares en ubicaciones diversas, que abarcan desde áreas marginadas hasta zonas más desarrolladas, lo que indica una diversidad en su perfil socioeconómico y de servicios.
# Copiar el dataset para segmentar por clases
<- df
dfc $Cluster <- as.character(dfc$Cluster)
dfcsummary(dfc$Cluster)
## Length Class Mode
## 599 character character
# Dar nombes a los clusters de acuerdo al análisis de sus características
$Cluster[dfc$Cluster == 1] = "Viviendas Media Residencial"
dfc$Cluster[dfc$Cluster == 2] = "Viviendas Premium"
dfc$Cluster[dfc$Cluster == 3] = "Viviendas Económicas"
dfc$Cluster[dfc$Cluster == 4] = "Viviendas Popular"
dfc
# Crear una tabla de contingencia para la variable 'EMPRESA' por cluster
<- table(dfc$Cluster, dfc$Alcaldia)
contingency <- prop.table(contingency, margin = 1) * 100
contingency print(contingency)
##
## Alvaro Obregon Azcapotzalco Benito Juárez
## Viviendas Económicas 0.000000 0.000000 0.000000
## Viviendas Media Residencial 43.169399 16.393443 0.000000
## Viviendas Popular 0.000000 0.000000 0.000000
## Viviendas Premium 0.000000 0.000000 31.707317
##
## Coyoacan Cuahtemoc Cuajimalpa Gustavo A. Madero
## Viviendas Económicas 0.000000 0.000000 0.000000 0.000000
## Viviendas Media Residencial 0.000000 14.754098 7.650273 0.000000
## Viviendas Popular 0.000000 0.000000 0.000000 41.361257
## Viviendas Premium 54.878049 0.000000 0.000000 0.000000
##
## Iztacalco Iztapalapa La Magdalena Contreras
## Viviendas Económicas 0.000000 64.335664 11.188811
## Viviendas Media Residencial 0.000000 0.000000 0.000000
## Viviendas Popular 3.664921 0.000000 0.000000
## Viviendas Premium 0.000000 0.000000 0.000000
##
## Miguel Hidalgo Milpa alta Tlahuac Tlalpan
## Viviendas Económicas 0.000000 7.692308 0.000000 0.000000
## Viviendas Media Residencial 0.000000 0.000000 0.000000 0.000000
## Viviendas Popular 0.000000 0.000000 41.361257 13.612565
## Viviendas Premium 13.414634 0.000000 0.000000 0.000000
##
## Venustiano Carranza Xochimilco
## Viviendas Económicas 0.000000 16.783217
## Viviendas Media Residencial 18.032787 0.000000
## Viviendas Popular 0.000000 0.000000
## Viviendas Premium 0.000000 0.000000
# Generación de Subconjuntos
<- subset(dfc, Cluster == "Viviendas Media Residencial")
VMediaResidencial
<- subset(dfc, Cluster == "Viviendas Popular")
VPopular
<- subset(dfc, Cluster == "Viviendas Premium")
VPremium
<- subset(dfc, Cluster == "Viviendas Económicas") VEcon
La tabla de contingencia sugiere que ciertas alcaldías están altamente especializadas en una categoría específica de vivienda. Esto podría deberse a varios factores socioeconómicos y de desarrollo urbano que han llevado a una segregación marcada del tipo de vivienda disponible en cada alcaldía. Reflejando valores donde los clusters son más representativos y significativos.
Álvaro Obregón: Una proporción significativa corresponde a Viviendas Media Residencial (43.17%), indicando una tendencia hacia viviendas con características medianas en términos de marginación.
Benito Juárez: Se destaca por tener un porcentaje considerable de Viviendas Premium (31.71%), lo cual sugiere que esta alcaldía alberga una cantidad significativa de propiedades de alto valor.
Iztapalapa: Predominan las Viviendas Económicas (64.34%), lo que refleja una mayor presencia de viviendas asequibles o con mayor marginación en esta zona.
Gustavo A. Madero: Presenta un porcentaje notable de Viviendas Popular (41.36%), lo que puede señalar una inclinación hacia viviendas más accesibles o populares.
Coyoacán y Miguel Hidalgo: Tienen una concentración de Viviendas Premium (54.88% y 13.41% respectivamente), sugiriendo un mercado inmobiliario con propiedades de gama alta.
Para profundizar en la comprensión del mercado inmobiliario de la CDMX y ofrecer recomendaciones personalizadas para cada segmento, se desarrollaron modelos predictivos específicos para cada tipo de vivienda identificado mediante clustering. Al construir un modelo separado para “Viviendas Media Residencial”, “Viviendas Premium”, “Viviendas Económicas” y “Viviendas Popular”, se busca capturar las dinámicas únicas y los factores influyentes que determinan el valor de las propiedades en cada cluster. Esta metodología permite una aproximación más ajustada a la realidad de cada segmento del mercado, proporcionando así insights más precisos para estrategias de inversión, desarrollo urbanístico y políticas de vivienda.
Este proceso involucró pasos clave para cada árbol, incluyendo la partición de datos en conjuntos de entrenamiento, validación y prueba (50,25,25), la construcción del árbol de decisión utilizando las características de infraestructura como predictores, la validación cruzada para ajustar la complejidad del árbol, la interpretación de variables críticas en el proceso de toma de decisiones, y finalmente, la evaluación del modelo mediante la predicción y comparación de los precios reales con las predicciones.
summary(VEcon)
## Alcaldia Colonia X1
## Iztapalapa :92 San Jerónimo Líndice : 11 Min. :1.860
## Xochimilco :24 Lomas Estrella : 10 1st Qu.:1.860
## La Magdalena Contreras:16 Tepalcates : 9 Median :1.860
## Milpa alta :11 Santa Martha Acatitla: 5 Mean :2.006
## Alvaro Obregon : 0 La Noria : 4 3rd Qu.:1.860
## Azcapotzalco : 0 San Lorenzo La Cebada: 4 Max. :2.800
## (Other) : 0 (Other) :100
## X2 X3 X4 X5
## Min. :3.810 Min. :46.68 Min. :21.30 Min. :30.32
## 1st Qu.:5.620 1st Qu.:47.82 1st Qu.:21.69 1st Qu.:32.20
## Median :5.620 Median :47.82 Median :21.69 Median :32.20
## Mean :5.305 Mean :47.89 Mean :21.76 Mean :32.05
## 3rd Qu.:5.620 3rd Qu.:47.82 3rd Qu.:21.69 3rd Qu.:32.20
## Max. :5.620 Max. :51.23 Max. :23.46 Max. :32.20
##
## X6 X7 X8 X9
## Min. :4.540 Min. : 0.710 Min. :0.1700 Min. : 8.250
## 1st Qu.:4.540 1st Qu.: 0.710 1st Qu.:0.1700 1st Qu.: 9.560
## Median :4.540 Median : 0.710 Median :0.1700 Median : 9.560
## Mean :5.228 Mean : 2.747 Mean :0.1746 Mean : 9.609
## 3rd Qu.:4.540 3rd Qu.: 0.710 3rd Qu.:0.1700 3rd Qu.: 9.560
## Max. :8.530 Max. :10.210 Max. :0.2300 Max. :13.060
##
## X10 Cocina_equip Gimnasio Amueblado Alberca Terraza Elevador
## Min. :50.06 No : 14 No :123 No :136 No :140 No :106 No :113
## 1st Qu.:50.08 Si :129 No : 0 No : 0 No : 0 No : 0 Si : 30
## Median :50.08 Si : 0 Si : 20 Si : 7 Si : 3 Si : 37 Si : 0
## Mean :51.15 Si : 0 Si : 0 si : 0 Si : 0
## 3rd Qu.:50.08 Si : 0
## Max. :63.97
##
## m2_construido Banos Recamaras Estacionamiento
## Min. : 34.00 Min. :1.000 Min. :1.000 Min. :0.000
## 1st Qu.: 54.00 1st Qu.:1.000 1st Qu.:2.000 1st Qu.:1.000
## Median : 65.00 Median :1.000 Median :2.000 Median :1.000
## Mean : 80.39 Mean :1.294 Mean :2.343 Mean :1.147
## 3rd Qu.: 86.00 3rd Qu.:1.500 3rd Qu.:3.000 3rd Qu.:1.000
## Max. :450.00 Max. :4.000 Max. :5.000 Max. :3.000
##
## Precio Cluster
## Min. : 150 Length:143
## 1st Qu.: 785 Class :character
## Median : 1280 Mode :character
## Mean : 1861
## 3rd Qu.: 1938
## Max. :10800
##
$Cluster <- NULL
VEcon
# Establecer la semilla para reproducibilidad
set.seed(123)
# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
<- createDataPartition(VEcon$Precio, p = 0.5, list = FALSE, times = 1)
trainIndex1 <- VEcon[trainIndex1, ]
train <- VEcon[-trainIndex1, ]
temp
# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
<- createDataPartition(temp$Precio, p = 0.5, list = FALSE, times = 1)
trainIndex2 <- temp[trainIndex2, ]
validation <- temp[-trainIndex2, ] testEcon
# Construir el árbol de decisión
<- rpart(Precio ~ m2_construido + Banos + Recamaras + Estacionamiento + Gimnasio + Cocina_equip + Gimnasio + Amueblado + Alberca + Terraza + Elevador, data = train, method = "anova", control = rpart.control(cp = 0))
tree rpart.plot(tree)
# Visualizar la curva de complejidad de costo
plotcp(tree)
Se construyó un árbol de decisión para predecir el precio de las viviendas en la CDMX. Se eligieron variables como metros cuadrados construidos, número de baños, recámaras, estacionamiento, y otras características relevantes, con un enfoque particular en los metros cuadrados y la cantidad de baños, dado que estas variables suelen tener una influencia significativa en el valor de una propiedad.
El uso de la técnica ANOVA en el modelo sugiere un intento de capturar las variaciones de precios a través de estas características. Posteriormente, la curva de complejidad se utilizó para evaluar el equilibrio entre la precisión del modelo y su complejidad. Esta curva ayuda a identificar el tamaño óptimo del árbol, minimizando el riesgo de sobreajuste y asegurando que el modelo sea lo suficientemente complejo para capturar las relaciones importantes en los datos.
set.seed(123)
<- preProcess(validation, method = "medianImpute")
preproc <- predict(preproc, VEcon)
validation_clean
# 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
<- trainControl(method = "cv", number = 10)
ctrl
# Entrenar el modelo con validación cruzada
<- train(Precio ~ ., data = validation_clean,
tree_model_cv_economic 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_economic)
## CART
##
## 143 samples
## 22 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
## Summary of sample sizes: 127, 128, 128, 129, 127, 130, ...
## Resampling results across tuning parameters:
##
## cp RMSE Rsquared MAE
## 0.0002265654 962.5014 0.6939193 658.0168
## 0.0004665129 959.7447 0.6960668 653.5596
## 0.0008052244 954.7189 0.7018464 642.6778
## 0.0024056419 946.7250 0.7097076 631.2843
## 0.0037821298 957.5687 0.7037688 646.6300
## 0.0075885014 982.7915 0.6736595 667.6045
## 0.0093075366 989.7040 0.6699152 674.5190
## 0.0163959588 1011.9723 0.6513945 691.3735
## 0.0776976294 1053.4816 0.6668810 736.2038
## 0.6850076345 1620.4865 0.7034096 1102.0062
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was cp = 0.002405642.
# Elegir un valor de cp basado en la gráfica y podar el árbol
<- prune(tree, cp = 0.0008)
pruned_tree
# Visualizar el árbol podado
rpart.plot(pruned_tree)
rpart.rules(pruned_tree,style = 'tall',cover = T)
## Precio is 889 with cover 24% when
## m2_construido < 55
## Banos < 2
##
## Precio is 1127 with cover 42% when
## m2_construido is 55 to 83
## Banos < 2
##
## Precio is 1842 with cover 11% when
## m2_construido is 83 to 111
## Banos < 2
##
## Precio is 2494 with cover 14% when
## m2_construido < 111
## Banos >= 2
##
## Precio is 5268 with cover 10% when
## m2_construido >= 111
Datos: 143 muestras con 22 predictores
Validación Cruzada: Se usó un enfoque de 10 pliegues.
Resultados de Rendimiento: Varias configuraciones del parámetro de complejidad (cp) fueron evaluadas. El modelo con cp (Complexity Parameter) = 0.002405642 tuvo el menor error cuadrático medio (RMSE), indicando el mejor equilibrio entre ajuste y complejidad, pues el proceso de poda del árbol, basado en este parámetro, elimina las divisiones del árbol que no aportan significativamente a su capacidad predictiva, según un cálculo de costo-complejidad.
Reglas del Árbol Podado: Se describen reglas específicas para predecir precios basados en metros cuadrados construidos y número de baños. Por ejemplo, para viviendas menores de 55 m² con menos de 2 baños, el precio estimado es 889.
El mismo procedimiento se realiza para las viviendas populares…
summary(VPopular)
## Alcaldia Colonia X1
## Gustavo A. Madero:79 Miguel Hidalgo : 9 Min. :1.130
## Tlahuac :79 La draga : 7 1st Qu.:1.400
## Tlalpan :26 Miguel Hidalgo : 7 Median :1.400
## Iztacalco : 7 Los olivos : 6 Mean :1.447
## Alvaro Obregon : 0 El Arbolillo : 4 3rd Qu.:1.540
## Azcapotzalco : 0 Fuentes de Tepepan: 4 Max. :1.540
## (Other) : 0 (Other) :154
## X2 X3 X4 X5
## Min. :4.470 Min. :40.21 Min. :16.53 Min. :25.42
## 1st Qu.:4.500 1st Qu.:40.21 1st Qu.:18.21 1st Qu.:25.42
## Median :4.600 Median :40.26 Median :18.21 Median :26.78
## Mean :4.715 Mean :42.89 Mean :18.70 Mean :26.37
## 3rd Qu.:4.990 3rd Qu.:46.56 3rd Qu.:20.05 3rd Qu.:26.78
## Max. :4.990 Max. :46.56 Max. :20.05 Max. :27.88
##
## X6 X7 X8 X9
## Min. :2.920 Min. :0.070 Min. :0.05000 Min. :6.220
## 1st Qu.:2.920 1st Qu.:0.300 1st Qu.:0.05000 1st Qu.:9.530
## Median :3.710 Median :0.960 Median :0.08000 Median :9.530
## Mean :3.904 Mean :1.056 Mean :0.07476 Mean :9.045
## 3rd Qu.:5.040 3rd Qu.:0.960 3rd Qu.:0.10000 3rd Qu.:9.610
## Max. :5.040 Max. :3.910 Max. :0.10000 Max. :9.610
##
## X10 Cocina_equip Gimnasio Amueblado Alberca Terraza Elevador
## Min. :36.76 No : 45 No :163 No :190 No :190 No :145 No :122
## 1st Qu.:43.86 Si :146 No : 0 No : 0 No : 0 No : 0 Si : 69
## Median :43.86 Si : 0 Si : 28 Si : 1 Si : 1 Si : 46 Si : 0
## Mean :46.40 Si : 0 Si : 0 si : 0 Si : 0
## 3rd Qu.:52.75 Si : 0
## Max. :52.75
##
## m2_construido Banos Recamaras Estacionamiento
## Min. : 40.00 Min. :1.00 Min. :1.00 Min. :0.000
## 1st Qu.: 53.00 1st Qu.:1.00 1st Qu.:2.00 1st Qu.:1.000
## Median : 60.00 Median :1.00 Median :2.00 Median :1.000
## Mean : 70.88 Mean :1.34 Mean :2.22 Mean :1.068
## 3rd Qu.: 76.00 3rd Qu.:2.00 3rd Qu.:2.00 3rd Qu.:1.000
## Max. :217.00 Max. :5.00 Max. :4.00 Max. :5.000
##
## Precio Cluster
## Min. : 116.0 Length:191
## 1st Qu.: 675.5 Class :character
## Median : 861.0 Mode :character
## Mean : 1306.9
## 3rd Qu.: 1267.5
## Max. :12200.0
##
$Cluster <- NULL
VPopular
# Establecer la semilla para reproducibilidad
set.seed(123)
# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
<- createDataPartition(VPopular$Precio, p = 0.5, list = FALSE, times = 1)
trainIndex1 <- VPopular[trainIndex1, ]
train <- VPopular[-trainIndex1, ]
temp
# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
<- createDataPartition(temp$Precio, p = 0.5, list = FALSE, times = 1)
trainIndex2 <- temp[trainIndex2, ]
validation <- temp[-trainIndex2, ] testPop
# Construir el árbol de decisión
<- rpart(Precio ~ m2_construido + Banos + Recamaras + Estacionamiento + Gimnasio + Cocina_equip + Gimnasio + Amueblado + Alberca + Terraza + Elevador, data = train, method = "anova", control = rpart.control(cp = 0))
tree rpart.plot(tree)
# Visualizar la curva de complejidad de costo
plotcp(tree)
set.seed(123)
<- preProcess(validation, method = "medianImpute")
preproc <- predict(preproc, VPopular)
validation_clean
# 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
<- trainControl(method = "cv", number = 10)
ctrl
# Entrenar el modelo con validación cruzada
<- train(Precio ~ ., data = validation_clean,
tree_model_cv_popular 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_popular)
## CART
##
## 191 samples
## 22 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
## Summary of sample sizes: 172, 172, 171, 171, 173, 172, ...
## Resampling results across tuning parameters:
##
## cp RMSE Rsquared MAE
## 0.00000000 1025.197 0.4966662 540.2378
## 0.04894713 1077.829 0.4329132 577.7041
## 0.09789426 1107.154 0.4025771 591.7837
## 0.14684138 1080.299 0.4564816 590.9161
## 0.19578851 1080.299 0.4564816 590.9161
## 0.24473564 1080.299 0.4564816 590.9161
## 0.29368277 1080.299 0.4564816 590.9161
## 0.34262990 1080.299 0.4564816 590.9161
## 0.39157702 1080.299 0.4564816 590.9161
## 0.44052415 1346.006 0.2732899 777.7428
##
## 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
<- prune(tree, cp = 0.0)
pruned_tree
# Visualizar el árbol podado
rpart.plot(pruned_tree)
rpart.rules(pruned_tree,style = 'tall',cover = T)
## Precio is 553 with cover 20% when
## Gimnasio is No
## Banos < 1.3
## Elevador is Si
##
## Precio is 786 with cover 10% when
## Gimnasio is No
## Banos < 1.3
## Elevador is No
## Cocina_equip is Si
## m2_construido < 52
##
## Precio is 791 with cover 7% when
## Gimnasio is No
## Banos < 1.3
## Elevador is No
## Cocina_equip is Si
## m2_construido >= 68
##
## Precio is 924 with cover 14% when
## Gimnasio is No
## Banos < 1.3
## Elevador is No
## Cocina_equip is Si
## m2_construido is 52 to 68
##
## Precio is 1022 with cover 18% when
## Gimnasio is No
## Banos < 1.3
## Elevador is No
## Cocina_equip is No
##
## Precio is 1169 with cover 14% when
## Gimnasio is No
## Banos >= 1.3
##
## Precio is 2945 with cover 18% when
## Gimnasio is Si
Precio 924: Para viviendas sin gimnasio, con menos de 1.3 baños, sin elevador, con cocina equipada y con un tamaño de 52 a 68 m², el precio estimado es de 924. Este grupo representa el 14% del total.
Precio 1022: Viviendas sin gimnasio, con menos de 1.3 baños, sin elevador y sin cocina equipada, tienen un precio estimado de 1022. Cubren el 18% del total.
Precio 1169: Viviendas sin gimnasio pero con 1.3 baños o más tienen un precio estimado de 1169, representando el 14%.
Precio 2945: Las viviendas con gimnasio tienen un precio significativamente mayor, estimado en 2945, y constituyen el 18% del total.
Estos resultados resaltan cómo características específicas como la presencia de gimnasio, número de baños, y las comodidades impactan en el precio de las viviendas populares.
Se realiza el mismo procedimiento para viviendas residenciales
summary(VMediaResidencial)
## Alcaldia Colonia X1
## Alvaro Obregon :79 Santa Fe : 22 Min. :0.900
## Venustiano Carranza:33 San Angel : 13 1st Qu.:0.960
## Azcapotzalco :30 Jardines del Pedregal: 6 Median :1.340
## Cuahtemoc :27 Nicolás Bravo : 6 Mean :1.171
## Cuajimalpa :14 Condesa : 5 3rd Qu.:1.340
## Benito Juárez : 0 Juárez : 5 Max. :1.550
## (Other) : 0 (Other) :126
## X2 X3 X4 X5 X6
## Min. :5.68 Min. :38.99 Min. :12.23 Min. :20.61 Min. :1.700
## 1st Qu.:5.68 1st Qu.:42.09 1st Qu.:15.50 1st Qu.:23.74 1st Qu.:1.830
## Median :5.76 Median :42.85 Median :17.83 Median :23.74 Median :3.190
## Mean :6.02 Mean :42.36 Mean :16.44 Mean :24.55 Mean :2.658
## 3rd Qu.:6.37 3rd Qu.:43.62 3rd Qu.:17.83 3rd Qu.:26.83 3rd Qu.:3.190
## Max. :6.78 Max. :44.36 Max. :18.90 Max. :28.25 Max. :4.170
##
## X7 X8 X9 X10
## Min. :0.0600 Min. :0.03000 Min. :6.210 Min. :30.68
## 1st Qu.:0.1100 1st Qu.:0.03000 1st Qu.:6.980 1st Qu.:35.22
## Median :0.2800 Median :0.03000 Median :6.980 Median :36.60
## Mean :0.2562 Mean :0.03705 Mean :7.151 Mean :36.18
## 3rd Qu.:0.2800 3rd Qu.:0.04000 3rd Qu.:7.570 3rd Qu.:39.08
## Max. :0.4600 Max. :0.06000 Max. :8.150 Max. :39.65
##
## Cocina_equip Gimnasio Amueblado Alberca Terraza Elevador m2_construido
## No : 2 No :80 No :167 No :119 No : 56 No : 35 Min. : 41.0
## Si :141 No :23 No : 12 No : 4 No : 4 Si :115 1st Qu.: 63.5
## Si : 40 Si :66 Si : 2 Si : 51 Si :103 Si : 33 Median : 90.0
## Si :14 Si : 2 si : 1 Si : 20 Mean :108.6
## Si : 8 3rd Qu.:141.0
## Max. :300.0
##
## Banos Recamaras Estacionamiento Precio
## Min. :1.000 Min. :1.000 Min. :0.000 Min. : 247
## 1st Qu.:1.000 1st Qu.:2.000 1st Qu.:1.000 1st Qu.: 1990
## Median :2.000 Median :2.000 Median :2.000 Median : 4800
## Mean :1.915 Mean :2.246 Mean :1.574 Mean : 4989
## 3rd Qu.:2.000 3rd Qu.:3.000 3rd Qu.:2.000 3rd Qu.: 7450
## Max. :4.000 Max. :3.000 Max. :4.000 Max. :12500
##
## Cluster
## Length:183
## Class :character
## Mode :character
##
##
##
##
$Cluster <- NULL
VMediaResidencial
# Establecer la semilla para reproducibilidad
set.seed(123)
# Paso 1: Dividir el conjunto de datos en entrenamiento (50%) y temporal (50%)
<- createDataPartition(VMediaResidencial$Precio, p = 0.5, list = FALSE, times = 1)
trainIndex1 <- VMediaResidencial[trainIndex1, ]
train <- VMediaResidencial[-trainIndex1, ]
temp
# Paso 2: Dividir el conjunto temporal en validación (50% de temp) y prueba (50% de temp)
<- createDataPartition(temp$Precio, p = 0.5, list = FALSE, times = 1)
trainIndex2 <- temp[trainIndex2, ]
validation <- temp[-trainIndex2, ] testResi
# Construir el árbol de decisión
<- rpart(Precio ~ m2_construido + Banos + Recamaras + Estacionamiento + Gimnasio + Cocina_equip + Gimnasio + Amueblado + Alberca + Terraza + Elevador, data = train, method = "anova", control = rpart.control(cp = 0))
tree rpart.plot(tree)
# Visualizar la curva de complejidad de costo
plotcp(tree)
set.seed(123)
<- preProcess(validation, method = "medianImpute")
preproc <- predict(preproc, VMediaResidencial)
validation_clean
# 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
<- trainControl(method = "cv", number = 10)
ctrl
# Entrenar el modelo con validación cruzada
<- train(Precio ~ ., data = validation_clean,
tree_model_cv_residencial 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_residencial)
## CART
##
## 183 samples
## 22 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
## Summary of sample sizes: 165, 163, 165, 167, 164, 164, ...
## Resampling results across tuning parameters:
##
## cp RMSE Rsquared MAE
## 0.003495378 1412.697 0.8171329 979.8117
## 0.004463342 1434.230 0.8112463 1000.4597
## 0.006091701 1438.484 0.8082939 1007.2666
## 0.006989497 1410.232 0.8124515 991.0224
## 0.009008367 1386.033 0.8278197 963.2951
## 0.017344947 1441.532 0.8162223 1052.4314
## 0.024773861 1546.643 0.7906413 1180.9564
## 0.083200306 1762.704 0.7179394 1361.8338
## 0.098483168 1925.277 0.6620508 1532.4232
## 0.636359286 3005.807 0.4681920 2545.2027
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was cp = 0.009008367.
# Elegir un valor de cp basado en el menor RMSE
<- prune(tree, cp = 0.017)
pruned_tree
# Visualizar el árbol podado
rpart.plot(pruned_tree)
rpart.rules(pruned_tree,style = 'tall',cover = T)
## Precio is 697 with cover 17% when
## m2_construido < 88
## Terraza is No or No
## Cocina_equip is Si
##
## Precio is 2411 with cover 12% when
## m2_construido < 88
## Terraza is No or No
## Cocina_equip is No or Si
##
## Precio is 3927 with cover 21% when
## m2_construido < 88
## Terraza is Si or Si
##
## Precio is 6052 with cover 28% when
## m2_construido is 88 to 139
##
## Precio is 8877 with cover 22% when
## m2_construido >= 139
Desempeño del Modelo: Con un rango de valores de cp, el modelo con cp = 0.009008367 obtuvo el menor RMSE, indicando ser el más óptimo en términos de precisión y complejidad.
Predicciones de Precio:
Precio 697: Para viviendas menores de 88 m² sin terraza y con cocina equipada. Precio 2411: Para viviendas menores de 88 m², independientemente del estado de la terraza o cocina equipada. Precio 3927: Para viviendas menores de 88 m² con terraza. Precio 6052: Para viviendas de tamaño entre 88 y 139 m². Precio 8877: Para viviendas de más de 139 m².
Estos resultados reflejan cómo las características como el tamaño, la presencia de terraza y la cocina equipada influyen significativamente en el precio de las viviendas residenciales.
<- function(predictions, actual) {
calculate_metrics <- mean(abs(predictions - actual))
mae <- sqrt(mean((predictions - actual)^2))
rmse <- mean(abs((predictions - actual) / actual)) * 100
mape return(c(MAE = mae, RMSE = rmse, MAPE = mape))
}
## Evaluación para Viviendas Económicas
<- predict(tree_model_cv_economic, newdata = testEcon)
pred_VEcon <- calculate_metrics(pred_VEcon, testEcon$Precio)
metrics_VEcon cat("Métricas para Viviendas Económicas:\n")
## Métricas para Viviendas Económicas:
cat("MAE:", metrics_VEcon["MAE"], "\n")
## MAE: 488.0508
cat("RMSE:", metrics_VEcon["RMSE"], "\n")
## RMSE: 926.7467
cat("MAPE:", metrics_VEcon["MAPE"], "%\n")
## MAPE: 43.43769 %
## Evaluación para Viviendas Popular
<- predict(tree_model_cv_popular, newdata = testPop)
pred_VPopular <- calculate_metrics(pred_VPopular, testPop$Precio)
metrics_VPopular cat("\nMétricas para Viviendas Popular:\n")
##
## Métricas para Viviendas Popular:
cat("MAE:", metrics_VPopular["MAE"], "\n")
## MAE: 480.5607
cat("RMSE:", metrics_VPopular["RMSE"], "\n")
## RMSE: 1106.681
cat("MAPE:", metrics_VPopular["MAPE"], "%\n")
## MAPE: 40.97677 %
## Evaluación para Viviendas Media Residencial
<- predict(tree_model_cv_residencial, newdata = testResi)
pred_VMediaResidencial <- calculate_metrics(pred_VMediaResidencial, testResi$Precio)
metrics_VMediaResidencial cat("\nMétricas para Viviendas Media Residencial:\n")
##
## Métricas para Viviendas Media Residencial:
cat("MAE:", metrics_VMediaResidencial["MAE"], "\n")
## MAE: 965.5537
cat("RMSE:", metrics_VMediaResidencial["RMSE"], "\n")
## RMSE: 1500.721
cat("MAPE:", metrics_VMediaResidencial["MAPE"], "%\n")
## MAPE: 37.66764 %
## Evaluación para Viviendas Premium
<- predict(tree_model_cv_premium, newdata = testPrem)
pred_VPremium <- calculate_metrics(pred_VPremium, testPrem$Precio)
metrics_VPremium cat("\nMétricas para Viviendas Premium:\n")
##
## Métricas para Viviendas Premium:
cat("MAE:", metrics_VPremium["MAE"], "\n")
## MAE: 619.3407
cat("RMSE:", metrics_VPremium["RMSE"], "\n")
## RMSE: 726.5856
cat("MAPE:", metrics_VPremium["MAPE"], "%\n")
## MAPE: 17.95077 %
Modelo Económico (Viviendas Económicas): El modelo económico muestra un MAE (Error Absoluto Medio) relativamente bajo y un RMSE (Error Cuadrático Medio de la Raíz) moderado. Esto sugiere que las predicciones tienden a estar cerca de los valores reales en promedio, pero hay algunas variaciones significativas en los errores de predicción. Además, el MAPE (Error Porcentual Absoluto Medio) del 43.44% indica que las predicciones pueden variar en un 43.44% en promedio en relación con los precios reales. En general, este modelo proporciona resultados aceptables para la predicción de precios de viviendas económicas, pero es importante considerar que aún existe un margen de mejora para reducir las variaciones en las predicciones y que el margen de error es demasiado alto para considerar al modelo como fiable y certero en sus predicciones.
Modelo Popular (Viviendas Popular): El modelo popular muestra un MAE similar al modelo económico, lo que sugiere una precisión similar en las predicciones en términos de valor promedio absoluto. Sin embargo, el RMSE más alto indica una mayor variabilidad en los errores de predicción, lo que podría ser atribuible a valores atípicos o predicciones menos precisas. El MAPE del 40.98% indica que las predicciones pueden variar en un 40.98% en promedio en relación con los precios reales. Esto señala que el modelo puede tener dificultades para predecir de manera consistente los precios de las viviendas populares, y podría requerir mejoras para reducir las variaciones en las predicciones.
Modelo Medio Residencial (Viviendas Media Residencial): El modelo de viviendas de nivel medio residencial muestra un MAE y un RMSE significativamente más altos en comparación con los modelos económico y popular. Esto indica una precisión de predicción general más baja y una mayor inconsistencia en las predicciones. El MAPE del 37.67% señala que las predicciones pueden variar en un 37.67% en promedio en relación con los precios reales. Estas métricas indican que el modelo tiene dificultades para predecir con precisión los precios de las viviendas de nivel medio residencial, y se recomienda una revisión exhaustiva y posibles mejoras en el modelo.
Modelo Premium (Viviendas Premium): El modelo premium muestra un MAE moderado y el RMSE más bajo de los cuatro modelos. Esto sugiere que, aunque existen errores en las predicciones, tienden a ser menos extremos en comparación con los otros modelos. El MAPE del 17.95% indica que las predicciones pueden variar en un 17.95% en promedio en relación con los precios reales, lo que es relativamente bajo en comparación con los otros modelos. En resumen, este modelo parece tener el mejor rendimiento en términos de consistencia y precisión en la predicción de precios para viviendas premium.
En resumen, es esencial considerar estas métricas al evaluar y comparar modelos predictivos. La efectividad de cada modelo dependerá del contexto del mercado y de las expectativas de precisión. Si se requiere una mayor precisión, es posible que se deban realizar mejoras en los modelos, especialmente en el caso del modelo de viviendas de nivel medio residencial. Estas métricas son fundamentales para respaldar la toma de decisiones basada en datos y mejorar la calidad de las predicciones en el mercado de viviendas.
Como reflexión final, los modelos predictivos elaborados reconocen que diferentes variables pueden influir en el precio de las viviendas en cada categoría, por tanto, Las reglas de decisión generadas por los árboles de decisión proporcionan recomendaciones valiosas para inversores y desarrolladores. Para obtener resultados aún más sólidos, se recomienda realizar una validación exhaustiva de los modelos y considerar la inclusión de más características relevantes, como ubicación geográfica, tendencias macroeconómicas y datos demográficos, así como ampliar el tamaño de la muestra de los datos.
En conclusión, Los insights obtenidos pueden aplicarse en estrategias de inversión, desarrollo de políticas de vivienda, y en la planificación urbana. Al entender las preferencias de los compradores y las tendencias del mercado, los desarrolladores y agentes inmobiliarios pueden adaptar sus proyectos y estrategias de marketing para satisfacer mejor las necesidades del mercado en la CDMX.
Gutiérrez, F. (2023). Situación de la vivienda en la CDMX: Precios más altos, pero con oferta más asequible ¿Cuál es la respuesta a esto? El Economista. https://www.eleconomista.com.mx/econohabitat/Situacion-de-la-vivienda-en-la-CDMX-Precios-mas-altos-pero-con-oferta-mas-asequible-Cual-es-la-respuesta-a-esto-20230529-0016.html
Real Estate Analytics. (2023). CDMX, Estudio de mercado inmobiliario. Real Estate Analytics. https://propiedades.com/blog/informacion-inmobiliaria/estudio-mercado-inmobiliario-cdmx