# Cargar datos desde el archivo Excel
file_path <- "E:/OneDrive/Escritorio/BI & BA/3. MODULO 3 - BUSINESS ANALYTICS/BI INTRODUCTION/W16604-XLS-ENG.xlsx"
data <- read_excel(file_path)
attach(data)
# Exploración inicial de los datos
str(data)
## tibble [62 × 10] (S3: tbl_df/tbl/data.frame)
## $ Web ID : chr [1:62] "F1410261" "V1089633" "V1052961" "V1071997" ...
## $ type : chr [1:62] "house" "house" "house" "house" ...
## $ subtype : chr [1:62] "Single Family Detached" "Condo Apartment" "Single Family Detached" "Single Family Detached" ...
## $ sqfoot : num [1:62] 4115 990 4359 2769 1975 ...
## $ bedrooms : num [1:62] 3 2 3 5 3 6 2 2 1 2 ...
## $ bathrooms : num [1:62] 4 2 4 4 3 4 2 1 1 1 ...
## $ half baths : num [1:62] 0 0 0 0 0 0 0 0 0 0 ...
## $ price : num [1:62] 1050000 199900 1399000 2798000 598800 ...
## $ status : chr [1:62] "STACT" "STACT" "STINA" "STINA" ...
## $ last update: chr [1:62] "2014-07-09 155732" "2014-10-10 152509" "2014-09-15 133614" "2014-08-19 154230" ...
summary(data)
## Web ID type subtype sqfoot
## Length:62 Length:62 Length:62 Min. : 0
## Class :character Class :character Class :character 1st Qu.: 996
## Mode :character Mode :character Mode :character Median :1422
## Mean :1958
## 3rd Qu.:2917
## Max. :5656
## bedrooms bathrooms half baths price
## Min. :0.000 Min. :0.000 Min. :0 Min. : 22500
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:0 1st Qu.: 371500
## Median :3.000 Median :2.000 Median :0 Median : 568950
## Mean :3.435 Mean :2.613 Mean :0 Mean : 706577
## 3rd Qu.:4.750 3rd Qu.:3.750 3rd Qu.:0 3rd Qu.: 839925
## Max. :9.000 Max. :8.000 Max. :0 Max. :2798000
## status last update
## Length:62 Length:62
## Class :character Class :character
## Mode :character Mode :character
##
##
##
# 1. Matriz de correlación
ggpairs(data[, c("price", "sqfoot", "bedrooms", "bathrooms")],
lower = list(continuous = "smooth"),
diag = list(continuous = "barDiag"),
axisLabels = "none")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# 2. Visualización del boxplot con colores diferentes
boxplot_price <- ggplot(data, aes(x = subtype, y = price, fill = subtype)) +
geom_boxplot() +
labs(title = "Boxplot de Price por Subtype",
x = "Subtype",
y = "Price") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
scale_fill_brewer(palette = "Set3") # Usar una paleta de colores de RColorBrewer
print(boxplot_price)

