CARGAMOS LA DATA Y REALIZAMOS LIMPIEZA DE DATOS A LA DATA GENERAL

## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Loading required package: summarytools

Revision de valores faltantes

# Revisar valores faltantes
colSums(is.na(data))
##           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

Limpieza de datos

1.1 Eliminación de duplicados

data <- data[!duplicated(data$id), ]

1.2 Imputación de valores faltantes

imputados con mediana

imputar_mediana <- function(x){
  x[is.na(x)] <- median(x, na.rm=TRUE)
  return(x)
}

data$areaconst <- imputar_mediana(data$areaconst)
data$parqueaderos <- imputar_mediana(data$parqueaderos)
data$banios <- imputar_mediana(data$banios)
data$habitaciones <- imputar_mediana(data$habitaciones)
data$preciom <- imputar_mediana(data$preciom)
data$estrato <- imputar_mediana(data$estrato)

1.3 DETECCIÓN DE ATÍPICOS

detectar_atipicos <- function(x){
  q1 <- quantile(x,0.25)
  q3 <- quantile(x,0.75)
  iqr <- q3-q1
  lim_inf <- q1 - 1.5*iqr
  lim_sup <- q3 + 1.5*iqr
  return(x < lim_inf | x > lim_sup)
}

Identificar atípicos

at_area <- detectar_atipicos(data$areaconst)
at_precio <- detectar_atipicos(data$preciom)

Eliminar atípicos extremos

data <- data[!at_area & !at_precio, ]

Filtramos Casas en zona norte

base1 <- data[data$tipo=="Casa" & data$zona=="Zona Norte", ]
head(base1,3)
## # A tibble: 3 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <fct>   <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            2      7            6
## # ℹ 4 more variables: tipo <fct>, barrio <fct>, longitud <dbl>, latitud <dbl>

Tablas de verificación

table(base1$tipo)
## 
## Apartamento        Casa 
##           0         640
table(base1$zona)
## 
##  Zona Centro   Zona Norte   Zona Oeste Zona Oriente     Zona Sur 
##            0          640            0            0            0

mapa de las casas

plot(base1$longitud,
     base1$latitud,
     pch=19,
     col="blue",
     main="Mapa viviendas Zona Norte",
     xlab="Longitud",
     ylab="Latitud")

#EDA

# Histogramas

hist(base1$preciom,
     main="Distribución precios",
     col="lightblue")

hist(base1$areaconst,
     main="Área construida",
     col="lightgreen")

# Relaciones

plot(base1$areaconst,
     base1$preciom,
     pch=19,
     col="red",
     xlab="Área",
     ylab="Precio",
     main="Precio vs Área")

plot(base1$banios,
     base1$preciom,
     pch=19,
     col="darkgreen",
     xlab="Baños",
     ylab="Precio")

plot(base1$habitaciones,
     base1$preciom,
     pch=19,
     col="purple",
     xlab="Habitaciones",
     ylab="Precio")

###############################################################
# MATRIZ DE CORRELACIÓN
###############################################################



vars <- base1[,c("preciom",
                 "areaconst",
                 "estrato",
                 "banios",
                 "habitaciones",
                 "parqueaderos")]

# Calcular matriz de correlación
correlacion <- cor(vars, use="complete.obs")

correlacion                                    
##                preciom areaconst    estrato    banios habitaciones parqueaderos
## preciom      1.0000000 0.7135622 0.68539581 0.5300689   0.25102540    0.2770120
## areaconst    0.7135622 1.0000000 0.50824643 0.4755497   0.33115313    0.2037202
## estrato      0.6853958 0.5082464 1.00000000 0.4054070   0.07403215    0.1507916
## banios       0.5300689 0.4755497 0.40540702 1.0000000   0.57428156    0.2324782
## habitaciones 0.2510254 0.3311531 0.07403215 0.5742816   1.00000000    0.1336643
## parqueaderos 0.2770120 0.2037202 0.15079156 0.2324782   0.13366427    1.0000000

4. MODELO DE REGRESIÓN

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

summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -282.76  -64.45  -15.40   42.55  521.74 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -191.89314   21.85333  -8.781  < 2e-16 ***
## areaconst       0.77055    0.05128  15.025  < 2e-16 ***
## estrato        75.89671    5.40228  14.049  < 2e-16 ***
## habitaciones   -2.65074    3.14485  -0.843      0.4    
## parqueaderos   17.70152    4.24753   4.167 3.51e-05 ***
## banios         21.51403    4.24153   5.072 5.17e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 106.6 on 634 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:  0.6781, Adjusted R-squared:  0.6756 
## F-statistic: 267.2 on 5 and 634 DF,  p-value: < 2.2e-16
# R2 DEL MODELO

