1 Objetivo

Construir y evaluar un modelo de regresión lineal simple para realizar predicciones de peso de jugadores de fútbol con los datos de FIFA de acuerdo a la variable estatura

2 Descripción

  • Cargar librerías

  • Cargar datos

  • Seleccionar variables de estudio estatura y peso

  • Crear datos de entrenamiento y datos de validación

  • Construir el modelo de regresión lineal simple

  • Realizar predicciones con los datos validación

  • Realizar predicciones con datos nuevos

  • Evaluar el modelo

  • Interpretación del caso

3 Desarrollo

3.1 Cargar librerías

library(readr) # Para importar datos
library(dplyr) # Para filtrar   
library(knitr) # Para datos tabulares
library(ggplot2) # Para visualizar
library(plotly)
library(caret)  # Para particionar
library(Metrics) # Para determinar rmse 

3.2 Cargar datos

datos <- read.csv("https://raw.githubusercontent.com/rpizarrog/Analisis-Inteligente-de-datos/main/datos/datos.FIFA.limpios.csv", stringsAsFactors = TRUE)

Explorar datos

str(datos)
## 'data.frame':    17955 obs. of  50 variables:
##  $ X                       : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Name                    : Factor w/ 16956 levels "\xc0ngel Rangel",..: 9545 3148 12385 4116 8543 4405 9553 9753 15251 7716 ...
##  $ Age                     : int  31 33 26 27 27 27 32 31 32 25 ...
##  $ Nationality             : Factor w/ 163 levels "Afghanistan",..: 7 123 21 140 14 14 36 158 140 137 ...
##  $ Overall                 : int  94 94 92 91 91 91 91 91 91 90 ...
##  $ Potential               : int  94 94 93 93 92 91 91 91 91 93 ...
##  $ Club                    : Factor w/ 651 levels " SSV Jahn Regensburg",..: 216 331 436 378 377 140 473 216 473 63 ...
##  $ Preferred.Foot          : Factor w/ 3 levels "","Left","Right": 2 3 3 3 3 3 3 3 3 3 ...
##  $ International.Reputation: int  5 5 5 4 4 4 4 5 4 3 ...
##  $ Weak.Foot               : int  4 4 5 3 5 4 4 4 3 3 ...
##  $ Skill.Moves             : int  4 5 5 1 4 4 4 3 3 1 ...
##  $ Height                  : Factor w/ 22 levels "","5'1","5'10",..: 10 15 12 17 4 11 11 13 13 15 ...
##  $ Weight                  : Factor w/ 58 levels "","110lbs","115lbs",..: 23 34 19 27 21 25 17 37 33 38 ...
##  $ Crossing                : int  84 84 79 17 93 81 86 77 66 13 ...
##  $ Finishing               : int  95 94 87 13 82 84 72 93 60 11 ...
##  $ HeadingAccuracy         : int  70 89 62 21 55 61 55 77 91 15 ...
##  $ ShortPassing            : int  90 81 84 50 92 89 93 82 78 29 ...
##  $ Volleys                 : int  86 87 84 13 82 80 76 88 66 13 ...
##  $ Dribbling               : int  97 88 96 18 86 95 90 87 63 12 ...
##  $ Curve                   : int  93 81 88 21 85 83 85 86 74 13 ...
##  $ FKAccuracy              : int  94 76 87 19 83 79 78 84 72 14 ...
##  $ LongPassing             : int  87 77 78 51 91 83 88 64 77 26 ...
##  $ BallControl             : int  96 94 95 42 91 94 93 90 84 16 ...
##  $ Acceleration            : int  91 89 94 57 78 94 80 86 76 43 ...
##  $ SprintSpeed             : int  86 91 90 58 76 88 72 75 75 60 ...
##  $ Agility                 : int  91 87 96 60 79 95 93 82 78 67 ...
##  $ Reactions               : int  95 96 94 90 91 90 90 92 85 86 ...
##  $ Balance                 : int  95 70 84 43 77 94 94 83 66 49 ...
##  $ ShotPower               : int  85 95 80 31 91 82 79 86 79 22 ...
##  $ Jumping                 : int  68 95 61 67 63 56 68 69 93 76 ...
##  $ Stamina                 : int  72 88 81 43 90 83 89 90 84 41 ...
##  $ Strength                : int  59 79 49 64 75 66 58 83 83 78 ...
##  $ LongShots               : int  94 93 82 12 91 80 82 85 59 12 ...
##  $ Aggression              : int  48 63 56 38 76 54 62 87 88 34 ...
##  $ Interceptions           : int  22 29 36 30 61 41 83 41 90 19 ...
##  $ Positioning             : int  94 95 89 12 87 87 79 92 60 11 ...
##  $ Vision                  : int  94 82 87 68 94 89 92 84 63 70 ...
##  $ Penalties               : int  75 85 81 40 79 86 82 85 75 11 ...
##  $ Composure               : int  96 95 94 68 88 91 84 85 82 70 ...
##  $ Marking                 : int  33 28 27 15 68 34 60 62 87 27 ...
##  $ StandingTackle          : int  28 31 24 21 58 27 76 45 92 12 ...
##  $ SlidingTackle           : int  26 23 33 13 51 22 73 38 91 18 ...
##  $ GKDiving                : int  6 7 9 90 15 11 13 27 11 86 ...
##  $ GKHandling              : int  11 11 9 85 13 12 9 25 8 92 ...
##  $ GKKicking               : int  15 15 15 87 5 6 7 31 9 78 ...
##  $ GKPositioning           : int  14 14 15 88 10 8 14 33 7 88 ...
##  $ GKReflexes              : int  8 11 11 94 13 8 9 37 11 89 ...
##  $ Valor                   : int  110500000 77000000 118500000 72000000 102000000 93000000 67000000 80000000 51000000 68000000 ...
##  $ Estatura                : num  1.7 1.88 1.75 1.93 1.8 1.73 1.73 1.83 1.83 1.88 ...
##  $ PesoKgs                 : num  72.1 83 68 76.2 69.8 ...
print("Estatura")
## [1] "Estatura"
summary(datos$Estatura)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.550   1.750   1.800   1.812   1.850   2.060      48
print("Peso")
## [1] "Peso"
summary(datos$PesoKgs)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   49.90   69.85   74.84   75.28   79.83  110.22      48

