Para el análisis del caso, se cuenta con una base de datos que contiene 8322 registros y 13 variables, las cuales son:

names(vivienda)
##  [1] "id"           "zona"         "piso"         "estrato"      "preciom"     
##  [6] "areaconst"    "parqueaderos" "banios"       "habitaciones" "tipo"        
## [11] "barrio"       "longitud"     "latitud"

Se verifican los valores nulos en el conjunto de datos:

datos_faltantes <- sapply(vivienda, function(x) sum(is.na(x)))
print(datos_faltantes)
##           id         zona         piso      estrato      preciom    areaconst 
##            3            3         2638            3            2            3 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##         1605            3            3            3            3            3 
##      latitud 
##            3

Se eliminan los datos faltantes de las variables “id”, “zona”, “estrato”, “preciom”, “areaconst”, “banios”, “habitaciones”, “tipo”, “barrio”, “longitud” y “latitud”, lo que resulta en una reducción de registros de 8322 a 8319 en total.

vivienda <- vivienda %>%
  filter(rowSums(is.na(.) & colnames(vivienda) %in% c("id", "zona", "estrato", "preciom", "areaconst", "banios", "habitaciones", "tipo", "barrio", "longitud", "latitud")) <= 3)
print(nrow(vivienda))
## [1] 8319

Obtención de los resultados para Vivienda 1

1. Realice un filtro a la base de datos e incluya solo las ofertas de apartamentos. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases).

Para el análisis del caso, se filtran los datos correspondientes al tipo de vivienda seleccionando las casas y, a su vez, se filtran aquellas que están ubicadas en la zona norte de la ciudad de Cali, obteniendo 722 registros con estas características.

# Se filtra el tipo de vivienda apartamento
vivienda_apartamento <- filter(vivienda, tipo == "Apartamento")

# Primeros registros de los datos filtrados
head(vivienda_apartamento, 3)
## # A tibble: 3 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  1212 Zona N… 01          5     260        90            1      2            3
## 2  1724 Zona N… 01          5     240        87            1      3            3
## 3  2326 Zona N… 01          4     220        52            2      2            3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
print(nrow(vivienda_apartamento))
## [1] 5100

Verificamos nuevamente los datos faltantes a partir de la información obtenida en el filtro anterior.

datos_faltantes_apartamento <- sapply(vivienda_apartamento , function(x) sum(is.na(x)))
print(datos_faltantes_apartamento)
##           id         zona         piso      estrato      preciom    areaconst 
##            0            0         1381            0            0            0 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##          869            0            0            0            0            0 
##      latitud 
##            0

Notamos que de los 5100 registros, hay 869 datos faltantes en la variable “parqueaderos” y 1381 en la variable “piso”. Por lo tanto, procedemos a eliminar las filas con valores nulos en esta variable para analizar su comportamiento.

# Crear una copia del dataframe vivienda_apartamento
copia_vivienda_apartamento1<- vivienda_apartamento
copia_vivienda_apartamento2<- vivienda_apartamento

# Eliminar filas con valores nulos en la variable "parqueaderos" en la copia1
copia_vivienda_apartamento1 <- copia_vivienda_apartamento1[!is.na(copia_vivienda_apartamento1$parqueaderos), ]

# Eliminar filas con valores nulos en la variable "piso" en la copia2
copia_vivienda_apartamento2 <- copia_vivienda_apartamento2[!is.na(copia_vivienda_apartamento2$piso), ]

Ahora procedemos a determinar la mediana de estas dos variables para realizar la imputación de los valores con estos valores determinados en cada caso.

