EL objetivo de la actividad se centra en la asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad.
Por lo tanto, se direcciona el tratamiento de la informacion hacia la prediccion del precio metro cuadrado de la vivienda acorde a unas preferencias especificas por los compradores
library(tidyverse) # Manejo de darta
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.2 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.0 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(kableExtra) #para la visualización de tablas
##
## Attaching package: 'kableExtra'
##
## The following object is masked from 'package:dplyr':
##
## group_rows
library(reshape2) # Para melt(), dibujo de correlación
##
## Attaching package: 'reshape2'
##
## The following object is masked from 'package:tidyr':
##
## smiths
library(gridExtra) # Unión de graficas
##
## Attaching package: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
library(GGally) # Presentacion de correlacion
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
library(leaflet) # Presentacion de mapa
library(plotly) # Presentacion de histogramas
##
## Attaching package: 'plotly'
##
## The following object is masked from 'package:ggplot2':
##
## last_plot
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following object is masked from 'package:graphics':
##
## layout
library(lmtest) # pruebas del modelo
## Loading required package: zoo
##
## Attaching package: 'zoo'
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(caret) # Parcialidad de la base de datos
## Loading required package: lattice
##
## Attaching package: 'caret'
##
## The following object is masked from 'package:purrr':
##
## lift
#install.packages("devtools") # solo la primera vez
#devtools::install_github("dgonxalex80/paqueteMODELOS", force =TRUE)
#library(paqueteMODELOS)
data <- paqueteMODELOS::vivienda
data <- as.data.frame(data)
# Conocer la dimension de la base
dimension <- dim(data)
paste("filas:",dimension[1], "columnas:", dimension[2])
## [1] "filas: 8322 columnas: 13"
sapply(data, function(x) class(x)) # identificacion de tipos por variables
## id zona piso estrato preciom areaconst
## "numeric" "character" "character" "numeric" "numeric" "numeric"
## parqueaderos banios habitaciones tipo barrio longitud
## "numeric" "numeric" "numeric" "character" "character" "numeric"
## latitud
## "numeric"
Se identifican algunos errores en el tipo de variable en los siguientes atributos: piso, estrato y parqueaderos., sin embargo, dadas los aspectos generales por parte de las preferencias de vivienda y el protagonismo de la variable estrato, no se procedera a hacer el cambio debido ni la eliminacion de la variable parqueaderos dado a criterios posteriores
# Correccion de tipos
data$piso <- as.numeric(data$piso)
data$parqueaderos <- as.numeric((data$parqueaderos))
sapply(data, function(x) class(x))
## id zona piso estrato preciom areaconst
## "numeric" "character" "numeric" "numeric" "numeric" "numeric"
## parqueaderos banios habitaciones tipo barrio longitud
## "numeric" "numeric" "numeric" "character" "character" "numeric"
## latitud
## "numeric"
El unico cambio de tipo de variable se hizo en piso
sapply(data, function(x) sum(is.na(x))) # Identificacion de NA's
## id zona piso estrato preciom areaconst
## 3 3 2638 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 1605 3 3 3 3 3
## latitud
## 3
Se presenta gran cantidad de NA’s en las variables piso y parqueadero; por lo cual, se imputaran los registros vacíos con sus respectivas medias.
# Imputación de medias
piso_media <- round(mean(data$piso, na.rm = T),2)
data$piso[is.na(data$piso)] <- piso_media
sapply(data, function(x) sum(is.na(x)))
## id zona piso estrato preciom areaconst
## 3 3 0 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 1605 3 3 3 3 3
## latitud
## 3
Dada la poca representatividad de los 3 registros vacíos se procedera a eliminarlos
#eliminacion de registros
data <- drop_na(data)
1. 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?).
# identificacion de los registros unicos en la variable zona y tipos dado a que ambas son criterio de filtros
list_unic <- list(n_zonas = unique(data$zona), n_tipos = unique(data$tipo))
list_unic
## $n_zonas
## [1] "Zona Oriente" "Zona Sur" "Zona Norte" "Zona Oeste" "Zona Centro"
##
## $n_tipos
## [1] "Casa" "Apartamento"
# Aplicacion de filtro Casas & Zona norte
base1 <- data %>% dplyr::filter(zona == "Zona Norte" & tipo == "Casa")
head(base1,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1 1209 Zona Norte 2 5 320 150 2 4
## 2 1592 Zona Norte 2 5 780 380 2 3
## 3 4460 Zona Norte 2 4 625 355 3 5
## habitaciones tipo barrio longitud latitud
## 1 6 Casa acopi -76.51341 3.47968
## 2 3 Casa acopi -76.51674 3.48721
## 3 5 Casa acopi -76.53179 3.40590
#Verificacion del cumplimiento de criterios de la base 1
tail(base1,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 433 747 Zona Norte 3.77 3 330 240 1 5
## 434 1113 Zona Norte 3.77 4 320 100 1 3
## 435 4975 Zona Norte 3.77 6 680 452 1 10
## habitaciones tipo barrio longitud latitud
## 433 7 Casa zona norte -76.50235 3.47350
## 434 4 Casa zona norte -76.51077 3.48795
## 435 10 Casa zona norte -76.53406 3.45962
# Se realiza una lista con valores unicos de la base para corroborar la buena aplicacion de criterios
list_cri1 <- list(unique(base1$zona), unique(base1$tipo))
list_cri1
## [[1]]
## [1] "Zona Norte"
##
## [[2]]
## [1] "Casa"
# MApeo con el paquete leaflet sugerido por la actividad
Casas_Norte <- leaflet(base1) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "blue", radius = 1)
Casas_Norte
A primera vista, se puede observar que no todos los puntos representativos a las casas de la base se encuentran ubicados en la zona norte, ya que se encuentran algunos distribuidos en la zonas centro y sur.
# Aplicacion de filtro Casas & Zona Oriente
base2 <- data %>% dplyr::filter(zona == "Zona Oriente" & tipo == "Casa")
head(base2,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1 1147 Zona Oriente 3.77 3 250 70 1 3
## 2 1169 Zona Oriente 3.77 3 320 120 1 2
## 3 1350 Zona Oriente 3.77 3 350 220 2 2
## habitaciones tipo barrio longitud latitud
## 1 6 Casa 20 de julio -76.51168 3.43382
## 2 3 Casa 20 de julio -76.51237 3.43369
## 3 4 Casa 20 de julio -76.51537 3.43566
# Verificacion de criterios por los ultimos 3 datos de la base
tail(base2,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 139 84 Zona Oriente 3.77 3 260 225 1 8
## 140 107 Zona Oriente 3.77 3 220 129 1 3
## 141 2149 Zona Oriente 3.77 3 385 140 2 2
## habitaciones tipo barrio longitud latitud
## 139 8 Casa zona oriente -76.48180 3.43482
## 140 2 Casa zona oriente -76.48377 3.45818
## 141 4 Casa zona oriente -76.51898 3.41205
Casas_Oriente <- leaflet(base2) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "green", radius = 1)
Casas_Oriente
De igual forma, se presenta la misma observacion del mapa anterior en las casas ubicadas en la zona Oriente de Cali, visualizandose algunos puntos en el Sur.
# Aplicacion de filtro Casas & Zona Sur
base3 <- data %>% dplyr::filter(zona == "Zona Sur" & tipo == "Casa")
head(base3,3)
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## 1 5992 Zona Sur 2.00 4 400 280 3 5 3
## 2 5157 Zona Sur 2.00 3 500 354 1 2 4
## 3 5156 Zona Sur 3.77 3 420 369 1 5 5
## tipo barrio longitud latitud
## 1 Casa 3 de julio -76.540 3.435
## 2 Casa alameda -76.535 3.437
## 3 Casa alameda -76.535 3.438
#Verificacion de los ultimos 3 registros segun el filtro aplicado
tail(base3,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1722 4865 Zona Sur 3.77 3 360 182 1 3
## 1723 6417 Zona Sur 3.77 6 1800 400 3 6
## 1724 8139 Zona Sur 3.77 5 530 142 2 4
## habitaciones tipo barrio longitud latitud
## 1722 9 Casa zona sur -76.53345 3.40969
## 1723 5 Casa zona sur -76.54261 3.35809
## 1724 4 Casa zona sur -76.55587 3.40889
# MApeo casa sur
Casa_Sur <- leaflet(base3) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "red", radius = 1)
Casa_Sur
Acorde al mapa visualizado, se puede observar que aunque la concentración de puntos se encuentra bien referenciada, hay algunos casos donde se presentan etiquetas erróneas acorde a la latitud y longitud representada, apreciandose casas al norte, centro y oriente del mapa
# Aplicacion de filtro Casas & Zona Oeste
base4 <- data %>% dplyr::filter(zona == "Zona Oeste" & tipo == "Casa")
head(base4,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1 6928 Zona Oeste 3 6 1850 302 4 4
## 2 7510 Zona Oeste 3 6 1950 400 4 5
## 3 7586 Zona Oeste 3 6 870 275 3 5
## habitaciones tipo barrio longitud latitud
## 1 3 Casa aguacatal -76.54600 3.44400
## 2 3 Casa aguacatal -76.55000 3.45600
## 3 4 Casa aguacatal -76.55074 3.45649
#Verificacion de los ultimos registros para observar el cumplimiento de criterios
tail(base4,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 130 7110 Zona Oeste 4.00 5 360 174 1 3
## 131 7995 Zona Oeste 5.00 4 150 67 1 2
## 132 236 Zona Oeste 3.77 6 1100 377 2 6
## habitaciones tipo barrio longitud latitud
## 130 8 Casa zona oeste -76.54754 3.42636
## 131 2 Casa zona oeste -76.55387 3.45359
## 132 5 Casa zona oeste -76.49003 3.44940
# Mapeo de Casas ubicadas al Oeste del municipio de Cali
Casas_Oeste <- leaflet(base4) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "purple", radius = 1)
Casas_Oeste
Como en resultados anteriores se observa que algunos puntos no se encuentran etiquetados de manera correcta, ubicandose algunos en la parte sur y oeste del mapa.
# Aplicacion de filtro Casas & Zona Centro
base5 <- data %>% dplyr::filter(zona == "Zona Centro" & tipo == "Casa")
head(base5,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1 5298 Zona Centro 1.00 3 650 240 2 4
## 2 5608 Zona Centro 3.00 3 295 200 1 5
## 3 3355 Zona Centro 3.77 4 1100 217 1 3
## habitaciones tipo barrio longitud latitud
## 1 4 Casa alameda -76.53564 3.43521
## 2 9 Casa alameda -76.53759 3.43403
## 3 1 Casa alameda -76.52600 3.43400
# Verificacion de los ultimos registros correspondiente a los filtros aplicados en la base
tail(base5,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 52 5195 Zona Centro 1.00 3 190 153 1 2
## 53 3188 Zona Centro 3.77 3 450 300 1 9
## 54 2753 Zona Centro 3.77 3 330 300 4 3
## habitaciones tipo barrio longitud latitud
## 52 5 Casa san juan bosco -76.53509 3.44311
## 53 9 Casa san nicolás -76.52431 3.45308
## 54 9 Casa santa helena de -76.52200 3.43300
# MApeo de las viviendas ubicadas en la zona centro del municipio
Casa_Centro <- leaflet(base5) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "black", radius = 1)
Casa_Centro
Por ultimo, la zona centro tambien presenta el mismo problema de sus antecesoras, por lo cual se puede concluir que la base de datos suministrada a nivel zona no cuenta con una informacion veraz sobre la ubicacion de la vivienda, siendo una variable poco confiable al momento de realizar un analis.
2. Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.
# Filtro de la base original
data <- data %>% dplyr::filter(tipo == "Casa")
plot_ly(data, x = ~preciom, type = "histogram") %>%
layout(title = "Histograma precios metro cuadrado de Casas (Miles)")
summary(data$preciom)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 89.0 335.0 450.0 583.7 720.0 1999.0
En el histograma de preciom se puede apreciar que presenta una simetria positiva donde su media es mayor que la mediana y la moda representados por la formulacion anterior donde la media es 583.7 y la mediana 450.
plot_ly(data, x = ~preciom, type = "box") %>%
layout(title = "Boxplot precios metro cuadrado de Casas (Miles)")
Se puede evidenciar outliers en esta variable, que para efectos de ajuste del modelo a representar se podrian omitir. Y ademas se corrobora, con el precio maximo 1999 pesos por precio metro cuadrado.
plot_ly(data, x = ~banios, type = "histogram", marker = list(color = "red"))%>%
layout(title = "Histograma comportamiento número de baños")
Ahora bien, correspondiente al histograma representativo de los baños se observa una grafica que en primera instancia sigue una distribucion normal y ademas se puede entrever que hay unidades de vivienda que no tienen este espacio dentro de su distribucion habitacional
#corroborando la info anterior
head(data[data$banios == 0,], 3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 65 1816 Zona Oriente 3.77 3 750 183 2 0
## 173 1425 Zona Sur 3.77 5 395 220 1 0
## 513 3703 Zona Sur 3.77 6 395 140 2 0
## habitaciones tipo barrio longitud latitud
## 65 0 Casa barrio el recuerdo -76.51772 3.46116
## 173 0 Casa caney -76.51600 3.37600
## 513 3 Casa ciudad jardín -76.52800 3.36500
summary(data$banios)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.000 3.000 4.000 4.095 5.000 10.000
Representadas por una media de 4.1 y una mediana de 4
plot_ly(data, x = ~banios, type = "box")%>%
layout(title = "Boxplot comportamiento número de baños")
Hay solo dos observaciones por fuera de la caja de bigotes representativos de los banios
plot_ly(data, x = ~estrato, type = "histogram")%>%
layout(title = "Histograma comportamiento de estratos")
Se observa que mayoritariamente las casas existentes pertenecen al estrato 5.
plot_ly(data, x = ~areaconst, type = "histogram", marker = list(color = "purple"))%>%
layout(title = "Histograma comportamiento de area construida en vivienda")
Al igual que el histograma mostrado en precios de la vivienda se encuentra una simetria positiva y posteriormente se validara con un boxplot la existencia de outliers de la variable
plot_ly(data, x = ~areaconst, type = "box")%>%
layout(title = "Boxplot comportamiento de area construida en vivienda")
summary(data$areaconst)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 30.0 165.0 250.0 285.9 356.8 1745.0
Se puede notar una media muy alejada del dato maximo de area construida
quantile(data$areaconst, c(0.25, 0.5, 0.75))
## 25% 50% 75%
## 165.00 250.00 356.75
Se valida dicha observacion con los quantiles suministrado por la grafica
Se hace la anotacion de que el modelo a efectuar puede mejorar si se eliminan los outliers de la base
plot_ly(data, x = ~zona, type = "histogram")%>%
layout(title = "Histograma comportamiento de las casas en las Zonas",
xaxis = list(title = "zonas"))
Se observa que las mayorias de las viviendas analizadas se ubican en la zona sur del municipio
plot_ly(data, x = ~habitaciones, type = "histogram")%>%
layout(title = "Histograma comportamiento de las casas en las Habitaciones",
xaxis = list(title = "Habitaciones"))
Al igual que la grafica de baños se observan algunas viviendas sin habitaciones
head(data[data$habitaciones == 0,],3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 65 1816 Zona Oriente 3.77 3 750 183 2 0
## 173 1425 Zona Sur 3.77 5 395 220 1 0
## 660 3347 Zona Sur 2.00 4 950 444 1 0
## habitaciones tipo barrio longitud latitud
## 65 0 Casa barrio el recuerdo -76.51772 3.46116
## 173 0 Casa caney -76.51600 3.37600
## 660 0 Casa cristóbal colón -76.52600 3.42300
# Dado que el ejercicio demanda una correlacion entre la variable dependiente preciom con zona, se procedio a convertirla a tipo factor y posteriormente a tipo numerico
data$zona <- as.factor(data$zona)
data$zona <- as.numeric(data$zona)
#Posteriormente se hace un filtro entre las variables numericas y se procede a hacer una correlacion entre la varible dependiente e independientes
num_df <- data[sapply(data, function(x) class(x))=='numeric']
num_df <- dplyr::select(num_df, preciom, zona, estrato, areaconst, banios, habitaciones,
-longitud, -latitud, -id) # Se eliminan id, latitud y longitud
#Se aplica la correlación
cor_mat <- round(cor(num_df),2)
cor_mat_long <- melt(cor_mat)
# Crear el mapa de calor con ggplot2
ggplot(data = cor_mat_long, aes(x = Var1, y = Var2, fill = value)) +
geom_tile(color = "white") + # Tiles con borde blanco
scale_fill_gradient(low = "lightblue", high = "darkblue") + # Escala de colores
labs(title = "Correlación", x = "", y = "") + # Títulos de ejes
geom_text(aes(label = value), color = "black") + #Valores
theme_minimal() + # Estilo del tema
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Ajustar la orientación del texto en el eje x
Como primera observacion se tiene que decir que se transformo la
variable zona a numerica acorde a las exigencias de la correlacion de
pearson con respecto a que las variables analizadas deben ser de tipo
numerico, y se complementa con la siguiente grafica.
ggpairs(num_df, title="Correlacion de variables numericas")
Acorde a las graficas anteriores la correlacion mas fuerte resulta entre
las variables preciom y areaconst con un 0,645,
posteriormente la misma variable dependiente se encuentra altamente
relacionada con la variable estrato.
De las demas relaciones se puede destacar areaconst y banios con 0,50 y por ultimo, banios con habitaciones con 0,453.
3. Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo)
#Construccion del modelo
modelo = lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = data)
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1190.80 -114.52 -25.94 74.59 986.16
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -413.87536 25.58852 -16.174 < 2e-16 ***
## areaconst 0.74227 0.02941 25.235 < 2e-16 ***
## estrato 116.07109 5.26618 22.041 < 2e-16 ***
## habitaciones -14.74995 3.18137 -4.636 3.73e-06 ***
## parqueaderos 64.29943 3.47719 18.492 < 2e-16 ***
## banios 39.03498 4.05083 9.636 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 205.2 on 2480 degrees of freedom
## Multiple R-squared: 0.6834, Adjusted R-squared: 0.6828
## F-statistic: 1071 on 5 and 2480 DF, p-value: < 2.2e-16
La ecuacion de regresion corresponde a Precio = −413.8 + 0.74(areaconst) + 116.1(estrato) - 14.7(habitaciones) + 64.3(parqueaderos) + 39.03 (banios)
Dado que todas lavariables explicativas utilizadas en el modelo tienen un p-value menor a 0,05; se rechaza la hipotesis nula de que sus betas sean igual a 0, por lo cual todas son de caracter significativa para el modelo.
Por ultimo, el R cuadrado posee un 0,68; significa que alrededor del 68% de la variabilidad en la variable dependiente es explicada con las variables independientes seleccionadas. Como se sugirio anteriormente, se podria eliminar outliers, ademas de la posible redundancia que hay entre la variable dependiente y areaconst.
4.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).
par(mfrow = c(2, 2))
plot(modelo)
summary(modelo$residuals)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -1190.80 -114.52 -25.94 0.00 74.59 986.16
t.test(modelo$residuals, mu=0)
##
## One Sample t-test
##
## data: modelo$residuals
## t = 3.62e-15, df = 2485, p-value = 1
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -8.063801 8.063801
## sample estimates:
## mean of x
## 1.488619e-14
Acorde a lo obtenido por test se tiene de que se cumple el supuesto de que el valor esperado de los residuos es igual a 0
lmtest::gqtest(modelo) # Determinacion de la heterocedasticidad.
##
## Goldfeld-Quandt test
##
## data: modelo
## GQ = 1.268, df1 = 1237, df2 = 1237, p-value = 1.525e-05
## alternative hypothesis: variance increases from segment 1 to 2
Dado a que el p value es menor a 0,05 no se tiene evidencia suficiente para eliminar el supuesto de heterocedasticidad en los errores, por lo cual el supuesto no se cumple.
Como sugerencia se puede eliminar variables que resulten redundantes en cuanto a su relacion, e inclusive utilizar otras tecnicas como el boostrapping
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.89699, p-value < 2.2e-16
Dado a que el p-value es menor a 0.05 no se rechaza la hipotesis nula de que los errores sigan una distribución normal.
COmo sugerencia nuevamente se parte de eliminar outliers para mejorar la normalidad de los datos
lmtest::dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.5759, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
Nuevamente a terminos de valoración del p-value se tiene la conclusión de que los errores no son independientes.
5. Realice una partición en los datos de forma aleatoria donde el 70% sea un set para entrenar el modelo y el 30% para prueba. Estime el modelo con la muestra del 70%. Muestre los resultados
# Creación de la partición de la base
particion <- createDataPartition(data$preciom, p = 0.7, list = FALSE)
# Crea los conjuntos de datos de entrenamiento y prueba
train <- data[particion, ]
test <- data[-particion, ]
# Estimación del nuevo modelo
modelo_2 = lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = train )
summary(modelo_2)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -782.67 -114.19 -25.51 73.27 982.87
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -397.61239 30.68435 -12.958 < 2e-16 ***
## areaconst 0.82302 0.03692 22.290 < 2e-16 ***
## estrato 113.69069 6.33829 17.937 < 2e-16 ***
## habitaciones -18.93521 3.82982 -4.944 8.39e-07 ***
## parqueaderos 64.26825 4.11607 15.614 < 2e-16 ***
## banios 37.28648 4.91724 7.583 5.48e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 203.6 on 1736 degrees of freedom
## Multiple R-squared: 0.6931, Adjusted R-squared: 0.6922
## F-statistic: 784.2 on 5 and 1736 DF, p-value: < 2.2e-16
Se obtienen nuevamente la conclusion de que todas las variables son significativas para explicar el comportamiento de la variable dependiente, a su vez se obtiene un R cuadrado ligeramente menor que con el antiguo modelo
6. Realice predicciones con el modelo anterior usando los datos de prueba (30%)
test$predicciones <- fitted(lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = test ))
# predicciones realizadas
head(select(test, preciom, predicciones), 5)
## preciom predicciones
## 2 320 117.8795
## 4 400 587.0126
## 5 320 500.6196
## 6 780 621.5123
## 9 600 328.9690
7. Calcule el error cuadratico medio, el error absoluto medio y el R2, interprete
# Error Cuadrático Medio (MSE)
mse <- mean((test$predicciones - test$preciom)^2)
# Error Absoluto Medio (MAE)
mae <- mean(abs(test$predicciones - test$preciom))
# Coeficiente de determinación (R^2)
r2 <- 1 - sum((test$preciom - test$predicciones)^2) / sum((test$preciom - mean(test$preciom))^2)
paste("El error cuadrático medio es:", mse)
## [1] "El error cuadrático medio es: 42786.4018081905"
paste("El error absoluto medio es:", mae)
## [1] "El error absoluto medio es: 141.838544766954"
paste("El Coeficiente de determinación es:", r2)
## [1] "El Coeficiente de determinación es: 0.666094541631454"
Error Cuadrático Medio (MSE): El MSE es Este valor indica el promedio de los cuadrados de las diferencias entre las predicciones realizadas al precio metro cuadrado de la vivienda elevado al cuadrado
El MAE es 139.1 representa el promedio de las diferencias absolutas entre las predicciones y los valores reales.
Coeficiente de Determinación (R²): El coeficiente de determinación es 0,71, por lo cual explica aceptablemente la variabilidad del modelo realizado.
Por lo tanto dado que el R cuadrado es relativamente alto y los errores cuadráticos y absolutos medios son moderados, los resultados sugieren que el modelo de regresión múltiple que se ha utilizado tiene una capacidad razonable para predecir el precio por metro cuadrado de la vivienda de la compañia C&A por lo cual puede utilizarse como insumo para dar respuesta al requerimiento de la empresa internacional hacia la inmobiliaria.