##Interpretación: Las propiedades de tipo Single Family Detached muestran precios más altos y mayor variabilidad (mediana alrededor de $1,000,000), con varios valores atípicos por encima de $2,000,000, en comparación con los Condo Apartment (mediana cercana a $500,000) y Townhouse (mediana alrededor de $300,000), que presentan distribuciones más estrechas con algunos valores atípicos dispersos.
# 3. Modelo de regresión lineal inicial
modelo <- lm(price ~ bathrooms + bedrooms + sqfoot, data = data)
summary(modelo)
##
## Call:
## lm(formula = price ~ bathrooms + bedrooms + sqfoot, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -737408 -205622 -63993 95905 1775480
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 34429.28 119832.68 0.287 0.7749
## bathrooms 66363.12 87176.02 0.761 0.4496
## bedrooms 122448.37 59400.69 2.061 0.0438 *
## sqfoot 39.87 92.47 0.431 0.6680
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 429500 on 58 degrees of freedom
## Multiple R-squared: 0.4216, Adjusted R-squared: 0.3917
## F-statistic: 14.09 on 3 and 58 DF, p-value: 5.205e-07
##Interpretación: El modelo explica aproximadamente el 42.16% de la variabilidad en los precios (price) Entre los predictores, el número de habitaciones (bedrooms) es el único significativo al nivel de significancia del 5% (p = 0.0438), sugiriendo que, manteniendo constantes las demás variables, cada habitación adicional aumenta el precio en promedio en 122,448.37 unidades monetarias. Ni los baños (bathrooms) ni el área en pies cuadrados (sqfoot) resultaron ser predictores significativos en este modelo inicial.
# 4. análisis stepwise para selección de variables
modelo_step <- step(modelo, direction = "both", trace = 1)
## Start: AIC=1612.18
## price ~ bathrooms + bedrooms + sqfoot
##
## Df Sum of Sq RSS AIC
## - sqfoot 1 3.4284e+10 1.0732e+13 1610.4
## - bathrooms 1 1.0689e+11 1.0805e+13 1610.8
## <none> 1.0698e+13 1612.2
## - bedrooms 1 7.8378e+11 1.1482e+13 1614.6
##
## Step: AIC=1610.38
## price ~ bathrooms + bedrooms
##
## Df Sum of Sq RSS AIC
## - bathrooms 1 2.6915e+11 1.1001e+13 1609.9
## <none> 1.0732e+13 1610.4
## + sqfoot 1 3.4284e+10 1.0698e+13 1612.2
## - bedrooms 1 1.0332e+12 1.1765e+13 1614.1
##
## Step: AIC=1609.92
## price ~ bedrooms
##
## Df Sum of Sq RSS AIC
## <none> 1.1001e+13 1609.9
## + bathrooms 1 2.6915e+11 1.0732e+13 1610.4
## + sqfoot 1 1.9655e+11 1.0805e+13 1610.8
## - bedrooms 1 7.4935e+12 1.8495e+13 1640.1
summary(modelo_step)
##
## Call:
## lm(formula = price ~ bedrooms, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -786279 -233397 -47116 121089 1796755
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 59522 114899 0.518 0.606
## bedrooms 188345 29462 6.393 2.69e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 428200 on 60 degrees of freedom
## Multiple R-squared: 0.4052, Adjusted R-squared: 0.3953
## F-statistic: 40.87 on 1 and 60 DF, p-value: 2.687e-08
###Este modelo final tiene un AIC de 1609.9, que es el más bajo de todos los modelos evaluados. La eliminación de bathrooms y sqfoot resultó en una mejora del AIC, mientras que mantener solo bedrooms como predictor resultó en el modelo más efectivo para predecir el price.
# Aplicar el análisis stepwise para selección de variables
conf_intervals <- confint(modelo_step)
print(conf_intervals)
## 2.5 % 97.5 %
## (Intercept) -170311.2 289354.2
## bedrooms 129412.6 247276.8
##El análisis de intervalos de confianza refuerza la significancia del número de habitaciones (bedrooms) como predictor en el modelo final, mostrando que su impacto en el precio es significativo y positivo
# 5. Análisis de residuos
## Gráficos de relación lineal entre los predictores numéricos y la variable respuesta
plot1 <- ggplot(data = data, aes(bathrooms, modelo_step$residuals)) +
geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
labs(title = "Residuos vs. Bathrooms") +
theme_bw()
plot2 <- ggplot(data = data, aes(bedrooms, modelo_step$residuals)) +
geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
labs(title = "Residuos vs. Bedrooms") +
theme_bw()
plot3 <- ggplot(data = data, aes(sqfoot, modelo_step$residuals)) +
geom_point() + geom_smooth(color = "firebrick") + geom_hline(yintercept = 0) +
labs(title = "Residuos vs. Sqfoot") +
theme_bw()
grid.arrange(plot1, plot2, plot3, ncol = 2)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

