Para iniciar con la actividad se realiza principalmente un análisis exploratorio de los datos y ajustes de limpieza de los datos.
Se llaman todos los paquetes y librerías a utilizar para el procesamiento, modelado y graficas.
# instalacion de librerias y paquetes
#install.packages("learnr") # solo la primera vez
#install.packages("devtools") # solo la primera vez
devtools::install_github("dgonxalex80/paqueteMODELOS", force =TRUE)
## digest (0.6.34 -> 0.6.35) [CRAN]
## package 'digest' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\PC\AppData\Local\Temp\RtmpY7NIWs\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
## checking for file 'C:\Users\PC\AppData\Local\Temp\RtmpY7NIWs\remotes4b885a042beb\dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION' ... ✔ checking for file 'C:\Users\PC\AppData\Local\Temp\RtmpY7NIWs\remotes4b885a042beb\dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION'
## ─ preparing 'paqueteMODELOS': (1.3s)
## checking DESCRIPTION meta-information ... ✔ checking DESCRIPTION meta-information
## ─ checking for LF line-endings in source and make files and shell scripts
## ─ checking for empty or unneeded directories
## ─ building 'paqueteMODELOS_0.1.0.tar.gz'
##
##
library(paqueteMODELOS)
library(dplR)
library(plotly)
library(corrplot)
#install.packages("PerformanceAnalytics")
library(PerformanceAnalytics)
#install.packages("mice")
library(mice)#install.packages("caret")
library(caret)
Se importa el data set vivienda y es llamado como “data” en este ejercicio.
# importacion del data set vivienda
data("vivienda")
Se identifica si el data set tienen valores faltantes.
# identificar valores nan
vivienda_na <- colSums(is.na(vivienda)) %>% as.data.frame()
print(vivienda_na)
## .
## id 3
## zona 3
## piso 2638
## estrato 3
## preciom 2
## areaconst 3
## parqueaderos 1605
## banios 3
## habitaciones 3
## tipo 3
## barrio 3
## longitud 3
## latitud 3
head(vivienda)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona O… <NA> 3 250 70 1 3 6
## 2 1169 Zona O… <NA> 3 320 120 1 2 3
## 3 1350 Zona O… <NA> 3 350 220 2 2 4
## 4 5992 Zona S… 02 4 400 280 3 5 3
## 5 1212 Zona N… 01 5 260 90 1 2 3
## 6 1724 Zona N… 01 5 240 87 1 3 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Se muestran gráficamente los datos faltantes.
# muestra los datos faltantes en la grafica
grafico <-md.pattern(vivienda, rotate.names = TRUE)
Se observa que existen dos filas totalmente vacías por lo que se procede a depurarla realizando eliminación de estos datos ya que no aportan información, para la variable parqueadero se sustituye por cero (0) y para la variable piso por la moda.
Se realiza ajuste donde se colocan las variables categóricas en mayúsculas para manejar un estándar.
# se colocan las variabloes categoricas en mayuscula
vivienda$barrio = toupper(vivienda$barrio)
vivienda$tipo = toupper(vivienda$tipo)
vivienda$zona = toupper(vivienda$zona)
Para los parqueaderos que cuentan con datos vacíos se realiza sustitución por el valor cero (0) indicando que no existen parqueaderos.
#limpieza de los dtaos
# parqueadero nulos se reemplazan por 0
vivienda$parqueaderos[is.na(vivienda$parqueaderos)] <- 0
grafico <-md.pattern(vivienda, rotate.names = TRUE)
Para la variable piso se realiza sustitución de los datos vacíos por la moda correspondiente.
moda <- as.numeric(names(sort(table(vivienda$piso), decreasing = TRUE)[1]))
# Reemplaza los NA por la moda
vivienda$piso[is.na(vivienda$piso)] = moda
grafico <-md.pattern(vivienda, rotate.names = TRUE)
Para las filas vacías se elimina la información.
#Eliminancion de filas nan
vivienda= na.omit(vivienda)
grafico <-md.pattern(vivienda, rotate.names = TRUE)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
De acuerdo a la imagen anterior podemos evidenciar que no existe ningún dato faltante por lo cual podemos proceder con el ejercicio.
# se seleccionan las casas de la zona norte de cali
# se realiza conteo de las zonas con su respectivo tipo de vivienda
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
Se selecciona la zona norte y las viviendas tipo casa.
# se selecciona la zona norte y las viviendas tipo casa
Data = subset(vivienda, vivienda$zona == "ZONA NORTE" & vivienda$tipo == "CASA")
Se muestran los primeros tres registros de la selección de casas de la zona norte.
# primeros 3 datos
print("Primeros 3 registros:")
## [1] "Primeros 3 registros:"
print(head(Data, 3))
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 ZONA N… 02 5 320 150 2 4 6
## 2 1592 ZONA N… 02 5 780 380 2 3 3
## 3 4057 ZONA N… 02 6 750 445 0 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Verificar con algunas tablas
print("Tabla de frecuencias de zona y tipo de vivienda:")
## [1] "Tabla de frecuencias de zona y tipo de vivienda:"
print(table(Data$zona, Data$tipo))
##
## CASA
## ZONA NORTE 722
print("Resumen de datos:")
## [1] "Resumen de datos:"
print(summary(Data))
## id zona piso estrato
## Min. : 58.0 Length:722 Length:722 Min. :3.000
## 1st Qu.: 766.2 Class :character Class :character 1st Qu.:3.000
## Median :2257.0 Mode :character Mode :character Median :4.000
## Mean :2574.6 Mean :4.202
## 3rd Qu.:4225.0 3rd Qu.:5.000
## Max. :8319.0 Max. :6.000
## preciom areaconst parqueaderos banios
## Min. : 89.0 Min. : 30.0 Min. : 0.000 Min. : 0.000
## 1st Qu.: 261.2 1st Qu.: 140.0 1st Qu.: 0.000 1st Qu.: 2.000
## Median : 390.0 Median : 240.0 Median : 1.000 Median : 3.000
## Mean : 445.9 Mean : 264.9 Mean : 1.314 Mean : 3.555
## 3rd Qu.: 550.0 3rd Qu.: 336.8 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1940.0 Max. :1440.0 Max. :10.000 Max. :10.000
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:722 Length:722 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.53
## Median : 4.000 Mode :character Mode :character Median :-76.52
## Mean : 4.507 Mean :-76.52
## 3rd Qu.: 5.000 3rd Qu.:-76.50
## Max. :10.000 Max. :-76.47
## latitud
## Min. :3.333
## 1st Qu.:3.452
## Median :3.468
## Mean :3.460
## 3rd Qu.:3.482
## Max. :3.496
Se seleccionan las variables más relevantes de acuerdo a la solicitud.
Data2 <- Data[, c(5, 6, 4, 8, 9)] # Selecciona las columnas 1, 3 y 5
print(head(Data2,5))
## # A tibble: 5 × 5
## preciom areaconst estrato banios habitaciones
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 320 150 5 4 6
## 2 780 380 5 3 3
## 3 750 445 6 7 6
## 4 625 355 4 5 5
## 5 750 237 5 6 6
Se presenta la correlación de las variables para saber el efecto que positivo que van a tener en el modelo.
# Calcular la matriz de correlación
matriz_correlacion <- cor(Data2[, c("preciom", "areaconst", "estrato", "banios", "habitaciones")])
# Imprimir la matriz de correlación
print(matriz_correlacion)
## preciom areaconst estrato banios habitaciones
## preciom 1.0000000 0.7313480 0.6123503 0.5233357 0.3227096
## areaconst 0.7313480 1.0000000 0.4573818 0.4628152 0.3753323
## estrato 0.6123503 0.4573818 1.0000000 0.4083039 0.1073141
## banios 0.5233357 0.4628152 0.4083039 1.0000000 0.5755314
## habitaciones 0.3227096 0.3753323 0.1073141 0.5755314 1.0000000
De acuerdo a la matriz de correlación se evidencia que la correlación más fuerte en el data set es el precio de la vivienda con el área construida con un 73% seguido del precio de la vivienda y el estrato con una correlación de 61%.
# Crear un gráfico de heatmap interactivo con plotly
heatmap <- plot_ly(z = matriz_correlacion, x = colnames(matriz_correlacion), y = colnames(matriz_correlacion), type = "heatmap", colorscale = "Viridis")
# Mostrar el gráfico
heatmap
Se grafica la matriz de correlación con un gráfico de dispersión en 3D.
# Gráfico de dispersión 3D
# Convertir la matriz a un data frame
datos_3d <- as.data.frame(as.table(matriz_correlacion))
# Crear un gráfico 3D interactivo
grafico_3d <- plot_ly(datos_3d, x = ~Var1, y = ~Var2, z = ~Freq, type = 'scatter3d', mode = 'markers')
# Mostrar el gráfico 3D
grafico_3d
columnas_numericas <- Data2[sapply(Data2, is.numeric)]
matrizcor <- cor(columnas_numericas)
corrplot (matrizcor, method = "number", number.cex = 0.5)
chart.Correlation(Data2, histogram = TRUE, method = "pearson")
Siguiendo la dinámica se observa nuevamente la fuerte correlación entre el precio de la vivienda con el área construida y el estrato, también se observa que la correlación más baja encontrada es entre el estrato y las habitaciones.
Se estima el modelo de regresión lineal múltiple.
Data3 <- Data[, c(5, 6, 4, 9, 7, 8)] # Selecciona las columnas 1, 3 y 5
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = Data3)
Se saca un resumen del modelo de regresion.
# Resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = Data3)
##
## Residuals:
## Min 1Q Median 3Q Max
## -964.04 -80.10 -17.08 50.06 1069.45
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -236.47551 30.36582 -7.788 2.40e-14 ***
## areaconst 0.82677 0.04368 18.926 < 2e-16 ***
## estrato 86.42579 7.39747 11.683 < 2e-16 ***
## habitaciones 1.44443 4.16411 0.347 0.729
## parqueaderos -1.67672 4.31505 -0.389 0.698
## banios 26.97978 5.34384 5.049 5.65e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 159.1 on 716 degrees of freedom
## Multiple R-squared: 0.6508, Adjusted R-squared: 0.6484
## F-statistic: 266.9 on 5 and 716 DF, p-value: < 2.2e-16
De acuerdo al modelo anterior se puede interpretar de la siguiente forma:
Área construida: Por cada metro cuadrado de la casa esperamos que el precio de la vivienda aumente en promedio un $0.83. manteniendo la demás información igual.
Estrato: Por cada estrato adicional en el que se encuentra la vivienda “CASA” esperamos que el precio de esta aumente en promedio un $86.63 esto indica la influencia que tienen el estrato con el precio de la vivienda.
Habitaciones y parqueaderos: En promedio no parece a ver ningún efecto significativo en el precio de la vivienda y no podemos estar seguro de estar relaciones ya que el valor p no es significativo y este tiene un impacto distinto en el pecio después de tener presente otras variables.
Baños: Por cada baño adiciona en la vivienda esperamos que el precio aumente en promedio un $26.98 esto da indicios a que por baño adicional puede agregar valor a la vivienda.
Se realiza las siguientes interpretaciones de los resultados.
#Interpretar los coeficientes
# Coeficientes estimados
coeficientes <- coef(modelo)
print(coeficientes)
## (Intercept) areaconst estrato habitaciones parqueaderos banios
## -236.475512 0.826774 86.425791 1.444431 -1.676721 26.979782
No se tendrá en cuenta la interpretación de los coeficientes ya que en el punto anterior se realiza la interpretación correspondiente y detallada.
# Intervalos de confianza para los coeficientes
intervalos_confianza <- confint(modelo)
print(intervalos_confianza)
## 2.5 % 97.5 %
## (Intercept) -296.0921999 -176.8588248
## areaconst 0.7410086 0.9125393
## estrato 71.9024643 100.9491180
## habitaciones -6.7309017 9.6197637
## parqueaderos -10.1483778 6.7949359
## banios 16.4883088 37.4712559
De acuerdo a los intervalos de confianza del 95% se puede interpretar que el área construida el coeficiente esta aproximadamente entre el 0.7441 y 0.913, esto indica que el precio esperado para la vivienda puede aumentar por cada metro adicional. En cuanto al estrato, está en aproximadamente 71.902 y 100.949 y por cada estrato puede aumentar el precio de la vivienda. Los baños el verdadero coeficiente está en aproximadamente 16.488 y 37.471 indicando el precio adicional por cada baño. Por otra parte, sin descartar las habitaciones y los baños no existe suficiente información y no está claro el efecto que puede tener en el precio de la vivienda esto indica que el coeficiente no es significativo y no podemos estar seguro del impacto que este genere en el precio final de la vivienda.
# Pruebas de hipótesis sobre los coeficientes
pruebas_hipotesis <- summary(modelo)$coef[, c("Estimate", "Pr(>|t|)")]
print(pruebas_hipotesis)
## Estimate Pr(>|t|)
## (Intercept) -236.475512 2.399693e-14
## areaconst 0.826774 4.397467e-65
## estrato 86.425791 5.495234e-29
## habitaciones 1.444431 7.287864e-01
## parqueaderos -1.676721 6.977058e-01
## banios 26.979782 5.646533e-07
De acuerdo a las hipótesis se puede observar e interpretar que los valores p para el área construida, estrato y baños tiene un efecto significativo en el precio de la vivienda, por otro lado, las habitaciones y parqueaderos no se tienen suficiente evidencia para indicar si tienen o no un efecto significativo en el precio de la vivienda.
Se crea una semilla para la reproducibilidad.
set.seed(123)
Se realiza la partición de los datos de forma aleatoria donde el 70% es para entrenar el modelo y el 30 % para la prueba del modelo.
# Partición de datos (70% entrenamiento, 30% prueba)
indice_particion <- createDataPartition(Data3$preciom, p = 0.7, list = FALSE)
datos_entrenamiento <- Data3[indice_particion, ]
datos_prueba <- Data3[-indice_particion, ]
Se ajusta el modelo con la muestra de entrenamiento del 70%.
modelo_entrenamiento <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos +
banios, data = datos_entrenamiento)
Por medio de la función summary se estiman los resultados del modelo de entrenamiento.
summary(modelo_entrenamiento)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = datos_entrenamiento)
##
## Residuals:
## Min 1Q Median 3Q Max
## -767.94 -82.43 -20.27 47.44 1026.16
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -238.0965 35.6840 -6.672 6.68e-11 ***
## areaconst 0.9132 0.0512 17.837 < 2e-16 ***
## estrato 81.8633 8.8550 9.245 < 2e-16 ***
## habitaciones 4.0646 4.8588 0.837 0.403
## parqueaderos -2.2614 5.1712 -0.437 0.662
## banios 24.4086 6.0513 4.034 6.35e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 156.1 on 501 degrees of freedom
## Multiple R-squared: 0.6832, Adjusted R-squared: 0.6801
## F-statistic: 216.1 on 5 and 501 DF, p-value: < 2.2e-16
A continuación, con ayuda de la función predict se predice el modelo con el set de prueba.
# Realiza predicciones con el modelo en el conjunto de prueba
predicciones <- predict(modelo_entrenamiento, newdata = datos_prueba)
Se para comprobar el modelo se muestran las primeras filas de las predicciones realizadas.
head(predicciones)
## 1 2 3 4 5 6
## 599.1478 351.1711 462.7797 214.6228 404.7525 202.5018
En el código anterior, predict se utiliza para obtener las predicciones del modelo entrenado (modelo entrenamiento) sobre los datos de prueba (datos prueba). El resultado es un vector de predicciones que se puede utilizar para comparar con los valores reales, es decir, La precisión del modelo comparando las predicciones con las respuestas reales. Por ejemplo, se puede calcular el error cuadrático medio (MSE) o el coeficiente de determinación ( r2). esto lo podemos evidenciar en el siguiente código de MSE.
# Calcula el MSE
mse <- mean((datos_prueba$preciom - predicciones)^2)
# Muestra el MSE
print(paste("Error Cuadrático Medio (MSE):", mse))
## [1] "Error Cuadrático Medio (MSE): 28256.6335796622"
# Cálculo del MSE
mse <- mean((datos_prueba$preciom - predicciones)^2)
# Cálculo del MAE
mae <- mean(abs(datos_prueba$preciom - predicciones))
# Cálculo del R^2
r_cuadrado <- 1 - sum((datos_prueba$preciom - predicciones)^2) / sum((datos_prueba$preciom - mean(datos_prueba$preciom))^2)
# Muestra los resultados
print(paste("Error Cuadrático Medio (MSE):", mse))
## [1] "Error Cuadrático Medio (MSE): 28256.6335796622"
print(paste("Error Absoluto Medio (MAE):", mae))
## [1] "Error Absoluto Medio (MAE): 102.751472496813"
print(paste("Coeficiente de Determinación (R^2):", r_cuadrado))
## [1] "Coeficiente de Determinación (R^2): 0.54532890848541"
Interpretación
MSE (Error Cuadrático Medio): Mide el promedio de los errores al cuadrado entre las predicciones y los valores reales. Cuanto más cercano a cero es mejor. En este caso el valor es de 28256.63 aproximados indicando que el modelo no se ajusta a los datos o que existe un alto grado de variabilidad, si este valor fuera más bajo, el modelo seria capas de predecir con mayor precisión los valores observados.
MAE (Error Absoluto Medio): Mide el promedio de las diferencias absolutas entre las predicciones y los valores reales. en este caso es de 102.75 aproximados y si este valor fuera mas bajo mejor es el ajuste del modelo a los datos.
R2 (Coeficiente de Determinación): Indica la proporción de la variabilidad total en la variable dependiente que es explicada por el modelo. Un R 2 cercano a 1 indica un buen ajuste, mientras que cercano a 0 indica un mal ajuste. En este caso el valor es de 0.54 aproximados indicando que el 54% de la variabilidad en la variable dependiente puede ser explicada por el modelo.