Elaborado por: Juan Carlos Villalba Acevedo

Presentado a: Prof. David Arango Londoño

Informe Ejecutivo

Teniendo en cuenta las dos solicitudes de vivienda requeridas en la ciudad de Cali, se logró seleccionar unas potenciales ofertas que cumplen las necesidades y características requeridas.

La técnica usada para seleccionar estas ofertas se basa en predecir mediante modelación el posible valor que puede tener una vivienda con unas características definidas, con ese valor y teniendo en cuenta el valor del préstamo pre-aprobado para cada uno de los casos se seleccionan un grupo de ofertas interesantes. Para esto se toma como insumo inicial una base de datos que contiene registros de viviendas en toda la ciudad de Cali con la información de sus principales características como tipo de vivienda, área construida, numero de parqueaderos, numero de baños, número de habitaciones, estrato en el que se encuentra, la zona dentro de la ciudad, el nombre del barrio y las coordenadas geográficas de la vivienda.

La primera solicitud está relacionada con una vivienda tipo casa ubicada en la zona norte de la ciudad. A continuación se presentan cinco posibles ofertas que satisfacen las necesidades del cliente:

No id piso estrato preciom areaconst parquea banios habitac barrio
1 464 2 4 330 165.0 1 4 4 el bosque
2 1108 2 4 330 260.0 1 3 4 la merced
3 2544 1 4 340 264.5 2 4 4 vipasa
4 4458 2 4 315 270.0 2 4 4 el bosque
5 4471 2 4 340 162.0 1 4 4 el bosque

Estas ofertas cumplen con las características solicitadas para la vivienda 1, dando prelación al rango del precio que se puede pagar, al estrato y al número de habitaciones. Si bien las variables baños y parqueadero no se usaron en el filtro para seleccionar las ofertas, sus valores cumplen con los requerimientos mínimos, que son 2 baños y 1 parqueadero. En cuanto a la variable área construida, el requerimiento solicitaba que fuera de 200 metros cuadrados, sin embargo, es mucho más difícil encontrar ofertas con esa área exacta y que adicionalmente cumplan con las demás características, que dar un peso mayor a variables como el número de habitaciones y el estrato, que son generalmente características que un comprador no suele negociar en su proceso de selección de vivienda. A pesar de esto, las áreas de construcción de las 5 ofertas son muy cercanas a los 200 metros cuadrados.

La segunda solicitud está relacionada con una vivienda tipo apartamento ubicada en la zona sur de la ciudad. A continuación, se presentan 8 alternativas que se asemejan a las características solicitadas por el cliente:

No id piso estrato preciom areaconst parquea banios habitac barrio
1 3603 1 6 833 213 2 3 3 ciudad jardin
2 3827 2 6 820 213 2 3 3 pance
3 3848 12 6 760 200 2 3 3 ciudad jardin
4 4380 1 6 754 180 2 3 3 ciudad jardin
5 4978 4 6 690 170 2 3 3 ciudad jardin
6 5242 6 5 704 141 2 3 2 ciudad jardin
7 5423 2 6 695 227 3 3 3 ciudad jardin
8 5693 6 6 780 168 2 3 3 ciudad jardin

Teniendo en cuenta que se tiene un rango de precio en el cual se debe encontrar la mejor oferta que cumpla con las caracteristicas de la vivienda 2, se realizo el filtro de apartamentos con precios entre 688 y 850 millones, sin embargo, ninguna de las ofertas que se encuentran en este rango cumplen con la necesidad de 5 habitaciones, por lo cual, fue necesario utilizar la variable baños para reducir la busqueda y encontrar posibles ofertas. Dentro de las 8 ofertas seleccionadas se encuentran apartamentos ubicados en la zona de sur de la ciudad con mas de 2 parqueaderos y en estrato 5 o 6. El número de habitaciones maximo que se pudo obtener con este rango de precios fue de 3 habitaciones. Quizas esta necesidad se sale de contexto, pues de acuerdo a las ofertas es muy dificil encontrar apartamentos en la zona con 5 habitaciones y con un precio entre 688 y 850 millones. El área de construcción de las 8 ofertas es muy variable, desde 141 metros cuadrados hasta 227, tampoco se logro obtener un valor muy cercano a la necesidad de la vivienda 2 que era de 300 metros cuadrados.

Anexo 1 - Plan de trabajo

La metodología a desarrollar para obtener los datos que se solicitan según los dos casos propuestos es:

  1. Definir el problema y las variables: Definir claramente el problema que se va a tratar de resolver y las variables que serán parte del modelo de regresión lineal múltiple. Se debe contar con al menos una variable dependiente (respuesta) y varias variables independientes (predictoras).

  2. Recopilación de datos: Se debe reunir los datos relevantes para las variables que se han identificado.

  3. Limpieza y preparación de datos: Este paso requiere eliminar datos faltantes, eliminar datos atípicos, codificar variables categóricas y escalar variables.

  4. Crear el modelo en R: Por medio de una librería de análisis estadístico y de datos en R, como “lm” se genera un modelo estimado. Se debe asegurar que las variables independientes y dependientes se encuentren en el formato adecuado.

  5. Evaluación del modelo: Utilizar el conjunto de datos de prueba para evaluar el rendimiento del modelo. Se puede utilizar métricas como el error cuadrático medio (RMSE), el coeficiente de determinación (R2) y otras métricas relevantes para evaluar que tan bien se ajusta el modelo a los datos de prueba.

  6. Interpretación de los resultados: Interpretar los coeficientes del modelo para entender como cada variable independiente contribuye a la predicción de la variable dependiente.

  7. Despliegue: Una vez satisfecho con el rendimiento del modelo, se puede usar para hacer predicciones con nuevos datos. Es importante monitoreas y actualizar el modelo según sea necesario.

Anexo 2 - Resultados de la modelación, validación y comparación de modelos

Caso de Vivienda 1

Características Vivienda 1
Tipo Casa
Área construida 200
Parqueaderos 1
Baños 2
Habitaciones 4
Estrato 4 o 5
Zona Norte
Crédito preaprobado 350 millones

Pasos requeridos para la obtención de los resultados:

0. Preparación de los datos:

La estructura inical de la base de datos es:

str(vivienda_0)
## 'data.frame':    8322 obs. of  13 variables:
##  $ id       : int  8312 8311 8307 8296 8297 8298 8299 8300 8286 8287 ...
##  $ zona     : chr  "Zona Oeste" "Zona Oeste" "Zona Oeste" "Zona Sur" ...
##  $ piso     : int  4 1 NA 2 NA NA 2 NA NA 2 ...
##  $ estrato  : int  6 6 5 3 5 5 6 5 5 5 ...
##  $ preciom  : int  1300 480 1200 220 330 1350 305 480 275 285 ...
##  $ areaconst: num  318 300 800 150 112 390 125 280 74 120 ...
##  $ parquea  : int  2 1 4 1 2 8 2 4 1 2 ...
##  $ banios   : int  4 4 7 2 4 10 3 4 2 4 ...
##  $ habitac  : int  2 4 5 4 3 10 3 4 3 3 ...
##  $ tipo     : chr  "Apartamento" "Casa" "Casa" "Casa" ...
##  $ barrio   : chr  "arboleda" "normandía" "miraflores" "el guabal" ...
##  $ longitud : num  -76576 -76571 -76568 -76565 -76565 ...
##  $ latitud  : num  3454 3454 3455 3417 3408 ...

Verificación de datos faltantes:

md.pattern(vivienda_0, rotate.names = TRUE)

##      preciom id zona estrato areaconst banios habitac tipo barrio longitud
## 4808       1  1    1       1         1      1       1    1      1        1
## 1909       1  1    1       1         1      1       1    1      1        1
## 876        1  1    1       1         1      1       1    1      1        1
## 726        1  1    1       1         1      1       1    1      1        1
## 1          1  0    0       0         0      0       0    0      0        0
## 2          0  0    0       0         0      0       0    0      0        0
##            2  3    3       3         3      3       3    3      3        3
##      latitud parquea piso     
## 4808       1       1    1    0
## 1909       1       1    0    1
## 876        1       0    1    1
## 726        1       0    0    2
## 1          0       0    0   12
## 2          0       0    0   13
##            3    1605 2638 4275