# Obtener la mediana de la variable 'parqueaderos' en copia_vivienda_apartamento1
mediana_parqueaderos <- median(copia_vivienda_apartamento1$parqueaderos, na.rm = TRUE)
cat("La mediana de la variable 'parqueaderos' es:", mediana_parqueaderos, "\n")
## La mediana de la variable 'parqueaderos' es: 1
#Se convierte las varible piso a tipo numérico
copia_vivienda_apartamento2$piso <- as.numeric(copia_vivienda_apartamento2$piso)
# Obtener la mediana de la variable 'piso' en copia_vivienda_apartamento2
mediana_piso <- median(copia_vivienda_apartamento2$piso, na.rm = TRUE)
cat("La mediana de la variable 'piso' es:", mediana_piso, "\n")
## La mediana de la variable 'piso' es: 4

Luego procedemos a realizar la correspondiente imputación de la mediana en la variable “parqueadero” y “piso” del conjunto de datos vivienda filtrado con antelación.

# Imputar la mediana en valores nulos de la variable 'parqueaderos'
vivienda_apartamento$parqueaderos[is.na(vivienda_apartamento$parqueaderos)] <- mediana_parqueaderos
# Imputar la mediana en valores nulos de la variable 'piso'
vivienda_apartamento$piso[is.na(vivienda_apartamento$piso)] <- mediana_piso

Verificamos nuevamente la presencia de valores nulos en el conjunto de datos filtrados y corroboramos que tenemos los 5100 registros completos.

datos_faltantes_apartamento2 <- sapply(vivienda_apartamento , function(x) sum(is.na(x)))
print(datos_faltantes_apartamento2)
##           id         zona         piso      estrato      preciom    areaconst 
##            0            0            0            0            0            0 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##            0            0            0            0            0            0 
##      latitud 
##            0
print(nrow(vivienda_apartamento))
## [1] 5100

A continuación, se presenta el mapa de la ciudad de Cali con la respectiva ubicación de cada uno de los apartamentos en toda la ciudad

mapa1 <- data.frame(vivienda_apartamento$longitud, vivienda_apartamento$latitud)

# Crea un mapa
map <- leaflet(mapa1) %>%
  addTiles() %>%
  addMarkers(
    lng = ~vivienda_apartamento$longitud,
    lat = ~vivienda_apartamento$latitud,
    popup = ~as.character(vivienda_apartamento$barrio) 
  )

map # Muestra el mapa

2. Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio del apartamento) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos e interprete los resultados.

Ahora se procede a verificar la asociación entre las variables área construida, estrato, numero de baños, numero de habitaciones.

# Seleccion de las variables
variables_apartamento <- vivienda_apartamento[, c("estrato", "areaconst", "banios", "habitaciones")]

# Crea una matriz de gráficos usando ggpairs
ggpairs(data = variables_apartamento, title = " ")

# Calcula la matriz de correlación
print(cor(variables_apartamento))
##                estrato areaconst    banios habitaciones
## estrato      1.0000000 0.5492273 0.6155148    0.1778522
## areaconst    0.5492273 1.0000000 0.7267377    0.4092708
## banios       0.6155148 0.7267377 1.0000000    0.5006605
## habitaciones 0.1778522 0.4092708 0.5006605    1.0000000

A partir de la matriz de correlación podemos decir:

estrato vs. areaconst: El coeficiente de correlación entre “estrato” y “areaconst” es aproximadamente 0.549. Esto sugiere una correlación positiva moderada entre el estrato de una vivienda y su área construida. En otras palabras, a medida que el estrato aumenta, tiende a haber un aumento moderado en el tamaño del área construida.

estrato vs. banios: El coeficiente de correlación entre “estrato” y “banios” es aproximadamente 0.616. Esto indica una correlación positiva considerable entre el estrato y el número de baños en una vivienda. A medida que el estrato aumenta, tiende a haber un aumento moderado en el número de baños.

estrato vs. habitaciones: El coeficiente de correlación entre “estrato” y “habitaciones” es aproximadamente 0.178. Esta correlación es más baja en comparación con las anteriores y sugiere una correlación positiva débil entre el estrato y el número de habitaciones en una vivienda. El estrato no parece estar fuertemente relacionado con el número de habitaciones.