3.3 Limpiar datos

Se detectaron 48 registros con valores NA por lo cual se quitan del conjunto de datos ya que solo representan tan solo el 0.26% o sea menos del 1%.

datos.limpios <- subset(datos, !is.na(Estatura))

3.4 Partir datos

Se identifica el numero de observaciones n y se siembra la semilla a 0432 para construir los mismos valores aleatorios por la función createDataPartition().

n <- nrow(datos.limpios)
# Modificar la semilla estableciendo como par´metro los útimos cuatro dígitos de su no de control. 
# Ej. set.seed(0732), o set.seed(1023)
# set.seed(2022) 
set.seed(0432)

De manera aleatoria se construyen los datos de entrenamiento y los datos de validación.

En la variable entrena se generan los registros que van a ser los datos de entrenamiento, de tal forma que los datos de validación serán los que no sena de entrenamiento [-entrena].

entrena <- createDataPartition(y = datos.limpios$PesoKgs, p = 0.70, list = FALSE, times = 1)
# Datos entrenamiento
datos.entrenamiento <- datos.limpios[entrena, ]  # [renglones, columna]
# Datos validación
datos.validacion <- datos.limpios[-entrena, ]

Mostrar los primeros 20 y últimos 20 registros de los datos de entrenamiento.

Solo se muestran las variables de consecutivo X, Name y las dos variables de interés Estatura y PesoKgs.

