Caso C&A

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:

imagen
imagen

Ayude a María a responder la solicitud, mediante técnicas modelación que usted conoce. Ella requiere le envíe un informe ejecutivo donde analice los dos casos y sus recomendaciones (Informe). Como soporte del informe debe anexar las estimaciones, validaciones y comparación de modelos requeridos (Anexos) . Los datos de los tres últimos meses se adjuntan en la base que puede obtener con el siguiente código en R.

PASOS A SEGUIR

library(mice)
library(tidyverse)
library(dplyr)
library(plotly)
library(lattice)
library(caret)
library(ggplot2)
library(Rcpp)
library(GGally)
library(ggcorrplot)
library(leaflet)
library(lmtest)
library(zoo)
library(gridExtra)
library(nortest)
library(Metrics)
library(olsrr)
library(stargazer)
library(knitr)

Primer punto

Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.

library(paqueteMODELOS)
## Loading required package: boot
## Warning: package 'boot' was built under R version 4.3.3
## 
## Attaching package: 'boot'
## The following object is masked from 'package:lattice':
## 
##     melanoma
## Loading required package: broom
## Warning: package 'broom' was built under R version 4.3.3
## Loading required package: summarytools
## 
## Attaching package: 'summarytools'
## The following object is masked from 'package:tibble':
## 
##     view
data(vivienda)
base1=subset(vivienda, vivienda$tipo=="Casa" & vivienda$zona=="Zona Norte")
base_3 <- head(base1, n=3)
base_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>

Se encuentran 722 registros que cumplen los criterios de la busqueda.

prop.table(table(base1$zona, base1$estrato))*100
##             
##                      3         4         5         6
##   Zona Norte 32.548476 22.299169 37.534626  7.617729

Se encuentra que las casas de la zona norte se distribuyen en el estrato 5 con 37.8%, seguido del estrato 3 con 32.5% y estrato 4 22.3%.

prop.table(table(base1$habitaciones))*100
## 
##          0          1          2          3          4          5          6 
##  2.7700831  0.2770083  1.6620499 23.6842105 30.7479224 18.9750693  8.3102493 
##          7          8          9         10 
##  5.8171745  4.0166205  1.9390582  1.8005540

Al verificar el numero de habitaciones de las casas ubicadas en la zona norte de la ciudad, se encuentra que el 54% de las casas ofertan entre 3 y 4 habitaciones; 20 viviendas tienen cero habitaciones, lo que llama la atencion y el maximo numero de habitaciones ofertadas por vivienda es de 10.

grafico <-md.pattern(base1, rotate.names = TRUE)
title(main="Figura 1. Variables perdidas en casas zona Norte")

Al verificar datos faltantes se encuentra que 287 registros no tienen dato de parqueadero y 372 de numero de pisos.

Se eliminan datos que no se analizaran como latitud, longitud, zona y barrio. Así como la variable piso debido al gran numero de datos faltantes.

base_cn = base1 [c("estrato", "preciom", "areaconst", "banios", "habitaciones", "parqueaderos")]

Se realiza analisis descriptivo de la base de datos para variables numericas:

summarytools::descr(base_cn)
## Descriptive Statistics  
## base_cn  
## N: 722  
## 
##                     areaconst   banios   estrato   habitaciones   parqueaderos   preciom
## ----------------- ----------- -------- --------- -------------- -------------- ---------
##              Mean      264.85     3.56      4.20           4.51           2.18    445.91
##           Std.Dev      167.17     1.52      0.98           1.83           1.40    268.36
##               Min       30.00     0.00      3.00           0.00           1.00     89.00
##                Q1      140.00     2.00      3.00           3.00           1.00    260.00
##            Median      240.00     3.00      4.00           4.00           2.00    390.00
##                Q3      337.00     4.00      5.00           5.00           3.00    550.00
##               Max     1440.00    10.00      6.00          10.00          10.00   1940.00
##               MAD      146.78     1.48      1.48           1.48           1.48    220.17
##               IQR      196.75     2.00      2.00           2.00           2.00    288.75
##                CV        0.63     0.43      0.23           0.41           0.64      0.60
##          Skewness        1.85     0.67      0.07           0.64           1.86      1.76
##       SE.Skewness        0.09     0.09      0.09           0.09           0.12      0.09
##          Kurtosis        6.24     1.00     -1.26           1.18           4.62      4.65
##           N.Valid      722.00   722.00    722.00         722.00         435.00    722.00
##         Pct.Valid      100.00   100.00    100.00         100.00          60.25    100.00