areaconst vs. banios: El coeficiente de correlación entre “areaconst” y “banios” es aproximadamente 0.727. Esto indica una correlación positiva considerable entre el tamaño del área construida y el número de baños en una vivienda. A medida que el área construida aumenta, tiende a haber un aumento considerable en el número de baños.

areaconst vs. habitaciones: El coeficiente de correlación entre “areaconst” y “habitaciones” es aproximadamente 0.409. Esto sugiere una correlación positiva moderada entre el tamaño del área construida y el número de habitaciones en una vivienda. A medida que el área construida aumenta, tiende a haber un aumento moderado en el número de habitaciones.

banios vs. habitaciones: El coeficiente de correlación entre “banios” y “habitaciones” es aproximadamente 0.501. Esto indica una correlación positiva moderada a fuerte entre el número de baños y el número de habitaciones en una vivienda. A medida que aumenta el número de baños, tiende a haber un aumento moderado a fuerte en el número de habitaciones.

3. Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

Se procede a construir el modelo de regresión lineal de la siguiente forma:

modelo_apartamento <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_apartamento)

summary(modelo_apartamento)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = vivienda_apartamento)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1706.19   -50.41     0.97    43.66  1030.31 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -269.2153    12.6949  -21.21   <2e-16 ***
## areaconst       2.0141     0.0423   47.61   <2e-16 ***
## estrato        53.6219     2.5317   21.18   <2e-16 ***
## habitaciones  -36.0841     3.2135  -11.23   <2e-16 ***
## parqueaderos   92.8962     3.6902   25.17   <2e-16 ***
## banios         48.1824     2.9578   16.29   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 130.8 on 5094 degrees of freedom
## Multiple R-squared:  0.7958, Adjusted R-squared:  0.7956 
## F-statistic:  3971 on 5 and 5094 DF,  p-value: < 2.2e-16

El modelo de regresión lineal múltiple es: \[ \hat{Y} = -269.2153 + 2.0141 \times \text{areaconst} + 53.6219 \times \text{estrato} -36.0841 \times \text{habitaciones} + 92.8962 \times \text{parqueaderos} + 48.1824 \times \text{banios} \]

Los resultados indican que el modelo es estadísticamente significativo, ya que el valor p global (p-value: < 2.2e-16) es extremadamente bajo, lo que sugiere que al menos una de las variables independientes está relacionada con la variable dependiente.

Ahora, vamos a interpretar los coeficientes:

Intercept (Intercepto): El valor del coeficiente de intercepción es -269.2153. Esto significa que cuando todas las demás variables independientes son iguales a cero, el precio estimado de una vivienda sería -269.2153. Sin embargo, esta interpretación no tiene sentido en el contexto de los datos, ya que las variables independientes nunca tomarán valores de cero en este caso.

areaconst (Área construida): El coeficiente para “areaconst” es 2.0141. Esto significa que, manteniendo constantes todas las demás variables, un aumento de una unidad en el área construida se asocia con un aumento de $2.0141 en el precio de la vivienda.

estrato (Estrato): El coeficiente para “estrato” es 53.6219. Esto significa que, manteniendo constantes todas las demás variables, un aumento de una unidad en el estrato se asocia con un aumento de $53.6219 en el precio de la vivienda.

habitaciones (Número de habitaciones): El coeficiente para “habitaciones” es -36.0841. lo cual se traduce en que por cada habitacion que tenga el apartamento el precio de la vivienda disminuye en $36.0841, lo cual no tiene sentido, por lo tanto podemos concluir que esta variable no es significativa en el modelo.

parqueaderos (Número de parqueaderos): El coeficiente para “parqueaderos” es 92.8962. Esto significa que, manteniendo constantes todas las demás variables, un aumento de una unidad en el número de parqueaderos se asocia con un aumento de $92.8962 en el precio de la vivienda.