Existen datos faltantes, por lo tanto, se eliminan esos registros:

vivienda_1 <- na.omit(vivienda_0)
grafico <-md.pattern(vivienda_1, rotate.names = TRUE)
##  /\     /\
## {  `---'  }
## {  O   O  }
## ==>  V <==  No need for mice. This data set is completely observed.
##  \  \|/  /
##   `-----'

Se toma una muestra aleatorea de los datos y se realiza una exploración general para identificar valores anómalos o problemas en los datos:

tamaño_muestra <- 50
muestra_aleatorea <- sample(nrow(vivienda_1), tamaño_muestra, replace = FALSE)
muestra <- vivienda_1[muestra_aleatorea, ]
muestra
##        id       zona piso estrato preciom areaconst parquea banios habitac
## 4176 2459   Zona Sur    3       5     430     182.0       2      5       5
## 7586 7306   Zona Sur    1       6     450     105.0       2      4       4
## 7865 7626 Zona Oeste    7       4     620     220.0       4      4       2
## 4128 2411 Zona Norte    1       5     250      89.0       1      3       4
## 4942 3641   Zona Sur    2       6    1100     320.0       8      6       4
## 3203 1175 Zona Norte    2       4     370     216.0       2      2       0
## 43   8193   Zona Sur    5       4     310     100.0       2      2       4
## 6429 5767   Zona Sur    6       6     950     287.0       4      5       3
## 7922 7712   Zona Sur    2       3     180      90.0       1      2       3
## 3112 1051   Zona Sur    2       4     432     198.0       2      4       5
## 2397   41   Zona Sur    3       4     225      78.0       1      2       3
## 222  7646 Zona Oeste    5       6    1584     257.0       3      4       3
## 846  5169   Zona Sur    5       5     310      75.0       1      2       3
## 4692 3219 Zona Norte    9       5     300     128.0       2      3       4
## 5652 4701   Zona Sur    3       5     318     112.0       2      3       3
## 1043 4633 Zona Oeste    4       5     275      74.0       1      2       2
## 1348 3552   Zona Sur   11       6     300      94.0       1      2       3
## 7353 6977   Zona Sur    1       3     200     297.0       2      1       3
## 8140 8048 Zona Oeste    5       6     700     151.0       3      5       3
## 5353 4245   Zona Sur    3       6     650     370.0       3      5       4
## 3960 2243   Zona Sur    2       4     450     300.0       3      3       3
## 2884  712 Zona Norte    1       5     350      85.0       1      2       3
## 1966 1472   Zona Sur    8       3     288      85.0       1      2       4
## 7435 7104   Zona Sur    4       3     105      68.0       1      2       3
## 8033 7866   Zona Sur    7       5     260      65.0       1      2       3
## 3693 1913   Zona Sur    5       5     300      90.0       1      3       3
## 5761 4861   Zona Sur    7       6     375     110.0       2      2       3
## 3903 2123   Zona Sur    8       4     198      70.0       1      2       3
## 5175 4067   Zona Sur    2       4     330     180.0       1      3       5
## 7531 7251 Zona Oeste    2       5     430     117.0       2      3       3
## 3154 1099 Zona Norte   10       5     395     120.0       2      3       4
## 2152  791   Zona Sur    5       3     130      58.0       1      1       3
## 7028 6532   Zona Sur    3       5     500     279.5       3      5       4
## 7842 7603 Zona Oeste    2       6     750     180.0       2      4       3
## 1495 3137   Zona Sur    1       4     225      71.0       1      2       3
## 6607 5978   Zona Sur    2       6    1600    1050.0       6      7       6
## 6950 6407 Zona Norte    4       3     124      64.0       1      2       3
## 5382 4274 Zona Norte    2       5    1270     950.0       4      5      10
## 6536 5907   Zona Sur    1       6     735     251.0       2      6       6
## 6314 5600   Zona Sur    7       4     250      79.0       1      2       3
## 7026 6530 Zona Oeste    4       6    1200     290.0       6      4       3
## 5873 5018   Zona Sur   12       5     450     148.0       2      3       4
## 4690 3217   Zona Sur    6       5     370     104.0       2      3       3
## 5484 4418   Zona Sur    5       6     720     170.0       2      5       4
## 5316 4208 Zona Norte    1       4     360     264.5       3      4       6
## 2237  485   Zona Sur    4       5     360     110.0       2      2       3
## 1030 4620 Zona Norte    4       6     940     227.0       2      3       3
## 7908 7698 Zona Oeste    4       6     998     217.0       2      4       3
## 3356 1386   Zona Sur    1       5     190      74.0       1      2       3
## 6826 6234 Zona Oeste    2       6     350     132.0       2      2       3
##             tipo                   barrio     longitud    latitud
## 4176        Casa           valle del lili    -76.52042    3.36689
## 7586 Apartamento            ciudad jardín    -76.54875    3.34001
## 7865 Apartamento               bellavista    -76.55093    3.44762
## 4128 Apartamento                 la flora    -76.52004    3.48797
## 4942        Casa                    pance    -76.52759    3.34644
## 3203        Casa                la merced    -76.51273    3.48214
## 43   Apartamento               el refugio -76557.00000 3397.00000
## 6429 Apartamento            ciudad jardín    -76.53806    3.36239
## 7922        Casa             buenos aires    -76.55151    3.38983
## 3112        Casa         nueva tequendama    -76.50872    3.40818
## 2397 Apartamento           valle del lili    -76.46994    3.42718
## 222  Apartamento               santa rita -76551.00000 3453.00000
## 846  Apartamento               el ingenio -76535.00000 3383.00000
## 4692 Apartamento                 la flora    -76.52477    3.48164
## 5652 Apartamento                pasoancho    -76.53239    3.41863
## 1043 Apartamento                normandía -76532.00000 3452.00000
## 1348 Apartamento            ciudad jardín -76527.00000 3365.00000
## 7353        Casa             buenos aires    -76.54631    3.38990
## 8140 Apartamento                arboledas    -76.55428    3.44780
## 5353        Casa               el ingenio    -76.53026    3.38330
## 3960        Casa                 el caney    -76.51928    3.38607
## 2884 Apartamento                 la flora    -76.50155    3.48434
## 1966 Apartamento                    caney -76516.00000 3382.00000
## 7435 Apartamento                  nápoles    -76.54749    3.39008
## 8033 Apartamento                 zona sur    -76.55259    3.39435
## 3693 Apartamento           valle del lili    -76.51830    3.37093
## 5761 Apartamento               el ingenio    -76.53340    3.38454
## 3903 Apartamento           valle del lili    -76.51889    3.37112
## 5175        Casa               colseguros    -76.52956    3.43242
## 7531 Apartamento             Santa Isabel    -76.54840    3.42969
## 3154 Apartamento               chipichape    -76.51001    3.42086
## 2152 Apartamento       ciudadela comfandi -76503.00000    3.40000
## 7028        Casa         nueva tequendama    -76.54307    3.41330
## 7842 Apartamento           santa teresita    -76.55078    3.45160
## 1495 Apartamento           valle del lili -76524.00000 3379.00000
## 6607        Casa            ciudad jardín    -76.53999    3.35878
## 6950 Apartamento               manzanares    -76.54242    3.43445
## 5382        Casa             santa monica    -76.53053    3.47468
## 6536        Casa            ciudad jardín    -76.53931    3.36558
## 6314 Apartamento           valle del lili    -76.53749    3.41267
## 7026 Apartamento                normandía    -76.54304    3.45191
## 5873 Apartamento           quintas de don    -76.53459    3.39174
## 4690 Apartamento               el ingenio    -76.52474    3.43936
## 5484 Apartamento      parcelaciones pance    -76.53134    3.33781
## 5316        Casa                   vipasa    -76.53008    3.45691
## 2237 Apartamento              camino real -76497.00000 3463.00000
## 1030 Apartamento santa mónica residencial -76532.00000 3452.00000
## 7908 Apartamento                arboledas    -76.55136    3.44651
## 3356 Apartamento           valle del lili    -76.51581    3.36943
## 6826 Apartamento                 el peñon    -76.54158    3.44981