summary(modelo)$r.squared
## [1] 0.6781453
# 4. MODELO DE REGRESIÓN


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

summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -282.76  -64.45  -15.40   42.55  521.74 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -191.89314   21.85333  -8.781  < 2e-16 ***
## areaconst       0.77055    0.05128  15.025  < 2e-16 ***
## estrato        75.89671    5.40228  14.049  < 2e-16 ***
## habitaciones   -2.65074    3.14485  -0.843      0.4    
## parqueaderos   17.70152    4.24753   4.167 3.51e-05 ***
## banios         21.51403    4.24153   5.072 5.17e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 106.6 on 634 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:  0.6781, Adjusted R-squared:  0.6756 
## F-statistic: 267.2 on 5 and 634 DF,  p-value: < 2.2e-16
anova(modelo)
## Analysis of Variance Table
## 
## Response: preciom
##               Df   Sum Sq  Mean Sq  F value    Pr(>F)    
## areaconst      1 11387503 11387503 1002.982 < 2.2e-16 ***
## estrato        1  3140688  3140688  276.624 < 2.2e-16 ***
## habitaciones   1    79135    79135    6.970  0.008493 ** 
## parqueaderos   1   267151   267151   23.530 1.549e-06 ***
## banios         1   292101   292101   25.727 5.170e-07 ***
## Residuals    634  7198213    11354                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# R2 DEL MODELO


summary(modelo)$r.squared
## [1] 0.6781453
# 5. VALIDACION DE SUPUESTOS


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

# Normalidad residuos
res <- residuals(modelo)

hist(res,
     main="Distribución residuos",
     col="orange")

qqnorm(res)
qqline(res)

# Homocedasticidad
plot(fitted(modelo),res,
     pch=19,
     main="Residuos vs Ajustados")

abline(h=0,col="red")


# 6. PREDICCION VIVIENDA 1


vivienda1 <- data.frame(
  areaconst=200,
  estrato=4,
  habitaciones=4,
  parqueaderos=1,
  banios=2
)

pred1 <- predict(modelo,
                 newdata=vivienda1,
                 interval="confidence")

pred1
##        fit      lwr     upr
## 1 315.9302 301.4733 330.387
# OFERTAS POTENCIALES

ofertas1 <- base1[
  base1$preciom <= 350 &
  base1$areaconst >=180 &
  base1$habitaciones>=4 &
  base1$banios>=2,
]

head(ofertas1)
## # A tibble: 6 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <fct>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  7471 Zona N… <NA>        4     330       240            2      4            4
## 2   309 Zona N… <NA>        3     250       240            1      2            4
## 3   612 Zona N… 01          3     270       196            1      2            4
## 4   750 Zona N… 02          3     305       268            2      4            8
## 5  4210 Zona N… 01          5     350       200            3      3            4
## 6  4267 Zona N… 01          5     335       202            1      4            5
## # ℹ 4 more variables: tipo <fct>, barrio <fct>, longitud <dbl>, latitud <dbl>
# MAPA OFERTAS


plot(base1$longitud,
     base1$latitud,
     col="gray",
     pch=16,
     main="Ofertas potenciales")

points(ofertas1$longitud,
       ofertas1$latitud,
       col="red",
       pch=19)

ANALISIS VIVIENDA 2

base2 <- data[data$tipo=="Apartamento",]

head(base2,3)
## # A tibble: 3 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <fct>   <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 <fct>, barrio <fct>, longitud <dbl>, latitud <dbl>
# MODELO APARTAMENTOS


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

summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base2)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -431.02  -45.12   -0.09   43.36  411.77 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -274.70269    8.78533  -31.27   <2e-16 ***
## areaconst       1.70430    0.03624   47.02   <2e-16 ***
## estrato        68.91062    1.65335   41.68   <2e-16 ***
## habitaciones  -24.34526    2.16586  -11.24   <2e-16 ***
## parqueaderos   37.79282    2.23623   16.90   <2e-16 ***
## banios         43.26423    2.01329   21.49   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 84.33 on 4855 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:  0.817,  Adjusted R-squared:  0.8168 
## F-statistic:  4336 on 5 and 4855 DF,  p-value: < 2.2e-16
# PREDICCION VIVIENDA 2


