Los datos proporcionados incluyen información sobre las propiedades inmobiliarias de Cali en una determinada zona, incluyendo el piso en el que se encuentran, su estrato socioeconómico, el precio en millones de pesos, el área construida, el número de parqueaderos, baños, habitaciones, el tipo de propiedad, el barrio en el que se encuentra, y las coordenadas de longitud y latitud.
data("vivienda")
vivienda=as.data.frame(vivienda[,-1])
head(vivienda, 3)## zona piso estrato preciom areaconst parqueaderos banios habitaciones
## 1 Zona Oriente <NA> 3 250 70 1 3 6
## 2 Zona Oriente <NA> 3 320 120 1 2 3
## 3 Zona Oriente <NA> 3 350 220 2 2 4
## tipo barrio longitud latitud
## 1 Casa 20 de julio -76.51168 3.43382
## 2 Casa 20 de julio -76.51237 3.43369
## 3 Casa 20 de julio -76.51537 3.43566
summary(vivienda)## zona piso estrato preciom
## Length:8322 Length:8322 Min. :3.000 Min. : 58.0
## Class :character Class :character 1st Qu.:4.000 1st Qu.: 220.0
## Mode :character Mode :character Median :5.000 Median : 330.0
## Mean :4.634 Mean : 433.9
## 3rd Qu.:5.000 3rd Qu.: 540.0
## Max. :6.000 Max. :1999.0
## NA's :3 NA's :2
## areaconst parqueaderos banios habitaciones
## Min. : 30.0 Min. : 1.000 Min. : 0.000 Min. : 0.000
## 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000 1st Qu.: 3.000
## Median : 123.0 Median : 2.000 Median : 3.000 Median : 3.000
## Mean : 174.9 Mean : 1.835 Mean : 3.111 Mean : 3.605
## 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000 3rd Qu.: 4.000
## Max. :1745.0 Max. :10.000 Max. :10.000 Max. :10.000
## NA's :3 NA's :1605 NA's :3 NA's :3
## tipo barrio longitud latitud
## Length:8322 Length:8322 Min. :-76.59 Min. :3.333
## Class :character Class :character 1st Qu.:-76.54 1st Qu.:3.381
## Mode :character Mode :character Median :-76.53 Median :3.416
## Mean :-76.53 Mean :3.418
## 3rd Qu.:-76.52 3rd Qu.:3.452
## Max. :-76.46 Max. :3.498
## NA's :3 NA's :3
La tabla muestra que hay 8.322 propiedades en total en la base, 5.100 apartamentos, 3.219 casas y 3 NA, evidenciando que hay valores faltantes en algunas variables. Por ejemplo, hay 2638 observaciones faltantes para la variable “piso” y 1605 en la variable “parqueaderos”. Antes de eliminar las filas que tienen datos faltantes se tiene en cuenta que la variable “piso” no se usará en el modelo por lo tanto esta se excluye de la base de datos, ahora bien, con respecto a la variable “parqueaderos” se observa que su rango está entre 1 y 10, por lo que se toma la descisión de reemplazar los valores faltantes por cero, al hacer esto se asume que estas viviendas no tienen parqueadero, ya que es probable que alguien que venda una vivienda sin parqueadero, no lo incluya en la información proporcionada.
Sin embargo, es importante tener en cuenta que esta es una asunción y podría no ser completamente precisa. En algunos casos, los valores faltantes podrían deberse a errores en la recopilación de datos o a que la información simplemente no se proporcionó. Por lo tanto, es importante analizar los datos cuidadosamente y tener en cuenta cualquier limitación o posible error al realizar el análisis.
## Se excluye la variable piso ya que no se usará en el modelo y tiene una gran cantidad de NA
vivienda = vivienda[,-c(2)]
## Parqueaderos en NA son 0
vivienda$parqueaderos[is.na(vivienda$parqueaderos)]=0Por ultimo se retiran de la base las filas restantes que cuentan con datos faltantes (NA)
## retirar NA restantes
viv2=na.omit(vivienda)Para el mapeo de los puntos se usa un objeto shape de las comunas de la ciudad de Cali, primero se carga el archivo, luego se filtra la base de viviendas en la zona norte y con las cordenadas de esta base filtrada se crea un obejeto espacial de puntos. Finalmente mediante la función plot se grafica el mapa con las viviendas.
require(sp)
library(raster)
library(sf)
library(tmap)
## Mapa de Cali con comunas
comunas=shapefile("C:/Users/jjbedoya/Desktop/Cali/Comunas.shp")
## Filtro de viviendas en Zona Norte
df_casa_norte=viv2[viv2$zona == "Zona Norte" & viv2$tipo == "Casa",]
head(df_casa_norte,3)## zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## 9 Zona Norte 5 320 150 2 4 6 Casa
## 10 Zona Norte 5 780 380 2 3 3 Casa
## 11 Zona Norte 6 750 445 0 7 6 Casa
## barrio longitud latitud
## 9 acopi -76.51341 3.47968
## 10 acopi -76.51674 3.48721
## 11 acopi -76.52950 3.38527
# tabla de todas las viviendas de cali
table(vivienda$zona, vivienda$tipo)##
## Apartamento Casa
## Zona Centro 24 100
## Zona Norte 1198 722
## Zona Oeste 1029 169
## Zona Oriente 62 289
## Zona Sur 2787 1939
# tabla de las viviendas tipo casa ubicadas en la zona norte de cali
table(df_casa_norte$zona, df_casa_norte$tipo)##
## Casa
## Zona Norte 722
De acuerdo con el filtro realizado, se obseva que para la zona norte y tipo de vivienda casa, se cuenta con 722 datos que serán georeferenciados a continuación.
## longitud en formato -xx.xxxxx
#longitud_c = df_casa_norte$longitud
#re = "(\\d{2})(\\d{2})"
#longitud_c = gsub(re, "\\1.\\2", longitud_c)
## latitud en formato xx.xxxxx
#latitud_c = df_casa_norte$latitud
#re = "(\\d{1,1})(\\d{1,4})"
#latitud_c = gsub(re, "\\1.\\2", latitud_c)
#df_casa_norte$longitud = as.double(longitud_c)
#df_casa_norte$latitud = as.double(latitud_c)
## se convierte en un objeto espacial
puntos = SpatialPointsDataFrame(coords = df_casa_norte[,c("longitud","latitud")],
data = df_casa_norte,
proj4string = CRS(proj4string(comunas)))## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
plot(comunas)
plot(puntos, add=T, pch=1, col="red")Se encontró que algunos puntos estaban ubicados en zonas que no correspondían a la zona norte. Para clasificar los puntos mal ubicados, se realizón un cruce de las viviendas con el mapa de cumunas teniendo en cuenta la información suministrada por la IDESC del Departamento Administrativo de Planeación - Cali que las comunas de la zona norte son las comunas 6, 5, 4 y 2 (fuente: https://www.cali.gov.co/planeacion/publicaciones/169423/zonas_geograficas_idesc/).
## Hay muchos puntos que no se encuentran al norte de la ciudad
## Para validar se cruzan los puntos con las comunas
## Se considera que las comunas de zona norte son la 6, 5, 4 y 2
## con esto se clasifican los puntos que estarian bien ubicados y los que estan mal
require(dplyr)## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:rgeos':
##
## intersect, setdiff, union
## The following objects are masked from 'package:raster':
##
## intersect, select, union
## The following object is masked from 'package:kableExtra':
##
## group_rows
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
result = over(puntos, comunas)
df_casa_norte$comuna = result$comuna
df_casa_norte$clasificacion = ifelse(df_casa_norte$comuna%in%c(6,5,4,2),"bien","mal")
df_casa_norte_ok = df_casa_norte[df_casa_norte$clasificacion == "bien",]
head(df_casa_norte_ok, 10)## zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## 9 Zona Norte 5 320 150 2 4 6 Casa
## 10 Zona Norte 5 780 380 2 3 3 Casa
## 31 Zona Norte 3 180 120 0 3 3 Casa
## 35 Zona Norte 5 520 455 0 5 4 Casa
## 43 Zona Norte 3 380 300 0 5 8 Casa
## 59 Zona Norte 5 395 165 0 4 4 Casa
## 82 Zona Norte 5 460 319 0 5 4 Casa
## 86 Zona Norte 5 390 357 0 3 6 Casa
## 87 Zona Norte 5 780 380 0 3 3 Casa
## 90 Zona Norte 4 420 265 0 6 7 Casa
## barrio longitud latitud comuna clasificacion
## 9 acopi -76.51341 3.47968 2 bien
## 10 acopi -76.51674 3.48721 2 bien
## 31 acopi -76.49768 3.47060 5 bien
## 35 acopi -76.49966 3.46284 5 bien
## 43 acopi -76.50743 3.46566 4 bien
## 59 acopi -76.51797 3.47651 2 bien
## 82 acopi -76.52190 3.47317 2 bien
## 86 acopi -76.52255 3.48133 2 bien
## 87 acopi -76.52293 3.48427 2 bien
## 90 acopi -76.52419 3.48054 2 bien
require(table1)## Loading required package: table1
##
## Attaching package: 'table1'
## The following objects are masked from 'package:base':
##
## units, units<-
y <- table1::table1(~barrio|zona, data = df_casa_norte_ok)
y| Zona Norte (N=527) |
Overall (N=527) |
|
|---|---|---|
| barrio | ||
| acopi | 11 (2.1%) | 11 (2.1%) |
| alameda del río | 1 (0.2%) | 1 (0.2%) |
| alamos | 2 (0.4%) | 2 (0.4%) |
| barranquilla | 3 (0.6%) | 3 (0.6%) |
| barrio tranquilo y | 1 (0.2%) | 1 (0.2%) |
| brisas de los | 16 (3.0%) | 16 (3.0%) |
| brisas del guabito | 1 (0.2%) | 1 (0.2%) |
| calima | 5 (0.9%) | 5 (0.9%) |
| calimio norte | 2 (0.4%) | 2 (0.4%) |
| centenario | 2 (0.4%) | 2 (0.4%) |
| chipichape | 5 (0.9%) | 5 (0.9%) |
| ciudad los álamos | 11 (2.1%) | 11 (2.1%) |
| el bosque | 32 (6.1%) | 32 (6.1%) |
| el guabito | 1 (0.2%) | 1 (0.2%) |
| el sena | 1 (0.2%) | 1 (0.2%) |
| flora industrial | 4 (0.8%) | 4 (0.8%) |
| floralia | 3 (0.6%) | 3 (0.6%) |
| gaitan | 1 (0.2%) | 1 (0.2%) |
| granada | 9 (1.7%) | 9 (1.7%) |
| jorge eliecer gaitán | 1 (0.2%) | 1 (0.2%) |
| juanamb√∫ | 8 (1.5%) | 8 (1.5%) |
| la campiña | 3 (0.6%) | 3 (0.6%) |
| la esmeralda | 1 (0.2%) | 1 (0.2%) |
| la flora | 82 (15.6%) | 82 (15.6%) |
| La Flora | 1 (0.2%) | 1 (0.2%) |
| la merced | 23 (4.4%) | 23 (4.4%) |
| la rivera | 8 (1.5%) | 8 (1.5%) |
| la rivera i | 1 (0.2%) | 1 (0.2%) |
| la rivera ii | 2 (0.4%) | 2 (0.4%) |
| la riviera | 1 (0.2%) | 1 (0.2%) |
| la villa del | 1 (0.2%) | 1 (0.2%) |
| las delicias | 2 (0.4%) | 2 (0.4%) |
| los andes | 10 (1.9%) | 10 (1.9%) |
| los guaduales | 8 (1.5%) | 8 (1.5%) |
| los guayacanes | 2 (0.4%) | 2 (0.4%) |
| manzanares | 1 (0.2%) | 1 (0.2%) |
| menga | 2 (0.4%) | 2 (0.4%) |
| metropolitano del norte | 1 (0.2%) | 1 (0.2%) |
| oasis de comfandi | 1 (0.2%) | 1 (0.2%) |
| occidente | 1 (0.2%) | 1 (0.2%) |
| pacara | 2 (0.4%) | 2 (0.4%) |
| parque residencial el | 1 (0.2%) | 1 (0.2%) |
| paseo de los | 2 (0.4%) | 2 (0.4%) |
| paso del comercio | 2 (0.4%) | 2 (0.4%) |
| popular | 2 (0.4%) | 2 (0.4%) |
| portada de comfandi | 1 (0.2%) | 1 (0.2%) |
| portales de comfandi | 1 (0.2%) | 1 (0.2%) |
| porvenir | 2 (0.4%) | 2 (0.4%) |
| prados del norte | 23 (4.4%) | 23 (4.4%) |
| quintas de salomia | 1 (0.2%) | 1 (0.2%) |
| salomia | 15 (2.8%) | 15 (2.8%) |
| san luis | 2 (0.4%) | 2 (0.4%) |
| san vicente | 23 (4.4%) | 23 (4.4%) |
| santa bárbara | 1 (0.2%) | 1 (0.2%) |
| santa monica | 14 (2.7%) | 14 (2.7%) |
| Santa Monica | 1 (0.2%) | 1 (0.2%) |
| santa mónica | 1 (0.2%) | 1 (0.2%) |
| santa monica norte | 1 (0.2%) | 1 (0.2%) |
| santa monica residencial | 5 (0.9%) | 5 (0.9%) |
| santa mónica residencial | 14 (2.7%) | 14 (2.7%) |
| santander | 1 (0.2%) | 1 (0.2%) |
| torres de comfandi | 2 (0.4%) | 2 (0.4%) |
| urbanización barranquilla | 1 (0.2%) | 1 (0.2%) |
| urbanización la flora | 20 (3.8%) | 20 (3.8%) |
| urbanización la merced | 4 (0.8%) | 4 (0.8%) |
| versalles | 14 (2.7%) | 14 (2.7%) |
| villa de veracruz | 3 (0.6%) | 3 (0.6%) |
| villa del prado | 33 (6.3%) | 33 (6.3%) |
| Villa Del Prado | 1 (0.2%) | 1 (0.2%) |
| villa del sol | 12 (2.3%) | 12 (2.3%) |
| villas de veracruz | 6 (1.1%) | 6 (1.1%) |
| Villas De Veracruz | 1 (0.2%) | 1 (0.2%) |
| vipasa | 27 (5.1%) | 27 (5.1%) |
| zona norte | 17 (3.2%) | 17 (3.2%) |
Al limpiar la base de datos, excluyendo los clasificdos como “mal” ubicadas se reduce a 527 datos correctos, esto puede estar dándose debido a: Algunos del barrio Acopi tienen direcciones que corresponden al municipio de Yumbo, pero en el proceso de geocodificación se puede estar buscando la dirección en la ciudad de Cali, lo que genera un error en la ubicación de estas viviendas. También se pueden ver algunos errores en cuanto al barrio siendo que uno de ellos es “zona norte” y este barrio no existe. Para lal depuración de la base de datos, se tiene como referncia la longitud y latitud para tener certeza de la ubicación de los predios.
## Georreferenciamos nuevamente las viviendas tipo casa de la zona norte
puntos1 = SpatialPointsDataFrame(coords = df_casa_norte_ok[,c("longitud","latitud")],
data = df_casa_norte_ok,
proj4string = CRS(proj4string(comunas)))## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
plot(comunas)
plot(puntos1, add=T, pch=1, col="purple")# Matriz de correlación
require(graphics)
require(plotly)
#viv2$estrato = as.numeric(viv2$estrato)
cor_mat = cor(viv2[,c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones", "estrato")])
cor_mat## preciom areaconst parqueaderos banios habitaciones
## preciom 1.0000000 0.6873520 0.6397779 0.6691456 0.26409121
## areaconst 0.6873520 1.0000000 0.4823840 0.6484165 0.51691292
## parqueaderos 0.6397779 0.4823840 1.0000000 0.5231299 0.19875551
## banios 0.6691456 0.6484165 0.5231299 1.0000000 0.58990641
## habitaciones 0.2640912 0.5169129 0.1987555 0.5899064 1.00000000
## estrato 0.6098066 0.2743233 0.5127889 0.4203218 -0.07137615
## estrato
## preciom 0.60980664
## areaconst 0.27432332
## parqueaderos 0.51278892
## banios 0.42032178
## habitaciones -0.07137615
## estrato 1.00000000
plot_ly(z = cor_mat, x = colnames(cor_mat), y = colnames(cor_mat), type = "heatmap", colorscale = "Plasma",zmin = -1, zmax = 1, reversescale = TRUE) %>% layout(title = "Matriz de correlación", xaxis = list(title = ""), yaxis = list(title = ""))Se puede ver que hay una correlación positiva moderada a fuerte entre el precio de la propiedad y el área construida, los parqueaderos, los baños y el estrato. La correlación entre el precio y el número de habitaciones es baja. El estrato tiene una correlación moderada positiva con los parqueaderos y una correlación negativa débil con el número de habitaciones.
## Boxplot de zonas
plot_ly(data = viv2, x = ~zona, y = ~preciom, type = "box")Ahora se realizará el modelo de regresión lineal múltiple para predecir el precio de las casas ubicadas en la zona norte de Cali, utilizando las variables de Área construida, número de parqueaderos, estrato, número de baños y número de habitaciones. Luego se ajusta el modelo de regresión lineal múltiple, para finalmente mostrar un resumen de los resultados del modelo.
df_casa_norte_ok$estrato = as.numeric(df_casa_norte_ok$estrato)
mod1=lm(preciom~ areaconst + parqueaderos + estrato + banios + habitaciones, df_casa_norte_ok)
summary(mod1)##
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + estrato + banios +
## habitaciones, data = df_casa_norte_ok)
##
## Residuals:
## Min 1Q Median 3Q Max
## -924.18 -66.95 -16.60 35.06 1107.53
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -170.84010 35.64048 -4.793 2.14e-06 ***
## areaconst 0.77882 0.05318 14.645 < 2e-16 ***
## parqueaderos 12.58900 4.77655 2.636 0.00865 **
## estrato 71.49706 8.78042 8.143 2.87e-15 ***
## banios 14.28141 6.53460 2.186 0.02930 *
## habitaciones 5.93136 5.12237 1.158 0.24742
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 149.1 on 521 degrees of freedom
## Multiple R-squared: 0.6413, Adjusted R-squared: 0.6379
## F-statistic: 186.3 on 5 and 521 DF, p-value: < 2.2e-16
El modelo ajustado a los datos muestra los siguientes coeficientes:
El coeficiente del intercepto es -170.84. Esto indica que el valor esperado del precio de una vivienda con todas las variables explicativas en cero (es decir, cuando el apartamento no tiene área construida, parqueaderos, estrato, baños o habitaciones) es de -170.84 millones de pesos. Sin embargo, este valor no tiene una interpretación práctica, ya que es poco probable que se encuentre una vivienda sin ninguna de estas características.
El coeficiente de área construida es 0.778. Esto indica que, manteniendo todas las demás variables constantes, un aumento de una unidad en el área construida de un apartamento se asocia, en promedio, con un aumento de 0.778 millones de pesos en el precio del apartamento.
El coeficiente de parqueaderos indica que, manteniendo todas las otras variables constantes, un incremento de 1 en la cantidad de parqueaderos se asocia con un aumento en el precio promedio de la vivienda de 12.58 millones de pesos.
El coeficiente de Estrato indica que, manteniendo todas las otras variables constantes, un incremento de 1 en el estrato se asocia con un incremento en el precio promedio de la vivienda de 71.49 millones de pesos.
El coeficiente de Baños indica que, manteniendo todas las otras variables constantes, un incremento de 1 en el número de baños se asocia con un incremento en el precio promedio de la vivienda de 14.28 millones de pesos.
El coeficiente de Habitaciones indica que, manteniendo todas las otras variables constantes, un incremento de 1 en el número de habitaciones se asocia con un incremento en el precio promedio de la vivienda de 5.93 millones de pesos. Sin embargo, el valor p es grande (0.247), lo que indica que no hay suficiente evidencia para rechazar la hipótesis nula de que el coeficiente es cero.
Se puede ver que el R-cuadrado es de 0.6413. Esto significa que alrededor del 64.13% de la variabilidad en el precio de las casas en la región norte se explica por las variables independientes incluidas en el modelo
Para mejorar el modelo se pude optar por las siguientes opciones:
Incluir variables adicionales: puede ser útil incluir variables adicionales que puedan estar relacionadas con el precio de la vivienda, como la ubicación, la antigüedad de la propiedad, la calidad de los materiales de construcción, etc.
Eliminar variables no significativas: es posible que algunas de las variables incluidas en el modelo no sean significativas y estén afectando negativamente la calidad del modelo. En este caso, se podrían eliminar estas variables para mejorar la precisión del modelo.
Transformar variables: en algunos casos, la relación entre la variable independiente y la variable dependiente no es lineal. En estos casos, se pueden utilizar transformaciones como la raíz cuadrada, el logaritmo, entre otras.
En esta sección se validan los supuestos del modelo.
## Validacion de supuestos
res=mod1$residuals
## Normalidad de residuales
shapiro.test(res)##
## Shapiro-Wilk normality test
##
## data: res
## W = 0.78594, p-value < 2.2e-16
H0: los errores tienen una distribución normal
Se rechaza H0 si el p-valor de la prueba es <= a 0.05
En este caso, se utilizó la prueba de Shapiro-Wilk para determinar si los residuos se distribuyen normalmente. El resultado muestra que el valor de W es 0.78594 y el p-value es aproximadamente 0, lo que indica que los residuos no se distribuyen normalmente.
## Homocedasticidad
library(lmtest)
bptest(mod1)##
## studentized Breusch-Pagan test
##
## data: mod1
## BP = 108.46, df = 5, p-value < 2.2e-16
H0: la varianza de los erroes es constante
En este caso, se utiliza la prueba de Breusch-Pagan para determinar si los residuos son homocedásticos. El resultado muestra que el valor de BP es 108.46 y el p-value es aproximadamente 0, lo que indica que los residuos no son homocedásticos.
## Independecia
dwtest(mod1)##
## Durbin-Watson test
##
## data: mod1
## DW = 1.7833, p-value = 0.005495
## alternative hypothesis: true autocorrelation is greater than 0
H0: no hay autocorrelación
En este caso, se utiliza la prueba de Durbin-Watson para determinar si los residuos son independientes. El resultado muestra que el valor de DW es 1.7833 y el p-value es 0.005495, lo que indica que los residuos no son independientes y están correlacionados entre sí.
Se requiere predecir el valor de una vivienda con las siguientes caracteristicas.
| Caracteristicas | 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 |
Mediante la función predict se realiza la predicción, primero declarando un dataframe con los datos sobre la vivienda que se quiere vender.
## Prediccion
new_dat = data.frame(
areaconst = 200,
parqueaderos = 1,
estrato = c(4, 5),
banios = 2,
habitaciones = 4
)
new_dat## areaconst parqueaderos estrato banios habitaciones
## 1 200 1 4 2 4
## 2 200 1 5 2 4
predict(mod1,new_dat)## 1 2
## 335.7888 407.2858
El resultado indica que una casa con estas caracteristicas de estrato 4 valdria en promedio 335.78 millones de pesos y si es estrato 5 valdría 407.28 millones de pesos.
Teniendo en cuenta el credito preaprobado de 350 millones, a cada casa de la base de datos de zona norte se le incluye la predicción del modelo y el residual asociado. Esto con el fin de filtrar casas de estrato 4 ó 5 que tengan una predicción menor a 350 millones cuyo residual sea negativo, con esto nos aseguramos que estas casas tendran un precio por debajo del credito aprobado y son potenciales ofertas ya que su predicción indica un precio mayor del que valen realmente.
## se incluyen predicciones y residuales en la base
df_casa_norte_ok$res<-res
df_casa_norte_ok$pred<-mod1$fitted.values
df<-head(df_casa_norte_ok[(df_casa_norte_ok$pred<=350 & df_casa_norte_ok$habitaciones>=4 & df_casa_norte_ok$banios>=2 & df_casa_norte_ok$parqueaderos>=1 & df_casa_norte_ok$res<=0 & df_casa_norte_ok$estrato %in% c(4, 5)),]%>% arrange(desc(pred)))
knitr::kable(df[,-c(9,10,11,12,13,14)],"pipe")| zona | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | pred |
|---|---|---|---|---|---|---|---|---|
| Zona Norte | 4 | 280 | 130 | 2 | 4 | 4 | Casa | 322.4234 |
| Zona Norte | 4 | 265 | 162 | 1 | 3 | 4 | Casa | 320.4751 |
| Zona Norte | 4 | 253 | 140 | 2 | 3 | 4 | Casa | 315.9302 |
| Zona Norte | 4 | 280 | 147 | 1 | 3 | 4 | Casa | 308.7929 |
| Zona Norte | 4 | 240 | 82 | 1 | 3 | 4 | Casa | 258.1698 |
| Zona Norte | 4 | 223 | 73 | 1 | 3 | 4 | Casa | 251.1604 |
En el resultado se puede observar que se presentan 6 viviendas opcionadas pero no con las especificaciones exactas del cleinte.
## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
Otra opción para analizar las mejores ofertas es revisar las casas cuyo precio sea menor a 350 millones y el residual en la predicción sea negativo, ya que segun el modelo estas casas por sus caracteristicas podrian valer más del precio que tienen actualmente en la base.
df2=head(df_casa_norte_ok[df_casa_norte_ok$preciom<350 & df_casa_norte_ok$res<=0,]%>% arrange(desc(preciom)),5)
knitr::kable(df2[,-c(9,10,11,14)],"pipe")| zona | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | comuna | clasificacion | pred |
|---|---|---|---|---|---|---|---|---|---|---|
| Zona Norte | 5 | 343 | 170 | 3 | 4 | 4 | Casa | 2 | bien | 437.6622 |
| Zona Norte | 5 | 342 | 250 | 1 | 4 | 6 | Casa | 2 | bien | 486.6522 |
| Zona Norte | 5 | 340 | 250 | 2 | 4 | 4 | Casa | 2 | bien | 487.3785 |
| Zona Norte | 5 | 340 | 208 | 0 | 6 | 4 | Casa | 4 | bien | 458.0530 |
| Zona Norte | 5 | 340 | 240 | 2 | 5 | 6 | Casa | 2 | bien | 505.7345 |
Aquí ya se presentan 2 ofertas potenciales de casas, en la fila 2 y en la fila 3.
## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
Se siguen los mismos pasos que en el modelo anterior inicialmente se realiza la validación en cuanto a las coordenadas de los apartamentos.
## Filtro de apartamentos en Zona sur
df_sur_apar = viv2[(viv2$zona=="Zona Sur" & viv2$tipo=="Apartamento"),]
## se convierte en un objeto espacial
puntos4 <- SpatialPointsDataFrame(coords = df_sur_apar[,c("longitud","latitud")],
data = df_sur_apar,
proj4string = CRS(proj4string(comunas)))## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
plot(comunas)
plot(puntos4, add=T, pch=20, col="blue")Al igual que en el caso anterior hay puntos mal ubicados, realizando la validación por comunas se obtiene el siguiente resultado. Asumiendo que las comunas de la zona sur son las 10, 16,17,18,19 y 22 de acuerdo con la infrmación suministrada por la IDESC del DAP-Cali.
## comunas 10,16,17,18,19,22
result1 = over(puntos4, comunas)
df_sur_apar$comuna = result1$comuna
df_sur_apar$clasificacion = ifelse(df_sur_apar$comuna%in%c(10,16,17,18,19,22),"bien","mal")
df_sur_apar_ok = df_sur_apar[df_sur_apar$clasificacion == "bien",]
head(df_sur_apar_ok, 10)## zona estrato preciom areaconst parqueaderos banios habitaciones
## 312 Zona Sur 4 220 75 1 2 3
## 315 Zona Sur 3 115 58 1 2 2
## 317 Zona Sur 4 220 84 0 2 3
## 341 Zona Sur 3 230 63 1 2 2
## 344 Zona Sur 5 344 107 2 2 3
## 444 Zona Sur 5 310 166 2 4 3
## 446 Zona Sur 5 175 64 1 2 2
## 447 Zona Sur 5 285 120 2 4 3
## 449 Zona Sur 6 305 125 2 3 3
## 451 Zona Sur 5 185 78 1 2 3
## tipo barrio longitud latitud comuna clasificacion
## 312 Apartamento alfv©rez real -76.54627 3.39109 18 bien
## 315 Apartamento alfv©rez real -76.54924 3.39121 18 bien
## 317 Apartamento alferez real -76.54600 3.39000 18 bien
## 341 Apartamento alto jordán -76.55300 3.37200 18 bien
## 344 Apartamento altos de guadalupe -76.55500 3.41000 19 bien
## 444 Apartamento bella suiza -76.56400 3.41000 19 bien
## 446 Apartamento bella suiza -76.56493 3.40916 19 bien
## 447 Apartamento bella suiza -76.56400 3.41000 19 bien
## 449 Apartamento bella suiza -76.56500 3.40800 19 bien
## 451 Apartamento bella suiza -76.56475 3.41022 19 bien
require(table1)
y <- table1::table1(~barrio|zona, data = df_sur_apar_ok)
y| Zona Sur (N=2461) |
Overall (N=2461) |
|
|---|---|---|
| barrio | ||
| alferez real | 1 (0.0%) | 1 (0.0%) |
| alférez real | 2 (0.1%) | 2 (0.1%) |
| alto jordán | 1 (0.0%) | 1 (0.0%) |
| altos de guadalupe | 1 (0.0%) | 1 (0.0%) |
| bella suiza | 5 (0.2%) | 5 (0.2%) |
| bochalema | 18 (0.7%) | 18 (0.7%) |
| bosques del limonar | 11 (0.4%) | 11 (0.4%) |
| brisas del limonar | 1 (0.0%) | 1 (0.0%) |
| buenos aires | 3 (0.1%) | 3 (0.1%) |
| caldas | 1 (0.0%) | 1 (0.0%) |
| Cali | 2 (0.1%) | 2 (0.1%) |
| calicanto | 2 (0.1%) | 2 (0.1%) |
| cambulos | 2 (0.1%) | 2 (0.1%) |
| camino real | 13 (0.5%) | 13 (0.5%) |
| Camino Real | 1 (0.0%) | 1 (0.0%) |
| campestre | 1 (0.0%) | 1 (0.0%) |
| caney | 55 (2.2%) | 55 (2.2%) |
| caney especial | 1 (0.0%) | 1 (0.0%) |
| cañasgordas | 5 (0.2%) | 5 (0.2%) |
| cañaveralejo | 8 (0.3%) | 8 (0.3%) |
| cañaverales | 17 (0.7%) | 17 (0.7%) |
| cañaverales los samanes | 1 (0.0%) | 1 (0.0%) |
| capri | 38 (1.5%) | 38 (1.5%) |
| cataya real | 1 (0.0%) | 1 (0.0%) |
| cerro cristales | 1 (0.0%) | 1 (0.0%) |
| champagnat | 1 (0.0%) | 1 (0.0%) |
| ciudad 2000 | 19 (0.8%) | 19 (0.8%) |
| ciudad bochalema | 35 (1.4%) | 35 (1.4%) |
| ciudad capri | 8 (0.3%) | 8 (0.3%) |
| ciudad jardin | 9 (0.4%) | 9 (0.4%) |
| ciudad jardín | 202 (8.2%) | 202 (8.2%) |
| ciudad jardin pance | 1 (0.0%) | 1 (0.0%) |
| ciudad melendez | 1 (0.0%) | 1 (0.0%) |
| ciudad meléndez | 1 (0.0%) | 1 (0.0%) |
| ciudad pacifica | 1 (0.0%) | 1 (0.0%) |
| Ciudad Pacifica | 1 (0.0%) | 1 (0.0%) |
| ciudadela comfandi | 1 (0.0%) | 1 (0.0%) |
| ciudadela melendez | 1 (0.0%) | 1 (0.0%) |
| ciudadela pasoancho | 3 (0.1%) | 3 (0.1%) |
| colinas del sur | 2 (0.1%) | 2 (0.1%) |
| colseguros | 20 (0.8%) | 20 (0.8%) |
| colseguros andes | 1 (0.0%) | 1 (0.0%) |
| cristales | 1 (0.0%) | 1 (0.0%) |
| cristobal colón | 2 (0.1%) | 2 (0.1%) |
| cuarto de legua | 29 (1.2%) | 29 (1.2%) |
| departamental | 14 (0.6%) | 14 (0.6%) |
| el caney | 112 (4.6%) | 112 (4.6%) |
| El Caney | 1 (0.0%) | 1 (0.0%) |
| el dorado | 6 (0.2%) | 6 (0.2%) |
| el gran limonar | 3 (0.1%) | 3 (0.1%) |
| el guabal | 4 (0.2%) | 4 (0.2%) |
| el ingenio | 120 (4.9%) | 120 (4.9%) |
| el ingenio 3 | 1 (0.0%) | 1 (0.0%) |
| el ingenio i | 12 (0.5%) | 12 (0.5%) |
| el ingenio ii | 9 (0.4%) | 9 (0.4%) |
| el ingenio iii | 9 (0.4%) | 9 (0.4%) |
| el jordán | 1 (0.0%) | 1 (0.0%) |
| el lido | 29 (1.2%) | 29 (1.2%) |
| el limonar | 52 (2.1%) | 52 (2.1%) |
| el refugio | 70 (2.8%) | 70 (2.8%) |
| gran limonar | 8 (0.3%) | 8 (0.3%) |
| guadalupe | 8 (0.3%) | 8 (0.3%) |
| ingenio | 1 (0.0%) | 1 (0.0%) |
| ingenio ii | 1 (0.0%) | 1 (0.0%) |
| la alborada | 4 (0.2%) | 4 (0.2%) |
| la cascada | 2 (0.1%) | 2 (0.1%) |
| la hacienda | 99 (4.0%) | 99 (4.0%) |
| La Hacienda | 1 (0.0%) | 1 (0.0%) |
| la luisa | 1 (0.0%) | 1 (0.0%) |
| la selva | 6 (0.2%) | 6 (0.2%) |
| las acacias | 1 (0.0%) | 1 (0.0%) |
| las camelias | 1 (0.0%) | 1 (0.0%) |
| las granjas | 6 (0.2%) | 6 (0.2%) |
| las vegas de | 1 (0.0%) | 1 (0.0%) |
| los cambulos | 18 (0.7%) | 18 (0.7%) |
| los cámbulos | 3 (0.1%) | 3 (0.1%) |
| los farallones | 2 (0.1%) | 2 (0.1%) |
| mayapan las vegas | 29 (1.2%) | 29 (1.2%) |
| melendez | 35 (1.4%) | 35 (1.4%) |
| meléndez | 17 (0.7%) | 17 (0.7%) |
| miraflores | 1 (0.0%) | 1 (0.0%) |
| multicentro | 21 (0.9%) | 21 (0.9%) |
| napoles | 1 (0.0%) | 1 (0.0%) |
| nápoles | 10 (0.4%) | 10 (0.4%) |
| nueva tequendama | 33 (1.3%) | 33 (1.3%) |
| oasis de pasoancho | 1 (0.0%) | 1 (0.0%) |
| pampa linda | 12 (0.5%) | 12 (0.5%) |
| pampalinda | 3 (0.1%) | 3 (0.1%) |
| panamericano | 2 (0.1%) | 2 (0.1%) |
| pance | 177 (7.2%) | 177 (7.2%) |
| parcelaciones pance | 17 (0.7%) | 17 (0.7%) |
| pasoancho | 5 (0.2%) | 5 (0.2%) |
| ponce | 1 (0.0%) | 1 (0.0%) |
| prados del limonar | 2 (0.1%) | 2 (0.1%) |
| Prados Del Limonar | 1 (0.0%) | 1 (0.0%) |
| primero de mayo | 22 (0.9%) | 22 (0.9%) |
| quintas de don | 56 (2.3%) | 56 (2.3%) |
| refugio | 1 (0.0%) | 1 (0.0%) |
| samanes | 1 (0.0%) | 1 (0.0%) |
| samanes de guadalupe | 1 (0.0%) | 1 (0.0%) |
| san fernando | 16 (0.7%) | 16 (0.7%) |
| san fernando nuevo | 3 (0.1%) | 3 (0.1%) |
| san fernando viejo | 4 (0.2%) | 4 (0.2%) |
| san joaquin | 1 (0.0%) | 1 (0.0%) |
| santa anita | 34 (1.4%) | 34 (1.4%) |
| Santa Anita | 1 (0.0%) | 1 (0.0%) |
| santa elena | 1 (0.0%) | 1 (0.0%) |
| santa isabel | 7 (0.3%) | 7 (0.3%) |
| santa teresita | 1 (0.0%) | 1 (0.0%) |
| santo domingo | 1 (0.0%) | 1 (0.0%) |
| sector cañaveralejo guadalupe | 2 (0.1%) | 2 (0.1%) |
| seminario | 19 (0.8%) | 19 (0.8%) |
| templete | 1 (0.0%) | 1 (0.0%) |
| tequendama | 14 (0.6%) | 14 (0.6%) |
| unicentro cali | 1 (0.0%) | 1 (0.0%) |
| urbanización colseguros | 2 (0.1%) | 2 (0.1%) |
| urbanizacion gratamira | 1 (0.0%) | 1 (0.0%) |
| urbanización nueva granada | 1 (0.0%) | 1 (0.0%) |
| urbanización río lili | 2 (0.1%) | 2 (0.1%) |
| urbanización tequendama | 2 (0.1%) | 2 (0.1%) |
| valle de lili | 1 (0.0%) | 1 (0.0%) |
| valle del lili | 727 (29.5%) | 727 (29.5%) |
| Valle Del Lili | 1 (0.0%) | 1 (0.0%) |
| zona sur | 32 (1.3%) | 32 (1.3%) |
Al limpiar la base de datos, excluyendo los clasificdos como “mal” ubicadas se reduce a 2.461 datos correctos, estos posibles errores se deben a: por ejemplo, el barrio bochalema debido a que al ser una zona nueva en la ciudad el proceso de geolocalización no ubica bien las direcciones de estos apartamentos.
puntos4s <- SpatialPointsDataFrame(coords = df_sur_apar_ok[,c("longitud","latitud")],
data = df_sur_apar_ok,
proj4string = CRS(proj4string(comunas)))## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
plot(comunas)
plot(puntos4s, add=T, pch=20, col="darkgreen")Se ajusta el modelo de regresión multiple para los apartamentos de zona sur
## Modelo
mod2=lm(preciom~ areaconst + parqueaderos + estrato + banios + habitaciones, df_sur_apar_ok)
summary(mod2)##
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + estrato + banios +
## habitaciones, data = df_sur_apar_ok)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1164.91 -43.94 -2.35 36.48 941.89
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -212.43832 14.62644 -14.524 < 2e-16 ***
## areaconst 1.35982 0.05258 25.862 < 2e-16 ***
## parqueaderos 56.21782 3.39733 16.548 < 2e-16 ***
## estrato 54.79524 3.01705 18.162 < 2e-16 ***
## banios 49.98059 3.31463 15.079 < 2e-16 ***
## habitaciones -23.71470 3.66809 -6.465 1.22e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 96.58 on 2455 degrees of freedom
## Multiple R-squared: 0.7487, Adjusted R-squared: 0.7482
## F-statistic: 1463 on 5 and 2455 DF, p-value: < 2.2e-16
El modelo ajustado cuenta con los siguientes coeficientes:
El coeficiente del intercepto es -212.43, esto indica que el valor esperado del precio de una vivienda con todas las variables explicativas en cero (es decir, cuando el apartamento no tiene área construida, parqueaderos, estrato, baños o habitaciones) es de -212.43 millones de pesos. Sin embargo, este valor no tiene una interpretación práctica, ya que es poco probable que se encuentre una vivienda sin ninguna de estas características.
El coeficiente de área construida es 1.35. Esto indica que, manteniendo todas las demás variables constantes, un aumento de una unidad en el área construida de un apartamento se asocia, en promedio, con un aumento de 1.35 millones de pesos en el precio del apartamento.
El coeficiente de parqueaderos indica que, manteniendo todas las otras variables constantes, un incremento de 1 en la cantidad de parqueaderos se asocia con una disminución en el precio promedio de la vivienda de 56.21 millones de pesos.
El coeficiente de Estrato indica que, manteniendo todas las otras variables constantes, un incremento de 1 en el estrato se asocia con un incremento en el precio promedio de la vivienda de 54.79 millones de pesos.
El coeficiente de Baños indica que, manteniendo todas las otras variables constantes, un incremento de 1 en el número de baños se asocia con un incremento en el precio promedio de la vivienda de 49.98 millones de pesos.
El coeficiente de Habitaciones indica que, manteniendo todas las otras variables constantes, un incremento de 1 en el número de habitaciones se asocia con una disminución en el precio promedio de la vivienda de 23.71 millones de pesos.
se puede ver que el R-cuadrado es de 0.7487. Esto significa que alrededor del 74.87% de la variabilidad en el precio de las casas en la región norte se explica por las variables independientes incluidas en el modelo.
plot_ly(data = df_sur_apar_ok, x = ~habitaciones, y = ~preciom, type = "box")En este caso puede que resulte un poco extraño el coeficiente de habitaciones, ya que este es negativo y no se espera que a mayor cantidad de habitaciones el precio de la vivienda sea menor, sin embargo obervando un grafico de cajas de el precio según el número de habitaciones, se puede ver que hay muchos apartamentos de 3 y 4 habitaciones que tienen precios de más de mil millones de pesos, mientras que los que tienen 6 habitaciones sólo uno supera este valor. Por lo tanto el coeficiente puede tener sentido
En esta sección se validan los supuestos del modelo.
## Validacion de supuestos
res2<-mod2$residuals
## Normalidad de residuales
shapiro.test(res2)##
## Shapiro-Wilk normality test
##
## data: res2
## W = 0.78088, p-value < 2.2e-16
En este caso, se utiliza la prueba de Shapiro-Wilk para determinar si los residuos se distribuyen normalmente. El resultado muestra que el valor de W es 0.78088 y el p-value es aproximadamente 0, lo que indica que los residuos no se distribuyen normalmente.
## Homocedasticidad
bptest(mod2)##
## studentized Breusch-Pagan test
##
## data: mod2
## BP = 848.53, df = 5, p-value < 2.2e-16
En este caso, se utiliza la prueba de Breusch-Pagan para determinar si los residuos son homocedásticos. El resultado muestra que el valor de BP es 848.53 y el p-value es aproximadamente 0, lo que indica que los residuos no son homocedásticos.
## Independecia
dwtest(mod2)##
## Durbin-Watson test
##
## data: mod2
## DW = 1.4939, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
En este caso, se utiliza la prueba de Durbin-Watson para determinar si los residuos son independientes. El resultado muestra que el valor de DW es 1.4939 y el p-value es aproximadamente 0, lo que indica que los residuos no son independientes y están correlacionados entre sí.
Se requiere predecir el valor de una vivienda con las siguientes caracteristicas.
| Caracteristicas | 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 |
Mediante la función predict se realiza la predicción, primero declarando un dataframe con los datos sobre la vivienda que se quiere vender.
## Prediccion
new_dat2 <- data.frame(
areaconst = 300,
parqueaderos = 3,
estrato = c(5, 6),
banios = 3,
habitaciones = 5
)
predict(mod2,new_dat2)## 1 2
## 669.5054 724.3007
El resultado indica que un apartamento con estas caracteristicas de estrato 5 valdria en promedio 669.5 millones de pesos y si es estrato 6 valdría 724.3 millones de pesos.
Siguiendo las mismas metodologias del modelo anterior se buscan ofertas potenciales para la vivienda solicitada.
## se incluyen predicciones y residuales en la base
df_sur_apar_ok$res = res2
df_sur_apar_ok$pred = mod2$fitted.values
df3 = head(df_sur_apar_ok[(df_sur_apar_ok$pred<=850 & df_sur_apar_ok$res<=0 & df_sur_apar_ok$estrato %in% c(5, 6)),]%>% arrange(desc(pred)),5)
knitr::kable(df3[,-c(9,10,11,12,13,14)],"pipe")| zona | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | pred |
|---|---|---|---|---|---|---|---|---|
| Zona Sur | 6 | 660 | 210 | 4 | 5 | 3 | Apartamento | 805.5253 |
| Zona Sur | 6 | 650 | 223 | 3 | 5 | 3 | Apartamento | 766.9852 |
| Zona Sur | 5 | 670 | 300 | 3 | 5 | 6 | Apartamento | 745.7519 |
| Zona Sur | 6 | 699 | 164 | 4 | 5 | 3 | Apartamento | 742.9736 |
| Zona Sur | 5 | 500 | 330 | 2 | 4 | 4 | Apartamento | 727.7775 |
De esta manera la mejor oferta es el apartemento de la fila 3 ya que es el unico que cumple parcialmente con las especificaciones dadas y tiene un precio de 670 millones.
## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
Resultados con el otro metodo:
df4=head(df_sur_apar_ok[df_sur_apar_ok$preciom<=850 & df_sur_apar_ok$res<=0,]%>% arrange(desc(preciom)),5)
knitr::kable(df4[,-c(9,10,11,12,13,14)],"pipe")| zona | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | pred |
|---|---|---|---|---|---|---|---|---|
| Zona Sur | 6 | 850 | 352 | 4 | 3 | 3 | Apartamento | 898.6585 |
| Zona Sur | 5 | 730 | 573 | 3 | 8 | 5 | Apartamento | 1290.6391 |
| Zona Sur | 6 | 699 | 164 | 4 | 5 | 3 | Apartamento | 742.9736 |
| Zona Sur | 5 | 690 | 486 | 2 | 4 | 4 | Apartamento | 939.9093 |
| Zona Sur | 5 | 670 | 300 | 3 | 5 | 6 | Apartamento | 745.7519 |
En este caso se pude ver que el apartamento anterior también se encuentra, solo que en la fila 5, con este metodo también se halla otra potencial oferta, que sería el apartamento de la fila 2, el cual cuenta con una mayor area construida y mayor cantidad de baños con un precio de 730 millones.
## Warning in proj4string(comunas): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html