kable(head(datos.entrenamiento[, c('X', 'Name', 'Estatura', 'PesoKgs')], 20), caption = "Datos de entrenamiento, primeros 20 registros")
Datos de entrenamiento, primeros 20 registros
X Name Estatura PesoKgs
1 1 L. Messi 1.70 72.12
2 2 Cristiano Ronaldo 1.88 83.01
3 3 Neymar Jr 1.75 68.04
4 4 De Gea 1.93 76.20
6 6 E. Hazard 1.73 73.94
7 7 L. Modric 1.73 66.22
8 8 L. Surez 1.83 86.18
9 9 Sergio Ramos 1.83 82.10
10 10 J. Oblak 1.88 87.09
11 11 R. Lewandowski 1.83 79.83
12 12 T. Kroos 1.83 76.20
19 19 M. ter Stegen 1.88 84.82
20 20 T. Courtois 1.98 96.16
22 22 E. Cavani 1.85 77.11
23 23 M. Neuer 1.93 92.08
24 24 S. Agero 1.73 69.85
27 27 M. Salah 1.75 71.21
28 28 Casemiro 1.85 83.91
29 29 J. Rodrguez 1.80 78.02
30 30 L. Insigne 1.63 58.97
kable(tail(datos.entrenamiento[, c('X', 'Name', 'Estatura', 'PesoKgs')], 20), caption = "Datos de entrenamiento, últimos 20 registros")
Datos de entrenamiento, últimos 20 registros
X Name Estatura PesoKgs
17926 17926 T. Hillman 1.80 67.13
17928 17928 L. Wahlstedt 1.83 79.83
17929 17929 J. Williams 1.88 73.94
17932 17932 Y. Gez 1.78 74.84
17933 17933 D. Horton 1.85 81.19
17936 17936 C. Ehlich 1.78 73.03
17938 17938 A. Kaltner 1.78 74.84
17939 17939 L. Watkins 1.75 79.83
17940 17940 J. Norville-Williams 1.80 76.20
17941 17941 S. Squire 1.85 74.84
17943 17943 J. Milli 1.91 84.82
17944 17944 S. Griffin 1.73 63.96
17947 17947 J. Livesey 1.80 69.85
17948 17948 M. Baldisimo 1.68 68.04
17949 17949 J. Young 1.75 71.21
17950 17950 D. Walsh 1.85 76.20
17952 17952 N. Christoffersson 1.91 77.11
17953 17953 B. Worman 1.73 67.13
17954 17954 D. Walker-Rice 1.78 69.85
17955 17955 G. Nugent 1.78 79.83

Mostrar los primeros 20 y últimos 20 registros de los datos de validación.

kable(head(datos.validacion[, c('X', 'Name', 'Estatura', 'PesoKgs')], 20), caption = "Datos de validación, primeros 20 registros")
Datos de validación, primeros 20 registros
X Name Estatura PesoKgs
5 5 K. De Bruyne 1.80 69.85
13 13 D. Godn 1.88 78.02
14 14 David Silva 1.73 67.13
15 15 N. Kant 1.68 72.12
16 16 P. Dybala 1.78 74.84
17 17 H. Kane 1.88 88.90
18 18 A. Griezmann 1.75 73.03
21 21 Sergio Busquets 1.88 76.20
25 25 G. Chiellini 1.88 84.82
26 26 K. Mbapp 1.78 73.03
33 33 Coutinho 1.73 68.04
39 39 G. Higuan 1.85 88.90
41 41 S. Handanovic 1.93 92.08
46 46 P. Pogba 1.93 83.91
50 50 Jordi Alba 1.70 68.04
55 55 Piqu 1.93 84.82
56 56 L. San 1.83 74.84
57 57 Bernardo Silva 1.73 63.96
61 61 R. Sterling 1.70 68.95
62 62 Roberto Firmino 1.80 76.20
kable(tail(datos.validacion[, c('X', 'Name', 'Estatura', 'PesoKgs')], 20), caption = "Datos de validación, últimos 20 registros")
Datos de validación, últimos 20 registros
X Name Estatura PesoKgs
17885 17885 N. Morahan 1.75 66.22
17891 17891 Chen Yajun 1.83 64.86
17893 17893 W. Henry 1.80 77.11
17894 17894 J. Garcia Sossa 1.70 62.14
17902 17902 J. Yabur 1.78 68.95
17903 17903 M. Dyrmose 1.75 69.85
17904 17904 M. Roberts 1.78 68.04
17920 17920 Nicolas Firmino 1.80 69.85
17923 17923 R. Takae 1.70 59.87
17924 17924 S. Adewusi 1.85 73.03
17927 17927 R. Roache 1.78 73.94
17930 17930 M. Hurst 1.85 78.02
17931 17931 C. Maher 1.80 60.78
17934 17934 E. Tweed 1.80 72.12
17935 17935 Zhang Yufeng 1.78 78.93
17937 17937 L. Collins 1.78 67.13
17942 17942 N. Fuentes 1.73 66.22
17945 17945 K. Fujikawa 1.70 66.22
17946 17946 D. Holland 1.78 63.96
17951 17951 J. Lundstram 1.75 60.78