También, se generan estadisticas descriptivas de cada una de las variables:

summary(vivienda_1)
##        id           zona                piso           estrato     
##  Min.   :   1   Length:4808        Min.   : 1.000   Min.   :3.000  
##  1st Qu.:2479   Class :character   1st Qu.: 2.000   1st Qu.:4.000  
##  Median :4474   Mode  :character   Median : 3.000   Median :5.000  
##  Mean   :4427                      Mean   : 3.886   Mean   :4.838  
##  3rd Qu.:6413                      3rd Qu.: 5.000   3rd Qu.:6.000  
##  Max.   :8316                      Max.   :12.000   Max.   :6.000  
##     preciom         areaconst         parquea           banios      
##  Min.   :  58.0   Min.   :  40.0   Min.   : 1.000   Min.   : 0.000  
##  1st Qu.: 244.5   1st Qu.:  85.0   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 350.0   Median : 123.0   Median : 2.000   Median : 3.000  
##  Mean   : 457.2   Mean   : 174.8   Mean   : 1.815   Mean   : 3.219  
##  3rd Qu.: 560.0   3rd Qu.: 225.0   3rd Qu.: 2.000   3rd Qu.: 4.000  
##  Max.   :1999.0   Max.   :1500.0   Max.   :10.000   Max.   :10.000  
##     habitac           tipo              barrio             longitud        
##  Min.   : 0.000   Length:4808        Length:4808        Min.   :-76576.00  
##  1st Qu.: 3.000   Class :character   Class :character   1st Qu.:   -76.55  
##  Median : 3.000   Mode  :character   Mode  :character   Median :   -76.54  
##  Mean   : 3.564                                         Mean   :-16216.63  
##  3rd Qu.: 4.000                                         3rd Qu.:   -76.52  
##  Max.   :10.000                                         Max.   :   -76.46  
##     latitud        
##  Min.   :   3.333  
##  1st Qu.:   3.383  
##  Median :   3.433  
##  Mean   : 725.008  
##  3rd Qu.:   3.487  
##  Max.   :3493.000

De la muestra seleccionada y del resumen de las variables se evidencia que la columna Tipo no esta estandarizada y que las columnas Longitud y Latitud almacenan datos que no son acordes a las coordenadas geográficas.

Por lo anterior, se procede a verificar los valores únicos de la variable Tipo:

unique(vivienda_1$tipo)
## [1] "Apartamento" "Casa"        "APARTAMENTO" "apto"        "casa"       
## [6] "CASA"

Se estandariza la variable Tipo:

vivienda_1$tipo[vivienda_1$tipo == "APARTAMENTO"] <- "Apartamento"
vivienda_1$tipo[vivienda_1$tipo == "apto"] <- "Apartamento"
vivienda_1$tipo[vivienda_1$tipo == "casa"] <- "Casa"
vivienda_1$tipo[vivienda_1$tipo == "CASA"] <- "Casa"
unique(vivienda_1$tipo)
## [1] "Apartamento" "Casa"

Ahora, se observan los datos almacenados en la columna latitud:

sample(vivienda_1$latitud,100)
##   [1]    3.44386    3.36970    3.38729 3414.00000    3.39198 3477.00000
##   [7]    3.42863 3398.00000    3.38122 3356.00000    3.39519 3413.00000
##  [13]    3.44918    3.39580    3.34118    3.42484    3.36991    3.44987
##  [19]    3.38015    3.37218    3.46684    3.44697    3.39693    3.44176
##  [25]    3.35736    3.45379    3.39629 3369.00000    3.37533    3.34698
##  [31]    3.45101    3.36759    3.38597    3.46853    3.41280 3451.00000
##  [37]    3.45516    3.36794    3.45112    3.34464    3.43820    3.39536
##  [43]    3.44987 3385.00000 3453.00000 3475.00000    3.44720    3.49196
##  [49] 3443.00000    3.35000    3.34364    3.42839    3.37112    3.45693
##  [55]    3.44987    3.37308    3.36590 3381.00000    3.36533 3487.00000
##  [61]    3.41550    3.45425    3.45340    3.38007    3.44311    3.45160
##  [67]    3.37724    3.40080    3.45000    3.40784    3.48091    3.44226
##  [73]    3.37112    3.48618 3371.00000    3.40516    3.48181 3452.00000
##  [79]    3.49380 3397.00000    3.41526    3.44563    3.39515    3.37063
##  [85]    3.38731    3.34721    3.35886    3.38205    3.39091    3.47672
##  [91]    3.43426 3367.00000 3452.00000    3.49419    3.41828 3431.00000
##  [97] 3393.00000    3.44987    3.48168    3.39182

Se observan los datos almacenados en la columna longitud:

sample(vivienda_1$longitud,100)
##   [1] -76505.00000    -76.50849 -76538.00000    -76.53188    -76.55078
##   [6]    -76.52786    -76.53239 -76524.00000    -76.54973    -76.54087
##  [11]    -76.54684    -76.51889    -76.52263    -76.53939    -76.55589
##  [16]    -76.51608 -76518.00000    -76.55110    -76.52072    -76.55000
##  [21]    -76.53823    -76.53281    -76.55156    -76.52713    -76.54973
##  [26]    -76.53677    -76.54196    -76.51191    -76.51794 -76533.00000
##  [31] -76499.00000    -76.54059    -76.51566    -76.52219    -76.51514
##  [36]    -76.52596    -76.51723    -76.50931    -76.52846    -76.52233
##  [41]    -76.51590    -76.51761    -76.57941 -76523.00000 -76532.00000
##  [46]    -76.49583    -76.53580    -76.54094    -76.52029 -76536.00000
##  [51]    -76.54173    -76.53454 -76517.00000    -76.52721    -76.54307
##  [56]    -76.51892    -76.54999 -76531.00000    -76.52872    -76.54087
##  [61]    -76.53179    -76.51437    -76.51889    -76.51714    -76.53838
##  [66]    -76.54852    -76.54973    -76.50826    -76.54825    -76.54033
##  [71]    -76.52097    -76.52344 -76526.00000 -76523.00000 -76553.00000
##  [76]    -76.50667 -76562.00000    -76.51602    -76.51874    -76.55210
##  [81]    -76.55059 -76554.00000    -76.54808 -76547.00000 -76503.00000
##  [86]    -76.52983    -76.52629    -76.53000    -76.49016    -76.54417
##  [91] -76526.00000    -76.52967 -76557.00000 -76553.00000    -76.52061
##  [96]    -76.54241    -76.55152    -76.53071    -76.53089    -76.55119

En ambas columnas (latitud y longitud) hay presencia de datos que no cumplen con las características que deben tener las coordenadas geográficas (longitud [-180,180] y latitud [-90,90]), esto hecho, genera la ubicación errónea de algunos registros. Para corregir este problema se procede a dividir por 1000 aquellos valores anómalos:

vivienda_1$latitud[vivienda_1$latitud > 90] <- vivienda_1$latitud[vivienda_1$latitud > 90] / 1000

vivienda_1$longitud[vivienda_1$longitud < -180] <- vivienda_1$longitud[vivienda_1$longitud < -180] / 1000

Se procede a verificar nuevamente la columna latitud:

sample(vivienda_1$latitud,100)
##   [1] 3.38330 3.44780 3.37017 3.42638 3.43619 3.36780 3.38200 3.37724 3.49090
##  [10] 3.45138 3.47363 3.43402 3.40320 3.37274 3.45160 3.42959 3.39253 3.35730
##  [19] 3.37200 3.38453 3.39800 3.37857 3.45777 3.38212 3.39291 3.37154 3.48088
##  [28] 3.42600 3.38340 3.44751 3.45200 3.35600 3.39327 3.35900 3.40812 3.41300
##  [37] 3.49240 3.36400 3.37112 3.48659 3.47504 3.46200 3.36920 3.37045 3.44987
##  [46] 3.39409 3.38596 3.37112 3.47668 3.48157 3.35961 3.44761 3.42972 3.44000
##  [55] 3.36882 3.49132 3.42500 3.38006 3.46516 3.38453 3.43700 3.45200 3.41207
##  [64] 3.43730 3.49062 3.38940 3.45149 3.43936 3.44100 3.42125 3.37112 3.33832
##  [73] 3.36600 3.46700 3.38296 3.46106 3.39922 3.37100 3.46200 3.47700 3.38078
##  [82] 3.43091 3.41471 3.40004 3.44731 3.39600 3.47100 3.48995 3.45178 3.43899
##  [91] 3.43267 3.37900 3.39900 3.38675 3.46500 3.42484 3.36297 3.40000 3.36679
## [100] 3.36786

