Maria comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.
Actualmente las ventas de bienes raíces en Cali se han visto disminuidas de manera significativa en lo corrido del año. Durante este periodo muchas instituciones bancarias de ahorro y vivienda están prestando grandes sumas de dinero para la industria y la construcción comercial y residencial. Cuando el efecto producto de las tensiones políticas y sociales disminuya, se espera que la actividad económica de este sector se reactive.
Hace dos días, María recibió una carta solicitando asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad. Las solicitudes incluyen las siguientes condiciones: Una empresa inmobiliaria líder en una gran ciudad está buscando comprender en profundidad el mercado de viviendas urbanas para tomar decisiones estratégicas más informadas. La empresa posee una base de datos extensa que contiene información detallada sobre diversas propiedades residenciales disponibles en el mercado. Se requiere realizar un análisis holístico de estos datos para identificar patrones, relaciones y segmentaciones relevantes que permitan mejorar la toma de decisiones en cuanto a la compra, venta y valoración de propiedades.
data("vivienda")
#Almacenar el dataset original en otro.
data_vivienda<-vivienda
#Seleccionar data filro solo para Casa ubicadas en Zona Norte
data_base1 <- subset(data_vivienda,tipo=="Casa" & zona=="Zona Norte")
write.xlsx(data_base1, file = "D://data_base1.xlsx")
Ver los primeros tres registros de la base filtrada
head(data_base1,3)
## # A tibble: 3 × 13
## 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 NA 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Ver el número total de casas en la Zona Norte
nrow(data_base1)
## [1] 722
# Mostrar estadísticas descriptivas de las casas en la Zona Norte
summary(data_base1)
## id zona piso estrato
## Min. : 58.0 Length:722 Length:722 Min. :3.000
## 1st Qu.: 766.2 Class :character Class :character 1st Qu.:3.000
## Median :2257.0 Mode :character Mode :character Median :4.000
## Mean :2574.6 Mean :4.202
## 3rd Qu.:4225.0 3rd Qu.:5.000
## Max. :8319.0 Max. :6.000
##
## preciom areaconst parqueaderos banios
## Min. : 89.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 261.2 1st Qu.: 140.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 390.0 Median : 240.0 Median : 2.000 Median : 3.000
## Mean : 445.9 Mean : 264.9 Mean : 2.182 Mean : 3.555
## 3rd Qu.: 550.0 3rd Qu.: 336.8 3rd Qu.: 3.000 3rd Qu.: 4.000
## Max. :1940.0 Max. :1440.0 Max. :10.000 Max. :10.000
## NA's :287
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:722 Length:722 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.53
## Median : 4.000 Mode :character Mode :character Median :-76.52
## Mean : 4.507 Mean :-76.52
## 3rd Qu.: 5.000 3rd Qu.:-76.50
## Max. :10.000 Max. :-76.47
##
## latitud
## Min. :3.333
## 1st Qu.:3.452
## Median :3.468
## Mean :3.460
## 3rd Qu.:3.482
## Max. :3.496
##
Mapa con los puntos de las base filtrada
# Crear el mapa
mapa <- leaflet(data_base1) %>%
addTiles() %>% # Agrega las tiles (fondo de mapa)
addMarkers(lng = ~longitud, lat = ~latitud, popup = ~paste("ID:", id, "<br>", "Barrio:", barrio))
# Mostrar el mapa
mapa
# Mapa marcadores agrupados base 1
mapa2 = leaflet(data = data_base1) %>%
addTiles() %>%
addMarkers(lng = ~longitud, lat = ~latitud, clusterOptions = markerClusterOptions())
mapa2
Para analizar los puntos que se encuentran en zonas incorrectas en el mapa, es fundamental contar con información detallada sobre el proceso de geocodificación utilizado para obtener las coordenadas. Si se identifica que algunos puntos ubicados fuera de la Zona Norte han sido asignados erróneamente, es crucial revisar y ajustar tanto el procedimiento de geocodificación como los criterios utilizados para determinar la inclusión de las viviendas en dicha zona. Este ajuste garantizará una clasificación precisa y evitará conclusiones erróneas en el análisis geoespacial.
se inicia con la revisión del Dataset, asi como con el resumen estadistico
# Revisar la estructura del dataset
kable(head(data_base1), format = "markdown")
id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
1592 | Zona Norte | 02 | 5 | 780 | 380 | 2 | 3 | 3 | Casa | acopi | -76.51674 | 3.48721 |
4057 | Zona Norte | 02 | 6 | 750 | 445 | NA | 7 | 6 | Casa | acopi | -76.52950 | 3.38527 |
4460 | Zona Norte | 02 | 4 | 625 | 355 | 3 | 5 | 5 | Casa | acopi | -76.53179 | 3.40590 |
6081 | Zona Norte | 02 | 5 | 750 | 237 | 2 | 6 | 6 | Casa | acopi | -76.54044 | 3.36862 |
7824 | Zona Norte | 02 | 4 | 600 | 160 | 1 | 4 | 5 | Casa | acopi | -76.55210 | 3.42125 |
# Resumen estadístico
summary(data_base1)
## id zona piso estrato
## Min. : 58.0 Length:722 Length:722 Min. :3.000
## 1st Qu.: 766.2 Class :character Class :character 1st Qu.:3.000
## Median :2257.0 Mode :character Mode :character Median :4.000
## Mean :2574.6 Mean :4.202
## 3rd Qu.:4225.0 3rd Qu.:5.000
## Max. :8319.0 Max. :6.000
##
## preciom areaconst parqueaderos banios
## Min. : 89.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 261.2 1st Qu.: 140.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 390.0 Median : 240.0 Median : 2.000 Median : 3.000
## Mean : 445.9 Mean : 264.9 Mean : 2.182 Mean : 3.555
## 3rd Qu.: 550.0 3rd Qu.: 336.8 3rd Qu.: 3.000 3rd Qu.: 4.000
## Max. :1940.0 Max. :1440.0 Max. :10.000 Max. :10.000
## NA's :287
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:722 Length:722 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.53
## Median : 4.000 Mode :character Mode :character Median :-76.52
## Mean : 4.507 Mean :-76.52
## 3rd Qu.: 5.000 3rd Qu.:-76.50
## Max. :10.000 Max. :-76.47
##
## latitud
## Min. :3.333
## 1st Qu.:3.452
## Median :3.468
## Mean :3.460
## 3rd Qu.:3.482
## Max. :3.496
##
#Se realiza la verificación de valores nulos por cada una de las variables que conforman la data.
# Verificar valores nulos
sum(is.na(data_base1))
## [1] 659
# Verificar la cantidad de valores nulos por columna
colSums(is.na(data_base1))
## id zona piso estrato preciom areaconst
## 0 0 372 0 0 0
## parqueaderos banios habitaciones tipo barrio longitud
## 287 0 0 0 0 0
## latitud
## 0
grafico_faltantes <-md.pattern(data_base1, rotate.names = TRUE)
# Ver la distribución de las variables categóricas
table(data_base1$zona)
##
## Zona Norte
## 722
table(data_base1$estrato)
##
## 3 4 5 6
## 235 161 271 55
table(data_base1$tipo)
##
## Casa
## 722
table(data_base1$barrio)
##
## acopi alameda del río alamos
## 70 1 3
## atanasio girardot barranquilla barrio tranquilo y
## 1 3 1
## base aérea berlin brisas de los
## 2 1 22
## brisas del guabito Cali calibella
## 1 13 1
## calima calimio norte cambulos
## 6 3 1
## centenario chapinero chipichape
## 3 1 5
## ciudad los álamos colinas del bosque cristales
## 11 1 1
## el bosque el cedro el gran limonar
## 37 1 1
## el guabito el sena el trébol
## 1 1 1
## evaristo garcía flora industrial floralia
## 1 4 3
## gaitan granada jorge eliecer gaitán
## 1 10 1
## juanamb√∫ la base la campiña
## 11 1 4
## la esmeralda la flora La Flora
## 1 99 1
## la floresta la merced la rivera
## 2 24 9
## la rivera i la rivera ii la riviera
## 1 2 1
## la villa del las acacias las américas
## 1 1 1
## las ceibas las delicias las granjas
## 2 3 1
## los andes los guaduales los guayacanes
## 13 10 2
## manzanares menga metropolitano del norte
## 1 2 1
## nueva tequendama oasis de comfandi occidente
## 1 1 1
## pacara parque residencial el paseo de los
## 2 1 2
## paso del comercio poblado campestre popular
## 2 1 5
## portada de comfandi portales de comfandi porvenir
## 1 1 2
## prados del norte quintas de salomia rozo la torre
## 31 1 1
## salomia san luis san luís
## 20 2 1
## san vicente santa bárbara santa monica
## 31 1 16
## Santa Monica santa mónica santa monica norte
## 1 1 1
## santa monica residencial santa mónica residencial santander
## 5 15 1
## tejares de san torres de comfandi unión de vivienda
## 1 2 1
## urbanización barranquilla urbanización la flora urbanización la merced
## 2 23 4
## urbanización la nueva valle del lili versalles
## 1 1 16
## villa colombia villa de veracruz villa del prado
## 1 4 40
## Villa Del Prado villa del sol villas de veracruz
## 1 12 7
## Villas De Veracruz vipasa zona norte
## 1 30 19
## zona oriente
## 1
Resumen estadístico de las variables numéricas
# Resumen estadístico de las variables numéricas
summary(data_base1[c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones", "longitud", "latitud")])
## preciom areaconst parqueaderos banios
## Min. : 89.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 261.2 1st Qu.: 140.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 390.0 Median : 240.0 Median : 2.000 Median : 3.000
## Mean : 445.9 Mean : 264.9 Mean : 2.182 Mean : 3.555
## 3rd Qu.: 550.0 3rd Qu.: 336.8 3rd Qu.: 3.000 3rd Qu.: 4.000
## Max. :1940.0 Max. :1440.0 Max. :10.000 Max. :10.000
## NA's :287
## habitaciones longitud latitud
## Min. : 0.000 Min. :-76.59 Min. :3.333
## 1st Qu.: 3.000 1st Qu.:-76.53 1st Qu.:3.452
## Median : 4.000 Median :-76.52 Median :3.468
## Mean : 4.507 Mean :-76.52 Mean :3.460
## 3rd Qu.: 5.000 3rd Qu.:-76.50 3rd Qu.:3.482
## Max. :10.000 Max. :-76.47 Max. :3.496
##
En esta etapa se inicia con la eliminación de los registros cuyo porcentaje en datos nulos es alto y la imputacion que se requiera para la demas data.
El grafico muestra que se deben eliminar tres registros e imputar los datos en la variable parqueaderos y piso
#Grafico con datos faltantes
grafico_faltantes <-md.pattern(data_base1, rotate.names = TRUE)
# Se inicia con la eliminacion de registros nulos si existen.
# Tratamiento de Datos Faltantes
data_base1 <- data_base1 %>% filter(id != "NA")
# Se vuelve a graficar para verificar el borrado de registros
grafico_faltantes <-md.pattern(data_base1, rotate.names = TRUE)
Se debe cambiar el formato de caracter a numerico de la varibale
piso.
data_base1$piso <- as.numeric(data_base1$piso)
glimpse(data_base1)
## Rows: 722
## Columns: 13
## $ id <dbl> 1209, 1592, 4057, 4460, 6081, 7824, 7987, 3495, 141, 243,…
## $ zona <chr> "Zona Norte", "Zona Norte", "Zona Norte", "Zona Norte", "…
## $ piso <dbl> 2, 2, 2, 2, 2, 2, 2, 3, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ estrato <dbl> 5, 5, 6, 4, 5, 4, 5, 5, 3, 3, 3, 3, 5, 3, 4, 4, 5, 5, 4, …
## $ preciom <dbl> 320, 780, 750, 625, 750, 600, 420, 490, 230, 190, 180, 50…
## $ areaconst <dbl> 150, 380, 445, 355, 237, 160, 200, 118, 160, 435, 120, 21…
## $ parqueaderos <dbl> 2, 2, NA, 3, 2, 1, 4, 2, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ banios <dbl> 4, 3, 7, 5, 6, 4, 4, 4, 2, 0, 3, 6, 5, 5, 3, 3, 4, 5, 5, …
## $ habitaciones <dbl> 6, 3, 6, 5, 6, 5, 5, 4, 3, 0, 3, 6, 4, 8, 4, 3, 4, 6, 4, …
## $ tipo <chr> "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "…
## $ barrio <chr> "acopi", "acopi", "acopi", "acopi", "acopi", "acopi", "ac…
## $ longitud <dbl> -76.51341, -76.51674, -76.52950, -76.53179, -76.54044, -7…
## $ latitud <dbl> 3.47968, 3.48721, 3.38527, 3.40590, 3.36862, 3.42125, 3.4…
# Imputar los valores faltantes de "piso" con la mediana
data_base1$piso[is.na(data_base1$piso)] <- median(data_base1$piso, na.rm = TRUE)
# Imputar los valores faltantes de "parqueaderos" con la mediana
data_base1$parqueaderos[is.na(data_base1$parqueaderos)] <- median(data_base1$parqueaderos, na.rm = TRUE)
glimpse(data_base1)
## Rows: 722
## Columns: 13
## $ id <dbl> 1209, 1592, 4057, 4460, 6081, 7824, 7987, 3495, 141, 243,…
## $ zona <chr> "Zona Norte", "Zona Norte", "Zona Norte", "Zona Norte", "…
## $ piso <dbl> 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
## $ estrato <dbl> 5, 5, 6, 4, 5, 4, 5, 5, 3, 3, 3, 3, 5, 3, 4, 4, 5, 5, 4, …
## $ preciom <dbl> 320, 780, 750, 625, 750, 600, 420, 490, 230, 190, 180, 50…
## $ areaconst <dbl> 150, 380, 445, 355, 237, 160, 200, 118, 160, 435, 120, 21…
## $ parqueaderos <dbl> 2, 2, 2, 3, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
## $ banios <dbl> 4, 3, 7, 5, 6, 4, 4, 4, 2, 0, 3, 6, 5, 5, 3, 3, 4, 5, 5, …
## $ habitaciones <dbl> 6, 3, 6, 5, 6, 5, 5, 4, 3, 0, 3, 6, 4, 8, 4, 3, 4, 6, 4, …
## $ tipo <chr> "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "…
## $ barrio <chr> "acopi", "acopi", "acopi", "acopi", "acopi", "acopi", "ac…
## $ longitud <dbl> -76.51341, -76.51674, -76.52950, -76.53179, -76.54044, -7…
## $ latitud <dbl> 3.47968, 3.48721, 3.38527, 3.40590, 3.36862, 3.42125, 3.4…
write.xlsx(data_base1, file = "D://archivo_amp.xlsx")
Se verifica que no existan datos faltantes
grafico_faltantes <-md.pattern(data_base1, rotate.names = TRUE)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
A continuación, se generan gráficos descriptivos para explorar las variables del conjunto de datos, con el objetivo de entender cómo afectan al precio de las viviendas. Estos gráficos ayudarán a visualizar las distribuciones y relaciones entre el precio y variables clave como el área construida, el estrato, el número de baños, el número de habitaciones y la zona. Se utilizarán gráficos interactivos mediante plotly para facilitar la interpretación de los resultados, identificar patrones y tendencias, y detectar posibles anomalías, lo cual es esencial para futuros análisis o modelización.
# Gráfico precio vs área construida
g1 <- plot_ly(data_base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(color = 'blue', size = 10)) %>%
layout(title = 'Relación entre Precio y Área Construida',
xaxis = list(title = 'Área Construida (m²)'),
yaxis = list(title = 'Precio de la Casa (m²)'))
g1
# Gráfico precio vs estrato
g2 <- plot_ly(data_base1, x = ~estrato, y = ~preciom, type = 'box',
boxmean = 'sd', marker = list(color = 'lightblue')) %>%
layout(title = 'Precio según el Estrato',
xaxis = list(title = 'Estrato'),
yaxis = list(title = 'Precio de la Casa'))
g2
# Gráfico precio vs baños
g3 <- plot_ly(data_base1, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(color = 'green', size = 10)) %>%
layout(title = 'Relación entre Precio y Número de Baños',
xaxis = list(title = 'Número de Baños'),
yaxis = list(title = 'Precio de la Casa'))
g3
# Gráfico precio vs habitaciones
g4 <- plot_ly(data_base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(color = 'red', size = 10)) %>%
layout(title = 'Relación entre Precio y Número de Habitaciones',
xaxis = list(title = 'Número de Habitaciones'),
yaxis = list(title = 'Precio de la Casa'))
g4
# Gráfico precio vs zona
g5 <- plot_ly(data_base1, x = ~zona, y = ~preciom, type = 'box',
boxmean = 'sd', marker = list(color = 'purple')) %>%
layout(title = 'Precio según la Zona',
xaxis = list(title = 'Zona'),
yaxis = list(title = 'Precio de la Casa'))
g5
# Gráfico área construida vs precio por zona
g6 <- plot_ly(data_base1, x = ~areaconst, y = ~preciom, color = ~zona, type = 'scatter', mode = 'markers',
marker = list(size = 10)) %>%
layout(title = 'Relación entre Precio y Área Construida por Zona',
xaxis = list(title = 'Área Construida (m²)'),
yaxis = list(title = 'Precio de la Casa'))
g6
# Calcular la matriz de correlación entre las variables numéricas
correlacion <- data_base1 %>%
select(preciom, areaconst, estrato, banios, habitaciones) %>%
cor()
# Mostrar la matriz de correlación
correlacion
## preciom areaconst estrato banios habitaciones
## preciom 1.0000000 0.7313480 0.6123503 0.5233357 0.3227096
## areaconst 0.7313480 1.0000000 0.4573818 0.4628152 0.3753323
## estrato 0.6123503 0.4573818 1.0000000 0.4083039 0.1073141
## banios 0.5233357 0.4628152 0.4083039 1.0000000 0.5755314
## habitaciones 0.3227096 0.3753323 0.1073141 0.5755314 1.0000000
Interpretacion de los Resultados
El area construida tiene una fuerte correlación positiva con el precio de la vivienda (0.731), lo que indica que a mayor área construida, mayor es el precio de la casa.
Estrato también está positivamente correlacionado con el precio (0.612), lo que sugiere que las viviendas en estratos más altos tienden a tener precios más altos.
La relación entre número de baños y precio es moderada (0.523), lo que implica que más baños generalmente aumentan el precio, pero no tan significativamente como el área o el estrato.
Número de habitaciones tiene una correlación débil con el precio (0.323), sugiriendo que este factor no influye tanto en el precio comparado con el área o el estrato.
Área construida está positivamente correlacionada con el número de baños (0.463) y el número de habitaciones (0.375), lo que indica que las casas más grandes suelen tener más baños y habitaciones.
El estrato tiene una relación moderada con el número de baños (0.408), pero una relación muy débil con el número de habitaciones (0.107), lo que sugiere que el estrato no es un buen predictor del número de habitaciones.
De forma general podemos indicar que el precio de la vivienda está más influenciado por el área construida y el estrato, mientras que el número de baños y habitaciones tiene una relación más débil con relacion al precio.
data_base1_num <- data_base1[, c("preciom","areaconst","estrato","habitaciones","parqueaderos","banios")]
head( data_base1_num)
## # A tibble: 6 × 6
## preciom areaconst estrato habitaciones parqueaderos banios
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 320 150 5 6 2 4
## 2 780 380 5 3 2 3
## 3 750 445 6 6 2 7
## 4 625 355 4 5 3 5
## 5 750 237 5 6 2 6
## 6 600 160 4 5 1 4
# Ajustar el modelo de regresión lineal múltiple
modelo = lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = data_base1_num)
# Ver el resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = data_base1_num)
##
## Residuals:
## Min 1Q Median 3Q Max
## -924.94 -77.71 -17.66 45.90 1081.29
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -251.05177 30.11848 -8.335 3.94e-16 ***
## areaconst 0.81090 0.04352 18.634 < 2e-16 ***
## estrato 84.61108 7.17727 11.789 < 2e-16 ***
## habitaciones 0.95948 4.10569 0.234 0.81529
## parqueaderos 16.55976 5.70396 2.903 0.00381 **
## banios 24.57669 5.35583 4.589 5.26e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 158.2 on 716 degrees of freedom
## Multiple R-squared: 0.6548, Adjusted R-squared: 0.6524
## F-statistic: 271.6 on 5 and 716 DF, p-value: < 2.2e-16
Interpretacion de los resultados:
Este modelo de regresión lineal múltiple desarrollado busca predecir el precio de la vivienda (variable dependiente: preciom) en función de las siguientes variables explicativas: área construida, estrato, número de habitaciones, número de parqueaderos y número de baños.
Coeficientes y Significancia:
Área construida (areaconst) tiene un impacto positivo y muy significativo en el precio. Por cada metro cuadrado adicional, el precio aumenta en 0.810 millones de pesos.
Estrato (estrato) también tiene un gran impacto positivo. Un aumento de una unidad en el estrato aumenta el precio en 84.6 millones de pesos.
Número de habitaciones (habitaciones) no es estadísticamente significativo en este modelo, lo que sugiere que no tiene un efecto claro sobre el precio de la vivienda.
Número de parqueaderos (parqueaderos) tiene un impacto positivo y significativo en el precio, aumentando 16.56 millones de pesos por cada parqueadero adicional.
Número de baños (banios) es altamente significativo, con un coeficiente de 24.58 millones de pesos por cada baño adicional construida y el estrato, mientras que el número de baños y habitaciones tiene una relación más débil con el precio.
El R² es una medida de qué tan bien los datos observados se ajustan al modelo de regresión. Es una medida de la proporción de la variabilidad en el precio de la vivienda que puede ser explicada por las variables independientes.
# Obtener el valor R-squared
modelo_R2 <- summary(modelo)$r.squared
# Ver el resumen del modelo
summary(modelo_R2)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.6548 0.6548 0.6548 0.6548 0.6548 0.6548
El análisis muestra que el coeficiente de determinación R² del modelo es 0.6548, lo que indica que el modelo explica el 65.48% de la variabilidad en el precio de las viviendas. Los valores de la estadística descriptiva (mínimo, cuartiles, mediana, media, máximo) para R² son constantes, lo que sugu09iere un ajuste uniforme y consistente en todas las observaciones.
Aunque el modelo tiene un buen ajuste, hay un 34.52% de variabilidad no explicada (diferencia entre 1 y el valor de R²), lo que podría implicar que faltan variables importantes o que hay relaciones no lineales que no se están capturando. Para mejorar el modelo, se podrían considerar más variables o transformaciones en las existentes.
En general, el modelo muestra un ajuste adecuado, pero se podrian explorar mejoras adicionales.
plot(modelo)
La relación entre las variables independientes y la variable dependiente
debe ser lineal. Para verificar la linealidad, podemos crear un gráfico
de residuos versus los valores ajustados. Si la relación es lineal, los
residuos deberían distribuirse aleatoriamente alrededor de cero sin
patrones evidentes.
# Graficar los residuos vs valores ajustados
plot(modelo$fitted.values, modelo$residuals,
main = "Residuos vs Valores Ajustados",
xlab = "Valores Ajustados",
ylab = "Residuos",
pch = 19, col = "blue")
abline(h = 0, col = "red", lwd = 2)
Independencia de los residuos
El supuesto de independencia implica que los residuos no deben estar correlacionados entre sí. Si los residuos están correlacionados, esto podría indicar que hay alguna variable importante omitida o que hay alguna estructura temporal o espacial no capturada por el modelo.
Podemos usar un gráfico de autocorrelación de los residuos para verificar esto.
# Comprobar la autocorrelación de los residuos
acf(modelo$residuals, main = "Autocorrelación de los Residuos")
# Graficar residuos vs valores ajustados para verificar homoscedasticidad
plot(modelo$fitted.values, modelo$residuals,
main = "Residuos vs Valores Ajustados (Homoscedasticidad)",
xlab = "Valores Ajustados",
ylab = "Residuos",
pch = 19, col = "blue")
abline(h = 0, col = "red", lwd = 2)
# Histograma de los residuos
hist(modelo$residuals,
main = "Histograma de los Residuos",
xlab = "Residuos",
col = "lightblue",
border = "black")
Interpretación:
# Prueba de normalidad Shapiro-Wilk
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.83433, p-value < 2.2e-16
Interpretación:
Si el valor p de la prueba de Shapiro-Wilk es menor a 0.05, eso indica que los residuos no siguen una distribución normal. Si el valor p es mayor a 0.05, eso sugiere que los residuos son distribuidos normalmente.
# Gráfico Q-Q de los residuos
qqnorm(modelo$residuals)
qqline(modelo$residuals, col = "red")
# Prueba de normalidad de los residuos (Shapiro-Wilk)
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.83433, p-value < 2.2e-16
# Estructura base1_num_na
str(data_base1_num)
## spc_tbl_ [722 × 6] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ preciom : num [1:722] 320 780 750 625 750 600 420 490 230 190 ...
## $ areaconst : num [1:722] 150 380 445 355 237 160 200 118 160 435 ...
## $ estrato : num [1:722] 5 5 6 4 5 4 5 5 3 3 ...
## $ habitaciones: num [1:722] 6 3 6 5 6 5 5 4 3 0 ...
## $ parqueaderos: num [1:722] 2 2 2 3 2 1 4 2 2 2 ...
## $ banios : num [1:722] 4 3 7 5 6 4 4 4 2 0 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ";"
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
El test de normalidad de Shapiro-Wilk realizado sobre los residuos del modelo de regresión muestra que los residuos no siguen una distribución normal, ya que el p-valor es muy pequeño (< 2.2e-16), lo que lleva a rechazar la hipótesis nula de normalidad.
Entonces podemos concluir que los residuos no son normales, lo que puede indicar una violación del supuesto de normalidad en la regresión lineal.Esto podría afectar la validez de las inferencias y predicciones del modelo, aunque en muestras grandes, los efectos pueden ser pequeños. Se podría considerar transformar las variables o explorar modelos alternativos si la no normalidad es un problema importante para el análisis.
Esto nos indica que el modelo no cumple con el supuesto de normalidad de los residuos, lo que debe ser tenido en cuenta en la interpretación de los resultados.
Sugerencias para mejorar el modelo si los supuestos no se cumplen
Transformar variables: Si la linealidad no se cumple, se pueden aplicar transformaciones logarítmicas o polinomiales a las variables.
Modelos robustos:
Si la homoscedasticidad no se cumple, se pueden usar modelos de regresión robusta que ajusten los errores estándar.
Incluir variables adicionales:
Si los residuos muestran autocorrelación, se podrían incluir variables omitidas que estén capturando la correlación no explicada.
Regresión no lineal:
Si la relación no es lineal, se podría considerar usar modelos no lineales o agregar términos cuadráticos o cúbicos en el modelo.
Este proceso de validación de supuestos no permite determinar si el modelo de regresión lineal es adecuado para mis datos y si es necesario que se realice ajustes o transformaciones.
# Datos Vivienda 1
data_vivienda1 = data.frame(
estrato = c(4, 5),
areaconst = 200,
habitaciones = 4,
banios = 2,
parqueaderos = 1
)
# Dataframe data_vivienda1
head(data_vivienda1)
## estrato areaconst habitaciones banios parqueaderos
## 1 4 200 4 2 1
## 2 5 200 4 2 1
# Predicción base1_model con datos vivienda1
predict(modelo, data_vivienda1)
## 1 2
## 319.1240 403.7351
Interpretacion de los resultados:
Para el estrato 4, el precio estimado de una casa con las caracteristicas de la vivienda1 es 319.12 millones de pesos. Para el estrato 5, el precio estimado de una casa con las caracteristicas de la vivienda1 es 403.74 millones de pesos.
Lo que indica que el precio de la vivienda aumenta significativamente con el estrato, lo cual es consistente con los coeficientes del modelo, que indican que cada unidad de aumento en el estrato incrementa el precio en aproximadamente 84.6 millones de pesos.
El modelo muestra que el estrato es un factor clave en la determinación del precio de la vivienda, con una diferencia considerable de precios entre los estratos 4 y 5.
data_ofertas <- subset(
data_base1,
preciom <= 350 &
areaconst >= 200 &
parqueaderos >= 1 &
banios >= 2 &
habitaciones >= 4 &
estrato %in% c(4,5)
)
# Verificar cuántas ofertas cumplen con el criterio
nrow(data_ofertas)
## [1] 39
# Mostrar las primeras filas de las ofertas filtradas
head(data_ofertas)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7471 Zona N… 2 4 330 240 2 4 4
## 2 4210 Zona N… 1 5 350 200 3 3 4
## 3 4267 Zona N… 1 5 335 202 1 4 5
## 4 4800 Zona N… 1 5 340 250 2 4 4
## 5 4209 Zona N… 2 5 350 300 3 5 6
## 6 4422 Zona N… 2 5 350 240 2 3 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
write.xlsx(data_ofertas, file = "D://data_ofertas.xlsx")
## Warning in file.create(to[okay]): cannot create file 'D://data_ofertas.xlsx',
## reason 'Permission denied'
# Crear un mapa con leaflet para mostrar las 5 ofertas potenciales
leaflet(data_ofertas) %>%
addTiles() %>%
addMarkers(~longitud, ~latitud,
popup = ~paste("ID:", id,
"<br>Precio:", preciom, "Millones",
"<br>Área:", areaconst, "m²",
"<br>Estrato:", estrato,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones))
Análisis de las ofertas:
Precio: Todas las ofertas están dentro del presupuesto de 350 millones de pesos, lo que las hace aptas para la solicitud de la Vivienda 1. Área construida: La mayoría de las ofertas tienen un área superior a la Vivienda1, lo cual puede ser una ventaja si la empresa busca más espacio. Sin embargo, todas estas propiedades se mantienen dentro de un rango razonable.
Número de habitaciones: Las ofertas seleccionadas tienen 4 o más habitaciones, cumpliendo con los requisitos mínimos de la Vivienda 1, que tiene 4 habitaciones.
Número de baños: Todas las ofertas tienen más de 2 baños, lo que es adecuado ya que la Vivienda 1 tiene 2 baños.
Parqueaderos: Las viviendas tienen entre 1 y 3 parqueaderos, lo que también se ajusta a la solicitud de la Vivienda 1, que tiene 1 parqueadero.
Utilizando las coordenadas proporcionadas en los datos, se visualizan las ofertas seleccionadas en el mapa lo que permite evaluar la proximidad entre ellas y a servicios relevantes. Esto puede ayudar a elegir opciones basadas en la ubicación.
Potenciales ventajas de estas ofertas:
En cuanto a la variación del tamaño algunas opciones tienen más área construida, lo que podría ser una ventaja si se busca una vivienda más espaciosa.
En cuanto a la proximidad entre ofertas las viviendas están ubicadas en zonas cercanas (principalmente en el barrio El Bosque), lo que podría ofrecer una buena conectividad y calidad de zona.
Todas las ofertas cumplen con los requisitos de precio, características de la vivienda1.
Sin embargo se recomienda que se visite las viviendas para evaluar aspectos como la condición del inmueble, el entorno del barrio y la accesibilidad; asi como tambien es importante evaluar el valor de reventa, el potencial de valorización y la seguridad de las zonas