Temas cubiertos: 7 (Análisis y algoritmos), 8 (Validación y evaluación de modelos)
Descripción: Este documento carga el dataset Gold del Script 2, construye modelos de regresión lineal (simple y múltiple) para predecir los puntos obtenidos en una carrera, evalúa su rendimiento con métricas (MSE, RMSE, R²) y realiza predicciones sobre nuevos datos.
IMPORTANTE: Ejecutar primero
01_ingesta_y_limpieza.Rmd y luego
02_transformacion_y_EDA.Rmd.
library(dplyr) # Manipulación de datos
library(ggplot2) # Visualizaciones
# [PROPORCIONADO]
df_gold <- readRDS("datos/gold/f1_datos_gold.rds")
cat("Dataset Gold cargado:", nrow(df_gold), "filas x", ncol(df_gold), "columnas\n")
## Dataset Gold cargado: 3760 filas x 43 columnas
head(df_gold)
## season round race_name circuit_id
## 1 2022 4 Russian Grand Prix sochi
## 2 2015 1 Hungarian Grand Prix hungaroring
## 3 2017 12 Hungarian Grand Prix hungaroring
## 4 2018 4 Austrian Grand Prix red_bull_ring
## 5 2014 5 Spanish Grand Prix catalunya
## 6 2022 16 Austrian Grand Prix red_bull_ring
## circuit_name date driver_id driver_name
## 1 Sochi Autodrom 2022-06-01 tsunoda Yuki Tsunoda
## 2 Hungaroring 2015-10-18 lawson Liam Lawson
## 3 Hungaroring 2017-08-18 hulkenberg Nico Hülkenberg
## 4 Red Bull Ring 2018-10-23 sargeant Logan Sargeant
## 5 Circuit de Barcelona-Catalunya 2014-11-05 raikkonen Kimi Räikkönen
## 6 Red Bull Ring 2022-04-14 sargeant Logan Sargeant
## driver_nationality constructor grid position position_text points laps
## 1 Japanese alfa romeo 6 20 20 0 67
## 2 New Zealander manor 1 4 4 12 65
## 3 German manor 5 19 19 0 56
## 4 American haas 5 NA R 0 20
## 5 Finnish ferrari 10 NA R 0 5
## 6 American alfa romeo 2 2 2 18 58
## status fastest_lap_time fastest_lap_speed posiciones_ganadas es_podio
## 1 +2 Laps 1:35.727 206.174 -14 0
## 2 Finished 1:33.721 230.861 -3 0
## 3 Finished NA -14 0
## 4 Hydraulics 1:23.903 231.109 NA NA
## 5 Gearbox 1:17.230 234.613 NA NA
## 6 Finished 1:18.126 232.487 0 1
## puntos_por_vuelta constructor_key driver_id_key nombre_equipo pais_sede
## 1 0.0000000 alfa romeo tsunoda Alfa Romeo Switzerland
## 2 0.1846154 manor lawson <NA> <NA>
## 3 0.0000000 manor hulkenberg <NA> <NA>
## 4 0.0000000 haas sargeant Haas United States
## 5 0.0000000 ferrari raikkonen Ferrari Italy
## 6 0.3103448 alfa romeo sargeant Alfa Romeo Switzerland
## anio_fundacion num_empleados director_equipo
## 1 2019 450 Alessandro Alunni Bravi
## 2 NA NA <NA>
## 3 NA NA <NA>
## 4 2016 300 Guenther Steiner
## 5 1929 1200 Frédéric Vasseur
## 6 2019 450 Alessandro Alunni Bravi
## nombre_equipo_presupuesto presupuesto_millones pct_desarrollo pct_personal
## 1 Alfa Romeo 89.8 39.1 39.6
## 2 <NA> NA NA NA
## 3 <NA> NA NA NA
## 4 <NA> NA NA NA
## 5 <NA> NA NA NA
## 6 Alfa Romeo 89.8 39.1 39.6
## code nombre apellido fecha_nacimiento nacionalidad equipo_actual
## 1 TSU Yuki Tsunoda 2000-05-11 Japanese AlphaTauri
## 2 <NA> <NA> <NA> <NA> <NA> <NA>
## 3 HUL Nico Hülkenberg 1987-08-19 German Haas
## 4 <NA> <NA> <NA> <NA> <NA> <NA>
## 5 RAI Kimi Räikkönen 1979-10-17 Finnish Retirado
## 6 <NA> <NA> <NA> <NA> <NA> <NA>
## estatura_cm peso_kg salario_anual_millones titulos_mundiales driver_id_bio
## 1 159 54 2 0 tsunoda
## 2 NA NA NA NA <NA>
## 3 184 74 4 0 hulkenberg
## 4 NA NA NA NA <NA>
## 5 175 70 0 1 raikkonen
## 6 NA NA NA NA <NA>
Referencia: Tema 7 — Análisis y algoritmos
Preparar el dataset para modelado:
points. Variables
predictoras sugeridas: grid,
laps, posiciones_ganadas.na.omit().points >= 0,
grid > 0, laps > 0).Guardar en df_modelo. Mostrar dim() y
summary().
# Seleccionamos variables relevantes y limpiamos datos para modelado
df_modelo <- df_gold %>%
select(points, grid, laps, posiciones_ganadas) %>%
filter(points >= 0, grid > 0, laps > 0) %>%
na.omit()
dim(df_modelo)
## [1] 2295 4
summary(df_modelo)
## points grid laps posiciones_ganadas
## Min. : 0.000 Min. : 1.00 Min. :48.00 Min. :-19.00000
## 1st Qu.: 0.000 1st Qu.: 5.00 1st Qu.:55.00 1st Qu.: -6.00000
## Median : 1.000 Median :10.00 Median :59.00 Median : 0.00000
## Mean : 5.134 Mean :10.38 Mean :59.69 Mean : -0.01743
## 3rd Qu.: 9.000 3rd Qu.:15.00 3rd Qu.:65.00 3rd Qu.: 6.00000
## Max. :25.000 Max. :20.00 Max. :70.00 Max. : 19.00000
El conjunto de modelado queda en 2295 observaciones con
4 variables. Al filtrar valores invalidos y eliminar NAs,
el modelo trabajara con un subconjunto mas coherente y comparable.
# [PROPORCIONADO] — Verificamos la correlación antes de modelar
cat("--- Correlación entre las variables seleccionadas ---\n")
## --- Correlación entre las variables seleccionadas ---
cor_modelo <- cor(df_modelo, use = "complete.obs")
print(round(cor_modelo, 3))
## points grid laps posiciones_ganadas
## points 1.000 -0.021 0.004 0.583
## grid -0.021 1.000 -0.019 0.709
## laps 0.004 -0.019 1.000 -0.011
## posiciones_ganadas 0.583 0.709 -0.011 1.000
# [PROPORCIONADO] — Scatter plots de las predictoras vs. la variable objetivo
pairs(df_modelo, main = "Scatter Plot Matrix - Variables del modelo")
Referencia: Tema 7 — Análisis y algoritmos (regresión lineal)
Entrenar un modelo de regresión lineal simple con
lm() que prediga points a partir de
grid.
PISTA:
modelo_simple <- lm(points ~ grid, data = df_modelo)
Mostrar summary() e interpretar:
grid es positivo o negativo? ¿Tiene
sentido?# Ajustamos un modelo de regresión lineal simple usando grid como predictor
modelo_simple <- lm(points ~ grid, data = df_modelo)
summary(modelo_simple)
##
## Call:
## lm(formula = points ~ grid, data = df_modelo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.382 -5.144 -4.250 3.869 20.120
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.40849 0.30664 17.638 <2e-16 ***
## grid -0.02640 0.02578 -1.024 0.306
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.162 on 2293 degrees of freedom
## Multiple R-squared: 0.0004573, Adjusted R-squared: 2.135e-05
## F-statistic: 1.049 on 1 and 2293 DF, p-value: 0.3059
coef_grid_simple <- coef(modelo_simple)["grid"]
r2_simple <- summary(modelo_simple)$r.squared
pvalor_grid_simple <- summary(modelo_simple)$coefficients["grid", "Pr(>|t|)"]
Tu interpretación aquí:
El coeficiente de grid es -0.02640, por lo que la relación estimada es negativa entre la posición de salida y los puntos obtenidos. Esto sugiere que, en promedio, salir en posiciones más retrasadas se asocia con una menor puntuación.
Sin embargo, el p-valor de grid es 0.306, superior a 0.05, lo que indica que esta relación no es estadísticamente significativa.
Además, el modelo presenta un R-cuadrado de 0.046%, lo que implica que prácticamente no explica la variabilidad de los puntos.
En conjunto, estos resultados sugieren que la posición de salida, por sí sola, no es un buen predictor del rendimiento final en este dataset.
Referencia: Tema 7 — Análisis y algoritmos
Entrenar un modelo de regresión lineal múltiple con
lm() y al menos 2 predictores (ej: grid y
laps, o grid y
posiciones_ganadas).
PISTA:
modelo_multiple <- lm(points ~ grid + laps, data = df_modelo)
Mostrar summary() y comparar:
# Ajustamos un modelo múltiple para capturar mejor la complejidad del rendimiento
modelo_multiple <- lm(points ~ grid + laps + posiciones_ganadas, data = df_modelo)
summary(modelo_multiple)
##
## Call:
## lm(formula = points ~ grid + laps + posiciones_ganadas, data = df_modelo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.8841 -3.2240 -0.6732 2.6481 10.2344
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 16.3333590 0.8196418 19.927 <2e-16 ***
## grid -1.0813006 0.0193494 -55.883 <2e-16 ***
## laps 0.0008096 0.0131923 0.061 0.951
## posiciones_ganadas 1.0533136 0.0137050 76.856 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.788 on 2291 degrees of freedom
## Multiple R-squared: 0.7207, Adjusted R-squared: 0.7203
## F-statistic: 1970 on 3 and 2291 DF, p-value: < 2.2e-16
r2_multiple <- summary(modelo_multiple)$r.squared
coeficientes_multiple <- summary(modelo_multiple)$coefficients
predictores_significativos <- rownames(coeficientes_multiple)[-1][coeficientes_multiple[-1, "Pr(>|t|)"] < 0.05]
Tu interpretación aquí:
El modelo múltiple alcanza un R-cuadrado de 0.7207, frente al 0.0005 del modelo simple, por lo que mejora de forma significativa la capacidad explicativa al añadir más predictores.
El coeficiente de grid es -1.0813, lo que indica una relación negativa: salir en posiciones más retrasadas se asocia con una menor puntuación.
El coeficiente de posiciones_ganadas es 1.0533, lo que sugiere que ganar posiciones durante la carrera tiene un impacto positivo y muy relevante en los puntos obtenidos.
Por otro lado, la variable laps presenta un p-valor de 0.951, por lo que no es estadísticamente significativa y no parece aportar capacidad explicativa al modelo.
En conjunto, los resultados indican que el modelo múltiple mejora sustancialmente respecto al modelo simple y que variables relacionadas con la posición en carrera (grid y posiciones ganadas) son determinantes para explicar el rendimiento, mientras que otras como el número de vueltas tienen un impacto limitado en este dataset.
Referencia: Tema 8 — Validación y evaluación de modelos
Calcular las métricas de evaluación del modelo múltiple:
predicciones <- predict(modelo_multiple, df_modelo)mse <- mean((df_modelo$points - predicciones)^2)rmse <- sqrt(mse)r2 <- summary(modelo_multiple)$r.squared# Evaluamos el modelo mediante métricas de error (MSE, RMSE) y ajuste (R2)
predicciones <- predict(modelo_multiple, df_modelo)
mse <- mean((df_modelo$points - predicciones)^2)
rmse <- sqrt(mse)
r2 <- summary(modelo_multiple)$r.squared
cat("MSE:", round(mse, 4), "\n")
## MSE: 14.3232
cat("RMSE:", round(rmse, 4), "\n")
## RMSE: 3.7846
cat("R2:", round(r2, 4), "\n")
## R2: 0.7207
# [PROPORCIONADO]
df_pred <- data.frame(
real = df_modelo$points,
predicho = predict(modelo_multiple, df_modelo)
)
ggplot(df_pred, aes(x = real, y = predicho)) +
geom_point(alpha = 0.3, color = "steelblue") +
geom_abline(intercept = 0, slope = 1, color = "red",
linetype = "dashed", linewidth = 1) +
labs(title = "Regresión Lineal Múltiple: Predicho vs. Real",
subtitle = paste("R² =", round(summary(modelo_multiple)$r.squared, 3)),
x = "Puntos reales",
y = "Puntos predichos") +
theme_minimal()
Referencia: Tema 7 — Análisis y algoritmos
(predict)
Usar predict() para estimar los puntos en un escenario
hipotético. El data.frame de nuevos datos debe tener
exactamente las mismas columnas predictoras del
modelo.
Probar al menos 2 escenarios y comentar si los resultados tienen sentido.
Ejemplo:
nuevos_datos <- data.frame(grid = 3, laps = 55)
prediccion <- predict(modelo_multiple, nuevos_datos)
# Generamos predicciones para escenarios hipotéticos
nuevos_datos <- data.frame(
grid = c(3, 12),
laps = c(55, 55),
posiciones_ganadas = c(2, -1)
)
predicciones_nuevas <- predict(modelo_multiple, nuevos_datos)
data.frame(
escenario = c("Salida P3 y gana 2 posiciones", "Salida P12 y pierde 1 posicion"),
prediccion_puntos = round(predicciones_nuevas, 2)
)
## escenario prediccion_puntos
## 1 Salida P3 y gana 2 posiciones 15.24
## 2 Salida P12 y pierde 1 posicion 2.35
Tu interpretación de las predicciones aquí:
Las predicciones son coherentes si el escenario mas favorable recibe
una estimacion de puntos mayor. En este caso, el escenario de salida P3
con ganancia de posiciones se estima en 15.24 puntos,
frente a 2.35 para el escenario de salida P12. Aun asi,
conviene recordar que el modelo no capta factores como lluvia,
estrategia, sanciones o abandonos.
# [PROPORCIONADO]
saveRDS(modelo_simple, "datos/gold/modelo_regresion_simple.rds")
saveRDS(modelo_multiple, "datos/gold/modelo_regresion_multiple.rds")
cat("\n========================================\n")
##
## ========================================
cat("Modelos guardados en datos/gold/\n")
## Modelos guardados en datos/gold/
cat("Script 3 completado con éxito.\n")
## Script 3 completado con éxito.
cat("========================================\n")
## ========================================
En este script se ha construido y evaluado un modelo predictivo para estimar los puntos obtenidos en una carrera.
El modelo simple ha mostrado una capacidad explicativa prácticamente nula, lo que indica que la posición de salida por sí sola no es suficiente para explicar el rendimiento.
Sin embargo, el modelo múltiple mejora significativamente el ajuste, destacando la importancia de variables como la posición en parrilla y la evolución durante la carrera.
A pesar de ello, el modelo sigue siendo una simplificación de la realidad, ya que no incorpora factores externos como estrategia, condiciones meteorológicas o abandonos, lo que limita su capacidad predictiva completa.
¿Qué significa el R-cuadrado de un modelo de regresión lineal? Si obtienes un R-cuadrado de 0.35, ¿cómo interpretarías el resultado? ¿Significa que el modelo es malo?
Tu respuesta aquí (5-10 líneas):
El R-cuadrado indica la proporcion de la variabilidad de la variable objetivo que el modelo consigue explicar a partir de las variables predictoras. Si el R-cuadrado es 0.35, significa que el modelo explica aproximadamente el 35% de la variacion observada, mientras que el resto depende de otros factores no incluidos o de ruido. Eso no implica automaticamente que el modelo sea malo: en problemas complejos, un valor asi puede ser razonable y util. Su interpretacion siempre depende del contexto, del objetivo del analisis y de si mejora frente a alternativas mas simples.