…y la columna longitud:

sample(vivienda_1$longitud,100)
##   [1] -76.52846 -76.54015 -76.51573 -76.54335 -76.55492 -76.53617 -76.53808
##   [8] -76.54943 -76.52713 -76.55229 -76.53514 -76.54778 -76.53716 -76.53600
##  [15] -76.54100 -76.53825 -76.55400 -76.55471 -76.52490 -76.54691 -76.53200
##  [22] -76.51785 -76.53600 -76.54067 -76.55888 -76.52355 -76.54595 -76.47209
##  [29] -76.53075 -76.53011 -76.54400 -76.51856 -76.50500 -76.54948 -76.55222
##  [36] -76.51899 -76.53378 -76.53969 -76.49971 -76.51889 -76.53285 -76.54847
##  [43] -76.52900 -76.53071 -76.51889 -76.49473 -76.53522 -76.52219 -76.53345
##  [50] -76.54370 -76.52200 -76.51771 -76.52800 -76.48840 -76.51138 -76.52012
##  [57] -76.54355 -76.51700 -76.51854 -76.53400 -76.54417 -76.51700 -76.53100
##  [64] -76.52793 -76.54978 -76.51857 -76.54200 -76.52353 -76.51978 -76.52338
##  [71] -76.54945 -76.52857 -76.53470 -76.52000 -76.52280 -76.51643 -76.52940
##  [78] -76.52733 -76.52879 -76.51759 -76.53004 -76.53621 -76.53198 -76.53436
##  [85] -76.50110 -76.51892 -76.51889 -76.53121 -76.51957 -76.52549 -76.53857
##  [92] -76.47112 -76.54312 -76.53522 -76.55102 -76.51000 -76.54292 -76.53798
##  [99] -76.51540 -76.53464

Se observa que los datos de las columnas latitud y longitud ahora se encuentra estandarizados.

La nueva estructura de la base de datos es:

str(vivienda_1)
## 'data.frame':    4808 obs. of  13 variables:
##  $ id       : int  8312 8311 8296 8299 8287 8288 8282 8274 8275 8277 ...
##  $ zona     : chr  "Zona Oeste" "Zona Oeste" "Zona Sur" "Zona Sur" ...
##  $ piso     : int  4 1 2 2 2 1 6 2 8 6 ...
##  $ estrato  : int  6 6 3 6 5 5 6 5 6 6 ...
##  $ preciom  : int  1300 480 220 305 285 310 640 416 700 700 ...
##  $ areaconst: num  318 300 150 125 120 166 157 98 123 240 ...
##  $ parquea  : int  2 1 1 2 2 2 2 1 2 2 ...
##  $ banios   : int  4 4 2 3 4 4 3 2 3 5 ...
##  $ habitac  : int  2 4 4 3 3 3 3 2 4 4 ...
##  $ tipo     : chr  "Apartamento" "Casa" "Casa" "Apartamento" ...
##  $ barrio   : chr  "arboleda" "normandía" "el guabal" "bella suiza" ...
##  $ longitud : num  -76.6 -76.6 -76.6 -76.6 -76.6 ...
##  $ latitud  : num  3.45 3.45 3.42 3.41 3.41 ...
##  - attr(*, "na.action")= 'omit' Named int [1:3514] 3 5 6 8 9 12 14 17 19 20 ...
##   ..- attr(*, "names")= chr [1:3514] "3" "5" "6" "8" ...

Y las nuevas estadísticas descriptivas básicas de las variables son:

summary(vivienda_1)
##        id           zona                piso           estrato     
##  Min.   :   1   Length:4808        Min.   : 1.000   Min.   :3.000  
##  1st Qu.:2479   Class :character   1st Qu.: 2.000   1st Qu.:4.000  
##  Median :4474   Mode  :character   Median : 3.000   Median :5.000  
##  Mean   :4427                      Mean   : 3.886   Mean   :4.838  
##  3rd Qu.:6413                      3rd Qu.: 5.000   3rd Qu.:6.000  
##  Max.   :8316                      Max.   :12.000   Max.   :6.000  
##     preciom         areaconst         parquea           banios      
##  Min.   :  58.0   Min.   :  40.0   Min.   : 1.000   Min.   : 0.000  
##  1st Qu.: 244.5   1st Qu.:  85.0   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 350.0   Median : 123.0   Median : 2.000   Median : 3.000  
##  Mean   : 457.2   Mean   : 174.8   Mean   : 1.815   Mean   : 3.219  
##  3rd Qu.: 560.0   3rd Qu.: 225.0   3rd Qu.: 2.000   3rd Qu.: 4.000  
##  Max.   :1999.0   Max.   :1500.0   Max.   :10.000   Max.   :10.000  
##     habitac           tipo              barrio             longitud     
##  Min.   : 0.000   Length:4808        Length:4808        Min.   :-76.59  
##  1st Qu.: 3.000   Class :character   Class :character   1st Qu.:-76.54  
##  Median : 3.000   Mode  :character   Mode  :character   Median :-76.53  
##  Mean   : 3.564                                         Mean   :-76.53  
##  3rd Qu.: 4.000                                         3rd Qu.:-76.52  
##  Max.   :10.000                                         Max.   :-76.46  
##     latitud     
##  Min.   :3.333  
##  1st Qu.:3.378  
##  Median :3.408  
##  Mean   :3.414  
##  3rd Qu.:3.451  
##  Max.   :3.498

1. Filtro a la base de datos:

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. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).

Desarrollo:

Se filtra los datos para obtener solamente los registros que corresponden a Casas ubicadas en la Zona Norte de la ciudad:

base_1 <- vivienda_1 %>% filter(tipo == "Casa" & zona == "Zona Norte" )
head(base_1,3)
##     id       zona piso estrato preciom areaconst parquea banios habitac tipo
## 1 6812 Zona Norte    7       4     670       470       4      5       5 Casa
## 2 6338 Zona Norte    3       4     540       306       3      4       4 Casa
## 3 6340 Zona Norte    2       4     530       400       4      3       3 Casa
##           barrio longitud latitud
## 1 tejares de san  -76.545   3.440
## 2     la campiña  -76.542   3.422
## 3      el bosque  -76.542   3.411

La estructura de la nueva base de datos filtrada es:

str(base_1)
## 'data.frame':    254 obs. of  13 variables:
##  $ id       : int  6812 6338 6340 5710 5152 4920 4778 4800 4544 4548 ...
##  $ zona     : chr  "Zona Norte" "Zona Norte" "Zona Norte" "Zona Norte" ...
##  $ piso     : int  7 3 2 2 2 2 4 1 2 2 ...
##  $ estrato  : int  4 4 4 5 5 5 6 5 5 5 ...
##  $ preciom  : int  670 540 530 1530 600 800 690 340 570 850 ...
##  $ areaconst: num  470 306 400 776 220 800 225 250 412 296 ...
##  $ parquea  : int  4 3 4 6 2 3 2 2 1 4 ...
##  $ banios   : int  5 4 3 6 4 7 5 4 3 2 ...
##  $ habitac  : int  5 4 3 10 4 7 3 4 5 4 ...
##  $ tipo     : chr  "Casa" "Casa" "Casa" "Casa" ...
##  $ barrio   : chr  "tejares de san" "la campiña" "el bosque" "san vicente" ...
##  $ longitud : num  -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud  : num  3.44 3.42 3.41 3.45 3.46 ...
##  - attr(*, "na.action")= 'omit' Named int [1:3514] 3 5 6 8 9 12 14 17 19 20 ...
##   ..- attr(*, "names")= chr [1:3514] "3" "5" "6" "8" ...