Visualizar dispersión de los datos de entrenamiento con las variables de interés Estatura y PesoKgs.

g <- plot_ly(data = datos.entrenamiento, 
             x = ~Estatura, 
             y = ~PesoKgs) %>%
layout(title = 'Jugadores FIFA. Dispersión de estatura en metros y peso en kilogramos.')
  
g

3.5 Construir el modelo

Con los datos de entrenamiento construir el modelo de regresión lineal simple.

\[ Y = a + bx \]

ó

\[ Y = \beta_0 + \beta_1\cdot x \]

De las dos variables de interés, Estatura y PesoKgs se determina que la variable predictora es Estatura y el PesoKgs es la variable de respuesta o también:

  • Estatura es variable independiente y

  • PesoKgs es variable dependiente

Es decir, la variable PesoKgs depende de la Estatura

modelo <- lm(data = datos.entrenamiento, formula = PesoKgs ~ Estatura)
modelo
## 
## Call:
## lm(formula = PesoKgs ~ Estatura, data = datos.entrenamiento)
## 
## Coefficients:
## (Intercept)     Estatura  
##      -67.76        78.94

3.5.1 Coeficientes del modelo

Se determinan los valores de a y b de la fórmula \(Y = a+bx\)

a <- modelo$coefficients[1]
b <- modelo$coefficients[2]
paste("Valor de la abcisa a es   : ", round(a, 6))
## [1] "Valor de la abcisa a es   :  -67.757977"
paste("Valor de la pendiente b es: ", round(b, 6))
## [1] "Valor de la pendiente b es:  78.939873"

3.5.2 Linea de tendencia del modelo

Con la el valor de los valores de tendencia o valores ajustados del modelo se visualiza la recta de tendencia del modelo.

La gráfica g se construye por partes, primero la dispersión, segundo la linea de tendencia, tercero se agrega el título, para luego solo mostrar la gráfica g.

g <- plot_ly(data = datos.entrenamiento, 
             x = ~Estatura, 
             y = ~PesoKgs, 
             name = 'Dispersión',
             type = 'scatter', 
             mode = 'markers', 
             color = I('blue')) 
g <- g %>% add_trace(x = ~Estatura,
                     y = ~modelo$fitted.values, name = 'Tendencia', mode = 'lines+markers', color = I('red'))
g <- g %>%
layout(title = 'Jugadores FIFA. Dispersión y Tendencia de estatura en metros y peso en kilogramos.')
g

3.6 Predicciones

Con los datos de validación, se hacen predicciones con la función predict(), luego se presentan algunas de las mismas prediccciones que pueden ser los mismos valores de Estatura o con nuevos valores calculadas manualmente usando la fórmula \(Y = a + bx\).

