Clase práctica: Estadística aplicada a la evaluación

Descriptiva, validación de instrumentos e inferencia

Blás Antonio Benítez Cristaldo

Propósito de la clase

Integrar tres procedimientos estadísticos aplicados a la evaluación educativa:

  1. Medidas numéricas descriptivas y gráficos.
  2. Validación de instrumentos de evaluación.
  3. Regresión lineal simple y múltiple.

Bases de datos de trabajo

Momento Archivo Uso principal
1 base_datos_estudiantes.xlsx Medidas descriptivas y gráficos
2 base_instrumento_validacion.xlsx Confiabilidad del examen
2 base_juicio_expertos.xlsx Validez de contenido
3 base_inferencia_evaluacion.xlsx Regresión simple y múltiple

Preparación del entorno

# Paquetes necesarios
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(knitr)
library(psych)
library(broom)
library(car)

Momento 1

Estadística descriptiva

El análisis descriptivo permite resumir, organizar e interpretar los datos antes de aplicar procedimientos inferenciales.

Se trabajarán:

  • Tendencia central.
  • Posición.
  • Dispersión.
  • Representaciones gráficas.

Cargar la base descriptiva

estudiantes <- read_excel("base_datos_estudiantes.xlsx", sheet = "estudiantes")

head(estudiantes)
# A tibble: 6 × 6
     id institucion   grupo   matematica_pre matematica_post asistencia
  <dbl> <chr>         <chr>            <dbl>           <dbl>      <dbl>
1     1 Institución A Control           56.1            64         84.2
2     2 Institución A Control           54.7            63.4       80.9
3     3 Institución A Control           62.6            65.9       93  
4     4 Institución A Control           63.6            65.9       89.7
5     5 Institución A Control           68.4            64.4       87.6
6     6 Institución A Control           60              59.2       85.7

Estructura de la base

glimpse(estudiantes)
Rows: 120
Columns: 6
$ id              <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,…
$ institucion     <chr> "Institución A", "Institución A", "Institución A", "In…
$ grupo           <chr> "Control", "Control", "Control", "Control", "Control",…
$ matematica_pre  <dbl> 56.1, 54.7, 62.6, 63.6, 68.4, 60.0, 60.7, 68.0, 79.6, …
$ matematica_post <dbl> 64.0, 63.4, 65.9, 65.9, 64.4, 59.2, 61.6, 67.4, 85.3, …
$ asistencia      <dbl> 84.2, 80.9, 93.0, 89.7, 87.6, 85.7, 90.9, 92.5, 86.0, …

Medidas de tendencia central

estudiantes %>%
  summarise(
    media_pre = mean(matematica_pre, na.rm = TRUE),
    mediana_pre = median(matematica_pre, na.rm = TRUE),
    media_post = mean(matematica_post, na.rm = TRUE),
    mediana_post = median(matematica_post, na.rm = TRUE),
    media_asistencia = mean(asistencia, na.rm = TRUE)
  ) %>%
  kable(digits = 2)
media_pre mediana_pre media_post mediana_post media_asistencia
65.92 66.6 70.54 70.3 84.96

Medidas de posición

estudiantes %>%
  summarise(
    q1_pre = quantile(matematica_pre, 0.25, na.rm = TRUE),
    q2_pre = quantile(matematica_pre, 0.50, na.rm = TRUE),
    q3_pre = quantile(matematica_pre, 0.75, na.rm = TRUE),
    p90_pre = quantile(matematica_pre, 0.90, na.rm = TRUE),
    q1_post = quantile(matematica_post, 0.25, na.rm = TRUE),
    q2_post = quantile(matematica_post, 0.50, na.rm = TRUE),
    q3_post = quantile(matematica_post, 0.75, na.rm = TRUE),
    p90_post = quantile(matematica_post, 0.90, na.rm = TRUE)
  ) %>%
  kable(digits = 2)