Analisis descriptivo

Metros cuadrados: La media en metros cuadrados para el area construida es de 265 y mediana de 240, el valor minimo es de 30 y el maximo de 1440 metros cuadrados. La mayoria de viviendas 75% constan de 337 metros cuadrados.Es decir que hay una asimetria de los datos hacia la derecha.

Baños: La media es de 3.5 baños con una mediana de 3 baños. El dato minimo es de cero baños, lo que llama la atención. El maximo numero de baños por vivienda es de 10, lo que influye en la simetria de los datos hacia la derecha.

Estrato: Las casas de la zona norte se ubican entre el estrato 3 (valor minimo) y el estrato 6 (valor maximo), con una media y mediana de estrato 4.

Numero de habitaciones: En cuanto al numero de habitaciones de las casas de la zona norte, se encuentra que la media y la mediana es de 4 habitaciones. Con un valor mnimo de cero habitaciones lo cual llama la atención, podria corresponder a viviendas de un solo ambiente; el valor maximo de habitaciones es de 10, lo que genera asimetria hacia la derecha.

Parqueaderos: La media y mediana es de dos parqueaderos por casa en la zona norte. El valor minimo es de 1 y maximo de 10, lo que genera asimetria hacia la derecha.

Precio: la media del precio de las casas de la zona norte es de 446 millones con mediana de 390 millones. La casa mas economica es de 89 millones y la mas costosa de 1940 millones, esto genera asimetría hacia la derecha. El tercer cuartil se ubica en 550 millones, es decir que el 75% de las casas de la norte se encuentra por debajo de este precio.

Segundo punto

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

library(plotly)
fig <- plot_ly(data = base_cn, x = ~areaconst, y = ~preciom)
fig <- fig %>% layout(title = "Diagrama de dispersion Area Construida (metros cuadrados) vs 
                      Precio (millones) de las Casas en la Zona Norte")
fig
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter
## No scatter mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

Acorde con el diagrama de dispersión se evidencia un patron aparentemente lineal positivo, es decir que a mayor area construida mayor precio de la vivienda. Tambien se evidencian dos puntos atipicos en la variable area construida (1188 y 1440 metros cuadrados). La mayoria de casas se concentran por debajo de los 400 metros construidos con valor menor a 500 millones.

fig2 <- plot_ly(data = base_cn, x = ~areaconst, y = ~preciom, color = ~estrato)
fig2 <- fig2 %>% layout(title = "Diagrama de dispersion Area Construida (metros cuadrados) 
                        vs Precio (millones) y estrato de las Casas en la Zona Norte")
fig2
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter
## No scatter mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

Al realizar este analisis por estrato, también se encuentra esta relacion lineal; las casas estrato 6 tienen valor por encima de 500 millones con un maximo de 1600 millones. El área varia entre los 200 y 1000 metros cuadrados. Las casas ubicadas en estrato 5 tienen un precio por encima de los 300 millones con un area menor a 800 metros cuadrados.Las casas estrato 4 se concentran por debajo de los 600 metros cuadrados con precios por debajo de los 800 millones, mientras que las casas estrato 3 se ubican por debajo de los 200 metros cuadrados con precios por debajo de los 400 millones.

fig_areac1 <- plot_ly(base_cn, x=~habitaciones, type = "histogram", alpha = 0.6) 
fig_areac1 <- fig_areac1 %>% add_histogram(x = ~habitaciones, type = "histogram", alpha = 0.6, color = ~estrato)
fig_areac1 <- fig_areac1 %>% layout(
  barmode = "overlay",
  xaxis = list(title = "Numero de habitaciones"),
  yaxis = list(title = "Frecuencia"),
  title = "Histograma de Numero de habitaciones segun estrato en casas en la Zona Norte"
)
fig_areac1
## Warning: textfont.color doesn't (yet) support data arrays
## Warning in min(x, na.rm = na.rm): ningún argumento finito para min; retornando
## Inf
## Warning in max(x, na.rm = na.rm): ningun argumento finito para max; retornando
## -Inf
## Warning: textfont.color doesn't (yet) support data arrays

Al analizar el numero de habitaciones de las casas de la zona norte por estrato, se encuentra que en el estrato 3 se ofertan la mayoria de viviendas que constan de 3 habitaciones(n= 168), mientras que en el estrato 4 se ofertan viviendas que constan de 4 habitaciones (n=218) y 5 habitaciones (n=138). Llama la atención que hay 20 viviendas sin habitaciones, podrian corresponder a apartaestudios o viviendas de un solo ambiente.En el estrato 6 se ofertan viviendas con 8 habitaciones.

fig4 <- base_cn %>%
  plot_ly(
    x = ~banios,
    y = ~preciom,
    split = ~banios,
    type = 'violin',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    )
  ) 

fig4 <- fig4 %>%
  layout(
    xaxis = list(
      title = "numero de baños"
    ),
    yaxis = list(
      title = "precio casas",
      zeroline = F
    )
  )

fig4

En cuanto al numero de baños, se evidencian casas sin baños con precios entre los 190 y 1200 millones, lo cual es bastante llamativo y seria importante revisar la captura de estos datos. Tambien se encuentran casas dotadas con un baño cuyo precio oscila entre 89 y 420 millones. Las casas con mas de 8 baños son las que presentan un valor mas alto.

data <- na.omit(base_cn)
base_cn$preciom=log(base_cn$preciom)
base_cn$areaconst=log(base_cn$areaconst)
GGally::ggpairs(data[,2:6], title="Correlacion de variables para casas de la zona Norte ")

Dado que no hay distribución normal de datos se verifica correlacion con Spearman:

cor.test(x = base_cn$areaconst, y = base_cn$preciom, method = "spearman", digits = 3)
## 
##  Spearman's rank correlation rho
## 
## data:  base_cn$areaconst and base_cn$preciom
## S = 11755535, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.8125943

Para verificar la asociación entre precio y area construida se realiza medicion de correlacion de spearman, teniendo en cuenta que hay presencia de datos atipicos en varias variables, este valor es estadisticamente significativo (p menor 0.05), es decir que estas variables si presentan una asociación entre ellas.

dfn<-select(data, estrato, preciom, areaconst, banios, habitaciones, parqueaderos)

r<-cor(dfn)

p2<-ggcorrplot(r,type="lower",
           title="Correlaciones entre variables",
           colors=c("red","yellow","blue"),
           lab = TRUE,
           outline.color="black", ggtheme = theme_test() + theme(text = element_text(size = 7)))
plotly::ggplotly(p2)

Al analizar la correlacion entre variables, se encuentra una relacion positiva considerable entre area construida y precio, la cual ya fue verificada. Tambien se presenta una correlacion positiva media entre (superior 0.50 y 0.70) las variables predictoras: precio de la casa y el estrato, precio y numero de baños, numero de baños y numero de habitaciones.

Tercer punto

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).

