Este informe presenta un análisis exhaustivo de los datos de viviendas en las zonas Norte y Sur de Santiago de Cali. El objetivo principal es evaluar la relación entre diversas variables que afectan el precio de las viviendas, con un enfoque en casas en la Zona Norte y apartamentos en la Zona Sur. Los resultados de este análisis permitirán una mejor comprensión del mercado inmobiliario en estas zonas y servirán como base para la toma de decisiones estratégicas.
El análisis se llevó a cabo utilizando técnicas de regresión lineal múltiple para modelar el precio de las viviendas en función de varias variables predictoras. El proceso incluyó los siguientes pasos:
###Carga y Limpieza de Datos: Se filtraron registros inválidos o con datos faltantes significativos. Se imputaron valores faltantes para la variable “parqueaderos” utilizando un modelo de regresión. Ajuste de Modelos de Regresión:
Se construyeron modelos de regresión lineal múltiple para predecir el precio de las viviendas en cada zona, considerando variables como área construida, estrato, número de habitaciones, número de parqueaderos y número de baños. Visualización de Datos:
Se generaron gráficos de dispersión y mapas de puntos para ilustrar la distribución geográfica y la relación entre las variables clave y el precio.
zona: ubicación de la vivienda : Zona Centro, Zona Norte,… piso: piso que ocupa la vivienda : primer piso, segundo piso… estrato: estrato socio-económico : 3,4,5,6 preciom: precio de la vivienda en millones de pesos areaconst: área construida parqueaderos: número de parqueaderos banios: número de baños habitaciones: número de habitaciones tipo: tipo de vivienda : Casa, Apartamento barrio: barrio de ubicación de la vivienda : 20 de Julio, alamos,.. longitud: coordenada geográfica latitud: coordenada geográfica
## Downloading GitHub repo dgonxalex80/paqueteMODELOS@HEAD
## stringi (1.8.3 -> 1.8.4 ) [CRAN]
## rlang (1.1.2 -> 1.1.4 ) [CRAN]
## glue (1.6.2 -> 1.7.0 ) [CRAN]
## cli (3.6.2 -> 3.6.3 ) [CRAN]
## Rcpp (1.0.11 -> 1.0.13) [CRAN]
## digest (0.6.33 -> 0.6.37) [CRAN]
## curl (5.2.1 -> 5.2.2 ) [CRAN]
## fastmap (1.1.1 -> 1.2.0 ) [CRAN]
## Installing 8 packages: stringi, rlang, glue, cli, Rcpp, digest, curl, fastmap
## Installing packages into 'C:/Users/felip/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'stringi' successfully unpacked and MD5 sums checked
## package 'rlang' successfully unpacked and MD5 sums checked
## package 'glue' successfully unpacked and MD5 sums checked
## package 'cli' successfully unpacked and MD5 sums checked
## package 'Rcpp' successfully unpacked and MD5 sums checked
## package 'digest' successfully unpacked and MD5 sums checked
## package 'curl' successfully unpacked and MD5 sums checked
## package 'fastmap' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\felip\AppData\Local\Temp\Rtmp6Fk23h\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
## ✔ checking for file 'C:\Users\felip\AppData\Local\Temp\Rtmp6Fk23h\remotes38c44f626eaa\dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION' (547ms)
## ─ preparing 'paqueteMODELOS': (3s)
## checking DESCRIPTION meta-information ... ✔ checking DESCRIPTION meta-information
## ─ checking for LF line-endings in source and make files and shell scripts
## ─ checking for empty or unneeded directories
## ─ building 'paqueteMODELOS_0.1.0.tar.gz'
##
##
## Installing package into 'C:/Users/felip/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## [1] 1
## Loading required package: boot
##
## Attaching package: 'boot'
## The following object is masked from 'package:psych':
##
## logit
## Loading required package: broom
## Loading required package: GGally
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
## Loading required package: knitr
## Loading required package: summarytools
##
## Attaching package: 'summarytools'
## The following object is masked from 'package:lessR':
##
## label
## The following object is masked from 'package:tibble':
##
## view
##Análisis de Datos Carga de Datos Los datos de vivienda se cargan y se preparan para el análisis. Se filtran los valores nulos y se realiza una conversión de codificación
# Calcular la cantidad de valores faltantes por cada columna
datos_faltantes <- vivienda %>%
summarise(across(everything(), ~sum(is.na(.))))
Se analiza la base de datos y se extrae los valores nulos
# Mostrar los resultados
print(datos_faltantes)
## # A tibble: 1 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 3 3 2638 3 2 3 1605 3 3
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>
Se inicia el análisis filtrando los registros que contienen un ID válido en el conjunto de datos de vivienda. Esto es crucial para asegurar que solo se utilicen observaciones completas y relevantes para el análisis posterior
# Filtrar los registros que tienen un ID válido
vivienda <- vivienda %>%
dplyr::filter(!is.na(id))
Se separan las observaciones con valores completos y aquellos con valores faltantes en la variable parqueaderos. Esto permite ajustar un modelo de regresión lineal utilizando solo los datos completos.
library(tidyverse)
# Separa las observaciones con valores completos y los faltantes en `parqueaderos`
data_completa <- dplyr::filter(vivienda, !is.na(parqueaderos))
data_faltantes <- dplyr::filter(vivienda, is.na(parqueaderos))
Se ajusta un modelo de regresión lineal para predecir el número de parqueaderos en función de otras variables como estrato, preciom, areaconst, banios, habitaciones y tipo. Este modelo se utiliza para imputar los valores faltantes.
# Ajusta un modelo de regresión lineal usando las observaciones completas
modelo <- lm(parqueaderos ~ estrato + preciom + areaconst + banios + habitaciones + tipo, data = data_completa)
Predice los valores faltantes usando el modelo ajustado
data_faltantes$parqueaderos <- predict(modelo, newdata = data_faltantes)
# Se combina las predicciones con el dataframe original
viviendas_imputadas <- vivienda %>%
mutate(parqueaderos = ifelse(is.na(parqueaderos), predict(modelo, newdata = .), parqueaderos))
Los valores faltantes en la variable parqueaderos se predicen utilizando el modelo ajustado y se combinan con el conjunto de datos original. Además, se truncan los valores imputados a enteros para mantener la coherencia de la variable.
# Trunca los valores imputados de parqueaderos a enteros
viviendas_imputadas$parqueaderos <- trunc(viviendas_imputadas$parqueaderos)
Se analiza los datos estadisticos de cada varible.
# Verifica los cambios
summary(viviendas_imputadas)
## id zona piso estrato
## Min. : 1 Length:8319 Length:8319 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 0.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 1.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.636 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8319 Length:8319 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
Después de realizar la imputación de valores faltantes en el conjunto de datos, es fundamental verificar que no queden variables nulas. Esto se logra calculando el número de datos faltantes por variable en el conjunto de datos viviendas_imputadas.
# Calcula el número de datos faltantes por variable después de la imputación
datos_faltantes <- viviendas_imputadas %>% summarise(across(everything(), ~sum(is.na(.))))
print(datos_faltantes)
## # A tibble: 1 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 0 0 2635 0 0 0 0 0 0
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>
La variable zona, que originalmente puede estar en formato categórico, se convierte a un formato numérico. Esto es importante para facilitar el análisis estadístico y la visualización de datos.
# Convertir la variable 'zona' a numérica
vivienda <- viviendas_imputadas
vivienda$zona_numeric <- as.numeric(factor(vivienda$zona,
levels = c("Zona Norte", "Zona Sur", "Zona Oriente", "Zona Oeste", "Zona Centro"),
labels = c(1, 2, 3, 4, 5)))
Finalmente, se filtran las casas que se encuentran en la Zona Norte. Este filtrado permite realizar un análisis más detallado sobre un subconjunto específico de los datos. El uso de dim(base1) proporciona las dimensiones del conjunto de datos filtrado, permitiendo conocer cuántas casas están disponibles en la Zona Norte. Este paso es útil para enfocar el análisis en áreas geográficas específicas y entender mejor el mercado inmobiliario en esas zonas.
# Filtrar las casas en la Zona Norte
base1 <- vivienda %>%
dplyr::filter(tipo == "Casa", zona == "Zona Norte")
dim(base1)
## [1] 722 14
Para tener una idea de los datos que se están analizando, se muestran los primeros tres registros de las casas en la Zona Norte. Esto permite verificar que los datos se han filtrado correctamente y que contienen la información relevante.
# Mostrar los primeros 3 registros de las casas en la Zona Norte
head(base1, 3)
## # A tibble: 3 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 3 7 6
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # zona_numeric <dbl>
Es importante verificar los nombres de las columnas en el conjunto de datos filtrado. Esto ayuda a confirmar que las columnas están correctamente nombradas y que se pueden utilizar en análisis posteriores. Este paso asegura que no haya errores tipográficos en los nombres de las columnas, lo que podría causar problemas en el análisis.
# Verificar los nombres de las columnas
colnames(base1)
## [1] "id" "zona" "piso" "estrato" "preciom"
## [6] "areaconst" "parqueaderos" "banios" "habitaciones" "tipo"
## [11] "barrio" "longitud" "latitud" "zona_numeric"
# Cargar ggplot2 para la visualización
library(ggplot2)
Se define una función llamada mapa_puntos, que permite crear un mapa de puntos utilizando las coordenadas de longitud y latitud, así como un color que representa otra variable (por ejemplo, el precio de las casas). Esta función es flexible y permite visualizar la distribución de las casas en la Zona Norte, facilitando la identificación de patrones geográficos en los datos. La utilización de un gradiente de color ayuda a representar visualmente la variable de interés, como el precio de las casas, lo que puede ser útil para análisis posteriores.
# Definir la función mapa_puntos sin usar aes_string()
mapa_puntos <- function(data, lon_col, lat_col, color_col) {
ggplot(data, aes(x = .data[[lon_col]], y = .data[[lat_col]], color = .data[[color_col]])) +
geom_point(size = 3) +
theme_minimal() +
labs(title = "Mapa de Puntos", x = "Longitud", y = "Latitud") +
scale_color_gradient(low = "blue", high = "red")
}
Se utiliza la función previamente definida mapa_puntos para crear un mapa de puntos que representa la distribución de las casas en la Zona Norte, utilizando las columnas de longitud, latitud y precio por metro cuadrado (preciom).
Este paso genera un gráfico que permite visualizar cómo se distribuyen las casas en función de su ubicación geográfica y su precio, facilitando la identificación de áreas con precios más altos o más bajos.
# Usar la función con tus datos
mapa_puntos(base1, "longitud", "latitud", "preciom")
## Carga de la Librería ggmap y Registro de la API de Google Para
obtener un mapa base de la ubicación deseada, se carga la librería ggmap
y se registra una clave API de Google. Esto es necesario para acceder a
los mapas de Google y utilizarlos en las visualizaciones.
Es importante asegurarse de que la clave API sea válida y tenga los permisos necesarios para acceder a los servicios de Google Maps.
library(ggmap)
## ℹ Google's Terms of Service: <https://mapsplatform.google.com>
## Stadia Maps' Terms of Service: <https://stadiamaps.com/terms-of-service/>
## OpenStreetMap's Tile Usage Policy: <https://operations.osmfoundation.org/policies/tiles/>
## ℹ Please cite ggmap if you use it! Use `citation("ggmap")` for details.
register_google(key = "AIzaSyDXnIbysrNyYahrrh8eSljaBfVfJoE9dj0") # Reemplaza "YOUR_API_KEY" con tu clave API válida
mapa_base <- get_map(location = "Santiago de Cali", zoom = 12)
## ℹ <https://maps.googleapis.com/maps/api/staticmap?center=Santiago%20de%20Cali&zoom=12&size=640x640&scale=2&maptype=terrain&language=en-EN&key=xxx>
## ℹ <https://maps.googleapis.com/maps/api/geocode/json?address=Santiago+de+Cali&key=xxx>
Se obtiene un mapa base centrado en “Santiago de Cali” con un nivel de zoom específico. Este mapa servirá como fondo para la visualización de los puntos.
Este paso es crucial para establecer el contexto geográfico de los datos que se están visualizando.
# Graficar los puntos en el mapa base (asegurarse de que mapa_base esté correctamente definido)
ggmap(mapa_base) +
geom_point(data = base1, aes(x = longitud, y = latitud), color = "red", size = 2) +
labs(title = "Distribución de Casas en la Zona Norte")
Graficar los Puntos en el Mapa Base Finalmente, se grafican los puntos
de las casas sobre el mapa base, utilizando un color rojo para destacar
su ubicación.
Este gráfico proporciona una representación visual clara de la distribución de las casas en la Zona Norte, permitiendo a los analistas y tomadores de decisiones identificar patrones y tendencias en el mercado inmobiliario de la región.
Se inicia el análisis seleccionando las variables que son de interés para el estudio. En este caso, se eligen las siguientes columnas del conjunto de datos vivienda:
preciom: Precio por metro cuadrado. areaconst: Área construida. estrato: Estrato socioeconómico. banios: Número de baños. habitaciones: Número de habitaciones. zona_numeric: Representación numérica de la zona.
# Selección de variables relevantes
variables_interes <- vivienda %>%
select(preciom, areaconst, estrato, banios, habitaciones, zona_numeric)
Cálculo de la Matriz de Correlación Una vez seleccionadas las variables, se procede a calcular la matriz de correlación. Este cálculo permite evaluar la relación entre las diferentes variables seleccionadas, ayudando a identificar patrones y posibles dependencias.
La matriz de correlación resultante mostrará los coeficientes de correlación entre cada par de variables, donde un valor cercano a 1 o -1 indica una fuerte relación positiva o negativa, respectivamente, y un valor cercano a 0 indica poca o ninguna relación.
# Calculo de la matriz de correlación
correlaciones <- cor(variables_interes, use = "complete.obs")
print(correlaciones)
## preciom areaconst estrato banios habitaciones
## preciom 1.0000000 0.68735196 0.60980664 0.6691456 0.26409121
## areaconst 0.6873520 1.00000000 0.27432332 0.6484165 0.51691292
## estrato 0.6098066 0.27432332 1.00000000 0.4203218 -0.07137615
## banios 0.6691456 0.64841648 0.42032178 1.0000000 0.58990641
## habitaciones 0.2640912 0.51691292 -0.07137615 0.5899064 1.00000000
## zona_numeric 0.2367851 0.07813894 0.19267616 0.1175058 0.02696498
## zona_numeric
## preciom 0.23678506
## areaconst 0.07813894
## estrato 0.19267616
## banios 0.11750583
## habitaciones 0.02696498
## zona_numeric 1.00000000
vivienda_filtrada <- base1 %>%
dplyr::filter(!is.na(preciom) & !is.na(areaconst) & !is.na(estrato) & !is.na(banios) & !is.na(habitaciones) & !is.na(zona_numeric)) %>%
mutate(across(everything(), ~iconv(., from = "UTF-8", to = "UTF-8", sub = "")))
Una vez que los datos han sido filtrados, se procede a la visualización de las relaciones entre las variables. En este caso, se genera un gráfico de dispersión que muestra la relación entre el precio por metro cuadrado (preciom) y el área construida (areaconst).
plot_area <- plot_ly(vivienda_filtrada, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Área Construida',
xaxis = list(title = 'Área Construida (m²)'),
yaxis = list(title = 'Precio (COP)'))
Se genera un gráfico de dispersión para visualizar la relación entre el precio de las viviendas (preciom) y el estrato socio-económico (estrato). Este análisis es importante para entender cómo el nivel socioeconómico puede influir en el precio de las propiedades.
En este gráfico: Se utiliza plot_ly() para crear un gráfico de dispersión donde el eje X representa el estrato y el eje Y representa el precio por metro cuadrado. Los puntos se colorean según el precio, utilizando la escala de colores Viridis, lo que permite una mejor visualización de las diferencias de precio en función del estrato. Se añaden títulos y etiquetas a los ejes para facilitar la interpretación del gráfico.
# Gráfico de relación entre Precio y Estrato
plot_estrato <- plot_ly(vivienda_filtrada, x = ~estrato, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Estrato',
xaxis = list(title = 'Estrato'),
yaxis = list(title = 'Precio (COP)'))
A continuación, se crea otro gráfico de dispersión para analizar la relación entre el precio de las viviendas y el número de baños (banios). Este análisis puede ayudar a identificar si hay una correlación entre la cantidad de baños y el precio de las propiedades
En este gráfico:
Se utiliza plot_ly() para crear un gráfico de dispersión donde el eje X representa el número de baños y el eje Y representa el precio por metro cuadrado. Al igual que en el gráfico anterior, los puntos se colorean según el precio, lo que permite observar cómo varía el precio en función del número de baños. Se añaden títulos y etiquetas a los ejes para mejorar la claridad del gráfico.
library(plotly)
# Crear el gráfico de dispersión para la relación entre Precio y Número de Baños
plot_banios <- plot_ly(vivienda_filtrada, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Número de Baños',
xaxis = list(title = 'Número de Baños'),
yaxis = list(title = 'Precio (COP)'))
# Mostrar el gráfico
plot_banios
Se crea un gráfico de dispersión para analizar la relación entre el precio de las viviendas (preciom) y el número de habitaciones (habitaciones). Este análisis es crucial para entender cómo la cantidad de habitaciones puede afectar el precio de las propiedades.
En este gráfico: Se utiliza plot_ly() para crear un gráfico de dispersión donde el eje X representa el número de habitaciones y el eje Y representa el precio por metro cuadrado. Los puntos se colorean según el precio, utilizando la escala de colores Viridis, lo que permite observar las variaciones de precio en función del número de habitaciones. Se añaden títulos y etiquetas a los ejes para facilitar la interpretación del gráfico.
# Crear el gráfico de dispersión para la relación entre Precio y Número de Habitaciones
plot_habitaciones <- plot_ly(vivienda_filtrada, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Número de Habitaciones',
xaxis = list(title = 'Número de Habitaciones'),
yaxis = list(title = 'Precio (COP)'))
# Mostrar el gráfico
plot_habitaciones
A continuación, se genera otro gráfico de dispersión para examinar la relación entre el precio de las viviendas y la zona en la que se encuentran (zona_numeric). Este análisis es importante para identificar cómo la ubicación puede influir en el precio de las propiedades.
# Crear el gráfico de dispersión para la relación entre Precio y Zona
plot_zona <- plot_ly(vivienda_filtrada, x = ~zona_numeric, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Zona',
xaxis = list(title = 'Zona (1: Norte, 2: Sur, 3: Oriente, 4: Oeste, 5: Centro)'),
yaxis = list(title = 'Precio (COP)'))
# Mostrar el gráfico
plot_zona
Primero, se realiza un filtrado de los datos para eliminar registros que contengan valores faltantes en las variables de interés. Esto es crucial para asegurar que el modelo de regresión lineal se ajuste a un conjunto de datos completo y representativo.
# Filtrar los datos para eliminar registros con valores faltantes en las variables de interés
vivienda_filtrada <- base1 %>%
dplyr::filter(!is.na(preciom) & !is.na(areaconst) & !is.na(estrato) & !is.na(habitaciones) & !is.na(parqueaderos) & !is.na(banios))
Una vez filtrados los datos, se ajusta un modelo de regresión lineal múltiple para explorar la relación entre el precio de las viviendas (preciom) y varias variables predictoras.
# Ajustar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_filtrada)
Finalmente, se genera un resumen del modelo ajustado para obtener información sobre los coeficientes, la significancia estadística y otros parámetros relevantes.
summary(modelo) El resumen del modelo incluye:
Coeficientes: Muestra el impacto estimado de cada variable independiente sobre el precio de la vivienda. Estadísticos de significancia: Indica si los coeficientes son significativamente diferentes de cero, lo que sugiere que la variable tiene un efecto en el precio. R-squared: Proporciona una medida de cuánta variabilidad en el precio de las viviendas es explicada por el modelo. Errores estándar: Indica la precisión de las estimaciones de los coeficientes.
# Resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda_filtrada)
##
## Residuals:
## Min 1Q Median 3Q Max
## -881.35 -77.16 -15.60 44.54 1028.87
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -219.36885 29.26709 -7.495 0.000000000000196 ***
## areaconst 0.77619 0.04362 17.796 < 0.0000000000000002 ***
## estrato 77.54993 7.23291 10.722 < 0.0000000000000002 ***
## habitaciones 0.53353 4.05051 0.132 0.895
## parqueaderos 29.95492 5.59289 5.356 0.000000114833871 ***
## banios 21.26676 5.32894 3.991 0.000072632539946 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 156.1 on 716 degrees of freedom
## Multiple R-squared: 0.6642, Adjusted R-squared: 0.6618
## F-statistic: 283.2 on 5 and 716 DF, p-value: < 0.00000000000000022
Se generan gráficos de dispersión para evaluar la relación entre los residuos estandarizados del modelo de regresión y las variables independientes. Esto es fundamental para verificar supuestos de la regresión, como la homocedasticidad y la linealidad.
Ejes X: Representan las variables independientes (área construida, estrato, habitaciones, parqueaderos y baños). Eje Y: Muestra los residuos estandarizados del modelo. Interpretación: Se busca que no haya patrones evidentes en los gráficos. Un patrón podría indicar problemas de homocedasticidad (varianza constante de los residuos) o que la relación entre las variables no es lineal.
# Gráfico de dispersión de residuos estandarizados vs variables independientes
par(mfrow = c(2, 3)) # Configurar la ventana gráfica para múltiples gráficos
plot(vivienda_filtrada$areaconst, rstandard(modelo), main = "Área Construida vs Residuos", xlab = "Área Construida", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$estrato, rstandard(modelo), main = "Estrato vs Residuos", xlab = "Estrato", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$habitaciones, rstandard(modelo), main = "Habitaciones vs Residuos", xlab = "Habitaciones", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$parqueaderos, rstandard(modelo), main = "Parqueaderos vs Residuos", xlab = "Parqueaderos", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$banios, rstandard(modelo), main = "Baños vs Residuos", xlab = "Baños", ylab = "Residuos Estandarizados")
## Prueba de Durbin-Watson La prueba de Durbin-Watson se utiliza para
detectar la autocorrelación en los residuos de un modelo de regresión.
Un valor cercano a 2 sugiere que no hay autocorrelación, mientras que
valores significativamente menores o mayores pueden indicar
problemas.
# Instalar el paquete 'lmtest' si no está ya instalado
if (!requireNamespace("lmtest", quietly = TRUE)) {
install.packages("lmtest")
}
# Cargar el paquete 'lmtest'
library(lmtest)
# Ejecutar la prueba de Durbin-Watson
dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.6278, p-value = 0.0000002202
## alternative hypothesis: true autocorrelation is greater than 0
La homocedasticidad se refiere a la propiedad de que los residuos de un modelo de regresión tienen varianza constante a lo largo de todos los niveles de las variables independientes. Para evaluar esto, se puede graficar los residuos estandarizados frente a los valores ajustados.
###Homoscedasticidad
# Gráfico de residuos estandarizados vs valores ajustados
plot(fitted(modelo), rstandard(modelo), main = "Valores Ajustados vs Residuos", xlab = "Valores Ajustados", ylab = "Residuos Estandarizados")
abline(h = 0, col = "red")
## Normalidad de los Errores La normalidad de los errores es otro
supuesto importante en la regresión lineal. Se puede evaluar mediante un
gráfico Q-Q (quantile-quantile), que compara los cuantiles de los
residuos estandarizados con los cuantiles de una distribución
normal.
###Normalidad de los Errores
# Gráfico Q-Q
qqnorm(rstandard(modelo))
qqline(rstandard(modelo), col = "red")
## Prueba de Normalidad Para cuantificar la normalidad de los residuos,
se puede realizar la prueba de Shapiro-Wilk, que evalúa la hipótesis
nula de que los datos provienen de una distribución normal.
residuos <- rstandard(modelo)
length(residuos)
## [1] 722
La normalidad de los residuos es un supuesto importante en la regresión lineal. Para evaluar esto, se puede utilizar la prueba de Shapiro-Wilk, que es adecuada para muestras pequeñas y medianas.
set.seed(123)
muestra_residuos <- sample(residuos, size = min(5000, length(residuos)))
shapiro.test(muestra_residuos)
##
## Shapiro-Wilk normality test
##
## data: muestra_residuos
## W = 0.83856, p-value < 0.00000000000000022
La multicolinealidad se refiere a la situación en la que dos o más variables independientes en un modelo de regresión están altamente correlacionadas, lo que puede afectar la estabilidad de las estimaciones de los coeficientes. Para evaluar la multicolinealidad, se puede calcular el Factor de Inflación de la Varianza (VIF).
### Ausencia de Multicolinealidad
# Instalar y cargar el paquete 'nortest'
if (!requireNamespace("nortest", quietly = TRUE)) {
install.packages("nortest")
}
library(nortest)
# Realizar la prueba de Lilliefors para la normalidad de los residuos estandarizados
lillie.test(rstandard(modelo))
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: rstandard(modelo)
## D = 0.1399, p-value < 0.00000000000000022
# Crear un histograma de los residuos estandarizados
hist(rstandard(modelo), breaks = 50, main = "Histograma de los residuos estandarizados", xlab = "Residuos estandarizados")
# Crear un gráfico Q-Q para evaluar la normalidad de los residuos estandarizados
qqnorm(rstandard(modelo))
qqline(rstandard(modelo), col = "red")
# Realizar la prueba de Anderson-Darling para la normalidad de los residuos estandarizados
ad.test(rstandard(modelo))
##
## Anderson-Darling normality test
##
## data: rstandard(modelo)
## A = 25.99, p-value < 0.00000000000000022
Prueba de Lilliefors: Evalúa la normalidad de los residuos estandarizados. Histograma: Proporciona una visualización de la distribución de los residuos. Gráfico Q-Q: Compara los cuantiles de los residuos con los cuantiles de una distribución normal. Prueba de Anderson-Darling: Otra prueba para evaluar la normalidad de los residuos.
# Instalar y cargar el paquete 'car'
if (!requireNamespace("car", quietly = TRUE)) {
install.packages("car")
}
library(car)
## Loading required package: carData
# Asegúrate de que 'modelo' es un objeto de modelo ajustado con lm() o similar
# Calcular el VIF (Variance Inflation Factor)
vif(modelo)
## areaconst estrato habitaciones parqueaderos banios
## 1.573739 1.496057 1.622464 1.422341 1.952212
Se crea un nuevo dataframe nueva_vivienda con características específicas de la vivienda (área construida, estrato, número de habitaciones, parqueaderos y baños). Luego, se utiliza la función predict() para estimar el precio de la vivienda basado en el modelo ajustado previamente (denominado modelo). Finalmente, se imprime el precio predicho.
# Crear un nuevo dataframe con las características de la vivienda
nueva_vivienda <- data.frame(
areaconst = 120,
estrato = 4,
habitaciones = 3,
parqueaderos = 2,
banios = 2
)
# Predecir el precio de la vivienda utilizando el modelo ajustado
precio_predicho <- predict(modelo, newdata = nueva_vivienda)
# Mostrar el precio predicho
print(precio_predicho)
## 1
## 288.0176
Se crea un dataframe ofertas que contiene información sobre varias ofertas de viviendas, incluyendo precio, área construida, estrato, número de habitaciones, parqueaderos, baños, zona y coordenadas geográficas. Luego, se utiliza ggplot2 para crear un mapa de puntos donde cada punto representa una oferta de vivienda, con el color del punto representando el precio y el tamaño representando el área construida. Finalmente, se convierte el mapa en un gráfico interactivo utilizando plotly.
# Crear un dataframe con las ofertas potenciales
ofertas <- data.frame(
precio = c(340, 320, 330, 300, 350),
areaconst = c(200, 200, 200, 200, 200),
estrato = c(4, 5, 4, 4, 5),
habitaciones = c(4, 4, 4, 4, 4),
parqueaderos = c(1, 1, 1, 1, 1),
banios = c(2, 2, 2, 2, 2),
zona = c("Norte", "Norte", "Norte", "Norte", "Norte")
)
# Cargar los paquetes necesarios
library(ggplot2)
library(plotly)
# Crear el gráfico de dispersión
mapa_ofertas <- ggplot(ofertas, aes(x = precio, y = areaconst, color = precio, size = areaconst)) +
geom_point() +
theme_minimal() +
labs(title = "Ofertas de Viviendas en Bogotá", x = "Precio", y = "Área Construida") +
scale_color_gradient(low = "blue", high = "red")
# Convertir el gráfico a un gráfico interactivo con plotly
mapa_interactivo <- ggplotly(mapa_ofertas)
# Mostrar el gráfico interactivo
mapa_interactivo
data(vivienda)
vivienda2 <- vivienda
##Análisis de Datos Carga de Datos Los datos de vivienda se cargan y se preparan para el análisis. Se filtran los valores nulos y se realiza una conversión de codificación
# Calcular la cantidad de valores faltantes por cada columna
datos_faltantes <- vivienda2 %>%
summarise(across(everything(), ~sum(is.na(.))))
Se analiza la base de datos y se extrae los valores nulos
# Mostrar los resultados
print(datos_faltantes)
## # A tibble: 1 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 3 3 2638 3 2 3 1605 3 3
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>
Se inicia el análisis filtrando los registros que contienen un ID válido en el conjunto de datos de vivienda. Esto es crucial para asegurar que solo se utilicen observaciones completas y relevantes para el análisis posterior
# Filtrar los registros que tienen un ID válido
vivienda2 <- vivienda2 %>%
dplyr::filter(!is.na(id))
Se separan las observaciones con valores completos y aquellos con valores faltantes en la variable parqueaderos. Esto permite ajustar un modelo de regresión lineal utilizando solo los datos completos.
library(tidyverse)
# Separa las observaciones con valores completos y los faltantes en `parqueaderos`
data_completa <- dplyr::filter(vivienda2, !is.na(parqueaderos))
data_faltantes <- dplyr::filter(vivienda2, is.na(parqueaderos))
Se ajusta un modelo de regresión lineal para predecir el número de parqueaderos en función de otras variables como estrato, preciom, areaconst, banios, habitaciones y tipo. Este modelo se utiliza para imputar los valores faltantes.
# Ajusta un modelo de regresión lineal usando las observaciones completas
modelo <- lm(parqueaderos ~ estrato + preciom + areaconst + banios + habitaciones + tipo, data = data_completa)
Predice los valores faltantes usando el modelo ajustado
data_faltantes$parqueaderos <- predict(modelo, newdata = data_faltantes)
# Se combina las predicciones con el dataframe original
viviendas_imputadas <- vivienda2 %>%
mutate(parqueaderos = ifelse(is.na(parqueaderos), predict(modelo, newdata = .), parqueaderos))
Los valores faltantes en la variable parqueaderos se predicen utilizando el modelo ajustado y se combinan con el conjunto de datos original. Además, se truncan los valores imputados a enteros para mantener la coherencia de la variable.
# Trunca los valores imputados de parqueaderos a enteros
viviendas_imputadas$parqueaderos <- trunc(viviendas_imputadas$parqueaderos)
Se analiza los datos estadisticos de cada varible.
# Verifica los cambios
summary(viviendas_imputadas)
## id zona piso estrato
## Min. : 1 Length:8319 Length:8319 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 0.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 1.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.636 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8319 Length:8319 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
Después de realizar la imputación de valores faltantes en el conjunto de datos, es fundamental verificar que no queden variables nulas. Esto se logra calculando el número de datos faltantes por variable en el conjunto de datos viviendas_imputadas.
# Calcula el número de datos faltantes por variable después de la imputación
datos_faltantes <- viviendas_imputadas %>% summarise(across(everything(), ~sum(is.na(.))))
print(datos_faltantes)
## # A tibble: 1 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 0 0 2635 0 0 0 0 0 0
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>
La variable zona, que originalmente puede estar en formato categórico, se convierte a un formato numérico. Esto es importante para facilitar el análisis estadístico y la visualización de datos.
# Convertir la variable 'Sur' a numérica
vivienda2 <- viviendas_imputadas
vivienda2$zona_numeric <- as.numeric(factor(vivienda2$zona,
levels = c("Zona Norte", "Zona Sur", "Zona Oriente", "Zona Oeste", "Zona Centro"),
labels = c(1, 2, 3, 4, 5)))
Finalmente, se filtran las casas que se encuentran en la Zona Sur. Este filtrado permite realizar un análisis más detallado sobre un subconjunto específico de los datos. El uso de dim(base1) proporciona las dimensiones del conjunto de datos filtrado, permitiendo conocer cuántas casas están disponibles en la Zona Norte. Este paso es útil para enfocar el análisis en áreas geográficas específicas y entender mejor el mercado inmobiliario en esas zonas.
# Filtrar las casas en la Zona Sur
base1 <- vivienda2 %>%
dplyr::filter(tipo == "Apartamento", zona == "Zona Sur")
dim(base1)
## [1] 2787 14
Para tener una idea de los datos que se están analizando, se muestran los primeros tres registros de las casas en la Zona Sur. Esto permite verificar que los datos se han filtrado correctamente y que contienen la información relevante.
# Mostrar los primeros 3 registros de las casas en la Zona Sur
head(base1, 3)
## # A tibble: 3 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 5098 Zona S… 05 4 290 96 1 2 3
## 2 698 Zona S… 02 3 78 40 1 1 2
## 3 8199 Zona S… <NA> 6 875 194 2 5 3
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # zona_numeric <dbl>
Es importante verificar los nombres de las columnas en el conjunto de datos filtrado. Esto ayuda a confirmar que las columnas están correctamente nombradas y que se pueden utilizar en análisis posteriores. Este paso asegura que no haya errores tipográficos en los nombres de las columnas, lo que podría causar problemas en el análisis.
# Verificar los nombres de las columnas
colnames(base1)
## [1] "id" "zona" "piso" "estrato" "preciom"
## [6] "areaconst" "parqueaderos" "banios" "habitaciones" "tipo"
## [11] "barrio" "longitud" "latitud" "zona_numeric"
Se define una función llamada mapa_puntos, que permite crear un mapa de puntos utilizando las coordenadas de longitud y latitud, así como un color que representa otra variable (por ejemplo, el precio de las casas). Esta función es flexible y permite visualizar la distribución de las casas en la Zona Sur, facilitando la identificación de patrones geográficos en los datos. La utilización de un gradiente de color ayuda a representar visualmente la variable de interés, como el precio de las casas, lo que puede ser útil para análisis posteriores.
# Definir la función mapa_puntos sin usar aes_string()
mapa_puntos <- function(data, lon_col, lat_col, color_col) {
ggplot(data, aes(x = .data[[lon_col]], y = .data[[lat_col]], color = .data[[color_col]])) +
geom_point(size = 3) +
theme_minimal() +
labs(title = "Mapa de Puntos", x = "Longitud", y = "Latitud") +
scale_color_gradient(low = "blue", high = "red")
}
Se utiliza la función previamente definida mapa_puntos para crear un mapa de puntos que representa la distribución de las casas en la Zona Sur, utilizando las columnas de longitud, latitud y precio por metro cuadrado (preciom).
Este paso genera un gráfico que permite visualizar cómo se distribuyen las casas en función de su ubicación geográfica y su precio, facilitando la identificación de áreas con precios más altos o más bajos.
# Usar la función con tus datos
mapa_puntos(base1, "longitud", "latitud", "preciom")
## Carga de la Librería ggmap y Registro de la API de Google Para
obtener un mapa base de la ubicación deseada, se carga la librería ggmap
y se registra una clave API de Google. Esto es necesario para acceder a
los mapas de Google y utilizarlos en las visualizaciones.
Es importante asegurarse de que la clave API sea válida y tenga los permisos necesarios para acceder a los servicios de Google Maps.
library(ggmap)
register_google(key = "AIzaSyDXnIbysrNyYahrrh8eSljaBfVfJoE9dj0") # Reemplaza "YOUR_API_KEY" con tu clave API válida
mapa_base <- get_map(location = "Santiago de Cali", zoom = 12)
## ℹ <https://maps.googleapis.com/maps/api/staticmap?center=Santiago%20de%20Cali&zoom=12&size=640x640&scale=2&maptype=terrain&language=en-EN&key=xxx>
## ℹ <https://maps.googleapis.com/maps/api/geocode/json?address=Santiago+de+Cali&key=xxx>
Se obtiene un mapa base centrado en “Santiago de Cali” con un nivel de zoom específico. Este mapa servirá como fondo para la visualización de los puntos.
Este paso es crucial para establecer el contexto geográfico de los datos que se están visualizando.
# Graficar los puntos en el mapa base (asegurarse de que mapa_base esté correctamente definido)
ggmap(mapa_base) +
geom_point(data = base1, aes(x = longitud, y = latitud), color = "red", size = 2) +
labs(title = "Distribución de Casas en la Zona Sur")
Graficar los Puntos en el Mapa Base Finalmente, se grafican los puntos
de las casas sobre el mapa base, utilizando un color rojo para destacar
su ubicación.
Este gráfico proporciona una representación visual clara de la distribución de las casas en la Zona Sur, permitiendo a los analistas y tomadores de decisiones identificar patrones y tendencias en el mercado inmobiliario de la región.
Se inicia el análisis seleccionando las variables que son de interés para el estudio. En este caso, se eligen las siguientes columnas del conjunto de datos vivienda2:
preciom: Precio por metro cuadrado. areaconst: Área construida. estrato: Estrato socioeconómico. banios: Número de baños. habitaciones: Número de habitaciones. zona_numeric: Representación numérica de la zona.
# Selección de variables relevantes
variables_interes <- base1 %>%
select(preciom, areaconst, estrato, banios, habitaciones, zona_numeric)
Cálculo de la Matriz de Correlación Una vez seleccionadas las variables, se procede a calcular la matriz de correlación. Este cálculo permite evaluar la relación entre las diferentes variables seleccionadas, ayudando a identificar patrones y posibles dependencias.
La matriz de correlación resultante mostrará los coeficientes de correlación entre cada par de variables, donde un valor cercano a 1 o -1 indica una fuerte relación positiva o negativa, respectivamente, y un valor cercano a 0 indica poca o ninguna relación.
# Calculo de la matriz de correlación
correlaciones <- cor(variables_interes, use = "complete.obs")
print(correlaciones)
## preciom areaconst estrato banios habitaciones zona_numeric
## preciom 1.0000000 0.7579955 0.6727067 0.7196705 0.3317538 NA
## areaconst 0.7579955 1.0000000 0.4815593 0.6618179 0.4339608 NA
## estrato 0.6727067 0.4815593 1.0000000 0.5686171 0.2125953 NA
## banios 0.7196705 0.6618179 0.5686171 1.0000000 0.5149227 NA
## habitaciones 0.3317538 0.4339608 0.2125953 0.5149227 1.0000000 NA
## zona_numeric NA NA NA NA NA 1
vivienda_filtrada <- base1 %>%
dplyr::filter(!is.na(preciom) & !is.na(areaconst) & !is.na(estrato) & !is.na(banios) & !is.na(habitaciones) & !is.na(zona_numeric)) %>%
mutate(across(everything(), ~iconv(., from = "UTF-8", to = "UTF-8", sub = "")))
Una vez que los datos han sido filtrados, se procede a la visualización de las relaciones entre las variables. En este caso, se genera un gráfico de dispersión que muestra la relación entre el precio por metro cuadrado (preciom) y el área construida (areaconst).
plot_area <- plot_ly(vivienda_filtrada, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Área Construida',
xaxis = list(title = 'Área Construida (m²)'),
yaxis = list(title = 'Precio (COP)'))
Se genera un gráfico de dispersión para visualizar la relación entre el precio de las viviendas (preciom) y el estrato socio-económico (estrato). Este análisis es importante para entender cómo el nivel socioeconómico puede influir en el precio de las propiedades.
En este gráfico: Se utiliza plot_ly() para crear un gráfico de dispersión donde el eje X representa el estrato y el eje Y representa el precio por metro cuadrado. Los puntos se colorean según el precio, utilizando la escala de colores Viridis, lo que permite una mejor visualización de las diferencias de precio en función del estrato. Se añaden títulos y etiquetas a los ejes para facilitar la interpretación del gráfico.
# Gráfico de relación entre Precio y Estrato
plot_estrato <- plot_ly(vivienda_filtrada, x = ~estrato, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Estrato',
xaxis = list(title = 'Estrato'),
yaxis = list(title = 'Precio (COP)'))
A continuación, se crea otro gráfico de dispersión para analizar la relación entre el precio de las viviendas y el número de baños (banios). Este análisis puede ayudar a identificar si hay una correlación entre la cantidad de baños y el precio de las propiedades
En este gráfico:
Se utiliza plot_ly() para crear un gráfico de dispersión donde el eje X representa el número de baños y el eje Y representa el precio por metro cuadrado. Al igual que en el gráfico anterior, los puntos se colorean según el precio, lo que permite observar cómo varía el precio en función del número de baños. Se añaden títulos y etiquetas a los ejes para mejorar la claridad del gráfico.
library(plotly)
# Crear el gráfico de dispersión para la relación entre Precio y Número de Baños
plot_banios <- plot_ly(vivienda_filtrada, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Número de Baños',
xaxis = list(title = 'Número de Baños'),
yaxis = list(title = 'Precio (COP)'))
# Mostrar el gráfico
plot_banios
Se crea un gráfico de dispersión para analizar la relación entre el precio de las viviendas (preciom) y el número de habitaciones (habitaciones). Este análisis es crucial para entender cómo la cantidad de habitaciones puede afectar el precio de las propiedades.
En este gráfico: Se utiliza plot_ly() para crear un gráfico de dispersión donde el eje X representa el número de habitaciones y el eje Y representa el precio por metro cuadrado. Los puntos se colorean según el precio, utilizando la escala de colores Viridis, lo que permite observar las variaciones de precio en función del número de habitaciones. Se añaden títulos y etiquetas a los ejes para facilitar la interpretación del gráfico.
# Crear el gráfico de dispersión para la relación entre Precio y Número de Habitaciones
plot_habitaciones <- plot_ly(vivienda_filtrada, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Número de Habitaciones',
xaxis = list(title = 'Número de Habitaciones'),
yaxis = list(title = 'Precio (COP)'))
# Mostrar el gráfico
plot_habitaciones
A continuación, se genera otro gráfico de dispersión para examinar la relación entre el precio de las viviendas y la zona en la que se encuentran (zona_numeric). Este análisis es importante para identificar cómo la ubicación puede influir en el precio de las propiedades.
# Crear el gráfico de dispersión para la relación entre Precio y Zona
plot_zona <- plot_ly(vivienda_filtrada, x = ~zona_numeric, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = ~preciom, colorscale = 'Viridis', showscale = TRUE)) %>%
plotly::layout(title = 'Relación entre Precio y Zona',
xaxis = list(title = 'Zona (1: Norte, 2: Sur, 3: Oriente, 4: Oeste, 5: Centro)'),
yaxis = list(title = 'Precio (COP)'))
# Mostrar el gráfico
plot_zona
Primero, se realiza un filtrado de los datos para eliminar registros que contengan valores faltantes en las variables de interés. Esto es crucial para asegurar que el modelo de regresión lineal se ajuste a un conjunto de datos completo y representativo.
# Filtrar los datos para eliminar registros con valores faltantes en las variables de interés
vivienda_filtrada <- base1 %>%
dplyr::filter(!is.na(preciom) & !is.na(areaconst) & !is.na(estrato) & !is.na(habitaciones) & !is.na(parqueaderos) & !is.na(banios))
Una vez filtrados los datos, se ajusta un modelo de regresión lineal múltiple para explorar la relación entre el precio de las viviendas (preciom) y varias variables predictoras.
# Ajustar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_filtrada)
Finalmente, se genera un resumen del modelo ajustado para obtener información sobre los coeficientes, la significancia estadística y otros parámetros relevantes.
summary(modelo) El resumen del modelo incluye:
Coeficientes: Muestra el impacto estimado de cada variable independiente sobre el precio de la vivienda. Estadísticos de significancia: Indica si los coeficientes son significativamente diferentes de cero, lo que sugiere que la variable tiene un efecto en el precio. R-squared: Proporciona una medida de cuánta variabilidad en el precio de las viviendas es explicada por el modelo. Errores estándar: Indica la precisión de las estimaciones de los coeficientes.
# Resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda_filtrada)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1201.45 -42.25 -1.60 36.71 935.81
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -215.05601 13.40840 -16.039 < 0.0000000000000002 ***
## areaconst 1.40640 0.04902 28.693 < 0.0000000000000002 ***
## estrato 54.35821 2.80476 19.381 < 0.0000000000000002 ***
## habitaciones -22.67919 3.37020 -6.729 0.0000000000206 ***
## parqueaderos 57.18042 3.29246 17.367 < 0.0000000000000002 ***
## banios 47.93433 3.01751 15.885 < 0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 94.47 on 2781 degrees of freedom
## Multiple R-squared: 0.7572, Adjusted R-squared: 0.7568
## F-statistic: 1735 on 5 and 2781 DF, p-value: < 0.00000000000000022
Se generan gráficos de dispersión para evaluar la relación entre los residuos estandarizados del modelo de regresión y las variables independientes. Esto es fundamental para verificar supuestos de la regresión, como la homocedasticidad y la linealidad.
Ejes X: Representan las variables independientes (área construida, estrato, habitaciones, parqueaderos y baños). Eje Y: Muestra los residuos estandarizados del modelo. Interpretación: Se busca que no haya patrones evidentes en los gráficos. Un patrón podría indicar problemas de homocedasticidad (varianza constante de los residuos) o que la relación entre las variables no es lineal.
# Gráfico de dispersión de residuos estandarizados vs variables independientes
par(mfrow = c(2, 3)) # Configurar la ventana gráfica para múltiples gráficos
plot(vivienda_filtrada$areaconst, rstandard(modelo), main = "Área Construida vs Residuos", xlab = "Área Construida", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$estrato, rstandard(modelo), main = "Estrato vs Residuos", xlab = "Estrato", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$habitaciones, rstandard(modelo), main = "Habitaciones vs Residuos", xlab = "Habitaciones", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$parqueaderos, rstandard(modelo), main = "Parqueaderos vs Residuos", xlab = "Parqueaderos", ylab = "Residuos Estandarizados")
plot(vivienda_filtrada$banios, rstandard(modelo), main = "Baños vs Residuos", xlab = "Baños", ylab = "Residuos Estandarizados")
## Prueba de Durbin-Watson La prueba de Durbin-Watson se utiliza para
detectar la autocorrelación en los residuos de un modelo de regresión.
Un valor cercano a 2 sugiere que no hay autocorrelación, mientras que
valores significativamente menores o mayores pueden indicar
problemas.
# Instalar el paquete 'lmtest' si no está ya instalado
if (!requireNamespace("lmtest", quietly = TRUE)) {
install.packages("lmtest")
}
# Cargar el paquete 'lmtest'
library(lmtest)
# Ejecutar la prueba de Durbin-Watson
dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.5063, p-value < 0.00000000000000022
## alternative hypothesis: true autocorrelation is greater than 0
La homocedasticidad se refiere a la propiedad de que los residuos de un modelo de regresión tienen varianza constante a lo largo de todos los niveles de las variables independientes. Para evaluar esto, se puede graficar los residuos estandarizados frente a los valores ajustados.
###Homoscedasticidad
# Gráfico de residuos estandarizados vs valores ajustados
plot(fitted(modelo), rstandard(modelo), main = "Valores Ajustados vs Residuos", xlab = "Valores Ajustados", ylab = "Residuos Estandarizados")
abline(h = 0, col = "red")
## Normalidad de los Errores La normalidad de los errores es otro
supuesto importante en la regresión lineal. Se puede evaluar mediante un
gráfico Q-Q (quantile-quantile), que compara los cuantiles de los
residuos estandarizados con los cuantiles de una distribución
normal.
###Normalidad de los Errores
# Gráfico Q-Q
qqnorm(rstandard(modelo))
qqline(rstandard(modelo), col = "red")
## Prueba de Normalidad Para cuantificar la normalidad de los residuos,
se puede realizar la prueba de Shapiro-Wilk, que evalúa la hipótesis
nula de que los datos provienen de una distribución normal.
residuos <- rstandard(modelo)
length(residuos)
## [1] 2787
La normalidad de los residuos es un supuesto importante en la regresión lineal. Para evaluar esto, se puede utilizar la prueba de Shapiro-Wilk, que es adecuada para muestras pequeñas y medianas.
set.seed(123)
muestra_residuos <- sample(residuos, size = min(5000, length(residuos)))
shapiro.test(muestra_residuos)
##
## Shapiro-Wilk normality test
##
## data: muestra_residuos
## W = 0.77554, p-value < 0.00000000000000022
La multicolinealidad se refiere a la situación en la que dos o más variables independientes en un modelo de regresión están altamente correlacionadas, lo que puede afectar la estabilidad de las estimaciones de los coeficientes. Para evaluar la multicolinealidad, se puede calcular el Factor de Inflación de la Varianza (VIF).
### Ausencia de Multicolinealidad
# Instalar y cargar el paquete 'nortest'
if (!requireNamespace("nortest", quietly = TRUE)) {
install.packages("nortest")
}
library(nortest)
# Realizar la prueba de Lilliefors para la normalidad de los residuos estandarizados
lillie.test(rstandard(modelo))
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: rstandard(modelo)
## D = 0.13311, p-value < 0.00000000000000022
# Crear un histograma de los residuos estandarizados
hist(rstandard(modelo), breaks = 50, main = "Histograma de los residuos estandarizados", xlab = "Residuos estandarizados")
# Crear un gráfico Q-Q para evaluar la normalidad de los residuos estandarizados
qqnorm(rstandard(modelo))
qqline(rstandard(modelo), col = "red")
# Realizar la prueba de Anderson-Darling para la normalidad de los residuos estandarizados
ad.test(rstandard(modelo))
##
## Anderson-Darling normality test
##
## data: rstandard(modelo)
## A = 89.881, p-value < 0.00000000000000022
Prueba de Lilliefors: Evalúa la normalidad de los residuos estandarizados. Histograma: Proporciona una visualización de la distribución de los residuos. Gráfico Q-Q: Compara los cuantiles de los residuos con los cuantiles de una distribución normal. Prueba de Anderson-Darling: Otra prueba para evaluar la normalidad de los residuos.
# Instalar y cargar el paquete 'car'
if (!requireNamespace("car", quietly = TRUE)) {
install.packages("car")
}
library(car)
# Asegúrate de que 'modelo' es un objeto de modelo ajustado con lm() o similar
# Calcular el VIF (Variance Inflation Factor)
vif(modelo)
## areaconst estrato habitaciones parqueaderos banios
## 2.072688 1.741592 1.418807 1.944476 2.481899
Se crea un nuevo dataframe nueva_vivienda con características específicas de la vivienda (área construida, estrato, número de habitaciones, parqueaderos y baños). Luego, se utiliza la función predict() para estimar el precio de la vivienda basado en el modelo ajustado previamente (denominado modelo). Finalmente, se imprime el precio predicho.
# Crear un nuevo dataframe con las características de la vivienda
nueva_vivienda <- data.frame(
areaconst = 120,
estrato = 4,
habitaciones = 3,
parqueaderos = 2,
banios = 2
)
# Predecir el precio de la vivienda utilizando el modelo ajustado
precio_predicho <- predict(modelo, newdata = nueva_vivienda)
# Mostrar el precio predicho
print(precio_predicho)
## 1
## 313.3369
Se crea un dataframe ofertas que contiene información sobre varias ofertas de viviendas, incluyendo precio, área construida, estrato, número de habitaciones, parqueaderos, baños, zona y coordenadas geográficas. Luego, se utiliza ggplot2 para crear un mapa de puntos donde cada punto representa una oferta de vivienda, con el color del punto representando el precio y el tamaño representando el área construida. Finalmente, se convierte el mapa en un gráfico interactivo utilizando plotly.
# Crear un dataframe con las ofertas potenciales
ofertas <- data.frame(
precio = c(750, 850, 650, 450, 650),
areaconst = c(300, 300, 300, 300, 300),
estrato = c(6, 5, 6, 6, 5),
habitaciones = c(5, 5, 5, 5, 5),
parqueaderos = c(3, 3, 3, 3, 3),
banios = c(3, 3, 3, 3, 3),
zona = c("Sur", "Sur", "Sur", "Sur", "Sur")
)
# Cargar los paquetes necesarios
library(ggplot2)
library(plotly)
# Crear el gráfico de dispersión
mapa_ofertas <- ggplot(ofertas, aes(x = precio, y = areaconst, color = precio, size = areaconst)) +
geom_point() +
theme_minimal() +
labs(title = "Ofertas de Viviendas en Bogotá", x = "Precio", y = "Área Construida") +
scale_color_gradient(low = "blue", high = "red")
# Convertir el gráfico a un gráfico interactivo con plotly
mapa_interactivo <- ggplotly(mapa_ofertas)
# Mostrar el gráfico interactivo
mapa_interactivo
Se analizaron 722 registros de casas en la Zona Norte. Las variables clave consideradas incluyeron el área construida, estrato socioeconómico, número de parqueaderos, número de baños y número de habitaciones. 3.1.2. Resultados del Modelo de Regresión
El modelo ajustado presentó un R-cuadrado ajustado de 0.6618, indicando que aproximadamente el 66.18% de la variabilidad en el precio de las casas puede ser explicada por las variables incluidas en el modelo. Las variables más influyentes en el precio fueron: Área Construida: A mayor área construida, mayor el precio de la vivienda. Estrato Socioeconómico: Las casas en estratos más altos tienen precios significativamente mayores. Número de Parqueaderos: La disponibilidad de parqueaderos también mostró un impacto positivo en el precio. Número de Baños: Las casas con más baños tienden a tener precios más elevados.
Se generó un mapa de puntos que muestra la distribución de los precios de las casas en la Zona Norte. Las áreas con precios más elevados están concentradas en ciertos barrios, lo que sugiere la existencia de zonas premium dentro de la Zona Norte.
Se analizaron 2787 registros de apartamentos en la Zona Sur. Las variables clave fueron similares a las de la Zona Norte, adaptadas para apartamentos.
El modelo ajustado para la Zona Sur presentó un R-cuadrado ajustado de 0.7568, lo que significa que el 75.68% de la variabilidad en el precio de los apartamentos se explica por las variables del modelo. Las variables más influyentes en el precio fueron: Área Construida: Similar a la Zona Norte, la superficie construida es un factor determinante del precio.
Estrato Socioeconómico: También es un fuerte predictor del precio en la Zona Sur. Número de Parqueaderos: Los apartamentos con más parqueaderos presentan precios más altos. Número de Habitaciones: Curiosamente, en contraste con las casas, el número de habitaciones mostró una relación negativa con el precio, sugiriendo que los apartamentos más caros pueden no necesitar muchas habitaciones para ser valorados más alto.
Al igual que en la Zona Norte, se creó un mapa de puntos para la Zona Sur. Los apartamentos más costosos están distribuidos en áreas específicas, lo que permite identificar las zonas con mayor valor de mercado dentro de la Zona Sur.
Al comparar los resultados de las dos zonas, se observan diferencias y similitudes en los factores que afectan los precios:
El área construida y el estrato socioeconómico son consistentemente significativos en ambas zonas. La disponibilidad de parqueaderos también es un factor importante en ambas zonas.
En la Zona Norte, el número de habitaciones no mostró una relación significativa con el precio, mientras que en la Zona Sur, esta relación fue negativa. Los modelos de regresión para la Zona Sur fueron más robustos, lo que sugiere una menor variabilidad inexplicada en los precios de los apartamentos.
El análisis muestra que tanto en la Zona Norte como en la Zona Sur, el área construida y el estrato socioeconómico son los principales determinantes del precio de las viviendas. Los apartamentos en la Zona Sur presentan un comportamiento de mercado más homogéneo en comparación con las casas en la Zona Norte, lo que se refleja en un mayor R-cuadrado ajustado.
Para futuros análisis, se sugiere incluir variables adicionales como la antigüedad de la propiedad y la proximidad a servicios esenciales, que podrían mejorar la capacidad predictiva de los modelos. Es recomendable realizar un análisis específico de las zonas premium identificadas en cada zona, para profundizar en los factores que las hacen más valiosas.
Este informe proporciona una visión completa del mercado inmobiliario en las zonas Norte y Sur, basado en un análisis detallado de los datos disponibles. La información aquí contenida será útil para la toma de decisiones estratégicas y el desarrollo de políticas orientadas a maximizar el valor de las propiedades en estas áreas.