Se hace un data.frame de comparaciones con lo cual se presentan los valores reales y los valores de las predicciones. Se presenta solo las primeras 20 y últimas 20 predicciones.

predicciones <- predict(object = modelo, newdata = datos.validacion)
comparaciones <- data.frame(Estatura = datos.validacion$Estatura, PesoKgs = datos.validacion$PesoKgs, predicccion = predicciones)
 kable(x = head(comparaciones, 20), caption = "Predicciones")
Predicciones
Estatura PesoKgs predicccion
5 1.80 69.85 74.33380
13 1.88 78.02 80.64899
14 1.73 67.13 68.80800
15 1.68 72.12 64.86101
16 1.78 74.84 72.75500
17 1.88 88.90 80.64899
18 1.75 73.03 70.38680
21 1.88 76.20 80.64899
25 1.88 84.82 80.64899
26 1.78 73.03 72.75500
33 1.73 68.04 68.80800
39 1.85 88.90 78.28079
41 1.93 92.08 84.59598
46 1.93 83.91 84.59598
50 1.70 68.04 66.43981
55 1.93 84.82 84.59598
56 1.83 74.84 76.70199
57 1.73 63.96 68.80800
61 1.70 68.95 66.43981
62 1.80 76.20 74.33380
  kable(x = tail(comparaciones, 20), caption = "Predicciones")
Predicciones
Estatura PesoKgs predicccion
17885 1.75 66.22 70.38680
17891 1.83 64.86 76.70199
17893 1.80 77.11 74.33380
17894 1.70 62.14 66.43981
17902 1.78 68.95 72.75500
17903 1.75 69.85 70.38680
17904 1.78 68.04 72.75500
17920 1.80 69.85 74.33380
17923 1.70 59.87 66.43981
17924 1.85 73.03 78.28079
17927 1.78 73.94 72.75500
17930 1.85 78.02 78.28079
17931 1.80 60.78 74.33380
17934 1.80 72.12 74.33380
17935 1.78 78.93 72.75500
17937 1.78 67.13 72.75500
17942 1.73 66.22 68.80800
17945 1.70 66.22 66.43981
17946 1.78 63.96 72.75500
17951 1.75 60.78 70.38680
x <- c(1.70, 1.80, 1.90)
Y = a + b * x
Y 
## [1] 66.43981 74.33380 82.22778

3.7 Evaluación del modelo

  • ¿Que tan bien predice el modelo?

  • ¿Es bueno el modelo de regresión lineal simple ?

  • ¿Cuáles estadísticos hay que calcular e identificar para evaluar el modelo?

summary(modelo)
## 
## Call:
## lm(formula = PesoKgs ~ Estatura, data = datos.entrenamiento)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -18.411  -2.905  -0.007   3.128  37.465 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -67.758      1.108  -61.16   <2e-16 ***
## Estatura      78.940      0.611  129.20   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4.638 on 12535 degrees of freedom
## Multiple R-squared:  0.5711, Adjusted R-squared:  0.5711 
## F-statistic: 1.669e+04 on 1 and 12535 DF,  p-value: < 2.2e-16

3.7.1 Valores residuales

Es la diferencia entre los valores reales y los valores de tendencia. Con estos valores residuales se pude calcular el Error cuadrático medio y la raiz del mismo par interpretar que tan lejos son los valores de predicción con respecto a los valores de tendencia.

n <- nrow(datos.entrenamiento)
rmse <- sqrt(sum(modelo$residuals ^ 2) / n) 
rmse
## [1] 4.637786

3.7.2 Error Cuadrático Medio (RMSE)

La raiz del Error Cuadrático Medio (RMSE) es una métrica que dice qué tan lejos están los valores predichos de los valores observados o reales en un análisis de regresión, en promedio. Se calcula como:

\[ RMSE = \sqrt{\frac{\sum(predicho_i - real_i)^{2}}{n}} \]