Para dar respuesta a este punto se debe trabajar los datos faltantes, se procede a imputar datos de parqueadero por la mediana (teniendo en cuenta que hay presencia de datos atipicos que afectan la media).

data_imputada <- as.data.frame(base_cn)
median_parqueaderos <- median(base_cn$parqueaderos, na.rm = TRUE)
base_cn$parqueaderos[is.na(base_cn$parqueaderos)] <- median_parqueaderos
head(data_imputada)
##   estrato  preciom areaconst banios habitaciones parqueaderos
## 1       5 5.768321  5.010635      4            6            2
## 2       5 6.659294  5.940171      3            3            2
## 3       6 6.620073  6.098074      7            6           NA
## 4       4 6.437752  5.872118      5            5            3
## 5       5 6.620073  5.468060      6            6            2
## 6       4 6.396930  5.075174      4            5            1

Cuando las variables predictoras son numéricos, la escala en la que se miden, así como la magnitud de su varianza pueden influir en gran medida en el modelo. De tal manera que, si no se igualan de alguna forma los predictores, aquellos que se midan en una escala mayor o que tengan más varianza, dominarán el modelo aunque no sean los que más relación tienen con la variable respuesta. Para ello se centraran los datos, previo a la generacion del modelo:

data_escalada <-scale(data_imputada, center = TRUE, scale = TRUE)
data_escalada  <-as.data.frame (data_escalada)

Se genera modelo de regresion lineal multiple con las variables solicitadas, con datos imputados de parqueadero y variables numericas centradas:

modelo1=lm(preciom ~ areaconst + banios + habitaciones + estrato + parqueaderos, data=data_escalada)
summary(modelo1)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + habitaciones + estrato + 
##     parqueaderos, data = data_escalada)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.43662 -0.27181 -0.02051  0.24768  1.78418 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.009971   0.022246   0.448 0.654224    
## areaconst    0.453414   0.030230  14.999  < 2e-16 ***
## banios       0.109160   0.032123   3.398 0.000742 ***
## habitaciones 0.048900   0.028920   1.691 0.091585 .  
## estrato      0.312041   0.028198  11.066  < 2e-16 ***
## parqueaderos 0.099837   0.023271   4.290 2.21e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4356 on 429 degrees of freedom
##   (287 observations deleted due to missingness)
## Multiple R-squared:  0.7246, Adjusted R-squared:  0.7214 
## F-statistic: 225.8 on 5 and 429 DF,  p-value: < 2.2e-16

Al verificar los resultados del modelo de regresion lineal multiple se encuentra que tienen mayor efecto en la variable precio de las casas, las variables: area construida, numero de baños y estrato de acuerdo con el valor de p, que en todos los casos es estadisticamente significativo. La variable parqueadero presenta tambien un valor de p, estadisticamente significativo aunque mas bajo que las anteriores variables. La variable habitacion no tiene ningun efecto en el precio de la casa, acorde con el valor de p obtenido (p mayor 0.05). Estos resultados son logicos teniendo en cuenta que el precio de las viviendas depende de su área en metros cuadrados, y que el área construida depende del equipamiento de la vivienda (baños y habitaciones principalmente) De igual manera, las viviendas con mayor numero de parqueaderos tienen mayor precio final. Lo que no es logico es que las habitaciones no se relacionen con el precio final, si el area construida depende del numero de habitaciones con las que cuenta la vivienda. En este caso, podria estar influenciado por aquellas casas que refieren tener cero habitaciones, valdria la pena revisar estos datos y la forma de captura de los mismos.

En cuanto al coeficiente R2 del modelo RLM permite determinar que las variables escogidas (area construida, numero de baños, numero de parqueaderos y estrato) explican en un 76% el precio de la vivienda. El modelo podria ajustarse en cuanto a realizar una mejor selección de variables predictoras, debido a posible muticolinealidad aproximada entre numero de baños y area construida, que valdría la pena revisar detalladamente. Por lo cual se requiere realizar una validación cruzada o realizar un analisis VIF con el fin de determinar la gravedad de la multicolinealidad entre variables predictoras.

Cuarto punto

Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

Residuales escalados, linealidad Q-Q

En un modelo lineal de regresión múltiple, los residuos son la diferencia entre los valores observados y los valores predichos por el modelo para cada uno de los puntos de datos. Idealmente, los residuos deberían ser aleatorios y tener una distribución normal con media cero y una varianza constante (homocedasticidad), lo que indica que el modelo captura correctamente la relación entre las variables independientes y la variable dependiente. Sin embargo, si los residuos no se distribuyen normalmente o no son homocedásticos, puede indicar que el modelo no es adecuado para los datos o que hay variables importantes que no se han incluido en el modelo.

El supuesto de normalidad puede chequearse bien sea con el gráfico de probabilidad normal de los residuales o con alguna de las pruebas analíticas de normalidad, entre las cuales se tienen las de Shapiro Wilk, Kolmogorov Smirnov, Cramér von Mises y Anderson Darling.

# Eliminar filas con NA antes de entrenar el modelo
data_escalada <- na.omit(data_escalada)

# Ajustar el modelo con los datos filtrados
modelo1 <- lm(preciom ~ areaconst + banios + habitaciones + estrato + parqueaderos, data = data_escalada)

# Agregar los residuos correctamente
data_escalada$residuals <- residuals(modelo1)

# Agregar residuos al dataframe
data_escalada$residuals <- residuals(modelo1)

# Crear los gráficos con la nueva columna residuals
plot1 <- ggplot(data = data_escalada, aes(x = areaconst, y = residuals)) +
    geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
    theme_bw()

plot2 <- ggplot(data = data_escalada, aes(x = banios, y = residuals)) +
    geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
    theme_bw()

plot3 <- ggplot(data = data_escalada, aes(x = habitaciones, y = residuals)) +
    geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
    theme_bw()

plot4 <- ggplot(data = data_escalada, aes(x = estrato, y = residuals)) +
    geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
    theme_bw()

plot5 <- ggplot(data = data_escalada, aes(x = parqueaderos, y = residuals)) +
    geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
    theme_bw()

# Mostrar los gráficos en una cuadrícula
library(gridExtra)
grid.arrange(plot1, plot2, plot3, plot4, plot5)

