\[\hat{y}_i = \beta_0 + \beta_1x_{i1} + \beta_2x_{i2} + \ldots + \beta_px_{ip}\]

## New names:
## Rows: 20640 Columns: 11
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (1): ocean_proximity dbl (10): ...1, longitude, latitude, housing_median_age,
## total_rooms, total_...
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`

veamos la cabecera de nuestros datos

head(Casas_de_California)

Exploramos nuestros Datos

glimpse(Casas_de_California)
## Rows: 20,640
## Columns: 10
## $ longitude          <dbl> -122.23, -122.22, -122.24, -122.25, -122.25, -122.2…
## $ latitude           <dbl> 37.88, 37.86, 37.85, 37.85, 37.85, 37.85, 37.84, 37…
## $ housing_median_age <dbl> 41, 21, 52, 52, 52, 52, 52, 52, 42, 52, 52, 52, 52,…
## $ total_rooms        <dbl> 880, 7099, 1467, 1274, 1627, 919, 2535, 3104, 2555,…
## $ total_bedrooms     <dbl> 129, 1106, 190, 235, 280, 213, 489, 687, 665, 707, …
## $ population         <dbl> 322, 2401, 496, 558, 565, 413, 1094, 1157, 1206, 15…
## $ households         <dbl> 126, 1138, 177, 219, 259, 193, 514, 647, 595, 714, …
## $ median_income      <dbl> 8.3252, 8.3014, 7.2574, 5.6431, 3.8462, 4.0368, 3.6…
## $ median_house_value <dbl> 452600, 358500, 352100, 341300, 342200, 269700, 299…
## $ ocean_proximity    <chr> "NEAR BAY", "NEAR BAY", "NEAR BAY", "NEAR BAY", "NE…

Observemos la variable Categórica “ocean_proximity” y su frecuencia.

Casas_de_California$ocean_proximity<-as.factor(Casas_de_California$ocean_proximity)
fct_count(Casas_de_California$ocean_proximity)
 Casas_de_California$ocean_proximity<- fct_relevel(Casas_de_California$ocean_proximity,
                                                         "<1H OCEAN", "INLAND" ,"NEAR OCEAN",
                                                         "NEAR BAY","ISLAND")

Visualizamos la variable categórica y sus frecuencias

**Al analizar nuestros datos, resulta relevante plantear la siguiente pregunta: ¿Cuántos valores faltantes (NA) contiene nuestro conjunto de datos? A continuación, procederemos a visualizar la respuesta mediante una gráfica.

plot_missing(Casas_de_California)

Dado que solo tenemos el 1% de valores faltantes en nuestros datos, es apropiado proceder a eliminarlos, ya que su ausencia no afecta significativamente al resultado general del estudio.

Casas_de_California <- na.omit(Casas_de_California)
colSums(is.na(Casas_de_California))
##          longitude           latitude housing_median_age        total_rooms 
##                  0                  0                  0                  0 
##     total_bedrooms         population         households      median_income 
##                  0                  0                  0                  0 
## median_house_value    ocean_proximity 
##                  0                  0

Continuemos explorando más nuestros datos.

plot_histogram(Casas_de_California)

Al visualizar los histogramas de nuestras variables, podemos obtener una idea inicial sobre si siguen o no una distribución normal. Sin embargo, para obtener más información detallada acerca de la distribución de cada variable, podemos realizar gráficos Q-Q (Quantile-Quantile) para cada una de ellas.

plot_qq(Casas_de_California)

Al observar que algunas de nuestras variables se ajustan a una distribución normal a través de los histogramas y los gráficos Q-Q, estamos en una mejor posición para continuar con el análisis de correlación de las variables numéricas.

# Seleccionar solo las columnas numéricas del dataframe
numeric_cols <- Casas_de_California %>%
  select_if(is.numeric)

# Calcular la matriz de correlación para las variables numéricas
cor_matrix <- cor(numeric_cols)

# Usar corrplot para visualizar la matriz de correlación
corrplot(cor_matrix, type = "lower")

Otra forma útil de analizar la correlación entre variables es mediante la visualización de las nubes de puntos (scatter plots) para cada par de variables numéricas.

library(GGally)

ggscatmat(data = Casas_de_California)

Análisis de la Distribución Geográfica de las Casas en función de su Valor y Tamaño de Población

Al examinar la correlación de nuestros datos, podemos representar gráficamente la relación entre dos variables puntuales:

- Correlación entre el Valor Mediano de la Vivienda y el Ingreso Mediano.

  ggplot(Casas_de_California, aes(x = median_income, y = median_house_value)) +
  geom_point(alpha = 0.4, color = "#1465bb") +
  xlim(0, 16) +
  ylim(0, 550000) +
  labs(title = "Diagrama de Dispersión",
       x = "Ingreso Mediano",
       y = "Valor Mediano de la Vivienda") + theme_bw()

Análisis Comparativo de la Ubicación en Relación al Promedio de Valor

## [1] "ocean_proximity"        "Promedio_precio_x_Casa"

Con base en la información obtenida durante el Análisis Exploratorio de Datos (EDA), procedemos a desarrollar un modelo de Regresión Lineal Múltiple.

Modelo<- lm(median_house_value ~ ., data = Casas_de_California)
summary(Modelo)
## 
## Call:
## lm(formula = median_house_value ~ ., data = Casas_de_California)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -556980  -42683  -10497   28765  779052 
## 
## Coefficients:
##                             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)               -2.270e+06  8.801e+04 -25.791  < 2e-16 ***
## longitude                 -2.681e+04  1.020e+03 -26.296  < 2e-16 ***
## latitude                  -2.548e+04  1.005e+03 -25.363  < 2e-16 ***
## housing_median_age         1.073e+03  4.389e+01  24.439  < 2e-16 ***
## total_rooms               -6.193e+00  7.915e-01  -7.825 5.32e-15 ***
## total_bedrooms             1.006e+02  6.869e+00  14.640  < 2e-16 ***
## population                -3.797e+01  1.076e+00 -35.282  < 2e-16 ***
## households                 4.962e+01  7.451e+00   6.659 2.83e-11 ***
## median_income              3.926e+04  3.380e+02 116.151  < 2e-16 ***
## ocean_proximityINLAND     -3.928e+04  1.744e+03 -22.522  < 2e-16 ***
## ocean_proximityNEAR OCEAN  4.278e+03  1.570e+03   2.726  0.00642 ** 
## ocean_proximityNEAR BAY   -3.954e+03  1.913e+03  -2.067  0.03879 *  
## ocean_proximityISLAND      1.529e+05  3.074e+04   4.974 6.62e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 68660 on 20420 degrees of freedom
## Multiple R-squared:  0.6465, Adjusted R-squared:  0.6463 
## F-statistic:  3112 on 12 and 20420 DF,  p-value: < 2.2e-16
# Obtener los residuos del modelo
residuos <- resid(Modelo)

observando el ouput podemos ver:

Veamos la distribucion de nuestros residuos

es importante que la districion de los residuos tenga una distibucion normal con media cercana a 0

# Crea un data frame con los residuos para visualizarlos en GGPLOT2

df_residuos <- data.frame(Residuos = residuos)

# Crea el histograma utilizando ggplot2
his_res<-ggplot(df_residuos, aes(x = Residuos)) +
  geom_histogram(binwidth = 10000, color = "white", fill = "#1465bb") +
  theme_bw() + labs(title = "Histograma de residuos",
       x = "Residuos",
       y = "Frecuencia")
print(his_res)

Una vez con el modelo procedamos a inspeccionar las variables para identificar cuáles de ellas contribuyen significativamente al modelo de Regresión Lineal Múltiple.

Utilizaremos la librería “MASS” para aplicar la función stepAIC(Modelo, direction = c(“both”)). Esta función realizará una iteración de todas las combinaciones posibles de variables para determinar cuáles no aportan valor al modelo y, posteriormente, eliminarlas.

library(MASS)
inspeccion_de_variables <- stepAIC(Modelo,direction = c("both"))
## Start:  AIC=455132.6
## median_house_value ~ longitude + latitude + housing_median_age + 
##     total_rooms + total_bedrooms + population + households + 
##     median_income + ocean_proximity
## 
##                      Df  Sum of Sq        RSS    AIC
## <none>                             9.6255e+13 455133
## - households          1 2.0901e+11 9.6464e+13 455175
## - total_rooms         1 2.8863e+11 9.6544e+13 455192
## - total_bedrooms      1 1.0103e+12 9.7266e+13 455344
## - ocean_proximity     4 2.6007e+12 9.8856e+13 455669
## - housing_median_age  1 2.8154e+12 9.9071e+13 455720
## - latitude            1 3.0323e+12 9.9288e+13 455764
## - longitude           1 3.2595e+12 9.9515e+13 455811
## - population          1 5.8679e+12 1.0212e+14 456340
## - median_income       1 6.3594e+13 1.5985e+14 465495

Al observar que el modelo con todas las variables tiene el AIC más bajo, procedemos a utilizar ese modelo, ya que en este caso es el que mejor se ajusta a los datos.

- Ahora es momento de realizar la validación del modelo para asegurarnos de su eficacia y capacidad de generalización.

# Fijar una semilla para reproducibilidad
set.seed(123)

# Número de filas en el conjunto de datos
total_filas <- nrow(Casas_de_California)

# Número de filas para el conjunto de entrenamiento (80%)
num_entrenamiento <- round(0.8 * total_filas)

# Indices aleatorios para el conjunto de entrenamiento
indices_entrenamiento <- sample(1:total_filas, num_entrenamiento)


conjunto_entrenamiento <- Casas_de_California[indices_entrenamiento, ]


conjunto_prueba <- Casas_de_California[-indices_entrenamiento, ]

modelo <- lm(median_house_value ~ ., data = conjunto_entrenamiento)


predicciones <- predict(modelo, newdata = conjunto_prueba)


rmse <- sqrt(mean((conjunto_prueba$median_house_value - predicciones)^2))

veamos nuestras predicciones de nuestro modelo.

head(predicciones,10)
##        1        2        3        4        5        6        7        8 
## 378962.7 255538.2 257098.7 188356.3 160631.5 222061.5 245206.2 170573.6 
##        9       10 
## 154967.1 144088.2

Concluyamos la evaluación de nuestro modelo calculando el RMSE (Raíz del Error Cuadrático Medio).

\[\text{RMSE} = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2}\]

print(rmse)
## [1] 67676.82