q1_pre q2_pre q3_pre p90_pre q1_post q2_post q3_post p90_post
61.95 66.6 70.1 73.36 64.88 70.3 75.43 79.34

Medidas de dispersión

estudiantes %>%
  summarise(
    rango_pre = max(matematica_pre, na.rm = TRUE) - min(matematica_pre, na.rm = TRUE),
    varianza_pre = var(matematica_pre, na.rm = TRUE),
    desviacion_pre = sd(matematica_pre, na.rm = TRUE),
    cv_pre = sd(matematica_pre, na.rm = TRUE) / mean(matematica_pre, na.rm = TRUE) * 100,
    rango_post = max(matematica_post, na.rm = TRUE) - min(matematica_post, na.rm = TRUE),
    varianza_post = var(matematica_post, na.rm = TRUE),
    desviacion_post = sd(matematica_post, na.rm = TRUE),
    cv_post = sd(matematica_post, na.rm = TRUE) / mean(matematica_post, na.rm = TRUE) * 100
  ) %>%
  kable(digits = 2)
rango_pre varianza_pre desviacion_pre cv_pre rango_post varianza_post desviacion_post cv_post
39.2 41.07 6.41 9.72 35.2 52.27 7.23 10.25

Descriptivos por grupo

estudiantes %>%
  group_by(grupo) %>%
  summarise(
    n = n(),
    media_pre = mean(matematica_pre, na.rm = TRUE),
    media_post = mean(matematica_post, na.rm = TRUE),
    sd_pre = sd(matematica_pre, na.rm = TRUE),
    sd_post = sd(matematica_post, na.rm = TRUE),
    asistencia_media = mean(asistencia, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  kable(digits = 2)
grupo n media_pre media_post sd_pre sd_post asistencia_media
Control 60 65.95 67.89 6.31 6.78 85.44
Experimental 60 65.89 73.20 6.56 6.72 84.48

Interpretación de las medidas descriptivas

  • Media: representa el promedio de los valores observados.
  • Mediana: valor central de la distribución.
  • Moda: valor que ocurre con mayor frecuencia.
  • Desviación estándar: mide la dispersión de los datos respecto a la media.
  • Coeficiente de variación: permite comparar la variabilidad entre variables con distintas unidades.

Histograma

ggplot(estudiantes, aes(x = matematica_post)) +
  geom_histogram(bins = 10, color = "white") +
  labs(
    title = "Distribución del rendimiento posterior",
    x = "Puntaje en matemática posterior",
    y = "Frecuencia"
  ) +
  theme_minimal()

Boxplot por grupo

ggplot(estudiantes, aes(x = grupo, y = matematica_post)) +
  geom_boxplot() +
  labs(
    title = "Rendimiento posterior según grupo",
    x = "Grupo",
    y = "Puntaje posterior"
  ) +
  theme_minimal()

Gráfico de barras

estudiantes %>%
  count(institucion) %>%
  ggplot(aes(x = institucion, y = n)) +
  geom_col() +
  labs(
    title = "Cantidad de estudiantes por institución",
    x = "Institución",
    y = "Cantidad"
  ) +
  theme_minimal()

Diagrama de dispersión

ggplot(estudiantes, aes(x = asistencia, y = matematica_post)) +
  geom_point() +
  labs(
    title = "Relación entre asistencia y rendimiento posterior",
    x = "Asistencia (%)",
    y = "Puntaje posterior"
  ) +
  theme_minimal()

Actividad del momento 1

Con la base base_datos_estudiantes.xlsx, responder:

  1. ¿Cuál es el promedio del pretest y del postest?
  2. ¿Qué grupo presenta mejor rendimiento posterior?
  3. ¿Qué variable presenta mayor dispersión?
  4. ¿Qué gráfico permite explicar mejor los resultados?

Momento 2

Validación de instrumentos

En evaluación educativa, un instrumento debe demostrar evidencias de calidad antes de ser utilizado para tomar decisiones.

Se analizarán:

  • Confiabilidad del examen.
  • Consistencia interna.
  • Validez de contenido mediante juicio de expertos.

Cargar base del instrumento

instrumento <- read_excel("base_instrumento_validacion.xlsx", sheet = "instrumento")

head(instrumento)
# A tibble: 6 × 10
  item1 item2 item3 item4 item5 item6 item7 item8 item9 item10
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
1     4     4     1     5     2     5     5     2     5      3
2     3     5     1     3     5     2     4     4     2      5
3     1     4     3     4     2     4     1     4     2      5
4     5     2     1     3     5     1     1     1     2      1
5     2     4     1     1     4     2     1     1     2      4
6     2     5     4     2     3     3     5     2     1      4

Alfa de Cronbach

alpha_resultado <- psych::alpha(instrumento)
Some items ( item2 item5 item10 ) were negatively correlated with the first principal component and 
probably should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' option
alpha_resultado$total
 raw_alpha std.alpha   G6(smc)  average_r       S/N      ase     mean        sd
 0.1185119 0.1158165 0.1609791 0.01292933 0.1309869 0.119582 3.051667 0.4822885
   median_r
 0.01273778

Tabla de ítems

alpha_resultado$item.stats %>%
  as.data.frame() %>%
  select(n, mean, sd, r.drop) %>%
  kable(digits = 3)
n mean sd r.drop
item1 120 2.925 1.524 0.071
item2 120 3.117 1.421 -0.093
item3 120 3.025 1.417 0.095
item4 120 3.067 1.407 0.017
item5 120 3.250 1.416 -0.059
item6 120 2.975 1.423 0.187
item7 120 3.050 1.425 0.063
item8 120 3.142 1.474 0.102
item9 120 2.983 1.484 0.027
item10 120 2.983 1.420 -0.017

Interpretación del alfa

alfa <- alpha_resultado$total$raw_alpha

interpretacion_alfa <- case_when(
  alfa >= .90 ~ "Excelente",
  alfa >= .80 ~ "Muy buena",
  alfa >= .70 ~ "Aceptable",
  alfa >= .60 ~ "Baja",
  TRUE ~ "Deficiente"
)

paste("Alfa de Cronbach =", round(alfa, 3), "-", interpretacion_alfa)
[1] "Alfa de Cronbach = 0.119 - Deficiente"

Interpretación del Alfa de Cronbach

Alfa Interpretación
≥ 0.90 Excelente
0.80–0.89 Muy buena
0.70–0.79 Aceptable
0.60–0.69 Cuestionable
< 0.60 Baja confiabilidad

Cargar juicio de expertos

expertos <- read_excel("base_juicio_expertos.xlsx", sheet = "expertos")

head(expertos)
# A tibble: 5 × 7
  experto item1 item2 item3 item4 item5 item6
  <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 E1          5     4     4     4     5     5
2 E2          4     5     4     5     5     4
3 E3          4     4     3     5     5     5
4 E4          4     4     3     5     3     5
5 E5          4     5     5     4     5     4

Función para calcular V de Aiken

v_aiken <- function(x, minimo = 1, maximo = 5) {
  n <- sum(!is.na(x))
  s <- sum(x - minimo, na.rm = TRUE)
  v <- s / (n * (maximo - minimo))
  return(v)
}

V de Aiken por ítem

v_aiken_items <- expertos %>%
  pivot_longer(
    cols = starts_with("item"),
    names_to = "item",
    values_to = "valor"
  ) %>%
  group_by(item) %>%
  summarise(
    n_expertos = n(),
    media = mean(valor, na.rm = TRUE),
    v_aiken = v_aiken(valor),
    interpretacion = case_when(
      v_aiken >= .80 ~ "Adecuado",
      v_aiken >= .70 ~ "Revisar",
      TRUE ~ "No adecuado"
    ),
    .groups = "drop"
  )

v_aiken_items %>%
  kable(digits = 3)
item n_expertos media v_aiken interpretacion
item1 5 4.2 0.80 Adecuado
item2 5 4.4 0.85 Adecuado
item3 5 3.8 0.70 Revisar
item4 5 4.6 0.90 Adecuado
item5 5 4.6 0.90 Adecuado
item6 5 4.6 0.90 Adecuado

Gráfico de V de Aiken

ggplot(v_aiken_items, aes(x = item, y = v_aiken)) +
  geom_col() +
  geom_hline(yintercept = .80, linetype = "dashed") +
  labs(
    title = "Validez de contenido por ítem",
    x = "Ítem",
    y = "V de Aiken"
  ) +
  theme_minimal()

Interpretación de la V de Aiken

V Interpretación
≥ 0.90 Excelente evidencia de validez
0.80–0.89 Buena
0.70–0.79 Aceptable
< 0.70 Se recomienda revisar el ítem

Actividad del momento 2

Con las bases de validación, responder:

  1. ¿El examen presenta confiabilidad aceptable?
  2. ¿Qué ítems deberían revisarse?
  3. ¿Qué ítems tienen mayor evidencia de validez de contenido?
  4. ¿Qué decisión metodológica tomaría el equipo evaluador?

Momento 3

Estadística inferencial

La estadística inferencial permite formular conclusiones sobre una población a partir de una muestra.

En esta clase se abordarán:

  • Regresión lineal simple.
  • Regresión lineal múltiple.
  • Interpretación de coeficientes.
  • Diagnóstico básico del modelo.

Cargar base inferencial

inferencia <- read_excel("base_inferencia_evaluacion.xlsx", sheet = "datos")

head(inferencia)
# A tibble: 6 × 9
  id    institucion  grupo sexo  grado matematica_pre matematica_post asistencia
  <chr> <chr>        <chr> <chr> <chr>          <dbl>           <dbl>      <dbl>
1 E001  Institución… Cont… M     1° M…           63.6            63.6       78  
2 E002  Institución… Cont… F     2° M…           73.1            74.3       80.5
3 E003  Institución… Cont… M     3° M…           79.8            82.2       80.2
4 E004  Institución… Cont… F     1° M…           81.5            84.3       87.5
5 E005  Institución… Cont… M     2° M…           65.8            66.7       85.1
6 E006  Institución… Cont… F     3° M…           69.7            72         74.5
# ℹ 1 more variable: desempeno <chr>

Pregunta inferencial

¿Cuáles son los factores que explican el rendimiento posterior en matemática?

Variable dependiente:

  • matematica_post

Variables predictoras:

  • matematica_pre
  • asistencia
  • grupo
  • sexo
  • grado
  • desempeno

Regresión lineal simple

modelo_simple <- lm(matematica_post ~ asistencia, data = inferencia)

summary(modelo_simple)

Call:
lm(formula = matematica_post ~ asistencia, data = inferencia)

Residuals:
     Min       1Q   Median       3Q      Max 
-19.4490  -6.5718  -0.0577   6.1054  23.7076 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 69.43138    9.24688   7.509 2.77e-12 ***
asistencia   0.04348    0.10806   0.402    0.688    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 9.033 on 178 degrees of freedom
Multiple R-squared:  0.0009088, Adjusted R-squared:  -0.004704 
F-statistic: 0.1619 on 1 and 178 DF,  p-value: 0.6879

Coeficientes del modelo simple

tidy(modelo_simple) %>%
  kable(digits = 3)
term estimate std.error statistic p.value
(Intercept) 69.431 9.247 7.509 0.000
asistencia 0.043 0.108 0.402 0.688

Bondad de ajuste del modelo simple

glance(modelo_simple) %>%
  select(r.squared, adj.r.squared, statistic, p.value) %>%
  kable(digits = 3)
r.squared adj.r.squared statistic p.value
0.001 -0.005 0.162 0.688

Gráfico del modelo simple

ggplot(inferencia, aes(x = asistencia, y = matematica_post)) +
  geom_point() +
  geom_smooth(method = "lm", se = TRUE) +
  labs(
    title = "Regresión lineal simple",
    subtitle = "Rendimiento posterior explicado por asistencia",
    x = "Asistencia (%)",
    y = "Rendimiento posterior"
  ) +
  theme_minimal()

Regresión lineal múltiple

modelo_multiple <- lm(
  matematica_post ~ matematica_pre + asistencia + grupo + sexo + grado + desempeno,
  data = inferencia
)

summary(modelo_multiple)

Call:
lm(formula = matematica_post ~ matematica_pre + asistencia + 
    grupo + sexo + grado + desempeno, data = inferencia)

Residuals:
    Min      1Q  Median      3Q     Max 
-9.2709 -1.8020  0.1935  1.8184  6.0586 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        24.077798   4.363752   5.518 1.25e-07 ***
matematica_pre      0.689093   0.041030  16.795  < 2e-16 ***
asistencia          0.049963   0.034795   1.436    0.153    
grupoExperimental   4.162500   0.471798   8.823 1.26e-15 ***
sexoM              -0.245410   0.413884  -0.593    0.554    
grado2° Medio      -0.002734   0.501935  -0.005    0.996    
grado3° Medio       0.245319   0.501697   0.489    0.625    
desempenoBajo     -10.724596   1.108364  -9.676  < 2e-16 ***
desempenoMedio     -5.534975   0.621220  -8.910 7.40e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.711 on 171 degrees of freedom
Multiple R-squared:  0.9136,    Adjusted R-squared:  0.9095 
F-statistic:   226 on 8 and 171 DF,  p-value: < 2.2e-16

Interpretación del modelo

Se deben analizar cuatro elementos.

  • Coeficientes
  • Valor p
  • Error residual

Coeficientes

β positivo

➡ Cuando aumenta X, también aumenta Y.

β negativo

➡ Cuando aumenta X, disminuye Y.

β = 0

➡ No existe efecto.

Significancia

p < 0.05

✔ Existe evidencia estadística de asociación.

p ≥ 0.05

✘ No existe evidencia suficiente para afirmar asociación.

Coeficiente de determinación

Interpretación
< 0.25 Bajo
0.25–0.50 Moderado
0.50–0.75 Alto
> 0.75 Muy alto

Ejemplo

R² = 0.68

El modelo explica el 68 % de la variabilidad del rendimiento académico.

Coeficientes del modelo múltiple

tidy(modelo_multiple) %>%
  kable(digits = 3)
term estimate std.error statistic p.value
(Intercept) 24.078 4.364 5.518 0.000
matematica_pre 0.689 0.041 16.795 0.000
asistencia 0.050 0.035 1.436 0.153
grupoExperimental 4.163 0.472 8.823 0.000
sexoM -0.245 0.414 -0.593 0.554
grado2° Medio -0.003 0.502 -0.005 0.996
grado3° Medio 0.245 0.502 0.489 0.625
desempenoBajo -10.725 1.108 -9.676 0.000
desempenoMedio -5.535 0.621 -8.910 0.000

Interpretación del VIF

VIF Interpretación
1 Sin colinealidad
1–5 Colinealidad baja
5–10 Colinealidad moderada
>10 Colinealidad alta

Objetivo

Todos los VIF deberían ser menores que 5.

Interpretación del GVIF

Cuando existen variables categóricas con varios niveles, R muestra:

  • GVIF
  • Df
  • GVIF^(1/(2×Df))

La columna que debe interpretarse es:

GVIF^(1/(2×Df))

Utilice los mismos criterios del VIF.

Bondad de ajuste del modelo múltiple

glance(modelo_multiple) %>%
  select(r.squared, adj.r.squared, statistic, p.value, AIC, BIC) %>%
  kable(digits = 3)
r.squared adj.r.squared statistic p.value AIC BIC
0.914 0.91 225.96 0 880.553 912.483

Comparación de modelos

anova(modelo_simple, modelo_multiple)
Analysis of Variance Table

Model 1: matematica_post ~ asistencia
Model 2: matematica_post ~ matematica_pre + asistencia + grupo + sexo + 
    grado + desempeno
  Res.Df     RSS Df Sum of Sq      F    Pr(>F)    
1    178 14523.8                                  
2    171  1256.3  7     13268 257.98 < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Diagnóstico: residuos

ggplot(data.frame(residuos = residuals(modelo_multiple)), aes(x = residuos)) +
  geom_histogram(bins = 10, color = "white") +
  labs(
    title = "Distribución de los residuos",
    x = "Residuos",
    y = "Frecuencia"
  ) +
  theme_minimal()

Diagnóstico: homocedasticidad

ggplot(data.frame(
  ajustados = fitted(modelo_multiple),
  residuos = residuals(modelo_multiple)
), aes(x = ajustados, y = residuos)) +
  geom_point() +
  geom_hline(yintercept = 0, linetype = "dashed") +
  labs(
    title = "Residuos frente a valores ajustados",
    x = "Valores ajustados",
    y = "Residuos"
  ) +
  theme_minimal()

Interpretación de los supuestos

✔ Residuos normales

La gráfica QQ Plot debe aproximarse a una línea recta.

✔ Homocedasticidad

Los residuos deben distribuirse aleatoriamente.

✔ Independencia

Durbin-Watson cercano a 2.

✔ Multicolinealidad

VIF < 5.

Diagnóstico: multicolinealidad

car::vif(modelo_multiple)
                   GVIF Df GVIF^(1/(2*Df))
matematica_pre 2.569531  1        1.602976
asistencia     1.151507  1        1.073083
grupo          1.363406  1        1.167650
sexo           1.030575  1        1.015173
grado          1.058962  2        1.014425
desempeno      2.710244  2        1.283075

Redacción APA del resultado

r2 <- glance(modelo_multiple)$r.squared
r2_aj <- glance(modelo_multiple)$adj.r.squared
f <- glance(modelo_multiple)$statistic
p <- glance(modelo_multiple)$p.value

glue::glue(
  "El modelo de regresión lineal múltiple explicó el {round(r2*100, 1)}% de la varianza del rendimiento posterior, R² = {round(r2, 3)}, R² ajustado = {round(r2_aj, 3)}, F = {round(f, 3)}, p = {round(p, 3)}."
)
El modelo de regresión lineal múltiple explicó el 91.4% de la varianza del rendimiento posterior, R² = 0.914, R² ajustado = 0.91, F = 225.96, p = 0.

Actividad del momento 3

Con base_inferencia_evaluacion.xlsx, responder:

  1. ¿La asistencia predice el rendimiento posterior?
  2. ¿Qué ocurre al agregar más variables al modelo?
  3. ¿Cuál modelo explica mejor el rendimiento?
  4. ¿Qué variables son estadísticamente significativas?
  5. ¿Cómo se redacta el resultado en formato APA?

Producto final de la clase

  1. Tabla descriptiva.
  2. Dos gráficos interpretados.
  3. Alfa de Cronbach.
  4. V de Aiken.
  5. Modelo de regresión simple.
  6. Modelo de regresión múltiple.
  7. Conclusión técnica.

Estructura sugerida del informe

  1. Introducción.
  2. Metodología.
  3. Resultados descriptivos.
  4. Validación del instrumento.
  5. Análisis inferencial.
  6. Conclusiones.
  7. Referencias.

Referencias

Aiken, L. R. (1985). Three coefficients for analyzing the reliability and validity of ratings. Educational and Psychological Measurement, 45(1), 131–142.

Cronbach, L. J. (1951). Coefficient alpha and the internal structure of tests. Psychometrika, 16(3), 297–334.

Field, A. (2018). Discovering statistics using IBM SPSS Statistics (5th ed.). Sage.

Hair, J. F., Black, W. C., Babin, B. J., & Anderson, R. E. (2019). Multivariate data analysis (8th ed.). Cengage.

Muchas gracias

Preguntas y comentarios.