Si la relación es lineal, los residuos deben de distribuirse aleatoriamente en torno a 0 con una variabilidad constante a lo largo del eje X. En la grafica anterior, se evidencia esta distribución para los residuos de las variables predictoras escaladas excepto para la variable numero de parqueaderos.En cuanto a la variable area construida se concentran en el eje x entre -2 y 2

Normalidad de los residuos

qqnorm(modelo1$residuals)
qqline(modelo1$residuals)

Los gráficos QQ identifican los cuantiles en los datos de la muestra y los grafican contra los cuantiles de una distribución teórica. Si los puntos de los residuos caen a lo largo de una línea diagonal recta en una gráfica QQ, es probable que el conjunto de datos siga una distribución normal.En este caso se evidencia que en los extremos los puntos, no siguen la diagnonal, principalmente entre segundo y tercer cuantil.

lillie.test(modelo1$residuals)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  modelo1$residuals
## D = 0.04578, p-value = 0.02929

Dado que el numero de observaciones es mayor a 50 se debe utilizar el test de Kolmogórov-Smirnov para evaluar si una variable sigue una distribución normal (hipotesis nula). En este caso, los resultados sugieren que los residuos no se distribuyen normalmente en la población y que este resultado es significativo estadisticamente (p menor 0.05). No se cumple este supuesto.

Homocedasticidad de los errores

Para chequear el supuesto de varianza constante, resulta útil un gráfico de residuales versus valores ajustados de la respuesta, al igual que la prueba de Goldfeld-Quandt, la cual se utiliza para determinar si la heterocedasticidad está presente en un modelo de regresión.

gqtest(modelo1)
## 
##  Goldfeld-Quandt test
## 
## data:  modelo1
## GQ = 1.1464, df1 = 212, df2 = 211, p-value = 0.1607
## alternative hypothesis: variance increases from segment 1 to 2

Acorde con los resultados obtenidos, se encuentra que el p valor rechaza la hipotesis nula (hay homocedasticidad) y se acepta la alterna hay heterocedasticidad. Es decir, que los errores estándar que se muestran en la tabla de salida de la regresión pueden no ser confiables.No se cumple este supuesto para el modelo.

residuos <- residuals(modelo1)
valores_ajustados <- fitted(modelo1)
plot(valores_ajustados, residuos, col = "blue", main = "Grafico de Residuos vs. Valores Ajustados")
abline(h = 0, col = "red")

Al representar los residuos frente a los valores ajustados por el modelo, los primeros se tienen que distribuir de forma aleatoria en torno a cero, manteniendo aproximadamente la misma variabilidad a lo largo del eje X. Si se observa algún patrón específico, por ejemplo forma cónica o mayor dispersión en los extremos, significa que la variabilidad es dependiente del valor ajustado y por lo tanto no hay homocedasticidad como en este caso.

Independencia de los errores

Para determinar la autocorrelacion de los errores se realiza la prueba de Durbin-Watson, ya que evalua la presencia de autocorrelación positiva en los errores de un modelo de regresión.

dwtest(modelo1)
## 
##  Durbin-Watson test
## 
## data:  modelo1
## DW = 1.7573, p-value = 0.004805
## alternative hypothesis: true autocorrelation is greater than 0

En este caso, el valor de Durbin-Watson es menor a 2, por lo cual hay evidencia de correlación serial positiva y este resultado es estadisticamente significativo (valor p muy bajo).Este supuesto no se cumple para el modelo.

Outliers

Siempre es conveniente identificar si hay algún posible outlier, observación con alto leverage o influyente, que podría estar condicionando en gran medida el modelo. La eliminación de este tipo de observaciones debe de analizarse con detalle y dependiendo de la finalidad del modelo. Si el fin es predictivo, un modelo sin outliers ni observaciones altamente influyentes suele ser capaz de predecir mejor la mayoría de casos. Sin embargo, es muy importante prestar atención a estos valores ya que, de no tratarse de errores de medida, pueden ser los casos más interesantes.

data_escalada$studentized_residual <- rstudent(modelo1)
ggplot(data = data_escalada, aes(x = predict(modelo1), y = abs(studentized_residual))) +
geom_hline(yintercept = 3, color = "grey", linetype = "dashed") +
# se identifican en rojo observaciones con residuos estandarizados absolutos > 3
geom_point(aes(color = ifelse(abs(studentized_residual) > 3, 'red', 'black'))) +
scale_color_identity() +
labs(title = "Distribucion de los residuos estudentizados",
     x = "prediccion modelo") + 