banios (Número de baños): El coeficiente para “banios” es 48.1824. Esto significa que, manteniendo constantes todas las demás variables, un aumento de una unidad en el número de baños se asocia con un aumento de $92.8962 en el precio de la vivienda.

Coeficiente de determinación (R^2): El R^2 del modelo es 0.7958, lo que significa que aproximadamente el 79.58% de la variabilidad en el precio de la vivienda se explica por las variables incluidas en el modelo.

En resumen, el área construida, el estrato, el número de parqueaderos y el número de baños son variables estadísticamente significativas y tienen un efecto positivo en el precio de la vivienda. Sin embargo, el número de habitaciones no es estadísticamente significativo en este modelo. El R^2 indica que el modelo explica una parte sustancial de la variabilidad en el precio, pero aún queda algo de variabilidad sin explicar.

4. Realice la validación de supuestos del modelo e interprete los resultados.

par(mfrow = c(2, 2))
plot(modelo_apartamento)

Para realizar la validación de supuestos del modelo de regresión lineal se tiene en cuenta:

Homocedasticidad

Se realiza la Prueba de Breusch-Pagan para evaluar si existe heterocedasticidad en los residuos del modelo de regresión.

# Prueba de Breusch-Pagan para heterocedasticidad
bptest(modelo_apartamento) 
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo_apartamento
## BP = 1424.4, df = 5, p-value < 2.2e-16

El valor de la estadística BP es 1424.4, y los grados de libertad son 5. El valor p: < 2.2e-16 asociado es extremadamente pequeño por lo cual se rechaza la hipótesis nula de homocedasticidad.

La prueba de Breusch-Pagan ha encontrado evidencia significativa de heterocedasticidad en el modelo. Esto significa que la varianza de los residuos no es constante a lo largo de los valores ajustados o las variables independientes, lo que puede afectar la validez de las inferencias y predicciones del modelo.

Normalidad de los Residuos

Para verificar la normalidad de los residuos se realiza la Prueba de Shapiro-Wilk.

# Obtén los residuales del modelo
residuales <- modelo_apartamento$residuals

# Define el tamaño de la muestra deseado (por ejemplo, 5000)
tamanio_muestra <- 5000

# Verifica el tamaño real de los residuales
tamanio_real <- length(residuales)

# Si el tamaño real es mayor que el tamaño deseado, toma una muestra aleatoria
if (tamanio_real > tamanio_muestra) {
  set.seed(123)  # Ajusta la semilla para reproducibilidad
  muestra_aleatoria <- sample(residuales, size = tamanio_muestra)
} else {
  muestra_aleatoria <- residuales
}

# Aplica la prueba de Shapiro-Wilk a la muestra aleatoria
resultado_shapiro <- shapiro.test(muestra_aleatoria)

# Muestra el resultado
print(resultado_shapiro)
## 
##  Shapiro-Wilk normality test
## 
## data:  muestra_aleatoria
## W = 0.82048, p-value < 2.2e-16

El valor de la estadística W es 0.82048, y el valor p: < 2.2e-16 asociado a esta prueba es prácticamente cero, lo que significa rechaza la hipótesis nula de normalidad. En este caso, la prueba de Shapiro-Wilk ha encontrado evidencia significativa de que los residuos no siguen una distribución normal.

Independencia de los Residuos

Para verificar la independencia de los residuos, se realiza la de prueba de Durbin-Watson para la autocorrelación.

# Prueba de Durbin-Watson para autocorrelación
dwtest(modelo_apartamento)
## 
##  Durbin-Watson test
## 
## data:  modelo_apartamento
## DW = 1.6329, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

El valor de la estadística Durbin-Watson es 1.6329, el valor p asociado al test es 2.2e-16. Esto sugiere que hay evidencia significativa en contra de la hipótesis nula de no autocorrelación. En otras palabras, los residuos muestran autocorrelación positiva en este caso.

5.Realice una partición en los datos de forma aleatoria donde 70% sea un set para entrenar el modelo y 30% para prueba. Estime el modelo con la muestra del 70%. Muestre los resultados.