##Interpretación: Los gráficos de residuos versus los predictores (bathrooms, bedrooms, sqfoot) no muestran patrones claros de heterocedasticidad o relaciones no lineales significativas, aunque se observa una ligera tendencia no lineal en bedrooms que podría requerir más investigación. En general, los residuos están distribuidos aleatoriamente, sugiriendo un buen ajuste del modelo.
# 5.1 Pruebas de normalidad
pearson_test <- pearson.test(modelo_step$residuals)
print(pearson_test)
##
## Pearson chi-square normality test
##
## data: modelo_step$residuals
## P = 26.71, p-value = 0.0007934
ad_test <- ad.test(modelo_step$residuals)
print(ad_test)
##
## Anderson-Darling normality test
##
## data: modelo_step$residuals
## A = 2.8047, p-value = 3.846e-07
###Interpretación: indican que los residuos del modelo no siguen una distribución normal (p < 0.001), lo que sugiere que las suposiciones de normalidad de los residuos pueden no ser válidas para este modelo
# 5.2 Gráfico de valores ajustados vs. residuos
plot_homocedasticidad <- ggplot(data = data, aes(modelo_step$fitted.values, modelo_step$residuals)) +
geom_point() +
geom_smooth(color = "firebrick", se = FALSE) +
geom_hline(yintercept = 0) +
labs(title = "Valores ajustados vs. Residuos") +
theme_bw()
print(plot_homocedasticidad)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

# 5.3 Prueba de Breusch-Pagan para homocedasticidad
bp_test <- bptest(modelo_step)
print(bp_test)
##
## studentized Breusch-Pagan test
##
## data: modelo_step
## BP = 4.0165, df = 1, p-value = 0.04506
###Interpretación: El análisis visual y la prueba de Breusch-Pagan indican que no hay evidencia significativa de heterocedasticidad en los residuos del modelo, lo que sugiere que la suposición de homocedasticidad se cumple.
# 6. Calcular la matriz de correlación entre los predictores
cor_matrix <- cor(dplyr::select(data, price, bathrooms, bedrooms, sqfoot))
corrplot(cor_matrix, method = "number", tl.col = "black")

##Interpretación: fuertes correlaciones entre los predictores (bathrooms y sqfoot: 0.87, bathrooms y bedrooms: 0.85, bedrooms y sqfoot: 0.83) sugieren la presencia de multicolinealidad, lo que puede afectar la precisión y estabilidad de los coeficientes del modelo de regresión.
# 7. Prueba de Durbin-Watson para autocorrelación
dwt_test <- dwt(modelo_step, alternative = "two.sided")
print(dwt_test)
## lag Autocorrelation D-W Statistic p-value
## 1 0.1196883 1.687974 0.25
## Alternative hypothesis: rho != 0
dw_test <- dwtest(modelo_step, alternative = "two.sided")
print(dw_test)
##
## Durbin-Watson test
##
## data: modelo_step
## DW = 1.688, p-value = 0.2146
## alternative hypothesis: true autocorrelation is not 0
## Interpretación: Las pruebas de Durbin-Watson (dwt y dwtest) indican que no hay evidencia significativa de autocorrelación en los residuos del modelo (p > 0.05), sugiriendo que los residuos son independientes entre sí.
# Gráfico de influencia para identificar valores atípicos e influyentes
influence_plot <- influencePlot(modelo_step)

print(influence_plot)
## StudRes Hat CookD
## 4 5.050214 0.02771627 0.25810830
## 12 4.157347 0.02771627 0.19376030
## 44 0.826137 0.11475911 0.04447378
## 47 -1.564196 0.16270902 0.23213469
## 62 -1.999820 0.11475911 0.24688408
###Interpretación: El gráfico de influencia identifica varias observaciones influyentes (e.g., 4, 12, 44, 47, 62) que tienen altos valores de leverage y residuos estudentizados. Estas observaciones pueden tener un impacto significativo en el modelo y deben ser investigadas más a fondo para determinar si representan datos válidos o si son valores atípicos que podrían distorsionar los resultados del análisis.