Profesor del programa de Ingeniería Industrial, Universidad Sergio Arboleda. Candidato a doctor en Ingeniería de la Universidad de los Andes.
La ciencia de datos es un campo multidisciplinario que incluye estadística, computación, aprendizaje automático y dominios profesionales para obtener conocimiento e información de los datos. Además, permite describir un proceso semiautomático cuyo propósito principal es analizar un gran volumen de datos sobre un problema específico con el propósito de crear patrones en diferentes campos científicos. Esos patrones, encontrados en formas múltiples como asociaciones, anomalías, agrupaciones, clases, etc., constituyen estructuras o instancias, que aparecen en los datos y son estadísticamente significativas.La ciencia de datos usualmente termina desarrollando, a partir de estos patrones, un producto de datos. Un producto de datos es el cambio de los datos de una empresa/organización/ciudad en un producto para resolver un problema.
Por ejemplo, un producto de datos puede ser el sistema de recomendación de productos utilizado en Amazon y Lazada. Estas empresas tienen una gran cantidad de datos basados en las compras de los compradores. Usando estos datos, Amazon y Lazada pueden identificar los patrones de compra de los compradores y crear un sistema de recomendación o producto de datos para recomendar otros productos cada vez que un comprador compra un producto.
El día de hoy vamos a empezar a crear nuestros primeros productos de datos: tablas, gráficos y regresiones lineales. Sin embargo, hay que seguir un proceso para que los datos nos dé todo el potencial que tienen. Así pues, primero hay que “limpiar” nuestros datos y luego preguntarnos ¿qué queremos saber de nuestros datos?. Sabiendo esto, vamos a empezar.
Como vimos la clase pasada, algunos de los comandos que podemos utilizar para cargar datos son read.table()y read.csv(). Estas funciones están cargadas en R y RStudio. Sin embargo, también hay paquetes que nos ayudan a cargar los datos que recibimos. La base de datos que trabajaremos hoy se llama “Clase 2.csv”. Recuerden revisar su Working Directory y poner los datos ahí.
El día de hoy vamos a trabajar con el paquete readr para hacer el cargue de los datos. Readrnos permite no solamente leer archivos en .csv sino, por ejemplo, logs de páginas web. Todas las funciones de empiezan por read_ más la extensión del archivo. Para cargar el paquete y los datos haremos lo siguiente:
#Llamar el paquete para que funcione
library('readr')
## Warning: package 'readr' was built under R version 3.4.4
#Leer los datos
data1 <- read_csv("Clase 2.csv")
## Warning: Missing column names filled in: 'X1' [1]
## Parsed with column specification:
## cols(
## .default = col_double(),
## Name = col_character(),
## Nationality = col_character(),
## Club = col_character(),
## `Preferred Foot` = col_character(),
## `Work Rate` = col_character(),
## `Body Type` = col_character(),
## Position = col_character(),
## Joined = col_character(),
## `Contract Valid Until` = col_character(),
## Height = col_character(),
## Weight = col_character()
## )
## See spec(...) for full column specifications.
Como podemos observar, tenemos una gran cantidad de información en esta base de datos. Hagámonos una idea del tamaño usando la función dim()
dim(data1)
## [1] 18207 49
De las 49 variables que tenemos, necesitamos saber qué información recogen. Para ello, la función str() que vimos la clase pasada seguirá aplicando. Miremos los datos que acabamos de cargar:
str(data1)
## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 18207 obs. of 49 variables:
## $ X1 : num 0 1 2 3 4 5 6 7 8 9 ...
## $ ID : num 158023 20801 190871 193080 192985 ...
## $ Name : chr "L. Messi" "Cristiano Ronaldo" "Neymar Jr" "De Gea" ...
## $ Age : num 31 33 26 27 27 27 32 31 32 25 ...
## $ Nationality : chr "Argentina" "Portugal" "Brazil" "Spain" ...
## $ Overall : num 94 94 92 91 91 91 91 91 91 90 ...
## $ Potential : num 94 94 93 93 92 91 91 91 91 93 ...
## $ Club : chr "FC Barcelona" "Juventus" "Paris Saint-Germain" "Manchester United" ...
## $ Preferred Foot : chr "Left" "Right" "Right" "Right" ...
## $ International Reputation: num 5 5 5 4 4 4 4 5 4 3 ...
## $ Weak Foot : num 4 4 5 3 5 4 4 4 3 3 ...
## $ Skill Moves : num 4 5 5 1 4 4 4 3 3 1 ...
## $ Work Rate : chr "Medium/ Medium" "High/ Low" "High/ Medium" "Medium/ Medium" ...
## $ Body Type : chr "Messi" "C. Ronaldo" "Neymar" "Lean" ...
## $ Position : chr "RF" "ST" "LW" "GK" ...
## $ Jersey Number : num 10 7 10 1 7 10 10 9 15 1 ...
## $ Joined : chr "Jul 1, 2004" "Jul 10, 2018" "Aug 3, 2017" "Jul 1, 2011" ...
## $ Contract Valid Until : chr "2021" "2022" "2022" "2020" ...
## $ Height : chr "5'7" "6'2" "5'9" "6'4" ...
## $ Weight : chr "159lbs" "183lbs" "150lbs" "168lbs" ...
## $ Crossing : num 84 84 79 17 93 81 86 77 66 13 ...
## $ Finishing : num 95 94 87 13 82 84 72 93 60 11 ...
## $ HeadingAccuracy : num 70 89 62 21 55 61 55 77 91 15 ...
## $ ShortPassing : num 90 81 84 50 92 89 93 82 78 29 ...
## $ Volleys : num 86 87 84 13 82 80 76 88 66 13 ...
## $ Dribbling : num 97 88 96 18 86 95 90 87 63 12 ...
## $ Curve : num 93 81 88 21 85 83 85 86 74 13 ...
## $ FKAccuracy : num 94 76 87 19 83 79 78 84 72 14 ...
## $ LongPassing : num 87 77 78 51 91 83 88 64 77 26 ...
## $ BallControl : num 96 94 95 42 91 94 93 90 84 16 ...
## $ Acceleration : num 91 89 94 57 78 94 80 86 76 43 ...
## $ SprintSpeed : num 86 91 90 58 76 88 72 75 75 60 ...
## $ Agility : num 91 87 96 60 79 95 93 82 78 67 ...
## $ Reactions : num 95 96 94 90 91 90 90 92 85 86 ...
## $ Balance : num 95 70 84 43 77 94 94 83 66 49 ...
## $ ShotPower : num 85 95 80 31 91 82 79 86 79 22 ...
## $ Jumping : num 68 95 61 67 63 56 68 69 93 76 ...
## $ Stamina : num 72 88 81 43 90 83 89 90 84 41 ...
## $ Strength : num 59 79 49 64 75 66 58 83 83 78 ...
## $ LongShots : num 94 93 82 12 91 80 82 85 59 12 ...
## $ Aggression : num 48 63 56 38 76 54 62 87 88 34 ...
## $ Interceptions : num 22 29 36 30 61 41 83 41 90 19 ...
## $ Positioning : num 94 95 89 12 87 87 79 92 60 11 ...
## $ Vision : num 94 82 87 68 94 89 92 84 63 70 ...
## $ Penalties : num 75 85 81 40 79 86 82 85 75 11 ...
## $ Composure : num 96 95 94 68 88 91 84 85 82 70 ...
## $ Marking : num 33 28 27 15 68 34 60 62 87 27 ...
## $ StandingTackle : num 28 31 24 21 58 27 76 45 92 12 ...
## $ SlidingTackle : num 26 23 33 13 51 22 73 38 91 18 ...
## - attr(*, "spec")=
## .. cols(
## .. X1 = col_double(),
## .. ID = col_double(),
## .. Name = col_character(),
## .. Age = col_double(),
## .. Nationality = col_character(),
## .. Overall = col_double(),
## .. Potential = col_double(),
## .. Club = col_character(),
## .. `Preferred Foot` = col_character(),
## .. `International Reputation` = col_double(),
## .. `Weak Foot` = col_double(),
## .. `Skill Moves` = col_double(),
## .. `Work Rate` = col_character(),
## .. `Body Type` = col_character(),
## .. Position = col_character(),
## .. `Jersey Number` = col_double(),
## .. Joined = col_character(),
## .. `Contract Valid Until` = col_character(),
## .. Height = col_character(),
## .. Weight = col_character(),
## .. Crossing = col_double(),
## .. Finishing = col_double(),
## .. HeadingAccuracy = col_double(),
## .. ShortPassing = col_double(),
## .. Volleys = col_double(),
## .. Dribbling = col_double(),
## .. Curve = col_double(),
## .. FKAccuracy = col_double(),
## .. LongPassing = col_double(),
## .. BallControl = col_double(),
## .. Acceleration = col_double(),
## .. SprintSpeed = col_double(),
## .. Agility = col_double(),
## .. Reactions = col_double(),
## .. Balance = col_double(),
## .. ShotPower = col_double(),
## .. Jumping = col_double(),
## .. Stamina = col_double(),
## .. Strength = col_double(),
## .. LongShots = col_double(),
## .. Aggression = col_double(),
## .. Interceptions = col_double(),
## .. Positioning = col_double(),
## .. Vision = col_double(),
## .. Penalties = col_double(),
## .. Composure = col_double(),
## .. Marking = col_double(),
## .. StandingTackle = col_double(),
## .. SlidingTackle = col_double()
## .. )
¿Notaron algo en los datos que acabamos de cargar? Si miran detenidamente las columnas, tenemos problemas con la altura, el peso y el año en que se termina su contrato. Además, el nombre de la primera variable parece no existir. Para eso, iremos al segundo paso que todo científico de datos debe tener en cuenta, el preprocesamiento de los datos.
Lo primero que hemos de detectar es qué información está incluida en las columnas que parece haber problemas. Para eso utilizaremos una función que vimos la clase pasada, unique(). Miremos cómo nos va:
# Los datos en Weight
unique(data1$Weight)
#Los datos en Height
unique(data1$Height)
#Los datos en Contract Valid Until
unique(data1$`Contract Valid Until`)
Dado que hemos visto que, por lo menos, en estas tres variables tenemos datos que son NA, lo primero que debemos hacer es eliminar estos datos. Para eso usaremos la función na.omit(). Esta función eliminará todos los registros que sean NA de cualquiera de las variables.
data2 <- na.omit(data1)
Ya nos aseguramos de que al menos no hay valores vacíos. Lo siguiente es arreglar el peso. Para eso debemos extraer el valor de la columna usando la función parse.number(). Esta función nos permitirá eliminar las letras antes y después del primer número disponible. La aplicaremos a la variable peso para que la podamos usar.
data2$Weight <- parse_number(data2$Weight)
Lo siguiente es eliminar los datos que no nos sirven de Contract valid until. Para esto, usaremos solamente las que nos interesan y las seleccionaremos usando expresiones lógicas. Miremos cómo funciona:
data3 <- data2[data2$`Contract Valid Until` <= 2021 & data2$`Contract Valid Until`>= 2018,]
Si revisamos, estos datos todavía aparecen como caracteres. ¿Qué hacer ahí? Vamos a convertir la variable en numérica usando la función as.numeric(). Miremos cómo lo hacemos:
data3$`Contract Valid Until` <- as.numeric(data3$`Contract Valid Until`)
Para la altura, debemos entender cuál es el problema que tenemos. ¿Qué es lo que pasa con esta variable? Al estar en una medida inglesa no podemos hacer operaciones con estas variables. Por tanto, lo que tendremos que hacer es usar la función substr(). Una vez separados los datos, haremos las operaciones respectivas para convertirlos en datos útiles.
#Extraemos los dos valores
pies <- substr(data3$Height, start = 1, stop = 1)
pulgadas <- substr(data3$Height, start = 3, stop = 3)
#Convertimos las columnas en números
pies <- as.numeric(pies)
pulgadas <- as.numeric(pulgadas)
#Asignamos la conversión a la variable
data3$Height <- pies * 0.3 + pulgadas * 0.03
Finalmente, nuestra primera variable nos dice que su nombre está mal ¿cómo lo cambiamos? Fácil, usaremos el comando colnames()
colnames(data3)[1] <- "Indicador"
Aunque esta revisión de datos no fue exhaustiva, hay otra forma de mirar toda la información que tenemos. Para eso vamos a utilizar la función summary().
summary(data3)
¿Y qué podemos hacer ya cuándo los datos están limpios? Fácil, nos empezaremos a hacer las preguntas importantes sobre nuestros datos.
Formular una pregunta puede ser una forma útil de guiar el proceso de análisis de datos exploratorios y limitar el número exponencial de rutas que se pueden tomar con cualquier conjunto de datos de tamaño considerable. En particular, una pregunta aguda o hipótesis puede servir como una herramienta de reducción de dimensión que puede eliminar variables que no son inmediatamente relevantes para la pregunta.
Por ejemplo, en este capítulo veremos un conjunto de datos de los jugadores que están en este momento inscritos en la FIFA para el año 2019. Una pregunta general podría ser:
*¿Los niveles de desempeño de un jugador son más altos si son más ágiles?
Pero una pregunta más específica podría ser
*¿Los niveles de desempeño potencial de un jugador son más altos para los jugadores esbeltos que para los jugadores normales?
Tenga en cuenta que ambas preguntas pueden ser de interés y que ninguna es correcta o incorrecta. Pero la primera pregunta requiere analizar todos los tipos de desempeño en todas las variables, mientras que la segunda pregunta solo requiere observar un solo tipo de desempeño en dos tipos de cuerpos.
Por lo general, es una buena idea dedicar unos minutos a averiguar cuál es la pregunta que realmente le interesa y reducirla para que sea lo más específica posible (sin dejar de ser interesante).
Para este capítulo, no nos centraremos en una pregunta específica, ya que veremos a lo largo del tiempo iremos cambiando la pregunta.
Como nota al margen, una de las preguntas más importantes que puede responder con un análisis exploratorio de datos es “¿Tengo los datos correctos para responder a esta pregunta?” A menudo, esta pregunta es difícil de responder al principio, pero puede ser más clara a medida que ordenamos y miramos los datos.
Para eso, empezaremos con las medidas de tendencia central.
Las medidas de posición (o medidas de tendencia central) describen brevemente la ubicación de los datos en la recta numérica real. Especifican un punto central alrededor del cual los datos tienen la tendencia a reunirse. Las medidas de posición más importantes son la moda, la media y la mediana.
La primera de la medida que expondremos es la moda. Dado que no existe una función específica en R (sin usar un paquete). Para hacerlo, usaremos la tabla de frecuencias y calcularemos el valor máximo. Nota: usaremos una variable que nos interese conocer
table(data3$Age)
La siguiente medida que nos interesa es la media. Esta es la medida más popular, y se calcula con la función mean():
mean(data3$Age)
Por último, nos interesa conocer la mediana. La mediana es el valor de la observación mediana, cuando las observaciones se ordenan en orden ascendente o descendente. Si el número de observaciones (n) es un número impar, entonces la observación mediana es el (n + 1) / 2, mientras que si el número de observaciones es un número par, tenemos dos observaciones de la mediana en las posiciones n / 2 yn / 2 +1, entonces la mediana es el valor medio de estos dos valores. Para calcularla, usaremos la función median():
median(data3$Age)
Ahora trataremos las medidas de dispersión. Estas medidas describen brevemente la variabilidad de los datos en la recta numérica real. En otras palabras, revelan la variabilidad de las observaciones. La variabilidad no siempre es clara a partir de las medidas de posición, como por ejemplo la media. Si los datos se recopilan alrededor de la media, por ejemplo, si la varianza es baja, la media puede representar datos de manera bastante efectiva. Sin embargo, en el escenario opuesto, las medidas de posición no proporcionan una manera efectiva de describir los datos. Para esto, las medidas de dispersión más importantes, que se describen más adelante, son el rango, la varianza, la desviación estándar, el coeficiente de variación y los valores percentiles.
Para calcular el rango tenemos dos opciones. Primero, usando los valores mínimos y máximos de la función y la segunda usando la función range():
#Versión 1: valores mínimos y máximos
minimo <- min(data3$Age)
maximo <- max(data3$Age)
maximo - minimo
## [1] 29
#Versión 2: función range
range(data3$Age)
## [1] 16 45
range(data3$Age)[2] - range(data3$Age)[1]
## [1] 29
El valor del percentil p de una muestra con n observaciones, se define como la observación para la cual el p% de las observaciones son más pequeñas que él y el (1-p)% de las observaciones son mayores que este. Para calcular estos cuantiles usaremos la función quantile():
quantile(data3$Age, 0.75, type=7)
## 75%
## 29
La varianza es el promedio de las diferencias al cuadrado de la media, y se usa para medir la extensión de los datos. Para calcular este valor, se usa la función var()
var(data3$Age)
## [1] 23.36141
Sin embargo, hay que hacer una aclaración. Esta es la varianza de la muestra, no de la población. Para ajustar este valor, deberá multiplicar por el tamaño de la muestra menos 1 y dividir por el tamaño de la muestra.
La desviación estándar es la raíz cuadrada de una varianza y mide la dispersión de los datos. Las variaciones se incrementan cuando hay más variaciones y se reducen cuando hay variaciones menores, porque la variación es un resultado cuadrado. Con la desviación estándar, la varianza es la raíz cuadrada, por lo que es más fácil de visualizar y aplicar. Para calcular la desviación estándar usaremos la función sd()
sd(data3$Age)
## [1] 4.833364
Ahora, ¿con estos datos puedo construir intervalos de confianza? Claro que si, ya tenemos suficiente información para lograr este resultado.
En este capítulo presentaremos las formas que podemos utilizar para visualizar nuestras observaciones. La visualización puede realizarse con vectores y tablas, pero también mediante diagramas como histogramas, gráficos de barras, gráficos circulares, etc. En cada caso, es muy importante distinguir nuestras observaciones en datos cuantitativos o cualitativos. Comenzamos con datos cualitativos, que generalmente se representan con tablas, gráficos de barras y gráficos circulares.
Lo primero que haremos será crear tablas de frecuencia. Para esto usaremos el comando table():
table(data3$`Body Type`)
##
## Akinfenwa Lean Messi Normal Stocky
## 1 4917 1 8302 871
Si lo que deseamos no son la frecuencias absolutas sino las frecuencias relativas usaremos la función prop.table() sobre la función table:
prop.table(table(data3$`Body Type`))*100
##
## Akinfenwa Lean Messi Normal Stocky
## 0.007096225 34.892137383 0.007096225 58.912858359 6.180811808
También podemos crear matrices de contingencia. Una matriz de contingencia tiene que ver con dos variables categóricas y muestra su distribución de frecuencia. Estas las creamos igual que las tablas de frecuencia:
table(data3$`Body Type`, data3$`Preferred Foot`)
##
## Left Right
## Akinfenwa 0 1
## Lean 1205 3712
## Messi 1 0
## Normal 1815 6487
## Stocky 186 685
prop.table(table(data3$`Body Type`, data3$`Preferred Foot`))*100
##
## Left Right
## Akinfenwa 0.000000000 0.007096225
## Lean 8.550950894 26.341186489
## Messi 0.007096225 0.000000000
## Normal 12.879648027 46.033210332
## Stocky 1.319897814 4.860913994
Ahora, trataremos de visualizar los datos a través de gráficas de barras. Para eso utilizaremos dos versiones, los gráficos de R y el paquete ggplot2. ggplot2 es un paquete que ofrece un poderoso lenguaje que permite crear gráficos que representan datos univariados, multivariados y categóricos de manera directa. La funcionalidad incorporada de R ofrece el trazado de gráficos, pero ggplot nos permite trazar gráficos más avanzados utilizando la gramática de gráficos. Sin embargo, dado que el curso es muy corto, les dejaré explorar las funcionalidades de ggplot2 en este link: https://cran.r-project.org/web/packages/ggplot2/ggplot2.pdf
Primero crearemos la gráfica con barplot() sobre la tabla de frecuencias relativas:
barplot(table(data3$`Body Type`))
Ahora haremos la versión de ggplot. Para esto, usaremos la función ggplot()y le añadiremos una capa con la función geom_bar():
#Primero cargamos el paquete
library("ggplot2")
## Warning: package 'ggplot2' was built under R version 3.4.4
#Usamos ggplot2 para crear los gráficos
ggplot(data3) + geom_bar(aes(x=data3$`Body Type`, fill="red"))
Finalmente, si queremos un gráfico de pie o circular, con R podemos usar el comando pie:
pie(table(data3$`Body Type`))
O si lo queremos hacer con ggplot2, lo que debemos hacer es añadir otra capa al gráfico que indique que las coordenadas son polares
ggplot(data3) + geom_bar(aes(x=data3$`Body Type`), fill="red") + coord_polar()
La primera tabla que veremos será la misma que en el caso anterior, la tabla de frecuencia. No lo explicaremos de nuevo, pero es una opción. Acá nos centraremos en tres tipos de gráficas, los histogramas, los gráficos de dispersión y los diagramas de caja.
un histograma es una representación gráfica de una variable en forma de barras, donde la superficie de cada barra es proporcional a la frecuencia de los valores representados. Sirven para obtener una “primera vista” general, o panorama, de la distribución de la población, o de la muestra, respecto a una característica, cuantitativa y continua (como la longitud o el peso).
Para representar un histograma con R, la función que utilizaremos será hist() y para personalizar la clases usaremos nclass:
hist(data3$Potential, nclass = 50)
Para crear un histograma con ggplot2, usaremos la capa geom_histogram() y las clases se personalizan con binds o binwidth:
ggplot(data3, aes(x=data3$Potential)) + geom_histogram(binwidth = 1)
El diagrama de caja es una forma adecuada de mostrar las características más importantes de la distribución de observación de las muestras. El diagrama de caja es un rectángulo basado en los valores del primer, segundo (mediana) y tercer cuartil, mientras que los bigotes varían desde el valor más pequeño hasta el más alto de las observaciones.
Para crear estos gráficos en R usaremos la función boxplot():
boxplot(data3$Potential)
boxplot(data3$Potential, data3$Overall)
Para hacer un boxplot en ggplot2 usaremos la capa geom_boxplot. Pero antes usaremos el preferred foot como un factor para hacer la comparación:
data3$`Preferred Foot`<- as.factor(data3$`Preferred Foot`)
ggplot(data3, aes(x=data3$`Preferred Foot`, y=data3$Potential)) + geom_boxplot(fill="grey") + labs(title="boxplot")
Finalmente, haremos un gráfico de dispersión para mirar la relación entre dos variables. Para esto, usaremos el graficador por excelencia de R, plot():
plot(data3$Potential ~ data3$Crossing)
Para hacer estos gráficos en ggplot2, la capa que agregaremos será geom_point():
ggplot(data3) + geom_point(aes(color="red", x=Potential, y=Crossing))
Ok, hemos finalizado el análisis exploratorio de datos. ¿Eso quiere decir que ya acabé? No, eso quiere decir que ahora va a empezar lo más interesante. Vamos a terminar la clase hablando de uno de los modelos por excelencia para la toma de decisiones basada en datos, la regresión lineal. Pero…y la relación de las variables. Tranquilos, empezaremos por hablar de correlaciones.
Para calcular la relación entre las variables tengo dos opciones, la correlación bivariada o la correlación parcial. Si deseo calcular la correlación bivariada podemos usar la función cor() o cor.test():
cor(data3$Height,data3$Potential)
## [1] -0.002380412
cor.test(data3$Height,data3$Potential)
##
## Pearson's product-moment correlation
##
## data: data3$Height and data3$Potential
## t = -0.28256, df = 14090, p-value = 0.7775
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.01889049 0.01413096
## sample estimates:
## cor
## -0.002380412
El análisis de regresión implica identificar relaciones entre variables. Dado un conjunto de variables independientes o predictoras, nuestro objetivo es predecir una variable dependiente o objetivo. En el análisis de regresión, la variable objetivo es numérica y las variables predictoras pueden ser numéricas, categóricas u ordinales.
Empezaremos con el modelo de regresión más sencillo, la regresión lineal simple. La regresión lineal simple es un caso especial de regresión lineal con una sola variable predictiva x y una variable objetivo y. Para realizar una regresión usaremos el comando lm():
reg1 <- lm(data3$Acceleration ~ data3$Weight)
reg1
##
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight)
##
## Coefficients:
## (Intercept) data3$Weight
## 141.4277 -0.4673
summary(reg1)
##
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight)
##
## Residuals:
## Min 1Q Median 3Q Max
## -62.747 -7.130 1.599 8.870 37.355
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 141.427706 1.196572 118.2 <2e-16 ***
## data3$Weight -0.467279 0.007178 -65.1 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 13.28 on 14090 degrees of freedom
## Multiple R-squared: 0.2312, Adjusted R-squared: 0.2312
## F-statistic: 4238 on 1 and 14090 DF, p-value: < 2.2e-16
Si queremos ver que tan bien nos fue con los datos, usando un gráfico de dispersión de nuestras variables podemos añadir nuestra línea de regresión con la función abline().
plot(data3$Acceleration ~ data3$Weight)
abline(reg1)
Si queremos una regresión que pase por el origen (sin intercepto) deberemos usar la siguiente expresión:
reg2 <- lm(data3$Acceleration ~ data3$Weight - 1)
summary(reg2)
##
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight - 1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -69.067 -9.404 4.729 14.483 45.692
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## data3$Weight 0.3774029 0.0009466 398.7 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 18.73 on 14091 degrees of freedom
## Multiple R-squared: 0.9186, Adjusted R-squared: 0.9186
## F-statistic: 1.589e+05 on 1 and 14091 DF, p-value: < 2.2e-16
plot(data3$Acceleration ~ data3$Weight)
abline(reg2)
Para la regresión lineal múltiple, a las variables predictoras las agregaremos con el comando +:
reg3 <- lm(data3$Acceleration ~ data3$Weight + data3$`Preferred Foot`+ data3$Height)
summary(reg3)
##
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight + data3$`Preferred Foot` +
## data3$Height)
##
## Residuals:
## Min 1Q Median 3Q Max
## -58.245 -6.985 1.284 8.583 38.292
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 168.49638 1.52321 110.62 <2e-16 ***
## data3$Weight -0.37007 0.00781 -47.38 <2e-16 ***
## data3$`Preferred Foot`Right -2.96994 0.25989 -11.43 <2e-16 ***
## data3$Height -23.55001 0.89578 -26.29 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 12.9 on 14088 degrees of freedom
## Multiple R-squared: 0.274, Adjusted R-squared: 0.2738
## F-statistic: 1772 on 3 and 14088 DF, p-value: < 2.2e-16
Sin embargo, hay una trinidad que debemos revisar para asegurar que se cumplan tres condiciones: multicolinealidad, heterocedasticidad y independencia de los residuos.
Para determinar si los residuos son independientes, usaremos un gráfico QQ. Usaremos las funciones qqnorm() y qqline():
plot(reg3$residuals)
qqnorm(reg3$residuals)
qqline(reg3$residuals)
Además, podemos usar el test de Durbin Watson para saber si se comportan normalmente. La función que nos permite hacer eso es durbinWatsonTest() de la librería car.
library(car)
## Warning: package 'car' was built under R version 3.4.4
## Loading required package: carData
## Warning: package 'carData' was built under R version 3.4.4
durbinWatsonTest(reg3)
## lag Autocorrelation D-W Statistic p-value
## 1 0.09085532 1.818067 0
## Alternative hypothesis: rho != 0
¿Cómo podríamos hacer las otras pruebas? Esa será su tarea, construyan su código para resolver estos problemas.
Taller
Ahora que ya hemos visto las formas de entender los datos, ustedes deberán hacer su propia investigación con la base de datos que tienen. Háganse al menos 5 preguntas sobre sus datos y traten de resolverlas usando lo que aprendimos el día de hoy.