El mapa con la ubicación geográfica de las 254 casas localizadas en la zona norte de la ciudad es el siguiente:

mapa <- leaflet(base_1) %>%
  setView(lng = -76.5320, lat = 3.4516, zoom = 12) %>%
  addTiles()  # Añadir capas base (mapa base)

for (i in 1:nrow(base_1)) {
  mapa <- mapa %>%
    addMarkers(lng = base_1$longitud[i], lat = base_1$latitud[i], popup = base_1$id[i])
}

mapa

La gran mayoría de las casas se encuentran localizadas en la zona norte de la ciudad de Cali, sin embargo, unas pocas se encuentran ubicadas en la zona sur de la ciudad. Es necesario eliminar esos registros que estan mal etiquetados con la zona norte para que no alteren el análisis de los datos.

Para lo anterior, se procede a filtrar solamente las casas que se encuentren ubicadas a una latitud mayor a 3.44°:

base_1 <- base_1 %>% filter(latitud > 3.44)

Se genera nuevamente el mapa para visualizar el cambio realizado:

mapa <- leaflet(base_1) %>%
  setView(lng = -76.5320, lat = 3.4516, zoom = 12) %>%
  addTiles()  # Añadir capas base (mapa base)

for (i in 1:nrow(base_1)) {
  mapa <- mapa %>%
    addMarkers(lng = base_1$longitud[i], lat = base_1$latitud[i], popup = base_1$id[i])
}

mapa

Se observa en el mapa que solo se visualizan las casas que se encuentran localizadas en la zona norte de la ciudad de Cali.

2. Análisis de Correlación:

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 interactivos con el paquete plotly e interprete los resultados.

Desarrollo:

Se realiza el filtro de los datos de acuerdo al enunciado:

base_1_sel <- select(base_1, preciom, areaconst, estrato, banios, habitac, zona)
head(base_1_sel,3)
##   preciom areaconst estrato banios habitac       zona
## 1    1530       776       5      6      10 Zona Norte
## 2     600       220       5      4       4 Zona Norte
## 3     800       800       5      7       7 Zona Norte

Se calcula la variable dicotómica a partir de la variable zona:

base_1_sel$D1=as.numeric(base_1_sel$zona=="Zona Norte")
head(base_1_sel,3)
##   preciom areaconst estrato banios habitac       zona D1
## 1    1530       776       5      6      10 Zona Norte  1
## 2     600       220       5      4       4 Zona Norte  1
## 3     800       800       5      7       7 Zona Norte  1

Se elimina la variable categorica zona:

base_1_sel <- select(base_1_sel, -zona)
head(base_1_sel,3)
##   preciom areaconst estrato banios habitac D1
## 1    1530       776       5      6      10  1
## 2     600       220       5      4       4  1
## 3     800       800       5      7       7  1

Se crea una matriz de gráficos para explorar el grado de las relaciones entre las variables numéricas:

ggpairs(base_1_sel[,1:6], title=" ")
## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

Se puede observar que la mayor relación de la variable y(preciom) con alguna de las variables independientes es con areaconst, con signo positivo lo que indica que las casas con áreas de construcción grandes tienen un precio mas alto. Caso similiar ocurre con la variable estrato, entre mas alto sea el estrato, mayor será el precio de la casa.

Es importante anotar que no existen fuertes correlaciones entre las variables independientes, el caso mas significativo es entre las variables banios y habitac, en el momento de la estimación del modelo se podra evaluar si su correlación afecta el resultado del modelo.

La variable dicotómica D1, calculada a partir de la variable zona, no aporta información para su análisis debido a que todos los registros filtrados para esta caso de estudio estan ubicados en la zona norte de la ciudad, por lo tanto, el uso de esta variable en una estimación de un modelo seria inecesaria.

3. Estimación de Modelo de Regresión Lineal Múltiple:

Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, numero de cuartos, numero de parqueaderos, numero 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).

Desarrollo:

Se realiza el filtro de los datos de acuerdo al enunciado:

base_1_sel <- select(base_1, preciom, areaconst, estrato, banios, habitac, parquea)
head(base_1_sel,3)
##   preciom areaconst estrato banios habitac parquea
## 1    1530       776       5      6      10       6
## 2     600       220       5      4       4       2
## 3     800       800       5      7       7       3

Estimación del modelo por el método de mínimos cuadrados ordinarios:

modelo_1 <- lm(preciom ~ areaconst+estrato+banios+habitac+parquea, data = base_1_sel)
summary(modelo_1)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitac + 
##     parquea, data = base_1_sel)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -751.10  -78.12  -15.79   48.75  929.26 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -233.62003   62.73717  -3.724 0.000247 ***
## areaconst      0.66080    0.06929   9.536  < 2e-16 ***
## estrato       82.62239   13.78418   5.994 7.89e-09 ***
## banios        12.49720   10.65345   1.173 0.241988    
## habitac        7.57391    7.49592   1.010 0.313368    
## parquea       29.57180    7.01310   4.217 3.57e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 153.5 on 229 degrees of freedom
## Multiple R-squared:  0.6019, Adjusted R-squared:  0.5932 
## F-statistic: 69.25 on 5 and 229 DF,  p-value: < 2.2e-16

En primera instancia, los coeficientes arrojados por el modelo tienen signo positivo, lo que implica que hay una relación positiva entre las variables predictoras y la variable de respuesta. Esto se traduce en que en la medida que las variables predictoras areaconst, estrato, banios, habitac y parquea aumenten, la variable respuesta preciom también aumentara. Esto sin duda tiene coherencia con la realidad del negocio inmobiliario.

En cuanto a la magnitud de los coeficientes, se observa que el coeficiente de la variable estrato tiene el más alto valor, esto indica que un cambio de la variable estrato manteniendo constante las otras variables predictoras impacta en gran medida el valor de la variable de respuesta preciom. Por el contrario, el coeficiente con magnitud mas baja es el de la variable areaconst, esto se traduce en que un cambio unitario de esta variable manteniendo constante las demas variables predictoras genera un cambio más moderado en el valor del precio de una casa.

Para evaluar si los coeficientes son estadisticamente significativos se evalua el valor p de cada uno de ellos. Si el valor p es menor que el límite de significancia (0.05), se puede concluir que el coeficiente es estadísticamente significativo, es decir, que hay evidencia suficiente para considerar que el coeficiente es diferente de cero. Para el caso del modelo estimado, los coeficientes que presentan un valor p menor al límite de significancia son los coeficientes de las variables areaconst, estrato y parquea, lo cual quiere decir que estos tres coeficientes son estadísticamente significativos. De acuerdo el valor p de los coeficientes de las variables predictoras banios y habitac, estos dos coeficientes no tienen un impacto real y medible en la variable respuesta preciom, por lo tanto no son estadísticamente significativos.

Para evaluar el ajuste del modelo a los datos se analiza el valor de R2. Un valor de R2 cercano a 1 sugiere que el modelo se ajusta bien a los datos, mientras que, un valor de R2 cercano a 0 indica que el modelo no es capaz de explicar suficiente variabilidad en la variable de respuesta. Para el caso de estudio, el valor de R2 sugiere que el modelo presenta un ajuste moderado a los datos. Quizas, si se estima nuevamente el modelo sin las variables predictoras banios y habitac, las cuales no son estadísticamente significativas, se obtenga un modelo mucho mas ajustado a los datos y con un valor de R2 mas cercano a 1.

4. Validación de Supuestos:

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

Desarrollo:

Varianza constante (Homocedasticidad) y Linealidad

Para evaluar este supuesto se utiliza una gráfica con los valores residuales vs los ajustados del modelo estimado:

plot(modelo_1, which = 1)

De acuerdo a lo observado en la gráfica se puede decir que el supuesto de homocedasticidad se cumple ya que los puntos estan dispersos de manera uniforme alrededor de cero a lo largo de todos los valores ajustados. Adicionalmente, los puntos en la gráfica no muestran un patrón discernible, esto sugiere que la relación entre las variables es lineal.

Para comprobar lo anterior, se puede acudir a la prueba de Goldfeld-Quandt:

gqtest(modelo_1)
## 
##  Goldfeld-Quandt test
## 
## data:  modelo_1
## GQ = 1.8943, df1 = 112, df2 = 111, p-value = 0.0004256
## alternative hypothesis: variance increases from segment 1 to 2

Como el valor p es menor a límite de significancia (0.05), se puede concluir que no hay evidencia suficiente para rechazar la hipótesis de homocedasticidad, es decir, los residuales tienen varianza constante.

Normalidad

Para evaluar este supuesto se acude a la prueba Shapiro Wilk sobre los residuales del modelo estimado:

shapiro.test(modelo_1$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo_1$residuals
## W = 0.86281, p-value = 1.159e-13

Como el valor p es menor que el límite de significancia (0.05), se puede considerar que hay evidencia en contra de la normalidad de los residuos, por lo tanto, el modelo estimado no cumpliria con el supuesto de normalidad.

Para evaluar gráficamente si los residuales siguen una distribución normal se acude al gráfico normal Q-Q:

plot(modelo_1, which = 2)

En la gráfica se puede observar que los puntos de los extremos se alejan de la línea diagonal, esto indica presencia de colas en la distribución de los residuales, lo que confirma la no normalidad de los residuales.

Para corregir o mejorar esta situación, se puede considerar aplicar transformaciones matemáticas a las variables predictoras, utilizar modelos alternativos no lineales o modelos de regresión robusta o agregar otras variables predictoras que puedan aportar al modelo estimado.

Independencia

Para evaluar la presencia de autocorrelación en los residuos del modelo estimado se utiliza la prueba de Durbin-Watson:

dwtest(modelo_1)
## 
##  Durbin-Watson test
## 
## data:  modelo_1
## DW = 2.0132, p-value = 0.5188
## alternative hypothesis: true autocorrelation is greater than 0

Para analizar el resultado de esta prueba es necesario tener en cuenta que si el valor es cercano a 2, no hay evidencia sustancial de autocorrelación en los residuos. En este caso, el valor p es menor que 2, esto podría indicar autocorrrelación positiva en los residuos, por lo tanto, no estaria cumpliendo el modelo estimado con el supuesto de independencia de los residuos.

Para mitigar este problema se podria considerar agregar nuevas variables en el modelo, eliminar variables irrelevantes, en este caso, se podria probar eliminando las variables banos y habitac las cuales no son estadísticamente significantes. Otra opción seria utilizar matrices de vecinos o de distancia para introducir autocorrelación espacial en el modelo, esto teniendo en cuenta que se tienen variables de tipo espacial como la latitud y la longitud.

5. Predicción:

Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

Desarrollo:

Con base en las carácteristicas definidas para el primer caso se procede a predecir el precio de la vivienda:

caso_1 <- data.frame(areaconst = 200, estrato = 4, banios = 2, habitac = 4, parquea = 1)

predicciones <- predict(modelo_1, newdata = caso_1)

print(predicciones)
##        1 
## 313.8914

El precio estimado para una casa en la zona norte de la ciudad de Cali, con área de 200 metros cuadrados, estrato 4, 2 baños, 4 habitaciones y 1 parqueadero, es de 313.9 millones.

6. Predicción:

Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

Desarrollo:

Teniendo en cuenta el precio estimado por el modelo para la vivienda del caso número uno y el tope máximo del credito pre-aprobado se seleccionaron las siguientes ofertas potenciales:

ofertas_1 <- base_1 %>% filter(preciom >= 314 & preciom < 350 & habitac == 4 & estrato == 4)

ofertas_1
##     id       zona piso estrato preciom areaconst parquea banios habitac tipo
## 1  464 Zona Norte    2       4     330     165.0       1      4       4 Casa
## 2 1108 Zona Norte    2       4     330     260.0       1      3       4 Casa
## 3 2544 Zona Norte    1       4     340     264.5       2      4       4 Casa
## 4 4458 Zona Norte    2       4     315     270.0       2      4       4 Casa
## 5 4471 Zona Norte    2       4     340     162.0       1      4       4 Casa
##      barrio  longitud latitud
## 1 el bosque -76.49657 3.45140
## 2 la merced -76.51060 3.48108
## 3    vipasa -76.52096 3.47665
## 4 el bosque -76.53176 3.48780
## 5 el bosque -76.53188 3.48770

Cabe resaltar, que estas ofertas cumplen con las caracteristicas solicitadas para la vivienda 1, dando prelación al rango del precio que se puede pagar, al estrato y al número de habitaciones. Si bien las variables baños y parqueadero no se usaron en el filtro para seleccionar las ofertas, sus valores cumplen con los requerimientos mínimos, que son 2 baños y 1 parqueadero. En cuanto a la variable área construida, el requerimiento solicitaba que fuera de 200 metros cuadrados, sin embargo, es mucho mas dificil encontrar ofertas con esa área exacta y que adicionalmente cumplan con las demas caracteristicas, que dar un peso mayor a variables como el número de habitaciones y el estrato, que son generalmente caracteristicas que un comprador no suele negociar en su proceso de selección de vivienda. A pesar de esto, las áreas de construcción de las 5 ofertas son muy cercanas a los 200 metros cuadrados.

mapa <- leaflet(ofertas_1) %>%
  setView(lng = -76.5320, lat = 3.4516, zoom = 12) %>%
  addTiles()  # Añadir capas base (mapa base)

for (i in 1:nrow(ofertas_1)) {
  mapa <- mapa %>%
    addMarkers(lng = ofertas_1$longitud[i], lat = ofertas_1$latitud[i], popup = ofertas_1$id[i])
}

mapa

En el mapa anterior, se puede ver la ubicación geográfica de las 5 ofertas potenciales.

Caso de Vivienda 2

Características Vivienda 2
Tipo Apartamento
Área construida 300
Parqueaderos 3
Baños 3
Habitaciones 5
Estrato 5 o 6
Zona Sur
Crédito preaprobado 850 millones

Pasos requeridos para la obtención de los resultados:

Para el desarrollo del segundo caso se inicia con la base de datos que no tiene registros vacios y tiene estandarizadas las columnas Tipo, Longitud y Latitud.

1. Filtro a la base de datos:

Realice un filtro a la base de datos e incluya solo las ofertas de: base_2: apartamento, de la zona sur de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).

Desarrollo:

Se filtra los datos para obtener solamente los registros que corresponden a los Apartamentos ubicados en la Zona Sur de la ciudad:

base_2 <- vivienda_1 %>% filter(tipo == "Apartamento" & zona == "Zona Sur" )
head(base_2,3)
##     id     zona piso estrato preciom areaconst parquea banios habitac
## 1 8299 Zona Sur    2       6     305       125       2      3       3
## 2 8287 Zona Sur    2       5     285       120       2      4       3
## 3 8288 Zona Sur    1       5     310       166       2      4       3
##          tipo      barrio longitud latitud
## 1 Apartamento bella suiza  -76.565   3.408
## 2 Apartamento bella suiza  -76.564   3.410
## 3 Apartamento bella suiza  -76.564   3.410

La estructura de la nueva base de datos filtrada es:

str(base_2)
## 'data.frame':    1860 obs. of  13 variables:
##  $ id       : int  8299 8287 8288 8228 8229 8192 8193 8164 8089 8090 ...
##  $ zona     : chr  "Zona Sur" "Zona Sur" "Zona Sur" "Zona Sur" ...
##  $ piso     : int  2 2 1 1 8 5 5 2 2 7 ...
##  $ estrato  : int  6 5 5 3 4 4 4 3 4 4 ...
##  $ preciom  : int  305 285 310 145 240 225 310 115 225 225 ...
##  $ areaconst: num  125 120 166 60 90 74 100 58 85 72 ...
##  $ parquea  : int  2 2 2 1 1 1 2 1 1 1 ...
##  $ banios   : int  3 4 4 2 2 2 2 1 2 2 ...
##  $ habitac  : int  3 3 3 3 3 3 4 3 3 3 ...
##  $ tipo     : chr  "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
##  $ barrio   : chr  "bella suiza" "bella suiza" "bella suiza" "meléndez" ...
##  $ longitud : num  -76.6 -76.6 -76.6 -76.6 -76.6 ...
##  $ latitud  : num  3.41 3.41 3.41 3.39 3.42 ...
##  - attr(*, "na.action")= 'omit' Named int [1:3514] 3 5 6 8 9 12 14 17 19 20 ...
##   ..- attr(*, "names")= chr [1:3514] "3" "5" "6" "8" ...

