En este proyecto desarrollaremos un modelo de regresión lineal simple
para analizar la relación entre las horas de estudio y las
calificaciones obtenidas por estudiantes, utilizamos el dataset
student_scores.csv
, el cual contiene información sobre el
tiempo dedicado al estudio (en horas) y las calificaciones
correspondientes obtenidas por cada estudiante.
La exploración de datos tiene como objetivo comprender la estructura y calidad de un conjunto de datos antes de aplicar modelos.
Este proceso nos permitirá identificar los tipo de datos presentes (numéricos o categóricos), transformar variables según sea necesario, detectar posibles errores, valores atípicos o datos faltantes, tambien nos ayudará a la facil visualización de distribuciones y relaciones entre variables.
# Cargar datos
datos <- read.csv("student_scores.csv")
# Número de filas y columnas de la base de datos.
"dim"(datos)
## [1] 25 2
# Nombres de las variables de la base de datos.
names(datos)
## [1] "Hours" "Scores"
# Tipos de variables..
str(datos)
## 'data.frame': 25 obs. of 2 variables:
## $ Hours : num 2.5 5.1 3.2 8.5 3.5 1.5 9.2 5.5 8.3 2.7 ...
## $ Scores: int 21 47 27 75 30 20 88 60 81 25 ...
# Nos muestra las primeras 6 filas de cada columna.
kable(head(datos))
Hours | Scores |
---|---|
2.5 | 21 |
5.1 | 47 |
3.2 | 27 |
8.5 | 75 |
3.5 | 30 |
1.5 | 20 |
# Control de calidad de datos - Comprobación de valores nulos
sapply(datos, function(x)(sum(is.na(x))))
## Hours Scores
## 0 0
# Resumen estadístico de cada variable.
summary(datos)
## Hours Scores
## Min. :1.100 Min. :17.00
## 1st Qu.:2.700 1st Qu.:30.00
## Median :4.800 Median :47.00
## Mean :5.012 Mean :51.48
## 3rd Qu.:7.400 3rd Qu.:75.00
## Max. :9.200 Max. :95.00
# Correlación
correlacion <- cor(datos)
kable(correlacion, caption = "Matriz de Correlación")
Hours | Scores | |
---|---|---|
Hours | 1.0000000 | 0.9761907 |
Scores | 0.9761907 | 1.0000000 |
# Gráfico de correlación
pairs(datos,
main = "Gráfico de Dispersión: Horas vs Calificaciones",
pch = 19,
col = "steelblue")
# Modelo de regresión lineal
regresion <- lm(Scores ~ Hours, data = datos)
# Resumen del modelo
summary(regresion)
##
## Call:
## lm(formula = Scores ~ Hours, data = datos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.578 -5.340 1.839 4.593 7.265
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.4837 2.5317 0.981 0.337
## Hours 9.7758 0.4529 21.583 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5.603 on 23 degrees of freedom
## Multiple R-squared: 0.9529, Adjusted R-squared: 0.9509
## F-statistic: 465.8 on 1 and 23 DF, p-value: < 2.2e-16
\[ Y=2.4837+9.7758x \]
Esto significa que por cada hora adicional de estudio, se espera un incremento promedio de 9.78 puntos en la calificación.
# Gráfica de la regresión
plot(datos$Hours, datos$Scores,
xlab = 'Horas de Estudio',
ylab = 'Calificación',
main = 'Relación Lineal: Horas de Estudio vs Calificaciones',
pch = 19,
col = "steelblue",
cex = 1.2)
abline(regresion, col = "red", lwd = 2)
legend("topleft",
legend = paste("R² =", round(summary(regresion)$r.squared, 4)),
bty = "n")
## Predicciones del Modelo
# Crear datos para predicción (1 a 10 horas)
nuevas.horas <- data.frame(Hours = seq(1, 10, by = 0.5))
# Calcular predicciones
predicciones <- predict(regresion, nuevas.horas)
# Crear tabla de predicciones
tabla_predicciones <- data.frame(
Horas = nuevas.horas$Hours,
Calificacion_Predicha = round(predicciones, 1)
)
kable(head(tabla_predicciones, 10),
caption = "Predicciones de Calificaciones según Horas de Estudio",
col.names = c("Horas de Estudio", "Calificación Predicha"))
Horas de Estudio | Calificación Predicha |
---|---|
1.0 | 12.3 |
1.5 | 17.1 |
2.0 | 22.0 |
2.5 | 26.9 |
3.0 | 31.8 |
3.5 | 36.7 |
4.0 | 41.6 |
4.5 | 46.5 |
5.0 | 51.4 |
5.5 | 56.3 |
# Intervalos de confianza al 95%
ic_95 <- confint(regresion, level = 0.95)
kable(ic_95,
caption = "Intervalos de Confianza al 95% para los Coeficientes",
digits = 4)
2.5 % | 97.5 % | |
---|---|---|
(Intercept) | -2.7535 | 7.7208 |
Hours | 8.8388 | 10.7128 |
# Intervalos de confianza al 90%
ic_90 <- confint(regresion, level = 0.90)
kable(ic_90,
caption = "Intervalos de Confianza al 90% para los Coeficientes",
digits = 4)
5 % | 95 % | |
---|---|---|
(Intercept) | -1.8553 | 6.8226 |
Hours | 8.9995 | 10.5521 |
# Calcular residuos estandarizados y valores ajustados
residuos <- rstandard(regresion)
valores.ajustados <- fitted(regresion)
# Gráfico de residuos vs valores ajustados
plot(valores.ajustados, residuos,
xlab = 'Valores Ajustados',
ylab = 'Residuos Estandarizados',
main = 'Análisis de Homocedasticidad',
pch = 19,
col = "steelblue")
# Línea horizontal en cero
abline(h = 0, col = "red", lty = 2)
# Líneas de referencia
abline(h = c(-2, 2), col = "orange", lty = 3)
# Q-Q Plot para evaluar normalidad
qqnorm(residuos,
main = "Q-Q Plot: Normalidad de Residuos",
pch = 19,
col = "steelblue")
qqline(residuos, col = "red", lwd = 2)
# Test de Shapiro-Wilk para normalidad
shapiro_test <- shapiro.test(residuos)
shapiro_test
##
## Shapiro-Wilk normality test
##
## data: residuos
## W = 0.90493, p-value = 0.02353
Interpretación del Test de Shapiro-Wilk: - p-value = 0.0235 - Se rechaza la hipótesis nula de normalidad (α = 0.05)
ANOVA
#install.packages("nortest")
require(nortest)
by(data= datos,INDICES = factor(datos$Scores),FUN = function(x){ lillie.test(datos$Hours)})
## factor(datos$Scores): 17
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 20
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 21
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 24
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 25
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 27
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 30
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 35
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 41
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 42
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 47
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 54
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 60
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 62
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 67
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 69
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 75
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 76
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 81
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 85
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 86
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 88
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
##
## ------------------------------------------------------------
## factor(datos$Scores): 95
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Hours
## D = 0.12534, p-value = 0.3951
"Los test de hipótesis no muestran evidencias de falta de normalidad."
## [1] "Los test de hipótesis no muestran evidencias de falta de normalidad."
fligner.test(Scores ~ Hours,datos)
##
## Fligner-Killeen test of homogeneity of variances
##
## data: Scores by Hours
## Fligner-Killeen:med chi-squared = 24, df = 22, p-value = 0.3472
ANOVA
anova <- aov(datos$Scores ~ factor(datos$Hours))
summary(anova)
## Df Sum Sq Mean Sq F value Pr(>F)
## factor(datos$Hours) 22 15293 695.1 26.23 0.0373 *
## Residuals 2 53 26.5
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(anova)
Relación Significativa: Existe una relación lineal positiva y significativa entre las horas de estudio y las calificaciones (R² = 0.9529).
Impacto Cuantificado: Cada hora adicional de estudio se asocia con un incremento promedio de 9.78 puntos en la calificación.
Capacidad Predictiva: El modelo explica el 95.3% de la variabilidad en las calificaciones.
Validez del Modelo: Los análisis de residuos sugieren que se cumplen razonablemente los supuestos del modelo de regresión lineal.
Recomendación: Los resultados proporcionan evidencia estadística sólida para promover el incremento en las horas de estudio como estrategia para mejorar el rendimiento académico.