Conjunto datos sintéticos que simula los comportamientos académicos y de estilo de vida de 80.000 estudiantes, incluyendo variables diversas como hábitos de estudio, salud mental, entorno familiar, motivación y factores ambientales. El objetivo es analizar cómo distintas variables influyen en el rendimiento estudiantil, medido a través del promedio académico (GPA) y las calificaciones en exámenes
Los datos utilizados fueron descargados de Kaggle y corresponden a un conjunto sintético que simula los hábitos, entorno y rendimiento académico de 80.000 estudiantes.
##install.packages("reticulate")# Recién reiniciada la sesión:
library(reticulate)
reticulate::use_condaenv("r_env_nuevo", required = TRUE)
#reticulate::py_install(c("scikit-learn", "matplotlib"), envname = "r_env_nuevo")
#reticulate::py_install("pyarrow")
reticulate::py_install("seaborn")## + "C:/Users/nicol/miniconda3/condabin/conda.bat" install --yes --prefix "C:/Users/nicol/miniconda3/envs/r_env_nuevo" -c conda-forge seaborn
Metodología de análisis predictivo basada en regresión lineal múltiple
nota_examen utilizando múltiples variables independientes
(previous_gpa y exam_anxiety_score).import polars as pl
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
# 1. Leer CSV con Polars
df = pl.read_csv(
r"C:\Users\nicol\Documents\Curso Big Data 2025 Sudameris\Trabajo Final\archive\enhanced_student_habits_performance_dataset.csv",
separator=";", # muy importante
encoding="latin1"
)
df | student_id | age | gender | major | study_hours_per_day | social_media_hours | netflix_hours | part_time_job | attendance_percentage | sleep_hours | diet_quality | exercise_frequency | parental_education_level | internet_quality | mental_health_rating | extracurricular_participation | previous_gpa | semester | stress_level | dropout_risk | social_activity | screen_time | study_environment | access_to_tutoring | family_income_range | parental_support_level | motivation_level | exam_anxiety_score | learning_style | time_management_score | exam_score |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| i64 | i64 | str | str | str | f64 | f64 | str | f64 | f64 | str | i64 | str | str | str | str | f64 | i64 | f64 | str | i64 | f64 | str | str | str | i64 | i64 | i64 | str | f64 | i64 |
| 100000 | 26 | "Male" | "Computer Scien… | "11,46" | 3.0 | 0.1 | "Yes" | 70.3 | 6.2 | "Poor" | 3 | "Some College" | "High" | "6.0" | "Yes" | 4.0 | 5 | 5.8 | "No" | 0 | 10.9 | "Co-Learning Gr… | "Yes" | "High" | 9 | 6 | 8 | "Reading" | 3.0 | 100 |
| 100001 | 28 | "Male" | "Arts" | "10,85" | 0.5 | 0.4 | "No" | 88.4 | 7.2 | "Good" | 4 | "PhD" | "Low" | "6.8" | "No" | 4.0 | 7 | 5.8 | "No" | 5 | 8.3 | "Co-Learning Gr… | "Yes" | "Low" | 7 | 7 | 10 | "Reading" | 6.0 | 99 |
| 100002 | 17 | "Male" | "Arts" | "1,21" | 4.2 | 0.7 | "No" | 82.1 | 9.2 | "Good" | 4 | "High School" | "Low" | "5.7" | "Yes" | 3.79 | 4 | 8.0 | "No" | 5 | 8.0 | "Library" | "Yes" | "High" | 3 | 4 | 6 | "Kinesthetic" | 7.6 | 98 |
| 100003 | 27 | "Other" | "Psychology" | "10,37" | 4.6 | 2.3 | "Yes" | 79.3 | 4.2 | "Fair" | 3 | "Master" | "Medium" | "8.5" | "Yes" | 4.0 | 6 | 4.6 | "No" | 3 | 11.7 | "Co-Learning Gr… | "Yes" | "Low" | 5 | 7 | 10 | "Reading" | 3.2 | 100 |
| 100004 | 25 | "Female" | "Business" | "9,29" | 0.8 | 2.7 | "Yes" | 62.9 | 6.5 | "Good" | 6 | "PhD" | "Low" | "9.2" | "No" | 4.0 | 4 | 5.7 | "No" | 2 | 9.4 | "Quiet Room" | "Yes" | "Medium" | 9 | 4 | 10 | "Reading" | 7.1 | 98 |
| 100005 | 17 | "Female" | "Engineering" | "8,4" | 0.5 | 2.5 | "No" | 49.2 | 9.2 | "Good" | 3 | "PhD" | "High" | "9.2" | "Yes" | 4.0 | 3 | 1.5 | "No" | 2 | 8.9 | "Quiet Room" | "No" | "High" | 1 | 10 | 5 | "Visual" | 3.9 | 94 |
| 100006 | 19 | "Male" | "Psychology" | "6,24" | 2.4 | 2.2 | "Yes" | 97.9 | 8.5 | "Good" | 6 | "Some College" | "High" | "5.8" | "No" | 4.0 | 2 | 2.5 | "No" | 3 | 9.2 | "Dorm" | "Yes" | "High" | 5 | 4 | 8 | "Kinesthetic" | 10.0 | 97 |
| 100007 | 17 | "Male" | "Psychology" | "10,4" | 3.2 | 0.9 | "No" | 44.3 | 7.4 | "Fair" | 5 | "Master" | "High" | "4.8" | "Yes" | 3.3 | 2 | 5.3 | "No" | 3 | 10.0 | "Co-Learning Gr… | "Yes" | "Low" | 9 | 6 | 10 | "Kinesthetic" | 7.5 | 84 |
| 100008 | 28 | "Female" | "Psychology" | "5,35" | 0.3 | 2.6 | "Yes" | 64.2 | 7.6 | "Fair" | 0 | "High School" | "Medium" | "3.5" | "No" | 2.61 | 2 | 4.0 | "No" | 3 | 4.8 | "Library" | "No" | "Low" | 4 | 3 | 10 | "Kinesthetic" | 5.8 | 70 |
| 100009 | 19 | "Male" | "Engineering" | "0,72" | 1.1 | 1.6 | "Yes" | 40.1 | 7.2 | "Fair" | 6 | "Master" | "Low" | "5.9" | "Yes" | 3.78 | 2 | 3.3 | "No" | 1 | 8.0 | "Cafe" | "Yes" | "Medium" | 7 | 8 | 6 | "Auditory" | 7.0 | 100 |
| 100010 | 16 | "Other" | "Arts" | "1,6" | 2.7 | 0.2 | "No" | 44.1 | 6.9 | "Poor" | 2 | "Some College" | "High" | "7.8" | "Yes" | 4.0 | 1 | 3.7 | "No" | 3 | 3.9 | "Co-Learning Gr… | "Yes" | "Medium" | 2 | 7 | 5 | "Visual" | 3.2 | 100 |
| 100011 | 26 | "Other" | "Biology" | "9,54" | 3.2 | 1.8 | "No" | 40.6 | 8.1 | "Good" | 1 | "PhD" | "Low" | "4.0" | "Yes" | 4.0 | 6 | 2.0 | "No" | 0 | 10.8 | "Dorm" | "No" | "Low" | 2 | 2 | 6 | "Auditory" | 2.9 | 100 |
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
| 179988 | 28 | "Female" | "Engineering" | "0,58" | 3.8 | 0.0 | "Yes" | 50.3 | 9.3 | "Poor" | 4 | "PhD" | "Medium" | "7.2" | "Yes" | 4.0 | 1 | 3.2 | "No" | 2 | 8.4 | "Cafe" | "Yes" | "High" | 5 | 1 | 5 | "Kinesthetic" | 5.8 | 98 |
| 179989 | 19 | "Other" | "Business" | "10,59" | 4.6 | 3.8 | "No" | 57.1 | 7.5 | "Good" | 1 | "PhD" | "High" | "5.2" | "Yes" | 2.63 | 6 | 6.7 | "No" | 1 | 13.4 | "Cafe" | "No" | "High" | 2 | 8 | 10 | "Auditory" | 8.8 | 65 |
| 179990 | 25 | "Male" | "Engineering" | "3,85" | 2.4 | 3.2 | "Yes" | 89.8 | 7.3 | "Poor" | 7 | "PhD" | "Low" | "4.7" | "No" | 4.0 | 3 | 3.4 | "No" | 4 | 8.6 | "Library" | "Yes" | "Low" | 10 | 7 | 9 | "Auditory" | 1.7 | 92 |
| 179991 | 24 | "Female" | "Engineering" | "11,06" | 2.5 | 1.2 | "Yes" | 62.3 | 4.1 | "Good" | 1 | "Bachelor" | "High" | "6.4" | "Yes" | 3.06 | 2 | 7.6 | "No" | 2 | 5.2 | "Dorm" | "No" | "High" | 4 | 9 | 10 | "Visual" | 4.0 | 81 |
| 179992 | 20 | "Other" | "Computer Scien… | "4,06" | 0.6 | 3.9 | "Yes" | 66.0 | 5.3 | "Good" | 6 | "PhD" | "Low" | "7.9" | "Yes" | 3.07 | 6 | 7.9 | "No" | 0 | 10.5 | "Co-Learning Gr… | "Yes" | "Low" | 2 | 1 | 8 | "Auditory" | 3.2 | 76 |
| 179993 | 28 | "Male" | "Arts" | "9,4" | 1.9 | 1.9 | "Yes" | 75.7 | 5.3 | "Good" | 4 | "Master" | "Medium" | "9.0" | "No" | 2.62 | 3 | 3.5 | "No" | 1 | 6.1 | "Quiet Room" | "Yes" | "Medium" | 2 | 2 | 10 | "Kinesthetic" | 8.3 | 60 |
| 179994 | 24 | "Other" | "Business" | "4,4" | 3.2 | 2.6 | "No" | 96.0 | 6.8 | "Good" | 3 | "Bachelor" | "Low" | "5.4" | "Yes" | 4.0 | 5 | 2.1 | "No" | 2 | 9.7 | "Library" | "No" | "Low" | 2 | 2 | 10 | "Auditory" | 1.6 | 100 |
| 179995 | 16 | "Male" | "Engineering" | "11,09" | 2.1 | 1.0 | "Yes" | 80.8 | 6.1 | "Fair" | 0 | "High School" | "Medium" | "1" | "No" | 3.4 | 2 | 2.1 | "No" | 1 | 8.3 | "Library" | "No" | "Low" | 1 | 8 | 10 | "Auditory" | 5.3 | 88 |
| 179996 | 16 | "Female" | "Business" | "8,98" | 0.4 | 2.9 | "No" | 99.5 | 4.1 | "Good" | 0 | "Some College" | "Low" | "5.7" | "Yes" | 2.26 | 1 | 3.9 | "No" | 3 | 4.7 | "Co-Learning Gr… | "No" | "Low" | 3 | 6 | 10 | "Kinesthetic" | 6.8 | 52 |
| 179997 | 26 | "Female" | "Arts" | "5,91" | 1.6 | 1.6 | "Yes" | 46.1 | 8.3 | "Good" | 7 | "Master" | "Low" | "6.7" | "Yes" | 3.15 | 3 | 5.6 | "No" | 3 | 7.5 | "Dorm" | "No" | "Medium" | 7 | 5 | 10 | "Visual" | 1.3 | 89 |
| 179998 | 23 | "Other" | "Biology" | "3,84" | 0.6 | 3.5 | "Yes" | 58.7 | 5.8 | "Good" | 2 | "PhD" | "High" | "7.6" | "Yes" | 3.67 | 6 | 2.4 | "No" | 4 | 9.3 | "Quiet Room" | "Yes" | "Low" | 2 | 3 | 7 | "Kinesthetic" | 3.7 | 96 |
| 179999 | 25 | "Other" | "Engineering" | "5,91" | 4.5 | 3.4 | "Yes" | 97.7 | 5.3 | "Fair" | 1 | "Some College" | "High" | "3.5" | "No" | 4.0 | 7 | 2.8 | "No" | 0 | 12.2 | "Co-Learning Gr… | "Yes" | "Medium" | 1 | 6 | 7 | "Reading" | 6.7 | 100 |
# 2. Normalizar nombres de columna
mapping = {
col: (
col.strip().lower()
.replace("á","a").replace("é","e")
.replace("í","i").replace("ó","o")
.replace("ú","u").replace("ñ","n")
.replace(" ", "_").replace("/", "_")
)
for col in df.columns
}
df = df.rename(mapping)
# 3. Convertir a pandas para usar .corr()
pdf = df.to_pandas()
# 4. Filtrar solo columnas numéricas
numeric_cols = pdf.select_dtypes(include="number").columns
# 5. Calcular correlaciones con exam_score
correlaciones = pdf[numeric_cols].corr()["exam_score"].sort_values(ascending=False)
# 6. Mostrar resultados Correlacion
print(correlaciones)## exam_score 1.000000
## previous_gpa 0.932940
## screen_time 0.169788
## sleep_hours 0.090820
## exercise_frequency 0.086983
## student_id 0.007557
## time_management_score 0.005940
## attendance_percentage 0.002876
## semester 0.000541
## age 0.000487
## motivation_level 0.000021
## netflix_hours -0.001271
## social_activity -0.002795
## parental_support_level -0.006333
## social_media_hours -0.006351
## stress_level -0.118550
## exam_anxiety_score -0.235909
## Name: exam_score, dtype: float64
# 7. Seleccionar y limpiar las variables más relevantes
df = (
df
.select([
pl.col("previous_gpa").alias("promedio_anterior"),
pl.col("exam_anxiety_score").alias("ansiedad_examen"),
pl.col("exam_score").alias("nota_examen")
])
.with_columns([
pl.col("promedio_anterior")
.str.replace(",", ".")
.cast(pl.Float64),
pl.col("ansiedad_examen")
.str.replace(",", ".")
.cast(pl.Float64),
pl.col("nota_examen")
.str.replace(",", ".")
.cast(pl.Float64)
])
.drop_nulls()
)
# 8. Convertir a pandas (ya hecho antes)
pdf = df.to_pandas()
X = pdf[["promedio_anterior", "ansiedad_examen"]].values
y = pdf["nota_examen"].values
# 9. Entrenar regresión
model = LinearRegression().fit(X, y)
y_pred = model.predict(X)
# 10. Métricas
print(f"Coeficientes: {model.coef_}")## Coeficientes: [2.33810692e+01 1.81972239e-02]
## Intercepto: 4.76
## MSE: 17.42
## R²: 0.8704
import matplotlib.pyplot as plt
import seaborn as sns
# 11. Primer gráfico: Nota vs. Promedio Anterior
plt.figure(figsize=(8,6))
sns.regplot(x=pdf["promedio_anterior"], y=pdf["nota_examen"], scatter_kws={'alpha':0.6})
plt.title("Nota de Examen vs. Promedio Anterior")
plt.xlabel("Promedio Anterior")
plt.ylabel("Nota de Examen")
plt.grid(True)
plt.tight_layout()
plt.show()# 12. Segundo gráfico: Nota vs. Ansiedad de Examen
plt.figure(figsize=(8,6))
sns.regplot(x=pdf["ansiedad_examen"], y=pdf["nota_examen"], scatter_kws={'alpha':0.6}, color="orange")
plt.title("Nota de Examen vs. Ansiedad ante el Examen")
plt.xlabel("Ansiedad en Examen")
plt.ylabel("Nota de Examen")
plt.grid(True)
plt.tight_layout()
plt.show()previous_gpa)Pendiente (coeficiente ≈ 0.93)
Cada punto adicional en el promedio académico previo se asocia con un
incremento estimado de 0.93 puntos en la nota del
examen.
Intercepto (≈ valor obtenido)
Representa la nota esperada cuando el promedio previo es cero. No tiene
interpretación práctica directa, pero permite ajustar la línea de
predicción.
Calidad del ajuste
- MSE: [valor]
- R² ≈ 0.93 → aproximadamente el 93 % de la variación
en la nota puede explicarse por el promedio anterior. Es un predictor
altamente confiable.
exam_anxiety_score)Pendiente (coeficiente ≈ -0.23)
Indica que cada punto más en el nivel de ansiedad se asocia con una
disminución estimada de 0.23 puntos en la nota.
Intercepto (≈ valor obtenido)
Nota estimada cuando la ansiedad es cero. Funciona como base del modelo,
aunque no siempre tiene sentido práctico.
Calidad del ajuste
- MSE: [valor]
- R² ≈ 0.05 → solo el 5 % de la variación se explica
por la ansiedad. Es un factor relevante pero débil por sí solo.
🔎 Conclusión: El promedio anterior es un predictor fuerte del rendimiento, mientras que la ansiedad aporta una señal más suave pero aún valiosa si se combina con otras variables.