theme_bw() + theme(plot.title = element_text(hjust = 0.5))

Los puntos de color rojo corresponden a outliers, que se identifican a continuación por su indice y valdría la pena revisarlos de forma detallada:

which(abs(data_escalada$studentized_residual) > 3)
## [1]  26 239

El modo adecuado a proceder cuando existen valores atípicos o influyentes como en este caso es calcular el modelo de regresión incluyendo y excluyendo dichos valores.

Multicolinealidad

La multicolinealidad se refiere a una alta correlación entre dos o más variables predictoras en un modelo de regresión, lo que puede ser problemático para la interpretación de los coeficientes y la estabilidad de las estimaciones.

Cuando se introduce una variable categórica como predictor, un nivel se considera el de referencia (normalmente codificado como 0) y el resto de niveles se comparan con él. En el caso de que el predictor categórico tenga más de dos niveles, se generan lo que se conoce como variables dummy, que son variables creadas para cada uno de los niveles del predictor categórico y que pueden tomar el valor de 0 o 1. Cada vez que se emplee el modelo para predecir un valor, solo una variable dummy por predictor adquiere el valor 1 (la que coincida con el valor que adquiere el predictor en ese caso) mientras que el resto se consideran 0. En este caso se incluyen las variables dummy para los estratos 3, 4, 5 y 6.

data2_imputada=data_imputada 
data2_imputada$E3<-as.numeric(data2_imputada$estrato==3) 
data2_imputada$E4<-as.numeric(data2_imputada$estrato==4)  
data2_imputada$E5<-as.numeric(data2_imputada$estrato==5)  
data2_imputada$E6<-as.numeric(data2_imputada$estrato==6)  
modelo2=lm(preciom ~ areaconst + parqueaderos + habitaciones + banios+ E3+ E4 + E5 + E6, data=data2_imputada)
summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + habitaciones + 
##     banios + E3 + E4 + E5 + E6, data = data2_imputada)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -0.7800 -0.1560 -0.0070  0.1326  1.0199 
## 
## Coefficients: (1 not defined because of singularities)
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   3.732681   0.154778  24.116  < 2e-16 ***
## areaconst     0.415234   0.027769  14.953  < 2e-16 ***
## parqueaderos  0.039706   0.009351   4.246 2.67e-05 ***
## habitaciones  0.018348   0.009029   2.032 0.042752 *  
## banios        0.034833   0.012110   2.876 0.004224 ** 
## E3           -0.578105   0.060617  -9.537  < 2e-16 ***
## E4           -0.304120   0.054020  -5.630 3.28e-08 ***
## E5           -0.184506   0.050132  -3.680 0.000263 ***
## E6                  NA         NA      NA       NA    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.2458 on 427 degrees of freedom
##   (287 observations deleted due to missingness)
## Multiple R-squared:  0.729,  Adjusted R-squared:  0.7245 
## F-statistic: 164.1 on 7 and 427 DF,  p-value: < 2.2e-16

Al verificar los resultados del segundo modelo de regresion lineal multiple (con la variable estrato como categorica y numero de parqueaderos imputados) se encuentra que tienen mayor efecto en la variable precio de las casas, las variables: area construida, numero de baños y los estratos 3, 4 y 5 de acuerdo con el valor de p, que en todos los casos es estadisticamente significativo. Todos ellos comparados con el estrato 6 por lo cual no se genera medición. En este modelo la variable parqueadero presenta tambien un valor igual a p valor por lo cual no es, estadisticamente significativo. La variable habitaciones tiene un ligero efecto en el precio de la casa, acorde con el valor de p obtenido (menor a 0.05). . En comparación con el primer modelo mejora, la predicción del numero de habitaciones sobre el precio de las casas, si se tiene en cuenta que el precio de las viviendas depende de su área en metros cuadrados, estrechamente relacionada con número de baños y habitaciones. En cuanto al estrato, se evidencia que todos los estratos tienen efecto sobre el precio final de las casas de la zona norte de la ciudad si se mantiene las demas variables predictoras constantes; el estrato 3 tiene en promedio 11 millones de pesos menos sobre las casas, el estrato 4 cerca de 5 millones menos y el estrato 5 aprox 3 millones menos, en comparacion con el estrato 6.

En cuanto al coeficiente R2 del modelo RLM permite determinar que las variables escogidas (area construida, numero de baños, numero de parqueaderos y estrato) explican en un 77% el precio de la vivienda. Respecto al primer modelo no mejora este indice.

