El Programme for International Student Assessment (PISA) es una evaluación internacional impulsada en 1997 por la Organización para la Cooperación y el Desarrollo Económicos (OCDE). Su propósito central es medir en qué medida los sistemas educativos preparan a los jóvenes de 15 años para enfrentar los desafíos de la vida adulta.
A diferencia de las pruebas tradicionales, PISA no se centra únicamente en el dominio de contenidos curriculares, sino en la capacidad de los estudiantes para aplicar conocimientos y habilidades en contextos reales.
PISA se aplica cada tres años a muestras representativas de entre 4,500 y 10,000 estudiantes por país. Evalúa principalmente tres áreas de conocimiento:
En cada ciclo, una de estas áreas se establece como foco principal. Además, en ediciones recientes se han incorporado nuevas dimensiones como la resolución colaborativa de problemas, la competencia financiera y el pensamiento creativo, reflejando las demandas emergentes de la sociedad contemporánea.
La primera edición, en el año 2000, contó con la participación de 32 países. Actualmente, más de 85 países y economías forman parte del programa, incluyendo tanto miembros de la OCDE como países asociados de distintas regiones. Esto convierte a PISA en el estudio educativo comparativo más amplio a nivel global.
Los resultados se presentan en una escala cuyo promedio se sitúa en
500 puntos, con una desviación estándar de 100. A
partir de esta escala se establecen niveles de
competencia que van desde el Nivel 1 (básico) hasta el Nivel 6
(avanzado).
- <400 puntos: desempeño bajo, con limitaciones en
la comprensión y aplicación de conceptos básicos.
- ≈500 puntos: promedio de los países de la OCDE.
- >600 puntos: alto rendimiento, característico de
países líderes como Singapur, Japón, Corea del Sur, Estonia y
Finlandia.
Los resultados de PISA proporcionan evidencia para la formulación de políticas educativas basadas en datos, ya que permiten comparar el desempeño entre países, identificar desigualdades y analizar factores asociados al aprendizaje (nivel socioeconómico, género, recursos escolares, etc.).
En consecuencia, PISA se ha consolidado como un referente mundial para evaluar la calidad y equidad de los sistemas educativos, impulsando la reflexión sobre la educación en el siglo XXI.
En PISA 2022, Finlandia se mantuvo por encima del promedio de la OCDE en todas las áreas evaluadas, con 484 puntos en matemáticas, 490 en lectura y 511 en ciencias, aunque se registró una leve disminución respecto a años anteriores. Las niñas superaron a los niños en lectura y matemáticas, y Finlandia destacó en pensamiento creativo, con el 39% de los estudiantes alcanzando los niveles más altos, especialmente en resolución de problemas sociales. Estos resultados reflejan la fortaleza y consistencia del sistema educativo finlandés, aunque con desafíos recientes en matemáticas y lectura.
Analizar la influencia de las características socioeconómicas, educativas y escolares en el rendimiento académico de los estudiantes finlandeses en la prueba PISA 2022, mediante métodos estadísticos tradiconales.
El Dataset utilizado fue learningtower que está dentro de un paquete de R el cual brinda acceso fácil a una versión limpia de los datos de PISA de la OCDE para los años 2000-2022.
Este contiene la base de student y school. La base student para el año 2022, contiene un total de 613.744 observaciones con 22 variables. En cambio, el dataset school contiene 131.385 observaciones con 13 variables.
Vamos a extraer variables, realizar transformaciones y vinculaciones para luego ejecturar estadística descripiva e inferencial y regresiones para analizar a detalle el rendimiento de Finlandia en las pruebas PISA del año 2022. Por lo cual, se muestra un poco la estructura de cada uno de ellos.
student: Datos de estudiantes de 15 años evaluados en PISA. Incluye las siguientes variables:
year): de tipo entero que denota el año en que se
realizó la prueba PISA. Para esta prueba se eligió el año 2022.country): de tipo factor que denota el código de cada
país que participó en la prueba PISA. En total tenemos 80 países que
participaron en la prueba.school_id): de tipo caracter que denota el código de
la escuela que participo en la prueba.student_id): de tipo entero que muestra el código de
cada uno de los estudiantes que participaron.mother_educ): de tipo factor que muestra el nivel
educativo de la madre. Tenemos 5 niveles desde el más bajo al más alto y
valores NA.father_educ): de tipo factor que muestra el nivel
educativo del padre. Tenemos 5 niveles desde el más bajo al más alto y
valores NA.gender): de tipo factor que muestra el género male o
female.computer): de tipo factor que muestra la tenencia de
un computador categorizado como yes, no y NA.internet): de tipo factor que muestra el acceso al
internet categorizado como yes, no y NA.math): de tipo numérico que muestra el puntaje
obtenido en matemáticas.read): de tipo numérico que muestra el puntaje en
lectura.science): de tipo numérico que muestra el puntaje en
cienciasstu_wgt): de tipo numérico que muestra el peso de la
ponderación del estudiante de 15 años.desk): de tipo factor que muestra la tenencia de un
escritorio para estudiar. La variable contiene valores NA.room): de tipo factor que muestrala tenencia de una
habitación para estudiar categorizado en yes y no con valores NA.dishwasher): de tipo factor que muestra la tenencia de
lavavajillas. La variable contiene valores NA.television): de tipo factor que muestra la tenencia de
número de televisores categorizado como 0, 1, 2, 3+ con valores NA.computer_n): de tipo factor que muestra la tenencia de
número de televisores categorizado como 0, 1, 2, 3+ con valores NA.car): de tipo factor que muestra la tenencia de número
de televisores categorizado como 0, 1, 2, 3+ con valores NA.book): de tipo factor que muestra la tenencia de
libros para estudiar categorizado en 6 niveles.wealth): de tipo numérico que muestra un índice de
riqueza familiar del estudiante.escs): de tipo numérico que muestra un índice de
estatus económico, social y cultural del estudiante.A continuación se muestra como resumen la estructura del dataset student:
#estructura del dataset
library(learningtower) #cargamos general
student_2022 <- load_student(year = 2022)#dataset puntual
str(student_2022)#estructura## tibble [613,744 × 22] (S3: tbl_df/tbl/data.frame)
## $ year : int [1:613744] 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 ...
## $ country : Factor w/ 80 levels "ALB","ARE","ARG",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ school_id : chr [1:613744] "800282" "800115" "800242" "800245" ...
## $ student_id : int [1:613744] 800001 800002 800003 800005 800006 800007 800008 800009 800010 800012 ...
## $ mother_educ: Factor w/ 5 levels "ISCED 1","ISCED 2",..: 1 1 3 1 3 3 3 4 3 3 ...
## $ father_educ: Factor w/ 5 levels "ISCED 1","ISCED 2",..: 2 2 2 1 2 3 3 4 4 NA ...
## $ gender : Factor w/ 2 levels "female","male": 1 2 2 1 1 2 2 1 1 1 ...
## $ computer : Factor w/ 2 levels "no","yes": 2 1 2 2 2 2 2 2 1 2 ...
## $ internet : Factor w/ 2 levels "no","yes": NA 1 2 2 2 2 2 2 2 2 ...
## $ math : num [1:613744] 180 308 268 273 435 ...
## $ read : num [1:613744] 248 258 285 322 464 ...
## $ science : num [1:613744] 335 315 359 215 435 ...
## $ stu_wgt : num [1:613744] 3.16 4.35 7.84 8.49 3.71 ...
## $ desk : Factor w/ 0 levels: NA NA NA NA NA NA NA NA NA NA ...
## $ room : Factor w/ 2 levels "no","yes": NA 1 2 2 2 1 2 NA 2 2 ...
## $ dishwasher : Factor w/ 0 levels: NA NA NA NA NA NA NA NA NA NA ...
## $ television : Factor w/ 4 levels "0","1","2","3+": NA 2 2 2 2 NA 2 NA 2 2 ...
## $ computer_n : Factor w/ 4 levels "0","1","2","3+": NA 1 2 2 2 2 2 NA 2 2 ...
## $ car : Factor w/ 4 levels "0","1","2","3+": NA 1 2 1 3 2 3 1 4 2 ...
## $ book : Factor w/ 6 levels "0-10","101-200",..: 2 3 2 3 3 6 5 3 5 5 ...
## $ wealth : num [1:613744] NA NA NA NA NA NA NA NA NA NA ...
## $ escs : num [1:613744] 1.111 -3.051 -0.187 -3.22 -1.055 ...
school: Información de las escuelas de los estudiantes. Incluye las siguientes variables:
year): de tipo entero que denota el año en que se
realizó la prueba PISA. Para esta prueba se eligió el año 2022.country): de tipo factor que denota el código de cada
país que participó en la prueba PISA. En total tenemos 80 países que
participaron en la prueba.school_id): de tipo caracter que denota el código de
la escuela que participo en la prueba.fund_gov): de tipo numérico que muestra el porcentaje
de financiamiento provenientes del gobierno.fund_fess): de tipo numérico que muestra el porcentaje
de financiamiento por cuotas de los estudiantes.fund_donation): de tipo numérico que muestra el
porcentaje de financiamiento por donaciones.enrol_boys): de tipo numérico que muestra el número de
niños matriculados en la escuela.enrol_girls): de tipo numérico que muestra el número
de niñas matriculados en la escuela.stratio): de tipo numérico que muestra el ratio
alumno/docente.public_private): de tipo factor que muestra el tipo de
institución educativa si es pública, mixta o privada.staff_shortage): de tipo numérico que muestra el
índice de escasez de personal docente.sch_wgt): de tipo numérico que muestra el peso
asignado a la escuela para correcciones estadísticas.school_size): de tipo numérico que muestra el tamaño
de la escuela.A continuación se muestra como resumen la estructura del dataset school:
## tibble [131,385 × 13] (S3: tbl_df/tbl/data.frame)
## $ year : int [1:131385] 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 ...
## $ country : chr [1:131385] "ALB" "ALB" "ALB" "ALB" ...
## $ school_id : chr [1:131385] "01001" "01004" "01005" "01010" ...
## $ fund_gov : num [1:131385] 100 98 91 100 0 95 100 20 100 100 ...
## $ fund_fees : num [1:131385] 0 1 5 0 50 2 0 80 0 0 ...
## $ fund_donation : num [1:131385] 0 1 2 0 30 3 0 0 0 0 ...
## $ enrol_boys : num [1:131385] 1191 334 403 114 250 ...
## $ enrol_girls : num [1:131385] 1176 479 600 201 248 ...
## $ stratio : num [1:131385] 23.7 24.6 NA 22.5 26.9 ...
## $ public_private: Factor w/ 4 levels "1","2","private",..: 4 4 4 4 3 4 4 4 4 4 ...
## $ staff_shortage: num [1:131385] 0.6 -0.95 -0.17 1.87 -0.95 0.27 -0.17 0.89 -0.17 -0.17 ...
## $ sch_wgt : num [1:131385] 1 1 1 1 1 1 1 1 1 1 ...
## $ school_size : num [1:131385] 2367 813 1003 315 498 ...
Tras revisar los datasets student y school, seleccionamos el año 2022 y el país Finlandia con código FIN y guardamos el resultado en dos objetos diferentes (school_FIN_2022 y student_FIN_2022). Posteriormente, realizamos una vinculación (JOIN) entre ambos datasets utilizando la variable en común school_id y guardamos el resultado en un nuevo objeto llamado Join_FIN el cual utilizaremos para el análisis.
#Activamos librería
library (tidyverse)
#Extraemos los colegios de FINLANDIA para el año 2022.
school_FIN_2022 <- school |>
filter(year == 2022 & country == "FIN")
#Extreamos los estudiantes de Finlandia para el año 2022.
student_FIN_2022 <-student_2022 |>
filter(year == 2022 & country == "FIN")
#Vinculación entre datasets a partir de la variable en común.
Join_FIN <- student_FIN_2022 |>
left_join(school_FIN_2022, by = "school_id")Nuestra varible dependiente sería el promedio del puntaje obtenido por cada estudiante en las evaluaciones de matemática, ciencia y lectura. Para ello, calculos el puntaje agrupando por student_id. Valor mínimo alcanzado es de 168.1 y máximo de 788,9.
#puntaje promedio por estudiante.
Join_FIN <- Join_FIN |>
group_by(student_id) |>
mutate(puntaje = sum(math, read, science)/3)
#estadísticos del puntaje promedio
summary(Join_FIN$puntaje)## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 168.1 413.2 488.2 483.7 555.7 788.9
Seleccionamos las variables que vamos a incluir en el estudio para luego realizar un análisis exploratorio.
## [1] "year.x" "country.x" "school_id" "student_id"
## [5] "mother_educ" "father_educ" "gender" "computer"
## [9] "internet" "math" "read" "science"
## [13] "stu_wgt" "desk" "room" "dishwasher"
## [17] "television" "computer_n" "car" "book"
## [21] "wealth" "escs" "year.y" "country.y"
## [25] "fund_gov" "fund_fees" "fund_donation" "enrol_boys"
## [29] "enrol_girls" "stratio" "public_private" "staff_shortage"
## [33] "sch_wgt" "school_size" "puntaje"
Iniciamos el análisis con la función summary que nos arroja estadísticos básicos como valor mínimo, máximo, quantiles, media y mediana y NA’s para entender un poco la distribución de los datos de cada variable y valores faltantes. Tenemos 10.239 escuelas participantes de las cuales 712 son públicas y 9497 son privadas con 30 valores NA’s. Tenemos 10.239 estudiantes (1 por escuela) de los cuales 4.995 son mujeres y 5.244 son hombres. El puntaje mínimo promedio obtenido fue de 168,01 con una media de 483,7, mediana de 488,20 y máximo de 788,9. Segregando el puntaje promedio por género vemos que, las mujeres obtuvieron un puntaje promedio mayor que los hombres de 493,53 y 474,41, respectivamente.
Revisando los valores de los puntajes por examen, vemos que en matemáticas el puntaje mínimo fue de 161,9 y máximo de 764,3 con un valor promedio de 475,3. En cambio, el valor mínimo en Lectura fue de 115,4 el cual estuvo por debajo del obtenido en matemáticas y por encima de Ciencias. El valor máximo fue de 804,2, el cual estuvo por encima de matemáticas pero por debajo de ciencias y la media de 478. Por último, el puntaje mínimo de Ciencias fue el más bajo de los 3 alcanzado el valor de 85,98 y un valor máximo de 881,14 siendo el mayor puntaje alcanzado y la media de 497,96 mayor también de los 3 exámenes. El puntaje no tiene valores NA’s problemáticos.
Como dato importante también tenemos la variable escs que refleja un índice estandarizado que combina información sobre nivel económico, social y cultural reflejando nivel educativo de los padres, ocupación, bienes culturales y materiales en el hogar. Tenemos valores muy negativos -6,84 que indica normalmente que los estudiantes provienen de un hogar con menor nivel socioeconómico y cultural y valores máximos de 4,91 que indica que los estudiantes provienen de un hogar con mayor nivel socioeconómico y cultural. Existen valor cercanos a 0 que muestran los estudiantes tienen un mivel socioeconómico y cultural promedio. Por último, vemos 308 valores NA’s.
## school_id student_id mother_educ
## Length:10239 Min. :24600002 ISCED 1 : 120
## Class :character 1st Qu.:24603031 ISCED 2 : 378
## Mode :character Median :24606109 ISCED 3A :5469
## Mean :24606099 ISCED 3B, C :3747
## 3rd Qu.:24609153 less than ISCED1: 100
## Max. :24612186 NA's : 425
##
## father_educ gender computer internet math
## ISCED 1 : 136 female:4995 no : 627 no : 268 Min. :161.9
## ISCED 2 : 561 male :5244 yes :9395 yes :9745 1st Qu.:408.1
## ISCED 3A :4033 NA's: 217 NA's: 226 Median :476.8
## ISCED 3B, C :4793 Mean :475.3
## less than ISCED1: 93 3rd Qu.:542.1
## NA's : 623 Max. :764.3
##
## read science computer_n book
## Min. :115.4 Min. : 85.98 0 :2910 0-10 : 211
## 1st Qu.:404.5 1st Qu.:418.59 1 :5631 101-200 :3345
## Median :484.7 Median :500.76 2 :1028 11-25 :1272
## Mean :478.0 Mean :497.96 3+ : 87 201-500 :1812
## 3rd Qu.:557.2 3rd Qu.:577.40 NA's: 583 26-100 :1599
## Max. :804.2 Max. :881.14 more than 500:1327
## NA's : 673
## escs fund_gov public_private puntaje
## Min. :-6.8407 Min. : 85.00 1 : 712 Min. :168.1
## 1st Qu.:-0.3981 1st Qu.:100.00 2 :9497 1st Qu.:413.2
## Median : 0.3037 Median :100.00 private: 0 Median :488.2
## Mean : 0.1936 Mean : 99.82 public : 0 Mean :483.7
## 3rd Qu.: 0.8842 3rd Qu.:100.00 NA's : 30 3rd Qu.:555.7
## Max. : 4.9173 Max. :100.00 Max. :788.9
## NA's :308 NA's :30
Revisado el dataset procedemos a graficar la distribución de la variable dependiente que contiene el valor promedio de los exámenes alcanzados por los estudiantes de Finlandia en la pruena PISA 2022. Se agregó una línea roja suavizada que simula una normalidad de los datos. Como resultado, vemos que el promedio de puntaje se asemeja a una distribución normal.
library(ggplot2) #"cargamos libreria"
# Histograma del PUNTAJE con densidad y suavizado con normalidad
ggplot(Join_FIN, aes(x = puntaje)) +
geom_histogram(aes(y = ..density..),
bins = 30, fill = "steelblue", color = "white", alpha = 0.7) +
stat_function(fun = dnorm, #función de normalidad.
args = list(mean = mean(Join_FIN$puntaje, na.rm = TRUE),
sd = sd(Join_FIN$puntaje, na.rm = TRUE)),
color = "red", size = 1) +
labs(title = "Distribución del puntaje promedio de los estudiantes",
subtitle = "Finlandia",
caption = "Pruebas PISA 2022",
x = "Puntaje promedio",
y = "Densidad") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Para indagar aún más en la distribución de la variable dependiente, procedemos a graficar un Q-Q Plot (Quantile-Quantile plot) que permite comparar la distribución de los datos con una distribución teórica de referencia, normalmente de tipo NORMAL. Podemos ver que la variable dependiente “PUNTAJE” tiende agruparse como una distribución normal mas que todo en el centro pero en los extremos existen desviaciones importantes llamados outliers con estudiantes con puntajes muy bajos o muy altos.
#Grafico de normalidad.
qqnorm(Join_FIN$puntaje, main = "Q-Q Plot de Normalidad del Puntaje")
qqline(Join_FIN$puntaje, col = "red")#grafica normalidad teóricaCalculamos el test de normalidad de Anderson-Darling para confirmar si la variable sigue o no una distribución normal. La interpretación del resultado seria:
p > 0.05 → No rechazo H₀ → los datos no difieren significativamente de una normal.
p < 0.05 → Rechazo H₀ → los datos no siguen una distribución normal.
# Cargar librería
library(nortest)
# Test de Anderson-Darling sobre la variable dependiente PUNTAJE
ad.test(Join_FIN$puntaje)##
## Anderson-Darling normality test
##
## data: Join_FIN$puntaje
## A = 12.536, p-value < 0.00000000000000022
El resultado nos muestra que la variable dependiente no sigue una distribución normal porque el valor de P < 0.05. Por lo cual, se rechaza la hipótesis nula de normalidad. Esto puede deberse a que, existen outliers con valores de puntaje muy altos o muy bajos que generan desviaciones en la distribución de los datos. En todo caso, está primera aproximación no es problema para ejecutar análisis con métodos paramétrico como las regresiones, ya que, no necesitamos normalidad de la variable dependiente, sino normalidad de los residuos del modelo.
Del mismo modo, revisamos la distribución de la variable independiente ESCS que refleja un índice estandarizado que resume el nivel socioeconómico y cultural de los estudiantes. Para ello, hacemos una gráfica de distribución típica con una línea roja suavizada que simula una normalidad de los datos.
La gráfica nos muestra el pico de la distribución cercana al nivel 0. Esto significa que la mayoría de los estudiantes en Finlandia tienen un nivel socieconómico y cultural promedio de tipo homogéneo. Hay pocos estudiantes con niveles socioeconómicos extremadamente bajos (valores muy negativos) o extremadamente altos (valores muy positivos).
# Histograma del índice ESCS con densidad y suavizado con normalidad
ggplot(Join_FIN, aes(x = escs)) +
geom_histogram(aes(y = ..density..),
bins = 30, fill = "green", color = "white", alpha = 0.7) +
stat_function(fun = dnorm, #función de normalidad.
args = list(mean = mean(Join_FIN$escs, na.rm = TRUE),
sd = sd(Join_FIN$escs, na.rm = TRUE)),
color = "red", size = 1) +
labs(title = "Distribución del índice ESCS promedio de los estudiantes",
subtitle = "Finlandia",
caption = "Pruebas PISA 2022",
x = "Nivel Socioeconómico y cultural",
y = "Densidad") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Calculamos el Q-Q plot de normalidad de la variable escs para observar si tiende a una normal y vemos que el resultado es bastante diferente al alcanzado con la variable Puntaje debido a que los extremos se encuentran mucho más dispersos con valores atípicos. Esto se traduce a que no sigue una distribución normal.
#Grafico de normalidad de ESCS.
qqnorm(Join_FIN$escs, main = "Q-Q Plot de Normalidad del Puntaje")
qqline(Join_FIN$escs, col = "red") #grafica normalidad teóricaCorremos una prueba de normalidad de Anderson-Darling por la cantidad de registros que tiene nuestra variable para confirmar nuestro supuesto de normalidad y efectivamente no sigue una distribución normal. Considerando que esta es una de las variables que representa el rango socioeconómico y cultural de los estudiantes.
##
## Anderson-Darling normality test
##
## data: Join_FIN$escs
## A = 79.926, p-value < 0.00000000000000022
Para medir la relación entre el PUNTAJE y ESCS, realizamos una gráfica de dispersión que muestra una relación positiva. Esto es, a medida que el nivel socioeconómico y cultural aumenta, los puntajes de los puntajes promedios de los estudiantes también tienden a ser mayores.
Un punto importante de resaltar sobre esta dispersión es que la mayoría de los estudiantes se concentra alrededor de ESCS cercano a 0 y puntajes entre aproximadamente 400 y 600. Esto a su vez, indica que la mayoría de los estudiantes tienen niveles socioeconómicos medios y puntajes promedio-alto.
Hay algunos estudiantes con ESCS muy bajo o muy alto que se alejan de la media. También hay puntajes atípicos (outliers) fuera de la tendencia principal. En todo caso, se podría decir que la variable independiente tiene un efecto notable sobre el rendimiento PISA aunque no explica toda la variabilidad. Este último punto se lo va a explicar con un modelo de correlación.
#grafica de dispersion
ggplot(Join_FIN, aes(x = escs, y = puntaje)) +
geom_point(alpha = 0.6, color = "blue") + # puntos del dataset
geom_smooth(method = "lm", color = "red", se = TRUE) + # línea de regresión
labs(title = "Dispersión entre Puntaje PISA y ESCS",
subtitle = "Finlandia 2022",
caption = "Pruebas PISA 2022",
x = "Nivel Socioeconómico y Cultural (ESCS)",
y = "Puntaje Total") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Como último, graficamos una dispersión entre el puntaje y el ESCS, considerando el género masculino y femenino para medir el comportamiento de forma independiente. La pendiente de la línea de tendencia para los hombres es notablemente más pronunciada que la de las mujeres. Esto sugiere que la relación entre el nivel socioeconómico y los puntajes PISA es más fuerte para los estudiantes masculinos. El rango de valores ESCS es un poco más amplio para los hombres, extendiéndose a niveles socioeconómicos más bajos y más altos.
En el punto en que el nivel socioeconómico en promedio es(ESCS = 0), la línea de tendencia para las mujeres se encuentra ligeramente por encima de la de los hombres. Esto podría sugerir que, en un nivel socioeconómico neutro, las mujeres tienden a obtener un puntaje PISA levemente superior. En todo caso, el gráfico revela una clara ventaja académica asociada a un mayor nivel socioeconómico para ambos géneros, pero subraya que esta relación es particularmente más marcada en los estudiantes varones de Finlandia.
ggplot(Join_FIN, aes(x = escs, y = puntaje)) +
geom_point(alpha = 0.6, color = "blue") + # puntos del dataset
geom_smooth(method = "lm", color = "red", se = TRUE) + # línea de regresión
labs(title = "Dispersión entre Puntaje PISA y ESCS",
subtitle = " Por Genero - Finlandia 2022",
caption = "Pruebas PISA 2022",
x = "Nivel Socioeconómico y Cultural (ESCS)",
y = "Puntaje Total") +
facet_wrap(~ gender, scales = "free") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Para confirmar esta relación notable entre la variable dependiente PUNTAJE y la variable independientes ESCS realizamos un análisis de correlación de pearson. Como resultado, obtenemos el valor de 0,3873544, indicando que existe una correlación positiva entre el puntaje y el índice ESCS pero esta relación no es muy fuerte porque existen dispersiones en los datos y el ESCS por si solo, no lo puede explicar. Se tendría que utilizar una regresión lineal simple para observar el resultado con mayor detalle y aplicar una regresión lineal múltiple con variables de control.
#correlacion entre puntaje y escs
cor(x = Join_FIN$puntaje, y = Join_FIN$escs, method = "pearson",
use = "complete.obs") #omitimos valores NA## [1] 0.3873544
Calculamos un regresión lineal simple usando la función lm () para conocer la relación entre el puntaje y el índice socioeconómico y cultural de los estudiantes y su influencia a mayor detalle. Como resultado vemos que, el Intercept - Alpha que representa el puntaje de los estudiantes es 477,7596 en promedio cuando el valor del Índice ESCS es 0.
Cuando Beta representado por el ìndice ESCS se incrementa en una unidad, el puntaje de los estudiantes se incrementa en 43,9281 puntos en promedio.
Analizando el Intervalo de Confianza de Alpha - Puntaje podemos decir con un 95% de confianza que el valor del puntaje de los estudiantes se encuentra entre 475,95 y 479.57. Adicionalmente, el Intervalo de Confianza de beta - Índice ESCS nos dice con un 95% de confianza que por cada unidad que suba el índice ESCS el valor del puntaje se incrementará entre 41,87 y 45,98, en promedio.
RegresionL_Punt_escs <- lm(puntaje ~ escs, data = Join_FIN)
summary(RegresionL_Punt_escs) #estadísticos de la regresión##
## Call:
## lm(formula = puntaje ~ escs, data = Join_FIN)
##
## Residuals:
## Min 1Q Median 3Q Max
## -368.76 -60.80 3.73 63.89 278.29
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 477.7596 0.9216 518.38 <0.0000000000000002 ***
## escs 43.9281 1.0493 41.87 <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 89.59 on 9929 degrees of freedom
## (308 observations deleted due to missingness)
## Multiple R-squared: 0.15, Adjusted R-squared: 0.15
## F-statistic: 1753 on 1 and 9929 DF, p-value: < 0.00000000000000022
#intervalo de confianza para el puntaje
ICPuntaje = c((477.7596 - 1.96 * 0.9216), (477.7596 + 1.96 * 0.9216))
ICPuntaje #valor## [1] 475.9533 479.5659
#intervalo de confianza para el índice ESCS
ICESCS = c((43.9281 - 1.96 * 1.0493), (43.9281 + 1.96 * 1.0493))
ICESCS #valor## [1] 41.87147 45.98473
Tanto la variable dependiente como la independiente son estadísticamente significativas, ya que, ambas están por debajo del nivel de significancia del 0,05%. Más sin embargo, el poder explicativo del modelo solo llega al explicar el 15% de la variable dependiente. Es necesario que se agreguen otras variables independiente para explicar mejor la variabilidad de la variable dependiente que en este caso es el puntaje de los estudiantes Finlandeses en las pruebas PISA 2022.
Como existe variabilidad que no a podido ser explicada por el Índice socioeconómico y cultural, vamos a usar una regresión lineal múltiple con variables de control para ver si el modelo mejora en su desempeño. Como punto preliminar, debemos estándarizar las varibles de control para que sean incluidas al modelo.
Las variables de control que se van a usar dentro del modelo son: mother_educ, father_educ, gender, computer, book, public_private. Primero separamos las variables de control en un nuevo objeto llamado cat_vars. Luego, estas variables de control las estandarizados entre 1 a x según las diferentes categorías que haya tenido cada variable y las convertimos en numéricas, esto se logra utilizando el mutate, across, everything.
Por último, separamos las variables predictora y a predecir en un nuevo objeto llamado num_vars y la unificamos usando bind_cols para crear un nuevo dataset con toda la información llamado Join_FIN_imputed, al cual, eliminamos los valores NA para evitar contratiempos con el modelo.
# Separar vatriables de control de tipo categóricas
cat_vars <- Join_FIN |>
dplyr::select(mother_educ, father_educ, gender, computer,
book, public_private)
# estándarizamos variables de control
cat_vars_num <- cat_vars |>
mutate(across(everything(), ~ as.numeric(as.factor(.))))
#Separar vatriables principales del modelo de tipo numérico
num_vars <- Join_FIN |>
dplyr::select(puntaje, escs)
# Unimos variables numéricas y categóricas (estándarizadas)
Join_FIN_imputed <- bind_cols(num_vars, cat_vars_num) |>
drop_na(escs, mother_educ, father_educ, gender, computer,
book, public_private)Una vez estándarizadas las variables de control y creado el dataset nuevo Join_FIN_imputed procedimos a realizar ciertas comprobaciones pevias a ejecutar el modelo de regresión múltiple.
La primera comprobación es realizar una correlación múltiple con todo el dataset utilizando la función cor. El resultado nos arroja una matriz de correlación entre todas las variables del estudio que elegimos para la regresión lineal múltiple y su relación consigo misma. Como podemos observar existe una correlación moderada entre puntaje y el índice socioeconómico y cultural ESCS de 0,38227 (que lo mencionamos en el análisis exploratorio) y prácticamente, existe correlación baja entre las diferentes variables independentes con la variable dependiente. Así como también, existe correlaciones bajas y entre variables independientes. Esto significa que cada predictor, por si solo, explica poco del puntaje de los estudiantes en las pruebas PISA 2022. Esto, no significa que sea malo. A veces, al introducirlas todas en la regresión lineal múltiple si logra explicar bastante el modelo.
A priori, se podría decir que no existe multicolinealidad, ya que, las variables independientes tienen una correlación baja. Para confirmar aquello, podemos corregir la función vif de la librería car que nos arroja un índicador de multicolinealidad.
## student_id...1 puntaje escs student_id...4
## student_id...1 1.000000000 0.008029133 0.01099019 1.000000000
## puntaje 0.008029133 1.000000000 0.38227162 0.008029133
## escs 0.010990194 0.382271617 1.00000000 0.010990194
## student_id...4 1.000000000 0.008029133 0.01099019 1.000000000
## mother_educ 0.004438516 -0.059541362 -0.13208343 0.004438516
## father_educ 0.004227476 -0.048776616 -0.10459173 0.004227476
## gender 0.017502196 -0.080191168 0.01273043 0.017502196
## computer 0.009202147 0.120290916 0.18562628 0.009202147
## book -0.006519746 0.144183420 0.18171233 -0.006519746
## public_private -0.009645427 -0.051114047 -0.02521694 -0.009645427
## mother_educ father_educ gender computer book
## student_id...1 0.004438516 0.004227476 0.01750220 0.009202147 -0.006519746
## puntaje -0.059541362 -0.048776616 -0.08019117 0.120290916 0.144183420
## escs -0.132083428 -0.104591730 0.01273043 0.185626282 0.181712330
## student_id...4 0.004438516 0.004227476 0.01750220 0.009202147 -0.006519746
## mother_educ 1.000000000 0.272392355 -0.04042247 0.008297939 -0.049845218
## father_educ 0.272392355 1.000000000 0.00569280 0.002480728 -0.055472082
## gender -0.040422466 0.005692800 1.00000000 0.035211149 -0.026849737
## computer 0.008297939 0.002480728 0.03521115 1.000000000 0.016483708
## book -0.049845218 -0.055472082 -0.02684974 0.016483708 1.000000000
## public_private 0.054178559 0.051249207 0.02519409 -0.002002095 -0.044327624
## public_private
## student_id...1 -0.009645427
## puntaje -0.051114047
## escs -0.025216938
## student_id...4 -0.009645427
## mother_educ 0.054178559
## father_educ 0.051249207
## gender 0.025194090
## computer -0.002002095
## book -0.044327624
## public_private 1.000000000
La segunda comprobación es aplicar la función VIF para detectar multicolinealidad sobre una regresión lineal múltiple temporal. El resultado nos dice cuánto está inflada la varianza de los coeficientes de una regresión por la multicolinealidad. Si este valor es alto, existe redundancia en la información. Por lo que, lo ideal sería obtener valores por debajo de 5. Las variables del modelo temporal nos arrojan valores VIF cercamos a 1. Por lo cual, se puede confirmar que no existe multicolinealidad.
#Variance Inflation Factor VIF. Detecta multicolinealidad.
library ("car")
modeloVIF <- lm(puntaje ~ escs + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
car::vif(modeloVIF)## escs mother_educ father_educ gender computer
## 1.094297 1.098082 1.088681 1.004767 1.038560
## book public_private
## 1.038534 1.006764
La última comprobación es aplicar la función stepAIC de la librería MASS en el modelo de regresión temporal que me indica de todas las variables independientes elegidas, cual de ellas, explica mejor la variable dependiente. Esto permite optimizar el modelo y decidir qué variables realmente aportan información. Aquí utilicé ambas direcciones, esto es, me agrega o me quita variables para buscar la mejor combinación.
El resultado del modelo stepAIC me dio arrojo el modelo inicial con valores de Start:AIC=81147.44, Step: AIC=81145.5, Step: AIC=81144.68. Si revisamos los valores, vemos que hizo 2 combinaciones posibles y los valores pasaron de 81147.44 a 81144.68 con una reducción de 2,76 puntos, diferencia muy pequeña lo que indica mejoras modestas. Esto se traduce a que una reducción de variables independientes (7 a 5) no necesariamente genera una mejora significativa del modelo.
# Modelo de selección de variables utilizando valor de AIC
library ("MASS")
modelo_step <- stepAIC(modeloVIF, direction = "both")## Start: AIC=81147.44
## puntaje ~ escs + mother_educ + father_educ + gender + computer +
## book + public_private
##
## Df Sum of Sq RSS AIC
## - father_educ 1 453 69564577 81145
## - mother_educ 1 7492 69571616 81146
## <none> 69564123 81147
## - public_private 1 106636 69670759 81159
## - computer 1 248945 69813069 81178
## - book 1 437038 70001161 81202
## - gender 1 586546 70150670 81222
## - escs 1 9686462 79250586 82328
##
## Step: AIC=81145.5
## puntaje ~ escs + mother_educ + gender + computer + book + public_private
##
## Df Sum of Sq RSS AIC
## - mother_educ 1 9093 69573670 81145
## <none> 69564577 81145
## + father_educ 1 453 69564123 81147
## - public_private 1 107258 69671835 81157
## - computer 1 248711 69813288 81176
## - book 1 438242 70002819 81200
## - gender 1 587200 70151776 81220
## - escs 1 9738277 79302853 82332
##
## Step: AIC=81144.68
## puntaje ~ escs + gender + computer + book + public_private
##
## Df Sum of Sq RSS AIC
## <none> 69573670 81145
## + mother_educ 1 9093 69564577 81145
## + father_educ 1 2054 69571616 81146
## - public_private 1 110779 69684449 81157
## - computer 1 245727 69819397 81175
## - book 1 441697 70015367 81200
## - gender 1 582072 70155742 81218
## - escs 1 9978430 79552100 82358
##
## Call:
## lm(formula = puntaje ~ escs + gender + computer + book + public_private,
## data = Join_FIN_imputed)
##
## Coefficients:
## (Intercept) escs gender computer book
## 470.636 41.125 -16.046 22.559 4.729
## public_private
## -13.921
Una vez hechas las comprobaciones, nos quedamos con todas las variables independientes seleccionadas y ejecutamos el modelo de regresión lineal múltiple. 476.3450
El resultado del nuevo modelo, me indica que, el Intercept - Alpha que representa el puntaje de los estudiantes es 476,3450 en promedio cuando el valor del Índice ESCS es 0.
Cuando el valor de Beta representado por el ìndice ESCS se incrementa en una unidad, el puntaje de los estudiantes se incrementa en 40.9465 puntos en promedio y el resto de variables se mantienen constantes.
Respecto a las variables de control podemos ver que algunas son significativas y otras no. De acuerdo al R2 que dio el valor de 0.1632, este valor fue mayor que el obtenido con la regresión lineal de 0.15. El poder explicativo de mi modelo se incremtó, pasando de explicar el 15,00% al 16.32% de la variabilidad total con un incremento del 1.32%.
Como primera aproximación, se podría decir que mis variables no siguen un patrón lineal. Por consiguiente, se deben evaluar los supuestos de una regresión para corregir ciertas imperfecciones y ver si al final, mejora el poder predictivo.
#regresión lineal múltiple con variables de control
RegresionL_M <- lm(puntaje ~ escs + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
#mostramos resultados del modelo.
summary(RegresionL_M)##
## Call:
## lm(formula = puntaje ~ escs + mother_educ + father_educ + gender +
## computer + book + public_private, data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -373.54 -59.35 3.40 61.68 278.36
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 476.3450 12.3751 38.492 < 0.0000000000000002 ***
## escs 40.9465 1.1527 35.522 < 0.0000000000000002 ***
## mother_educ -1.5218 1.5404 -0.988 0.323218
## father_educ -0.3404 1.4010 -0.243 0.808006
## gender -16.1240 1.8446 -8.741 < 0.0000000000000002 ***
## computer 22.7215 3.9899 5.695 0.0000000127437938 ***
## book 4.7073 0.6239 7.545 0.0000000000000495 ***
## public_private -13.6844 3.6716 -3.727 0.000195 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.62 on 9062 degrees of freedom
## Multiple R-squared: 0.1632, Adjusted R-squared: 0.1625
## F-statistic: 252.4 on 7 and 9062 DF, p-value: < 0.00000000000000022
A continuación, evaluamos los supuestos de una regresión lineal para ver si nuestro modelo cumple con todos o si debemos realizar ajustes.
Normalidad
Para aplicar este supuesto, se asume que los residuos tienen un distribución normal. Para ello, graficamos los residuos y evaluamos visualmente si siguen una distribución normal.
# creamos dataframe de residuos.
data_residuos_ML <- data.frame (residuos = RegresionL_M$residuals,
ajustado = RegresionL_M$fitted.values)
# Histograma de los Residuos del modelo RegresionL_M
ggplot(data_residuos_ML, aes(x = RegresionL_M$residuals)) +
geom_histogram(aes(y = ..density..),
bins = 30, fill = "green", color = "white", alpha = 0.7) +
stat_function(fun = dnorm, #función de normalidad.
args = list(mean = mean(RegresionL_M$residuals, na.rm = TRUE),
sd = sd(RegresionL_M$residuals, na.rm = TRUE)),
color = "red", size = 1) +
labs(title = "Distribución de los residuos del modelo vs Distribución normal",
subtitle = "Supusto de Normalidad",
caption = "Regresión Lineal Múltiple - PISA 2022",
x = "Residuos del modelo",
y = "Densidad de Probabilidad Estimada") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Podemos ver que los residuos del modelo se encuentran ajustados sobre una curva real de normalidad estimada. Esto refleja que, hacia la derecha de la curva, se ven valores que sobresalen de la curva y también la curva está más alargada hacía la izquierda.
Probamos con un Q-Q plot para observar la si los residuos tienen una distribución normal utilizando quantiles de los residuos y quantiles de una normal. Como vemos, tenemos unos residuos normales en el centro pero en los extremos tienden a dispersarse alejándose de la normalidad.
#Q-Q plot de una normal
qqnorm(data_residuos_ML$residuos) # crea el gráfico base
qqline(data_residuos_ML$residuos, col = "red") # añade la líneaComo última revisión corremos el Test de Normalidad de Anderson-Darling porque tenemos más de 5000 registros y con ello confirmamos si los residuos siguen una distribución normal para dar cumplimiento al primer supuesto. La prueba nos arroja un p-value = 0.0000000000000006423, considerando que p < 0.05 → los residuos no son normales.
##
## Anderson-Darling normality test
##
## data: data_residuos_ML$residuos
## A = 6.4908, p-value = 0.0000000000000006423
Linealidad
Dado que los residuos no siguen una distribución normal. Revisamos si siguen una relación lineal. Como se puede observar, los residuos parecen estar centrados en 0 pero la línea roja se curva en los extremos, lo que podría intuirse que la relación no es perfectamente lineal y mi modelo podría estar dejado patrones sin capturar.
#Distribución de residuos y valorea ajustados.
ggplot(data = data_residuos_ML, aes(x= ajustado, y= residuos)) +
geom_point(color= "black") +
geom_smooth(se = FALSE, color = "red", size = 1) +
geom_hline(yintercept = 0, linetype = "dashed", color = "blue", size = 1) +
labs(title = "Distribución de los residuos y valores ajustados",
subtitle = "Supusto de Linealidad",
caption = "Regresión Lineal Múltiple - PISA 2022",
x = "Valores ajustados",
y = "Residuos") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Para confirmar la linealidad de mi modelo, podemos aplicar un test utilizando el paquete lmtest y la función resettest. Al haber obtenido un p-value = 0.000003276 se rechaza la linealidad. Por lo cual, demos realizar transformaciones a las variables para mejorar el rendimiento y predicción del modelo.
##
## RESET test
##
## data: RegresionL_M
## RESET = 12.647, df1 = 2, df2 = 9060, p-value = 0.000003276
Independencia y Autocorrelación
El supuesto de independencia sugiere que los residuos deben ser independientes de mi variable explicativa. Esto es, que deben ser exogenas al término del error. Demos graficar los residuos y la variable explicativa para comprender la independencia y la autocorrelación. Como resultado, vemos que los residuos parecen distribuirse aleatoriamente alrededor de cero y no siguen una tendencia positiva o negativa. Esto indica que los residuos son independientes y no tienen autocorrelación.
#Distribución de residuos y variable predictora
ggplot(data = RegresionL_M, aes(x= RegresionL_M$model$escs, y= RegresionL_M$residuals)) +
geom_point(color= "black") +
geom_smooth(se = FALSE, color = "red", size = 1) +
geom_hline(yintercept = 0, linetype = "dashed", color = "blue", size = 1) +
labs(title = "Relación de la Variable Explicativa vs Residuos",
subtitle = "Supusto de Independencia",
caption = "Regresión Lineal Múltiple - PISA 2022",
x = "ESCS",
y = "Residuos") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Para confirmar el supuesto de independencia y autocorrelación, se usó el Test de Durbin-Watson, el cual, nos arrojo un valor de DW ~ 2, lo que se traduce ausencia de autocorrelación en los residuos. El p-value = 0.7394 indicando que no se rechaza H0 y podemos evidenciar que los residuos de mi modelo son independientes.
Los residuos de mi modelo de regresión parecen independientes y no tienen autocorrelación.
# Librería para Durbin-Watson
library(lmtest)
#prueba de independencia y autocorrelación.
dwtest(RegresionL_M)##
## Durbin-Watson test
##
## data: RegresionL_M
## DW = 2.0135, p-value = 0.7394
## alternative hypothesis: true autocorrelation is greater than 0
Homocedasticidad
El supuesto de homocedasticidad tiene que ver con que los errores tienen una varianza constante. Esto es, los residuos del modelo tienen una dispersión constante independientemente del valor de x y deberían dispersarse en línea horizontal en y=0.
El gráfico muestra que la mayoría de los puntos se concentran en una franja horizontal. Sin embargo, se observa una ligera curvatura en la línea de tendencia roja, lo que sugiere cierta tendencia en función de los valores ajustados. Más sin embargo, no parece haber un patrón claro donde los valores aumenten o disminuyan en función de x.
Para confirmar si existe Homocedasticidad, se utilizó el test estadístico de Breusch-Pagan (bptest).
#Distribución de residuos y valorea ajustados.
ggplot(data = RegresionL_M, aes(x = RegresionL_M$fitted.values, y= RegresionL_M$residuals)) +
geom_point(color= "black") +
geom_smooth(se = FALSE, color = "red", size = 1) +
geom_hline(yintercept = 0, linetype = "dashed", color = "blue", size = 1) +
labs(title = "Distribución de los residuos y valores ajustados",
subtitle = "Supusto de Homocedasticidad",
caption = "Regresión Lineal Múltiple - PISA 2022",
x = "Valores ajustados",
y = "Residuos") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))El test de bptest nos arroja un valor de significancia que se interpreta de la siguiente forma: - Hipótesis nula (H0): los residuos son homocedásticos (varianza constante). - Hipótesis alternativa (H1): existe heterocedasticidad (la varianza depende de los predictores).
Si el p-value es < 0,05 se rechaza H0 y se confirma que existe heterocedasticidad. Si el p-value es > 0,05 no se rechaza H0, indicando que no existe evidencia suficiente para confirmar heterocedasticidad.
Al ejecutar la función bptest arroja como resultado un p-value = 0.00000001188, lo que se traduce a que existe heterocedasticidad en mi modelo.
##
## studentized Breusch-Pagan test
##
## data: RegresionL_M
## BP = 50.433, df = 7, p-value = 0.00000001188
Habiendo evaluado los supuestos de una regresión, podemos evidenciar que el supuesto de Normalidad, Linealidad y Homocedasticidad no cumplen. Solo fue posible cumplir con Independencia y Autocorrelación. Por lo cual, es necesario realizar ciertas transformaciones para mejorar el modelo.
Logarítmica
Vamos aplicar una transformación logarítmica de tipo Modelo log-lineal a la variable dependiente para ver si el modelo mejora su desempeño. Vemos que con tal solo aplicar logarítmo a la variable dependente, pasamos de tener un modelo que explicaba el 16,32% de variabilidad a tener solo 15,87%. En este sentido, el modelo empeoró.
#modelo log-lineal
RM_puntaje_log <- lm(log(puntaje) ~ escs + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
#resumen del modelo
summary(RM_puntaje_log)##
## Call:
## lm(formula = log(puntaje) ~ escs + mother_educ + father_educ +
## gender + computer + book + public_private, data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.14925 -0.11286 0.02416 0.13624 0.57241
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.1172076 0.0270174 226.417 < 0.0000000000000002 ***
## escs 0.0887983 0.0025166 35.285 < 0.0000000000000002 ***
## mother_educ -0.0006422 0.0033631 -0.191 0.84856
## father_educ 0.0016797 0.0030587 0.549 0.58290
## gender -0.0362098 0.0040272 -8.991 < 0.0000000000000002 ***
## computer 0.0536469 0.0087109 6.159 0.000000000765 ***
## book 0.0087840 0.0013620 6.449 0.000000000118 ***
## public_private -0.0253433 0.0080159 -3.162 0.00157 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1913 on 9062 degrees of freedom
## Multiple R-squared: 0.1587, Adjusted R-squared: 0.158
## F-statistic: 244.2 on 7 and 9062 DF, p-value: < 0.00000000000000022
Vamos aplicar el Modelo de tipo Modelo lineal-log para ver el comportamiento. El resultado obtenido fue peor que el modelo log-lineal. Tenemos un R-squared de 8,891% de explicación.
#modelo lineal-log
RM_escs_log <- lm(puntaje ~ log(escs) + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
#resumen del modelo
summary(RM_escs_log)##
## Call:
## lm(formula = puntaje ~ log(escs) + mother_educ + father_educ +
## gender + computer + book + public_private, data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -414.00 -56.61 5.22 61.52 266.08
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 580.5648 18.4456 31.474 < 0.0000000000000002 ***
## log(escs) 17.1692 1.3000 13.207 < 0.0000000000000002 ***
## mother_educ -12.4500 2.5071 -4.966 0.0000007045896640 ***
## father_educ -7.6108 2.1433 -3.551 0.000387 ***
## gender -18.1517 2.3580 -7.698 0.0000000000000163 ***
## computer 23.3136 6.4200 3.631 0.000284 ***
## book 6.9656 0.7654 9.101 < 0.0000000000000002 ***
## public_private -18.7548 4.4968 -4.171 0.0000308359697347 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.15 on 5499 degrees of freedom
## (3563 observations deleted due to missingness)
## Multiple R-squared: 0.08891, Adjusted R-squared: 0.08775
## F-statistic: 76.66 on 7 and 5499 DF, p-value: < 0.00000000000000022
Como último punto, aplicamos un modelo de tipo Modeo log-log para evaluar su comportamiento. No tuve una mejora, Su resultado fue similar al modelo Modelo lineal-log.
#modelo log-log
RM_log_log <- lm(log(puntaje) ~ log(escs) + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
#resumen del modelo
summary(RM_log_log)##
## Call:
## lm(formula = log(puntaje) ~ log(escs) + mother_educ + father_educ +
## gender + computer + book + public_private, data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.23368 -0.10089 0.02559 0.12779 0.48057
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.346818 0.038605 164.403 < 0.0000000000000002 ***
## log(escs) 0.035547 0.002721 13.065 < 0.0000000000000002 ***
## mother_educ -0.024426 0.005247 -4.655 0.000003316182843288 ***
## father_educ -0.013565 0.004486 -3.024 0.002506 **
## gender -0.039865 0.004935 -8.078 0.000000000000000804 ***
## computer 0.050184 0.013437 3.735 0.000190 ***
## book 0.013414 0.001602 8.374 < 0.0000000000000002 ***
## public_private -0.034787 0.009411 -3.696 0.000221 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1824 on 5499 degrees of freedom
## (3563 observations deleted due to missingness)
## Multiple R-squared: 0.08362, Adjusted R-squared: 0.08246
## F-statistic: 71.69 on 7 and 5499 DF, p-value: < 0.00000000000000022
Polinomiales
Vamos a probar términos polinomiales para ver si mejora el modelo. Considerando que la relación entre variable dependiente e independientes no es lineal. Estas transformaciones consideran curvaturas. Se usan más relaciones cuadráticas. Vemos que el modelo no mejoro su desempeño, obtuvo un valor de 4,748%.
#modelo cuadrático
RM_cuadraticaescs <- lm(puntaje ~ I(escs^2) + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
#resumen del modelo
summary(RM_cuadraticaescs)##
## Call:
## lm(formula = puntaje ~ I(escs^2) + mother_educ + father_educ +
## gender + computer + book + public_private, data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -362.80 -65.39 4.70 68.04 300.46
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 456.6451 13.3505 34.204 < 0.0000000000000002 ***
## I(escs^2) -2.5885 0.9177 -2.821 0.004804 **
## mother_educ -7.6331 1.6377 -4.661 0.00000319213116586 ***
## father_educ -3.9451 1.4951 -2.639 0.008338 **
## gender -15.7085 1.9681 -7.982 0.00000000000000162 ***
## computer 48.2710 4.2008 11.491 < 0.0000000000000002 ***
## book 8.6820 0.6568 13.219 < 0.0000000000000002 ***
## public_private -14.8869 3.9171 -3.801 0.000145 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 93.48 on 9062 degrees of freedom
## Multiple R-squared: 0.04748, Adjusted R-squared: 0.04674
## F-statistic: 64.53 on 7 and 9062 DF, p-value: < 0.00000000000000022
Visualizamos el efecto cuadrático entre el valor del índice ESCS y los residuos.
#graficamos resultado
ggplot(data = RM_cuadraticaescs, aes(x = RM_cuadraticaescs$fitted.values,
y = RM_cuadraticaescs$residuals)) +
geom_point(color= "black", alpha = 0.3) +
geom_smooth(se = FALSE, color = "red", size = 1) +
geom_hline(yintercept = 0, linetype = "dashed", color = "blue", size = 1) +
labs(title = "Distribución cuadrática de valores estimados y residuos del modelo",
subtitle = "Transformacion cuadrática",
caption = "Regresión Lineal Múltiple - PISA 2022",
x = "Valores estimados",
y = "Residuos del modelo") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Como última instancia, probamos una relación cúbica de la variable independiente. Vemos que el modelo no mejoró en su desempeño general.
#modelo cúbico
RM_cubicoescs <- lm(puntaje ~ I(escs^3) + mother_educ + father_educ + gender + computer
+ book + public_private, data = Join_FIN_imputed)
#resumen del modelo
summary(RM_cubicoescs)##
## Call:
## lm(formula = puntaje ~ I(escs^3) + mother_educ + father_educ +
## gender + computer + book + public_private, data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -361.71 -64.21 3.75 66.90 827.47
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 463.1590 13.1078 35.335 < 0.0000000000000002 ***
## I(escs^3) 2.8648 0.2260 12.676 < 0.0000000000000002 ***
## mother_educ -6.4852 1.6220 -3.998 0.00006429220976942 ***
## father_educ -3.1133 1.4796 -2.104 0.0354 *
## gender -15.5444 1.9516 -7.965 0.00000000000000185 ***
## computer 42.0678 4.1863 10.049 < 0.0000000000000002 ***
## book 7.8935 0.6521 12.104 < 0.0000000000000002 ***
## public_private -15.1425 3.8845 -3.898 0.00009762962450227 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 92.7 on 9062 degrees of freedom
## Multiple R-squared: 0.06325, Adjusted R-squared: 0.06253
## F-statistic: 87.41 on 7 and 9062 DF, p-value: < 0.00000000000000022
Visualizamos el efecto cúbico entre el índice ESCS y los valores de los residuos del modelo. El resultado nos arroja que los valores quedan más ajustados en un marge más estrecho con menor variabilidad, en comparación los el modelo cuadrático.
#graficamos resultado
ggplot(data = RM_cubicoescs, aes(x = RM_cubicoescs$fitted.values,
y = RM_cubicoescs$residuals)) +
geom_point(color= "black", alpha = 0.3) +
geom_smooth(se = FALSE, color = "red", size = 1) +
geom_hline(yintercept = 0, linetype = "dashed", color = "blue", size = 1) +
labs(title = "Distribución cúbica de valores estimados y residuos del modelo",
subtitle = "Transformacion cúbica",
caption = "Regresión Lineal Múltiple - PISA 2022",
x = "Valores estimados",
y = "Residuos del modelo") +
theme_bw() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 13, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 10),
axis.title.x = element_text(face = "bold"),
axis.title.y = element_text(face = "bold"))Centrado de variables independientes
Aplicamos el centrado de variables independientes a su media para ver si el modelo mejora en su desempeño. Como resultado vemos que el valor de Multiple R-squared:16,32%. El mismo valor que obtuvimos al aplicar una regresión múltiple.
#centrado de variables independientes a la media.
centrado <- mutate (Join_FIN_imputed, across(escs:public_private, ~.x - mean(.x)))
#modelo con variables independientes centradas
modelo_centrado <- lm(puntaje ~ escs + mother_educ + father_educ + gender + computer
+ book + public_private, data = centrado)
#vemos el resultado
summary(modelo_centrado)##
## Call:
## lm(formula = puntaje ~ escs + mother_educ + father_educ + gender +
## computer + book + public_private, data = centrado)
##
## Residuals:
## Min 1Q Median 3Q Max
## -373.54 -59.35 3.40 61.68 278.36
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 487.8257 0.9200 530.259 < 0.0000000000000002 ***
## escs 40.9465 1.1527 35.522 < 0.0000000000000002 ***
## mother_educ -1.5218 1.5404 -0.988 0.323218
## father_educ -0.3404 1.4010 -0.243 0.808006
## gender -16.1240 1.8446 -8.741 < 0.0000000000000002 ***
## computer 22.7215 3.9899 5.695 0.0000000127437938 ***
## book 4.7073 0.6239 7.545 0.0000000000000495 ***
## public_private -13.6844 3.6716 -3.727 0.000195 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.62 on 9062 degrees of freedom
## Multiple R-squared: 0.1632, Adjusted R-squared: 0.1625
## F-statistic: 252.4 on 7 and 9062 DF, p-value: < 0.00000000000000022
Estandarización Z-scores
Como última transformación probamos la estandarización Z-score que convierte los valores crudos en unidades de desviación estándar. Por lo que, la variable transformada tendrá media en 0 y desviación estándar en 1. Estas transformaciones son útiles si las variables están en escalas diferentes y permite comparar efectos de distintos predictores en igualdad de condiciones.
#estpandarizado de variables independientes.
z_score <- mutate (Join_FIN_imputed, across(escs:public_private, ~ as.numeric(scale(.x))))
#modelo con variables independientes estándarizadas.
modelo_z_score <- lm(puntaje ~ escs + mother_educ + father_educ + gender + computer
+ book + public_private, data = z_score)
#vemos el resultado
summary(modelo_z_score)##
## Call:
## lm(formula = puntaje ~ escs + mother_educ + father_educ + gender +
## computer + book + public_private, data = z_score)
##
## Residuals:
## Min 1Q Median 3Q Max
## -373.54 -59.35 3.40 61.68 278.36
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 487.8257 0.9200 530.259 < 0.0000000000000002 ***
## escs 34.1877 0.9624 35.522 < 0.0000000000000002 ***
## mother_educ -0.9524 0.9641 -0.988 0.323218
## father_educ -0.2333 0.9600 -0.243 0.808006
## gender -8.0613 0.9222 -8.741 < 0.0000000000000002 ***
## computer 5.3393 0.9376 5.695 0.0000000127437938 ***
## book 7.0744 0.9376 7.545 0.0000000000000495 ***
## public_private -3.4406 0.9231 -3.727 0.000195 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.62 on 9062 degrees of freedom
## Multiple R-squared: 0.1632, Adjusted R-squared: 0.1625
## F-statistic: 252.4 on 7 and 9062 DF, p-value: < 0.00000000000000022
El resultado del modelo no mejoró. Sigue explicando el 16,32% de los datos del puntaje.
Interacciones
Se pobraron interacciones para ver si el modelo captura efectos combinados y mejora su desempeño. Se pobró la interacción entre el nivel socioeconómico y cultural ESCS y la variable género que es estadísticamente significativa porque podría pensar que el impacto del nivel socioeconómico y cultural sobre el puntaje depende de que si es hombre o mujer. También, se pobró si el nivel socieconómico y cultural depende de si la escuela es pública o privada. Vemos que el Rajustado subió un par de puntos pero no representa mucha variabilidad.
# Modelo con interacción entre escs - género y escs - escuelas.
modelo_interaccion1 <- lm(puntaje ~ escs * gender + escs * public_private + mother_educ
+ father_educ + gender + computer + book + public_private,
data = Join_FIN_imputed)
#resumen del modelo.
summary(modelo_interaccion1)##
## Call:
## lm(formula = puntaje ~ escs * gender + escs * public_private +
## mother_educ + father_educ + gender + computer + book + public_private,
## data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -382.23 -59.50 3.52 61.70 277.68
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 469.9618 12.5462 37.459 < 0.0000000000000002 ***
## escs 68.8260 8.9338 7.704 0.000000000000014571 ***
## gender -15.3976 1.8892 -8.150 0.000000000000000411 ***
## public_private -10.8462 3.8361 -2.827 0.00470 **
## mother_educ -1.5853 1.5410 -1.029 0.30363
## father_educ -0.3509 1.4008 -0.251 0.80220
## computer 22.8629 3.9885 5.732 0.000000010227876152 ***
## book 4.6389 0.6241 7.432 0.000000000000116281 ***
## escs:gender -4.1869 2.2068 -1.897 0.05782 .
## escs:public_private -11.2057 4.3000 -2.606 0.00918 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.57 on 9060 degrees of freedom
## Multiple R-squared: 0.1641, Adjusted R-squared: 0.1633
## F-statistic: 197.7 on 9 and 9060 DF, p-value: < 0.00000000000000022
Voy a probar una última interacción para ver si tiene mejor efecto el nivel socioeconómico y cultural con respecto al nivel educativo de la madre y del padre aunque sean variables no significativas. Quizás su significancia cambie al generar la interacción. Como resultado tenemos que el valor de Adjusted R-squared subió unos puntos a 0.1656 y la variable mother_educ se volvió significativa y las interacciones igual.
# Escenario con más de una interacción
modelo_interaccion2 <- lm(puntaje ~ escs * mother_educ + escs * father_educ +
mother_educ + father_educ +
gender + computer + book + public_private,
data = Join_FIN_imputed)
summary(modelo_interaccion2)##
## Call:
## lm(formula = puntaje ~ escs * mother_educ + escs * father_educ +
## mother_educ + father_educ + gender + computer + book + public_private,
## data = Join_FIN_imputed)
##
## Residuals:
## Min 1Q Median 3Q Max
## -398.23 -58.72 3.02 61.69 305.35
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 489.1349 12.5385 39.011 < 0.0000000000000002 ***
## escs 72.2107 5.4247 13.311 < 0.0000000000000002 ***
## mother_educ -4.3869 1.6341 -2.685 0.007276 **
## father_educ -1.4919 1.4320 -1.042 0.297515
## gender -16.1968 1.8413 -8.796 < 0.0000000000000002 ***
## computer 22.8177 3.9827 5.729 0.000000010411466 ***
## book 4.5426 0.6233 7.288 0.000000000000342 ***
## public_private -13.2632 3.6667 -3.617 0.000299 ***
## escs:mother_educ -6.3485 1.5707 -4.042 0.000053443244506 ***
## escs:father_educ -3.2295 1.4607 -2.211 0.027064 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.45 on 9060 degrees of freedom
## Multiple R-squared: 0.1664, Adjusted R-squared: 0.1656
## F-statistic: 201 on 9 and 9060 DF, p-value: < 0.00000000000000022
En todo caso, los modelos ejecutados no superaron el 20% de explicación de la variabilidad del puntaje obtenido por los estudiantes de Finlandia en las pruebas PISA 2022.
Problema planteado: Comparar el promedio del puntaje obtenido en Ciencias entre el periodo 2018 y 2022 de los estudiantes de Finlandia para ver si existen diferencias significativas entre periodos.
Primero cargamos la base del 2018, filtramos por país y calculamos los estadísticos necesarios para calcular el test de hipótesis.
#cargamos base del 2018
PISA_2018 <- load_student(year = 2018)
#calculamos media, desvio estandar y tamaño muestral para el periodo 2018.
hipotesis_2018 <- PISA_2018 |>
filter(country == "FIN") |>
summarise(media_2018 = mean(science, na.rm = TRUE),
desvio_2018 = sd(science, na.rm = TRUE),
varianza_2018 = var(science, na.rm = TRUE),
n_2018 = n())Para el año 2022, ya tenemos la base cargada. Solo debemos calcular los estadísticos necesarios para el test de hipótesis.
#calculamos media, desvio estandar y tamaño muestral para el periodo 2022.
hipotesis_2022 <- student_FIN_2022 |>
summarise(media_2022 = mean(science, na.rm = TRUE),
desvio_2022 = sd(science, na.rm = TRUE),
varianza_2022 = var(science, na.rm = TRUE),
n_2022 = n())Determinamos la diferencia de la media muestral.
Estadístico con el valor de t y grados de libertad
#calcular el valor de t
t_value <- diff_media / sqrt((hipotesis_2018$varianza_2018 / hipotesis_2018$n_2018) +
(hipotesis_2022$varianza_2022 / hipotesis_2022$n_2022))
#grados de libertad
df <- min(hipotesis_2018$n_2018 - 1, hipotesis_2022$n_2022 - 1)Valor crítco T bilateral para un nivel de significancia del 0,05%.
Decisión del test de hipótesis
#decisión
if (abs(t_value) > T_critical) {
cat("Rechazar H0: hay una diferencia significativa entre los años.\n")
} else {
cat("No rechazar H0: no hay diferencia significativa entre los años.\n")
}## Rechazar H0: hay una diferencia significativa entre los años.
## Estadística T: 12.72748
## Valor crítico T: 1.960384
## Valor-p: 0
Interpretación:
Realizado el test de hipótesis podemos identificar que T_value > T_critical, por lo cual se rechaza H0, demostrando que hay una diferencia significativa entre la media del puntaje en ciencias entre el periodo 2018 y 2022.
USANDO LA FUNCIÓN T.TEST
Una forma más práctica de calcular el test de hipótesis es utilizando la función t.test pero debemos tener el puntaje de ciencias en un solo objeto separado por año como se muestra a continuación.
#selecciono el año y el puntaje total de ciencias para 2018
PISA_2018_hip <- PISA_2018 |>
dplyr::filter(country == "FIN") |>
dplyr::select(year, science)
#selecciono el año y el puntaje total de ciencias para 2022
PISA_2022_hip <- student_FIN_2022 |>
dplyr::select(year, science)
#unimos ambos resultados
PISAall <- rbind(PISA_2018_hip, PISA_2022_hip)Luego calculamos el t.test tomando las siguientes consideraciones:
##
## Welch Two Sample t-test
##
## data: science by year
## t = 12.727, df = 13164, p-value < 0.00000000000000022
## alternative hypothesis: true difference in means between group 2018 and group 2022 is not equal to 0
## 95 percent confidence interval:
## 18.15676 24.76747
## sample estimates:
## mean in group 2018 mean in group 2022
## 519.4270 497.9649
El resultado obtenido es el mismo del que realizamos de forma manual.
Con un intervalo de confianza del 95% podemos asumir que la diferencia del promedio puede estar entre los valores de 18,17 y 24,77. Dicho esto, en PROMEDIO, los estudiantes en 2022 obtuvieron alrededor de 21,46 puntos menos en ciencia que en el año 2018.
La conclusión de los Modelos.-
Como conclusión puedo indicar que los modelos muestran que el contexto socioeconómico y educativo explica parte del rendimiento, per ono la mayoría. El poder explicativo de las variables es bajo, alcanzando un R² ~0,16. El predictores (escs) y las variables de control (gender, computer, book, public_private) son estadísticamente significativos y sí influyen en el modelo pero solo explican una pequeña parte de la variación en los puntajes de los estudiantes. Por otro lado, las variables de control (mother_educ y father_educ) no son estadísticamente significativos. Por lo cual, no influyen dentro del modelo y podrían no utilizarse.
Puede que existan variables omitidas que forman predictores clave que expliquen mejor la variabilidad del puntaje como por ejemplo factores psicológicos, pedagógicos, motivación, calidad del docente, entre otros muchos factores.
Se probaron interacciones que podrían haber ayudado a captar mejor efectos combinados entre variables y mejorar el desempeño del modelo pero no superaron el 20% de explicación de la variabilidad del puntaje.
La conclusión de las Transformaciones
La conclusión del test de hipótesis
-Package: learningtower
-Title: OECD PISA Datasets from 2000-2022 in an Easy-to-Use Format
-Version: 1.1.0