set.seed(123)
#Partición aleatoria en 70% de entrenamiento y 30% de prueba
indices_particion <- createDataPartition(vivienda_apartamento$preciom, p = 0.7, list = FALSE)

# Crea conjuntos de entrenamiento y prueba
conjunto_entrenamiento <- vivienda_apartamento[indices_particion, ]
conjunto_prueba <- vivienda_apartamento[-indices_particion, ]


modelo_apartamento_entrenamiento <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = conjunto_entrenamiento)

# Muestra los resultados del modelo
 summary(modelo_apartamento_entrenamiento)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = conjunto_entrenamiento)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1670.51   -50.45     0.20    43.45  1043.15 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -281.00776   15.14240 -18.558   <2e-16 ***
## areaconst       1.97309    0.05047  39.091   <2e-16 ***
## estrato        57.54070    3.04266  18.911   <2e-16 ***
## habitaciones  -33.33537    3.81823  -8.731   <2e-16 ***
## parqueaderos   93.22171    4.50302  20.702   <2e-16 ***
## banios         43.55958    3.55251  12.262   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 131.6 on 3566 degrees of freedom
## Multiple R-squared:  0.7861, Adjusted R-squared:  0.7858 
## F-statistic:  2621 on 5 and 3566 DF,  p-value: < 2.2e-16

6.Realice predicciones con el modelo anterior usando los datos de prueba (30%).

# Realiza predicciones con el modelo en el conjunto de prueba
predicciones <- predict(modelo_apartamento_entrenamiento, newdata = conjunto_prueba)

# Muestra las primeras filas de las predicciones
head(predicciones)
##         1         2         3         4         5         6 
## 302.24897 225.31222 383.48057  58.40634 187.29937  48.74805

con el fin de comparar el modelo original y el entrenado, vamos a predecir el precio de un apartamento con las siguientes caracteristicas.

Predicción con el modelo original

predict(modelo_apartamento,list(areaconst=120,parqueaderos=1,estrato=4,habitaciones=3, banios=2))
##        1 
## 267.9677

Con el modelo sin entrenar se tiene que u apartamento con estas caracteristicas tiene un costo aproximado de $269.9677

Predicción con el Modelo entrenado

predict(modelo_apartamento_entrenamiento,list(areaconst=120,parqueaderos=1,estrato=4,habitaciones=3, banios=2))
##        1 
## 266.2607

Como podemos observar el valor predicho por el modelo entrenado es de $266.2607, por lo que sus predicciones no estan muy lejanas.

7.Calcule el error cuadrático medio, el error absoluto medio y el R2, interprete.

# Calcular el Error Cuadrático Medio 
mse <- mean((conjunto_prueba$preciom - predicciones)^2)

# Calcular el Error Absoluto Medio 
mae <- mean(abs(conjunto_prueba$preciom - predicciones))

# Calcular R2
r2 <- 1 - sum((conjunto_prueba$preciom - predicciones)^2) / sum((conjunto_prueba$preciom - mean(conjunto_prueba$preciom))^2)

# Mostrar los resultados
cat("Error Cuadrático Medio (MSE):", mse, "\n")
## Error Cuadrático Medio (MSE): 16669.2
cat("Error Absoluto Medio (MAE):", mae, "\n")
## Error Absoluto Medio (MAE): 78.52596
cat("R^2:", r2, "\n")
## R^2: 0.8150904

Teniendo en cuenta el error cuadratico medio de 16669.2, se puede decir que en promedio los errores cuadraticos de las predicciones con respecto a los valores reales son relativamente altos, por otro lado, el error absoluto medio indica que las predicciones tiene un error absoluro de 78.52596 unidades con respecto a los valores reales. El R2 de 0.8150904 es alto, lo cual quiere decir que el modelo esta explicando en una gran proporción el precio de los apartamentos.