Se realiza análisis de Inflación de Varianza (VIF) para el primer modelo:

library(car)
## Warning: package 'carData' was built under R version 4.3.3
vif(modelo1)
##    areaconst       banios habitaciones      estrato parqueaderos 
##     1.641579     1.976961     1.706185     1.413563     1.238530

se evidencia que existe cierto grado de correlación entre las variables predictoras no obstante la correlación no es alta (mayor a 5), es decir que no hay redundancia en el modelo.

Quinto punto

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)
# Se crean los índices de las observaciones de entrenamiento
train <- createDataPartition(y = data2_imputada$preciom, p = 0.7, list = FALSE, times = 1)
datos_train <- data2_imputada[train, ]
datos_test  <- data2_imputada[-train, ]
dim(datos_train)
## [1] 507  10
dim(datos_test)
## [1] 215  10

Se genera modelo con el 70% de datos de entrenamiento:

modelo_train=lm(preciom ~ areaconst + banios + habitaciones + E3+ E4 + E5 +E6 + parqueaderos, data=datos_train)
summary(modelo_train)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + habitaciones + E3 + 
##     E4 + E5 + E6 + parqueaderos, data = datos_train)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.74182 -0.14828 -0.01071  0.13562  0.70099 
## 
## Coefficients: (1 not defined because of singularities)
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   3.74097    0.18517  20.203  < 2e-16 ***
## areaconst     0.41290    0.03225  12.805  < 2e-16 ***
## banios        0.02715    0.01378   1.970 0.049796 *  
## habitaciones  0.03318    0.01022   3.246 0.001305 ** 
## E3           -0.62416    0.07271  -8.585 5.38e-16 ***
## E4           -0.34604    0.06427  -5.384 1.49e-07 ***
## E5           -0.22096    0.06040  -3.659 0.000301 ***
## E6                 NA         NA      NA       NA    
## parqueaderos  0.04351    0.01146   3.797 0.000178 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.2408 on 294 degrees of freedom
##   (205 observations deleted due to missingness)
## Multiple R-squared:  0.7566, Adjusted R-squared:  0.7508 
## F-statistic: 130.6 on 7 and 294 DF,  p-value: < 2.2e-16

Se verifican supuestos del modelo con datos de entrenamiento:

normalidad

res <- residuals(modelo_train)
res <- as.data.frame(res)
ggplot(res,aes(res)) +  geom_histogram(fill='blue',alpha=0.5)

Los residuos presentan una distribución asimetrica.

Linealidad y outliers

residuos <- rstandard(modelo_train) # residuos estándares del modelo ajustado (completo) 
par(mfrow = c(1,2)) # divide la ventana en una fila y tres columnas 
boxplot(residuos) # diagrama de cajas de los residuos estandarizados 
qqnorm(residuos) # gráfico de cuantiles de los residuos estandarizados 
qqline(residuos)

Tampoco se cumple supuesto de linealidad de los residuos y persisten los outliers.

Sexto punto

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

set.seed(123)
predicciones <- predict(object =  modelo_train, newdata = datos_test)
predicciones_df <- data.frame(datos_test, predicciones)
head(predicciones_df)
##    estrato  preciom areaconst banios habitaciones parqueaderos E3 E4 E5 E6
## 2        5 6.659294  5.940171      3            3            2  0  0  1  0
## 6        4 6.396930  5.075174      4            5            1  0  1  0  0
## 7        5 6.040255  5.298317      4            5            4  0  0  1  0
## 9        3 5.438079  5.075174      2            3           NA  1  0  0  0
## 10       3 5.247024  6.075346      0            0           NA  1  0  0  0
## 11       3 5.192957  4.787492      3            3           NA  1  0  0  0
##    predicciones
## 2      6.240722
## 6      5.808483
## 7      6.156242
## 9            NA
## 10           NA
## 11           NA

Septimo punto

Calcule el error cuadrático medio (RMSE), el error absoluto medio (MAE) y el R2 e interprete.

La diferencia entre la predicción y el valor real es el error, este es una variable aleatoria, que puede depender de las características dadas.