RMSE es una forma útil de ver qué tan bien un modelo de regresión puede ajustarse a un conjunto de datos.

Cuanto mayor sea el RMSE, mayor será la diferencia entre los valores predichos y reales, lo que significa que peor se ajusta un modelo de regresión a los datos. Por el contrario, cuanto más pequeño sea el RMSE, mejor podrá un modelo ajustar los datos.

Usando el data.frame comparaciones que son las predicciones de los datos de validación previamente construído se determina el RMSE manualmente.

n <- nrow(comparaciones)
rmse1 <- sqrt(sum((comparaciones$PesoKgs - comparaciones$predicccion)^2) / n)
rmse1
## [1] 4.669584

Se puede usar la función rmse() de la librería Metrics

rmse2 <- rmse(actual = comparaciones$PesoKgs, predicted = comparaciones$predicccion)
rmse2
## [1] 4.669584

Usando la función RMSE() de la librería caret

rmse3 <- RMSE(obs = comparaciones$PesoKgs, pred = comparaciones$predicccion)
rmse3
## [1] 4.669584

En todos los cálculos el valor de rmse es de 4.631735, ¿que significa el valor de 4.6695841?

Con base en RMSE, se puede comparar dos modelos diferentes entre sí y poder identificar qué modelo se ajusta mejor a la predicción de los datos.

3.7.3 Multiple R-squared

De acuerdo al estadístico Multiple R-squared con valor 0.5711, significa que la variable Estatura representa tan solo el 57.11% del valor del PesoKgs.

El coeficiente de determinación identificado por expresión R^2 e identificado como Multiple R-squared determina la calidad del modelo para replicar los resultados y la proporción de variación de los resultados que puede explicarse por el modelo.

Este valor Multiple R-squared es relativo al compararlo con un criterio inicial o con una métrica inicial. Por ejemplo, si al principio se hubiera establecido que el modelo se acepta si hay un 70% o mas el modelo se acepta, entonces bajo esta premisa tal vez el modelo no se acepta ya que Multiple R-squared es 0.57 que está por debajo del 70%.

Sin embargo, si se hubiera establecido que se acepta con un valor por encima del 50%, entonces este modelo si se acepta ya que Multiple R-squared es 0.57 o 57%.

3.7.4 Variables estadísticamente significativas

Se observan que las variables estadísticas tanto el coeficiente de intersección como la variable predictiva Estatura si son altamente y estadísticamente significativas por debajo del 0.001 o con un nivel de confianza mayor al 99.9%. Se observa con los ‘***’ en las variables.

4 Interpretación

Para el caso de Regresión Lineal Simple para los datos de Peso-Estatura se utilizo el archivo de FIFA que contiene 17955 observaciones y 50 variables. Pero para la limpieza de datos, algunas datos de los jugadores venían en NA, siendo en total 48 registros representando el 0.26% de los registros o sea menos del 1%. Al ser un valor menor se decidió borrarlos ya que no afectaban en nada en los demás cálculos.

Con la semilla planteada se utilizo los últimos 4 dígitos de mi numero de control que fueron 0432, permitiendo de manera aleatoria construir los datos de entrenamiento y los datos de validación. Una vez obtenida los datos separados y graficados en una gráfica de dispersión, se pudo obtener una vez calculado los datos dio una correlación de 4.637786 siendo una correlación positiva considerable. El valor de Multiple R-squeared: fue de 0.5711 (57.11%) significando que la variable Estatura representa tan solo el 57.11% del valor del PesoKgs. Si se hubiera establecido que el modelo de aceptación con un 70% o mas el modelo se acepta, entonces bajo esta premisa tal vez el modelo no se acepta ya que Multiple R-squared es 0.5711 (57.11%) que está por debajo del 70%. La variable Estatura es altamente y estadísticamente significativas por debajo del 0.001 o con un nivel de confianza mayor al 99.9%. El modelo establecido predice positivamente considerable como se ve en la correlación.