vivienda2 <- data.frame(
  areaconst=300,
  estrato=5,
  habitaciones=5,
  parqueaderos=3,
  banios=3
)

pred2 <- predict(modelo2,
                 newdata=vivienda2,
                 interval="confidence")

pred2
##       fit      lwr      upr
## 1 702.584 688.7262 716.4417
# OFERTAS POTENCIALES 2


ofertas2 <- base2[
  base2$preciom <= 850 &
  base2$areaconst >=280 &
  base2$habitaciones>=5 &
  base2$banios>=3,
]

head(ofertas2)
## # A tibble: 6 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <fct>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  7012 Zona N… <NA>        6     850       310            2      4            5
## 2  6383 Zona O… 02          6     600       350            2      4            5
## 3  7321 Zona O… 08          6     620       317            2      6            5
## 4  4855 Zona S… 02          4     390       300            2      5            6
## 5  5511 Zona O… <NA>        3     240       315            2      5            9
## 6  6868 Zona S… 03          3     370       300            3      6            5
## # ℹ 4 more variables: tipo <fct>, barrio <fct>, longitud <dbl>, latitud <dbl>
# MAPA OFERTAS 2


plot(base2$longitud,
     base2$latitud,
     col="gray",
     pch=16,
     main="Ofertas potenciales apartamento")

points(ofertas2$longitud,
       ofertas2$latitud,
       col="blue",
       pch=19)

Con el propósito de apoyar a la empresa C&A (Casas y Apartamentos) en la asesoría solicitada por una compañía internacional interesada en adquirir dos viviendas en la ciudad de Cali, se llevó a cabo un proceso de análisis de datos y modelación estadística. Para ello se emplearon técnicas de regresión lineal múltiple, con el fin de estimar el valor esperado de las viviendas a partir de sus características y así identificar posibles opciones disponibles en el mercado que cumplieran con los requisitos de los compradores.

En una primera etapa se realizó la limpieza y preparación de la base de datos. Este proceso incluyó la eliminación de registros duplicados, la imputación de valores faltantes mediante la mediana y la identificación de valores atípicos en variables relevantes como el área construida y el precio de las viviendas. Los valores extremos detectados fueron eliminados para garantizar mayor consistencia en la información utilizada. Estas acciones permitieron trabajar con una base de datos más depurada y confiable para el análisis posterior.

Posteriormente se desarrolló un análisis exploratorio de datos (EDA) con el objetivo de identificar relaciones entre las variables. Los resultados mostraron que el precio de las viviendas presenta una alta correlación con el área construida (0.71) y con el estrato socioeconómico (0.68), lo que sugiere que estas variables tienen una influencia importante en la determinación del valor de las propiedades. También se evidenció una relación moderada con el número de baños y una relación más baja con variables como el número de habitaciones y de parqueaderos.

Con base en estos hallazgos se construyó un modelo de regresión lineal múltiple para estimar el precio de las viviendas tipo casa ubicadas en la zona norte de la ciudad. El modelo obtuvo un coeficiente de determinación (R²) de 0.678, lo que indica que aproximadamente el 67.8% de la variabilidad del precio puede explicarse a partir de las variables incluidas en el modelo. Entre los factores que mostraron mayor influencia se encuentran el área construida, el estrato socioeconómico, el número de baños y el número de parqueaderos.

A partir de este modelo se realizó la predicción del precio para una vivienda con características específicas, obteniendo un valor estimado cercano a 316 millones de pesos, con un intervalo de confianza aproximado entre 301 y 330 millones de pesos. Con base en este rango se identificaron diferentes ofertas disponibles en el mercado que cumplen con las condiciones solicitadas por el cliente y cuyo precio se encuentra dentro del valor esperado.

Adicionalmente, se construyó un segundo modelo para apartamentos, el cual presentó un R² de 0.817, lo que refleja un mayor poder explicativo en comparación con el modelo de casas. En este caso, variables como el área construida, el estrato socioeconómico, el número de baños y la cantidad de parqueaderos también mostraron una influencia significativa en el precio. Para una vivienda con las características solicitadas, el modelo estimó un valor cercano a 703 millones de pesos, con un intervalo de confianza aproximado entre 689 y 716 millones de pesos.