#install.packages("ModelMetrics")  # Instalar solo si no está instalado
library(ModelMetrics)  # Cargar la librería correcta
## Warning: package 'ModelMetrics' was built under R version 4.3.3
## 
## Attaching package: 'ModelMetrics'
## The following objects are masked from 'package:Metrics':
## 
##     auc, ce, logLoss, mae, mse, msle, precision, recall, rmse, rmsle
## The following objects are masked from 'package:caret':
## 
##     confusionMatrix, precision, recall, sensitivity, specificity
## The following object is masked from 'package:base':
## 
##     kappa
mae(datos_train$preciom, unlist(predicciones_df))
## [1] 1.133819
#mae(datos_train$preciom, predicciones_df)

La diferencia absoluta promedio entre los valores observados en el conjunto de entrenamiento y los valores predichos en el conjunto de test es de 0.64. En general, cuanto más bajo sea el valor del MAE, mejor podrá un modelo ajustarse a un conjunto de datos.

El RMSE, por otro lado, es una medida de la magnitud promedio de los errores al cuadrado en una predicción.Un RMSE bajo también indica que el modelo está produciendo predicciones precisas como en este caso, pero penaliza más los errores grandes que el MAE.

rmse(as.numeric(datos_train$preciom), as.numeric(unlist(predicciones_df)))
## [1] 1.496899
#rmse(datos_train$preciom, unlist(predicciones_df))
#rmse(datos_train$preciom, predicciones_df)

El MAE es útil cuando los errores tienen una distribución simétrica y penaliza igualmente los errores positivos y negativos. El RMSE es más adecuado cuando los errores tienen una distribución asimétrica y penaliza más los errores grandes.Ambas medidas se pueden utilizar para comparar diferentes modelos o para ajustar los parámetros del modelo para mejorar la precisión de las predicciones.

g1 <- glance(modelo1)
g2 <- glance(modelo2)
g3 <- glance(modelo_train)

kable(rbind(g1, g2, g3), digits = 2) 
r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs
0.72 0.72 0.44 225.77 0 5 -252.73 519.47 548.00 81.41 429 435
0.73 0.72 0.25 164.06 0 7 -2.79 23.58 60.26 25.80 427 435
0.76 0.75 0.24 130.58 0 7 5.57 6.85 40.25 17.04 294 302

Por su parte, el R-cuadrado tiene la propiedad útil de que su escala es intuitiva, va de 0 a 1, con 0 indicando que el modelo propuesto no mejora la predicción sobre el modelo medio y 1 indica una predicción perfecta. La mejora en el modelo de regresión da como resultado aumentos proporcionales en R-cuadrado. Al comparar el modelo 1 (datos sin transformados), modelo 2(variable estrato transformada) y el modelo 3 entrenado con dataset ;al azar con todas las variables introducidas como predictores tienen un R2 alto (0.76-0.77), siendo el modelo 1 el que presenta un R cuadrado menor. Es decir que los 3 modelos explican entre el 77 y 79% de la variabilidad observada en el precio de las casas de la zona Norte de Cali. El p-value de los tres modelos es significativo, por lo que se puede aceptar que el modelo no es por azar, al menos uno de los coeficientes parciales de regresión es distinto de 0. No obstante, los modelos 2 y 3 presentan un mejor comportamiento en los indicadores AIC y BIC. Esto demuestra la importancia de transformar las variables ordinales o categoricas en la contruccion de estos modelos de regresion multiple, para analizarlos como predictores por separado por lo cual el mejor modelo es el tercero.

Conclusiones

En general las variables predictoras seleccionadas en los modelos (areaconst + banios + habitaciones + estrato ) logran explicar el 77-79% del precio de las viviendas de la zona Norte de Cali.

En los modelos generados se identifico que el área construida y el estrato, tienen una alta correlacion con el precio de las casas de la zona norte. Teniendo en cuenta que el numero de habitaciones y baños de la vivienda, dependen o determinan el area construida, se podrian generar modelos obviando estas variables, acorde con el principio de parsimonia de los modelos.

Para mejorar el modelo se pueden incluir otras variables que expliquen de mejor manera el modelo y de esta manera aumentar el R2.

Es importante verificar los outliers, en caso de encontrar para mejorar la medición de los residuos del modelo y por ende, el ajuste del modelo.

Por otro lado, tambien debe revisar las viviendas reportadas con cero habitaciones y baños dado que la información no es concordante.

Tambien se pueden hacer pruebas cruzadas para ajustar mejor la ecuacion y la prediccion del modelo de tal manera que nos permita buscar las variables optimas.

Se hace necesario realizar tratamiento de datos faltantes previamente y generar variables dummy para variables categoricas u ordinales, para la generación de modelos de regresion lineal.