En este reporte se analizará el dataset de mtcars, un dataset que nos arroja datos extraídos de 1974 de la revista Motor Trend US; contiene el gasto de gasolina, 10 aspectos del diseño y rendimiento de 32 automóviles Para poder comprender qué variables afectan el rendimiento de gasolina, se usará regresión lineal simple y múltiple para este análisis.

Formato del dataset: 32 observaciones en 11 variables númericas

[, 1] mpg Miles/(US) gallon

[, 2] cyl Number of cylinders

[, 3] disp Displacement (cu.in.)

[, 4] hp Gross horsepower

[, 5] drat Rear axle ratio

[, 6] wt Weight (1000 lbs)

[, 7] qsec 1/4 mile time

[, 8] vs Engine (0 = V-shaped, 1 = straight)

[, 9] am Transmission (0 = automatic, 1 = manual)

[,10] gear Number of forward gears

[,11] carb Number of carburetors

data(mtcars)
library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# The data in more readable fashion
head(mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
my.mtcars <- mtcars

Para las variables de transmisión (am): 0: Automatico 1: Manual

Para las variables del tipo de motor (vs): 0: V-shaped 1: Straight

my.mtcars$am <- factor(my.mtcars$am, levels = c(0,1), labels = c("Automatic", "Manual"))
my.mtcars$vs <- factor(my.mtcars$vs, levels = c(0,1), labels = c("V-shaped", "Straight"))

Regresión lineal simple

Ya que analizamos los datos, podemos hacer un análisis con una regresión lineal simple.

Una regresión lineal simple es una técnica estadística y de aprendizaje automático que modela la relación entre una variable dependiente (objetivo) y una o más variables independientes (predictores) mediante una línea recta. Busca la mejor línea de ajuste minimizando la distancia entre los puntos de datos y dicha recta.

Para este análisis se identificará si el peso del vehículo afecta el rendimiento de la gasolina.

mpg: Variable dependiente

wt: Variable independiente

model_simple <- lm(mpg ~ wt, data = my.mtcars)
summary(model_simple) #Obtenemos la información importante del modelo 
## 
## Call:
## lm(formula = mpg ~ wt, data = my.mtcars)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4.5432 -2.3647 -0.1252  1.4096  6.8727 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  37.2851     1.8776  19.858  < 2e-16 ***
## wt           -5.3445     0.5591  -9.559 1.29e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.046 on 30 degrees of freedom
## Multiple R-squared:  0.7528, Adjusted R-squared:  0.7446 
## F-statistic: 91.38 on 1 and 30 DF,  p-value: 1.294e-10

Este modelo nos arroja lo siguiente:

El coeficiente wt (-5.3445) indica que por cada unidad adicional de peso, el rendimiento de millas por galón (mpg) disminuye 5.34, por lo que vehículos más pesados tienden a consumir más combustible. Por otra parte, tenemos un p-value < 0.001, indicando que los coeficientes son estadísticamente significativos, determinando que el peso es un predictor muy relevante en el rendimiento de combustible. A su vez, el R2 de 0.7528, teniendo un 75.28% de la variabilidad en mpg, con el R2 ajustado que está cerca del R2 real, indica que el modelo no está sobreajustado.

En general, el F statistic de 91.38 y el p-value nos dicen que el peso sí aporta información relevante para determinar el rendimiento de millas por hora, con residuos que están relativamente centrados alrededor de 0 (mediana ≈ -0.125).

# The output plot
ggplot(my.mtcars, aes(x = wt, y = mpg)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(title = "Simple Linear Regression: MPG vs Weight",
    x = "Weight (1000 lbs)",
    y = "Miles per Gallon") +
  theme_minimal(base_size = 14)
## `geom_smooth()` using formula = 'y ~ x'

Su representación gráfica ejemplifica esta relación inversa entre peso y eficacia (consumo de combustible).

Sin embargo, el margen de error no se adecúa a los datos, es decir, que el modelo no es perfecto y no está prediciendo con la mejor exactitud gran parte de los resultados. Esto no indica que deban existir otras variables que también influyan en el rendimiento.

Para una mejor visualización, se realizará un gráfico que determine los residuales con los valores ajustados.

my.mtcars$resid_simple <- residuals(model_simple)
my.mtcars$fitted_simple <- fitted(model_simple)

ggplot(my.mtcars, aes(x = fitted_simple, y = resid_simple)) +
  geom_point(size = 3) +
  geom_hline(yintercept = 0, linetype = "dashed") +
  labs(title = "Residual Plot for Simple Linear Regression",
    x = "Fitted values",
    y = "Residuals") +
  theme_minimal(base_size = 14)

# -------------------------------

Residuos: error en el modelo

Residuos Valor real - Valor predicho

Los residuos no están distribuidos completamente de manera aleatoria alrededor del cero, pudiendo existir la presencia de valores atípicos o que rompan el supuesto de linealidad. Concluyendo que, aunque el modelo es significativo, podría mejorarse incorporando términos no lineales u otras variables explicativas.

Regresión lineal Multiple

Ahora realizaremos una regresión lineal múltiple para ver si el modelo mejora incluyendo ahora la variable de horsepower (caballos de fuerza).

model_multiple <- lm(mpg ~ wt + hp, data = mtcars)
summary(model_multiple) 
## 
## Call:
## lm(formula = mpg ~ wt + hp, data = mtcars)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -3.941 -1.600 -0.182  1.050  5.854 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 37.22727    1.59879  23.285  < 2e-16 ***
## wt          -3.87783    0.63273  -6.129 1.12e-06 ***
## hp          -0.03177    0.00903  -3.519  0.00145 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.593 on 29 degrees of freedom
## Multiple R-squared:  0.8268, Adjusted R-squared:  0.8148 
## F-statistic: 69.21 on 2 and 29 DF,  p-value: 9.109e-12

Este modelo nos arroja lo siguiente:

El modelo de regresión lineal múltiple muestra que tanto el peso (wt) como los caballos de fuerza (hp) tienen una relación negativa y estadísticamente significativa con el rendimiento de combustible (mpg). En particular, el coeficiente de wt (-3.87783) indica que, manteniendo constantes los caballos de fuerza, por cada unidad adicional de peso el rendimiento disminuye aproximadamente 3.88 mpg. De manera similar, el coeficiente de hp (-0.03177) indica que, manteniendo constante el peso, un incremento en los caballos de fuerza reduce ligeramente el rendimiento de combustible.

Los valores p asociados a ambos coeficientes son menores a 0.01, lo que confirma que son predictores estadísticamente significativos. Además, el modelo presenta un buen ajuste, con un R2 de 0.8268, lo que indica que explica el 82.68% de la variabilidad en mpg. El R2 ajustado es cercano, lo que sugiere que no existe sobreajuste.

Por otro lado, el estadístico F (69.21) junto con un p-value muy pequeño indica que el modelo en su conjunto es significativo. Finalmente, los residuos se encuentran relativamente centrados alrededor de cero, lo que sugiere un ajuste adecuado del modelo.

En conclusión, el modelo es bueno y tanto el peso como los caballos de fuerza son variables relevantes para explicar el rendimiento de combustible.

Gracias a este análisis podemos determinar una gráfica para ver la diferencia entre los puntos observados y los puntos predichos con una recta, es aquí donde podemos ver los residuos.

# Observed vs predicted values
my.mtcars$pred_multiple <- predict(model_multiple)
ggplot(my.mtcars, aes(x = mpg, y = pred_multiple)) +
  geom_point(size = 3) +
  geom_abline(intercept = 0, slope = 1, linetype = "dashed") +
  labs(title = "Observed vs Predicted MPG",
    x = "Observed MPG",
    y = "Predicted MPG") +
  theme_minimal(base_size = 14)

El modelo sigue una tendencia lineal con mucha mayor claridad y poca dispersión en relación a la referencia.

Gracias a esta gráfica ahora podemos determinar cómo los rendimientos por galón son afectados por el peso y cómo los caballos de fuerza disminuyen su rendimiento.

Esto se analizará con un bubble plot; este es un diagrama de dispersión que tiene un tamaño de burbuja para representar una tercera variable, permitiendo analizar relaciones multivariadas de manera visual.

# Effect of weight colored by horsepower
ggplot(my.mtcars, aes(x = wt, y = mpg, size = hp)) +
  geom_point(alpha = 0.8) +
  labs(title = "MPG, Weight, and Horsepower",
    x = "Weight (1000 lbs)",
    y = "Miles per Gallon",
    size = "Horsepower") +
  theme_minimal(base_size = 14)

En este gráfico podemos confirmar lo visto en la regresión lineal múltiple, teniendo una relación negativa entre el peso del vehículo y el rendimiento del combustible. Con esto se observa cómo las dos variables afectan: mientras más peso tenga el vehículo y mayor caballos de fuerza tenga, menos rendimiento por galón En conjunto, se observa que tanto el peso como los caballos de fuerza influyen negativamente en la eficiencia del combustible.

Por otra parte, podemos hacer un análisis con los residuales creando una gráfica.

# the residuals
my.mtcars$resid_multiple <- residuals(model_multiple)
my.mtcars$fitted_multiple <- fitted(model_multiple)

ggplot(my.mtcars, aes(x = fitted_multiple, y = resid_multiple)) +
  geom_point(size = 3) +
  geom_hline(yintercept = 0, linetype = "dashed") +
  labs(title = "Residual Plot for Multiple Linear Regression",
    x = "Fitted values",
    y = "Residuals") +
  theme_minimal(base_size = 14)

summary(model_simple)$r.squared
## [1] 0.7528328
summary(model_multiple)$r.squared
## [1] 0.8267855
summary(model_simple)$adj.r.squared
## [1] 0.7445939
summary(model_multiple)$adj.r.squared
## [1] 0.8148396

La gráfica muestra que hay varios datos distribuidos por el cero, aumentando la confianza en el resultado de la R2, ya que no hay tanto margen de error entre los puntos predichos.

Concluyendo que, quizás, el modelo se pueda mejorar aumentando las variables y haciendo pruebas, pero se considera que es bastante bueno y es posible predecir igualmente con ese R2 alto.

Regresión logística

Podemos hacer un análisis de las variables de forma categórica, observando la probabilidad que existe de que la transmisión de algún carro sea automática (0) o manual (1) en relación al peso y los caballos de fuerza.

model_logistic <- glm(am ~ wt + hp, data = my.mtcars, family = binomial)
summary(model_logistic)
## 
## Call:
## glm(formula = am ~ wt + hp, family = binomial, data = my.mtcars)
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)   
## (Intercept) 18.86630    7.44356   2.535  0.01126 * 
## wt          -8.08348    3.06868  -2.634  0.00843 **
## hp           0.03626    0.01773   2.044  0.04091 * 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 43.230  on 31  degrees of freedom
## Residual deviance: 10.059  on 29  degrees of freedom
## AIC: 16.059
## 
## Number of Fisher Scoring iterations: 8

El modelo de regresión logística clasifica si el auto es automático o manual según reglas; en base a esto, el modelo nos dice:

El peso con un estimado negativo (-8.083) nos indica que un auto pesado posiblemente es automático.

Para los caballos de fuerza y con un estimado positivo (0.03), se establece que los autos con mayor potencia son manuales.

Los valores p en ambas son menores a 0.05 e indica que nuestros resultados no se deben al azar.

Podemos ver que las variables seleccionadas para el modelo son relevantes y ayudarán a explicar la transmisión con certeza.

# predicted probabilities
my.mtcars$prob_manual <- predict(model_logistic, type = "response")
head(my.mtcars[, c("am", "wt", "hp", "prob_manual")])
##                          am    wt  hp prob_manual
## Mazda RX4            Manual 2.620 110 0.842335537
## Mazda RX4 Wag        Manual 2.875 110 0.404782533
## Datsun 710           Manual 2.320  93 0.970240822
## Hornet 4 Drive    Automatic 3.215 110 0.041728035
## Hornet Sportabout Automatic 3.440 175 0.069388122
## Valiant           Automatic 3.460 105 0.004988159

Recordamos que -> automático (0) o manual (1)

Con esta tabla podemos observar cómo trabaja el modelo para predecir si un auto es manual. Para esto, la prob debe ser mayor a 0.5 o acercarse lo más posible a (1).

El modelo ha estimado que un Mazda RX4 con un peso bajo de 2.620 tiene una prob. del 84% de ser manual. Este resultado puede compararse con “am” para verificarse.

# probability vs weight
ggplot(my.mtcars, aes(x = wt, y = prob_manual)) +
  geom_point(size = 3) +
  labs(title = "Predicted Probability of Manual Transmission",
    x = "Weight (1000 lbs)",
    y = "Probability of Manual") +
  theme_minimal(base_size = 14)

Observamos que aquellos carros pesados suelen estar del lado derecho y tener bajas probabilidades de ser manuales, mientras que los carros ligeros estan a la izquierda superior y son automáticos El gráfico respeta el límite establecido de 0.5 para categorizar.

OJO, en ciertas ocasiones existen excepciones donde los datos coinciden con una categoría, pero pertenecen a otra.

# colored by actual class
ggplot(my.mtcars, aes(x = wt, y = prob_manual, color = am)) +
  geom_point(size = 3) +
  labs(title = "Predicted Probability of Manual Transmission by Weight",
    x = "Weight (1000 lbs)",
    y = "Predicted Probability",
    color = "Actual Class") +
  theme_minimal(base_size = 14)

Dándole color a los puntos, podemos observar estos errores claramente.

La precisión de nuestro modelo se compara con los hechos; solo se equivoca una vez por cada categoría.

Esto indica que nuestro modelo tiene una gran precisión (93%) para categorizar carros manuales de automáticos.

# convert probabilities to predicted classes
my.mtcars$pred_am <- ifelse(my.mtcars$prob_manual > 0.5, "Manual", "Automatic")
my.mtcars$pred_am <- factor(my.mtcars$pred_am, levels = c("Automatic", "Manual"))

table(Predicted = my.mtcars$pred_am, Actual = my.mtcars$am)
##            Actual
## Predicted   Automatic Manual
##   Automatic        18      1
##   Manual            1     12
# Accuracy?
mean(my.mtcars$pred_am == my.mtcars$am)
## [1] 0.9375

Nuestras conclusiones de predicción anteriores pueden desglozarse en un gráfico claro y resumido como el de a continuación:

# Confussion-style bar plot
results <- my.mtcars %>% count(am, pred_am)

ggplot(results, aes(x = am, y = n, fill = pred_am)) +
  geom_col(position = "dodge") +
  labs(title = "Actual vs Predicted Transmission Type",
    x = "Actual Class",
    y = "Count",
    fill = "Predicted Class") +
  theme_minimal(base_size = 14)