El mapa con la ubicación geográfica de los 1860 apartamentos localizados en la zona sur de la ciudad es el siguiente:

mapa_2 <- leaflet(base_2) %>%
  setView(lng = -76.5320, lat = 3.40, zoom = 12) %>%
  addTiles()  # Añadir capas base (mapa base)

for (i in 1:nrow(base_2)) {
  mapa_2 <- mapa_2 %>%
    addMarkers(lng = base_2$longitud[i], lat = base_2$latitud[i], popup = base_2$id[i])
}

mapa_2

Se observa en el mapa que no todas las observaciones se encuentran localizadas en la zona sur de la ciudad, por lo tanto, se requiere eliminar los registros que estan mal etiquetados con la zona sur para que no alteren el análisis de los datos.

Para lo anterior, se procede a filtrar solamente los apartamentos que se encuentren ubicados a una latitud menor a 3.40°:

base_2 <- base_2 %>% filter(latitud < 3.40)
str(base_2)
## 'data.frame':    1324 obs. of  13 variables:
##  $ id       : int  8228 8192 8193 7925 7942 7946 7649 7652 7346 7349 ...
##  $ zona     : chr  "Zona Sur" "Zona Sur" "Zona Sur" "Zona Sur" ...
##  $ piso     : int  1 5 5 3 1 10 4 8 9 1 ...
##  $ estrato  : int  3 4 4 4 4 3 4 4 6 3 ...
##  $ preciom  : int  145 225 310 220 175 230 210 495 1350 165 ...
##  $ areaconst: num  60 74 100 113 75 63 69 237 212 65 ...
##  $ parquea  : int  1 1 2 1 1 1 2 2 3 1 ...
##  $ banios   : int  2 2 2 2 2 2 2 4 5 2 ...
##  $ habitac  : int  3 3 4 3 3 2 3 3 3 3 ...
##  $ tipo     : chr  "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
##  $ barrio   : chr  "meléndez" "el refugio" "el refugio" "el refugio" ...
##  $ longitud : num  -76.6 -76.6 -76.6 -76.6 -76.6 ...
##  $ latitud  : num  3.39 3.4 3.4 3.4 3.39 ...
##  - attr(*, "na.action")= 'omit' Named int [1:3514] 3 5 6 8 9 12 14 17 19 20 ...
##   ..- attr(*, "names")= chr [1:3514] "3" "5" "6" "8" ...

Como resultado del filtro, se redujo el número de observaciones a 1324 apartamentos.

Se genera nuevamente el mapa para ver gráficamente el resultado:

mapa_2 <- leaflet(base_2) %>%
  setView(lng = -76.5320, lat = 3.40, zoom = 12) %>%
  addTiles()  # Añadir capas base (mapa base)

for (i in 1:nrow(base_2)) {
  mapa_2 <- mapa_2 %>%
    addMarkers(lng = base_2$longitud[i], lat = base_2$latitud[i], popup = base_2$id[i])
}

mapa_2

Se observa en el mapa los registros correspondientes a los apartamentos que se encuentran localizados en la zona sur de la ciudad de Cali.

2. Análisis de Correlación:

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 interactivos con el paquete plotly e interprete los resultados.

Desarrollo:

Se realiza el filtro de los datos de acuerdo al enunciado:

base_2_sel <- select(base_2, preciom, areaconst, estrato, banios, habitac, zona)
head(base_2_sel,3)
##   preciom areaconst estrato banios habitac     zona
## 1     145        60       3      2       3 Zona Sur
## 2     225        74       4      2       3 Zona Sur
## 3     310       100       4      2       4 Zona Sur

Se calcula la variable dicotómica a partir de la variable zona:

base_2_sel$D1=as.numeric(base_2_sel$zona=="Zona Sur")
head(base_2_sel,3)
##   preciom areaconst estrato banios habitac     zona D1
## 1     145        60       3      2       3 Zona Sur  1
## 2     225        74       4      2       3 Zona Sur  1
## 3     310       100       4      2       4 Zona Sur  1

Se elimina la variable categorica zona:

base_2_sel <- select(base_2_sel, -zona)
head(base_2_sel,3)
##   preciom areaconst estrato banios habitac D1
## 1     145        60       3      2       3  1
## 2     225        74       4      2       3  1
## 3     310       100       4      2       4  1

Se crea una matriz de gráficos para explorar el grado de las relaciones entre las variables numéricas:

ggpairs(base_2_sel[,1:6], title=" ")
## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

Para este caso de estudio se observa que la relación mas fuerte existe entre la variable respuesta preciom y la variable predictora banios, con signo positivo lo que indica que los apartamentos con más número de baños tienen un precio mas alto. Lo mismo sucede con la variable areaconst, siendo la segunda relación más fuerte con la variable predictora preciom, lo que implica que a mayor área de construcción mayor será el precio del apartamento.

En cuanto a las variables independientes o predictoras, la relación más fuerte que se presenta es entre banios y areaconst, esto podria influir negativamente en el ajuste del modelo a estimar.

La variable dicotómica D1, calculada a partir de la variable zona, no aporta información para su análisis debido a que todos los registros filtrados para esta caso de estudio estan ubicados en la zona sur de la ciudad, por lo tanto, el uso de esta variable en una estimación de un modelo seria inecesaria.

3. Estimación de Modelo de Regresión Lineal Múltiple:

Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, numero de cuartos, numero de parqueaderos, numero 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).

Desarrollo:

Se realiza el filtro de los datos de acuerdo al enunciado:

base_2_sel <- select(base_2, preciom, areaconst, estrato, banios, habitac, parquea)
head(base_2_sel,3)
##   preciom areaconst estrato banios habitac parquea
## 1     145        60       3      2       3       1
## 2     225        74       4      2       3       1
## 3     310       100       4      2       4       2

Estimación del modelo por el método de mínimos cuadrados ordinarios:

modelo_2 <- lm(preciom ~ areaconst+estrato+banios+habitac+parquea, data = base_2_sel)
summary(modelo_2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitac + 
##     parquea, data = base_2_sel)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -987.05  -42.29   -0.54   40.53  923.06 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -271.36828   21.51226  -12.62  < 2e-16 ***
## areaconst      1.16221    0.07098   16.37  < 2e-16 ***
## estrato       53.69064    4.33951   12.37  < 2e-16 ***
## banios        58.73194    4.75473   12.35  < 2e-16 ***
## habitac      -19.24001    5.40498   -3.56 0.000385 ***
## parquea       87.30582    6.13176   14.24  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 100 on 1318 degrees of freedom
## Multiple R-squared:  0.7494, Adjusted R-squared:  0.7485 
## F-statistic: 788.4 on 5 and 1318 DF,  p-value: < 2.2e-16

A primera vista causa curiosidad el valor negativo del coeficiente de la variable habitac, esto indica que al aumentar en una unidad esta variable hay un efecto negativo en el valor del precio del apartamento, lo cual no concuerda con la realidad del negocio inmobiliario. Este efecto de la variable habitac puede deberse a la relación existen con la variable banios.

En cuanto a los demas coeficientes de las variables predictoras, se observan que tienen signo positivo, lo que infiere una relación positiva con la variable de respuesta, es decir, que a medida que las variables predictoras aumenten, con execpción de la variable habitac, la variable respuesta preciom también aumentará.

Si se observa la magnitud de los coeficientes, se puede analizar que el coeficiente con mayor magnitud es parquea, esto nos indica que esta variable aporta mucho al valor de un apartamento, es decir, que la diferencia de precio puede ser grande entre un apartamento con un solo parqueadero y un apartamento con dos parqueaderos. Las magnitudes de los coeficientes de las varibles estrato y banios son muy cercanas y su aporte al modelo se puede decir que es moderado comparado con la magnitud del coeficiente de la variable areaconst, la cual es muy pequeña, siendo el mismo efecto presente en el caso de la vivienda numero 1, donde se dijo que un cambio unitario de la variable areaconst manteniendo constante las demas variables predictoras genera un cambio modesto en el valor del precio de un apartamento.

En este caso, a pesar que en el analisis de correlación se identifico una fuerte correlación entre las variables banios y areaconst, todos los coeficientes son estadísticamente significativos. Esto se evidencia porque los valores p de todos los coeficientes son menores al límite de significancia (0.05), lo que implica que hay evidencia suficiente para considerar que los coeficientes son diferentes de cero. Lo anterior se traduce en que todas la variables tienen un impacto real y medible en la variable respuesta preciom.

El ajuste obtenido en este modelo 2 es mucho mejor que el del caso de la vivienda numero 1. Esto se evidencia con el valor de R2, el cual es más cercano a 1, lo que sugiere que el modelo se ajusta bien a los datos y es capaz de explicar suficientemente la variabilidad en la variable respuesta.

4. Validación de Supuestos:

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

Desarrollo:

Varianza constante (Homocedasticidad) y Linealidad

Para evaluar este supuesto se utiliza una gráfica con los valores residuales vs los ajustados del modelo estimado:

plot(modelo_2, which = 1)

El gráfico muestra los puntos un tanto dispersos al final de los valores ajustados, esto sugeriría que el supuesto de homocedasticidad se podría poner en duda, sin embargo, no hay un patrón marcado en los puntos, esto sugiere que la relacion entre las variables es lineal.

Para despejar las dudas anteriores, se acude a la prueba de Goldfeld-Quandt:

gqtest(modelo_2)
## 
##  Goldfeld-Quandt test
## 
## data:  modelo_2
## GQ = 2.6535, df1 = 656, df2 = 656, p-value < 2.2e-16
## alternative hypothesis: variance increases from segment 1 to 2

Como el valor p es menor a límite de significancia (0.05), se puede concluir que no hay evidencia suficiente para rechazar la hipótesis de homocedasticidad, es decir, los residuales tienen varianza constante.

Normalidad

Para evaluar este supuesto se acude a la prueba Shapiro Wilk sobre los residuales del modelo estimado:

shapiro.test(modelo_2$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo_2$residuals
## W = 0.75383, p-value < 2.2e-16

Como el valor p es menor que el límite de significancia (0.05), se puede considerar que hay evidencia encontra de la normalidad de los residuos, por lo tanto, el modelo estimado no cumpliria con el supuesto de normalidad.

Para evaluar gráficamente si los residuales siguen una distribución normal se acude al gráfico normal Q-Q:

plot(modelo_2, which = 2)

De la misma forma que se presento en el modelo estimado para el caso de la vivienda 1, en la gráfica se puede observar que los puntos de los extremos se alejan de la línea diagonal, esto indica presencia de colas en la distribución de los residuales, lo que confirma la no normalidad de los residuales.

Para corregir o mejorar esta situación, se puede considerar aplicar transformaciones matemáticas a las variables predictoras, utilizar modelos alternativos no lineales o modelos de regresión robusta o agregar otras variables predictoras que puedan aportar al modelo estimado.

Independencia

Para evaluar la presencia de autocorrelación en los residuos del modelo estimado se utiliza la prueba de Durbin-Watson:

dwtest(modelo_2)
## 
##  Durbin-Watson test
## 
## data:  modelo_2
## DW = 1.8654, p-value = 0.006669
## alternative hypothesis: true autocorrelation is greater than 0

De acuerdo al valor p obtenido, un valor menor a 2 sugiere la presencia de autocorrelación positiva en los residuos. Es decir, las inferencias del modelo pueden ser sesgadas y las estimaciones de los coeficientes pueden no ser confiables, por lo tanto, el supuesto de independencia de los residuales no se estaría cumpliendo.

Para una correlación serial positiva, se podria considerar agregar rezagos de la variable dependiente y / o independiente al modelo. Adicionalmente, para mitigar este problema se podria considerar agregar nuevas variables en el modelo, eliminar variables irrelevantes, en este caso, se podria probar eliminando una de las variables banos y areaconst. Otra opción seria utilizar matrices de vecinos o de distancia para introducir autocorrelación espacial en el modelo, esto teniendo en cuenta que se tienen variables de tipo espacial como la latitud y la longitud.

5. Predicción:

Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

Desarrollo:

Con base en las carácteristicas definidas para el primer caso se procede a predecir el precio de la vivienda:

caso_2 <- data.frame(areaconst = 300, estrato = 5, banios = 3, habitac = 5, parquea = 3)

predicciones <- predict(modelo_2, newdata = caso_2)

print(predicciones)
##        1 
## 687.6617

El precio estimado para un apartamento en la zona sur de la ciudad de Cali, con un área de 300 metros cuadrados, estrato 5, 3 baños, 5 habitaciones y 3 parqueaderos, es de 687.7 millones.

6. Predicción:

Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 2. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 850 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

Desarrollo:

Teniendo en cuenta el precio estimado por el modelo para la vivienda del caso número dos y el tope máximo del credito pre-aprobado se seleccionaron las siguientes ofertas potenciales:

ofertas_2 <- base_2 %>% filter(preciom >= 688 & preciom < 850 & banios == 3)

ofertas_2
##     id     zona piso estrato preciom areaconst parquea banios habitac
## 1 3603 Zona Sur    1       6     833       213       2      3       3
## 2 3827 Zona Sur    2       6     820       213       2      3       3
## 3 3848 Zona Sur   12       6     760       200       2      3       3
## 4 4380 Zona Sur    1       6     754       180       2      3       3
## 5 4978 Zona Sur    4       6     690       170       2      3       3
## 6 5242 Zona Sur    6       5     704       141       2      3       2
## 7 5423 Zona Sur    2       6     695       227       3      3       3
## 8 5693 Zona Sur    6       6     780       168       2      3       3
##          tipo              barrio  longitud latitud
## 1 Apartamento ciudad jardin pance -76.52726 3.34865
## 2 Apartamento               pance -76.52888 3.35064
## 3 Apartamento       ciudad jardín -76.52897 3.36403
## 4 Apartamento               pance -76.53102 3.34318
## 5 Apartamento       ciudad jardín -76.53410 3.36531
## 6 Apartamento       ciudad jardín -76.53530 3.35959
## 7 Apartamento       ciudad jardín -76.53638 3.36905
## 8 Apartamento       ciudad jardín -76.53798 3.35961

Teniendo en cuenta que se tiene un rango de precio en el cual se debe encontrar la mejor oferta que cumpla con las caracteristicas de la vivienda 2, se realizo el filtro de apartamentos con precios entre 688 y 850 millones, sin embargo, ninguna de las ofertas que se encuentran en este rango cumplen con la necesidad de 5 habitaciones, por lo cual, fue necesario utilizar la variable baños para reducir la busqueda y encontrar posibles ofertas. Dentro de las 8 ofertas seleccionadas se encuentran apartamentos ubicados en la zona de sur de la ciudad con mas de 2 parqueaderos y en estrato 5 o 6. El número de habitaciones maximo que se pudo obtener con este rango de precios fue de 3 habitaciones. Quizas esta necesidad se sale de contexto, pues de acuerdo a las ofertas es muy dificil encontrar apartamentos en la zona con 5 habitaciones y con un precio entre 688 y 850 millones. El área de construcción de las 8 ofertas es muy variable, desde 141 metros cuadrados hasta 227, tampoco se logro obtener un valor muy cercano a la necesidad de la vivienda 2 que era de 300 metros cuadrados.

mapa_2 <- leaflet(ofertas_2) %>%
  setView(lng = -76.5320, lat = 3.40, zoom = 12) %>%
  addTiles()  # Añadir capas base (mapa base)

for (i in 1:nrow(ofertas_2)) {
  mapa_2 <- mapa_2 %>%
    addMarkers(lng = ofertas_2$longitud[i], lat = ofertas_2$latitud[i], popup = ofertas_2$id[i])
}

mapa_2

En el mapa anterior se puede observar la ubicación geográfica de las 8 ofertas potenciales de apartamentos que se asemejan a las caracteristicas solicitadas para el caso de la vivienda número 2.