La regresión lineal simple es una técnica estadística que permite modelar la relación entre dos variables cuantitativas: una variable independiente X y una variable dependiente Y.
El objetivo del método de Mínimos Cuadrados es encontrar la recta que minimiza la suma de los cuadrados de los residuales (distancias entre los valores reales y los valores predichos por la recta).
La ecuación del modelo es:
\[\hat{Y} = b_0 + b_1 \cdot X\]
Donde:
Se analizan 6 observaciones de temperatura (°C) y ventas de helados (unidades).
# Ingreso de datos
temperatura <- c(20, 24, 28, 32, 36, 40)
ventas <- c(30, 45, 58, 70, 85, 95)
n <- length(temperatura)
# Tabla de datos
datos <- data.frame(
i = 1:n,
X_temp = temperatura,
Y_ventas = ventas,
X2 = temperatura^2,
XY = temperatura * ventas
)
# Totales
totales <- colSums(datos[, -1])
datos_tabla <- rbind(datos, c(NA, totales))
datos_tabla$i[nrow(datos_tabla)] <- "Σ"
knitr::kable(datos_tabla,
col.names = c("i", "X (temp °C)", "Y (ventas)", "X²", "XY"),
caption = "Tabla de datos: Temperatura vs Ventas de helados",
align = "c")| i | X (temp °C) | Y (ventas) | X² | XY |
|---|---|---|---|---|
| 1 | 20 | 30 | 400 | 600 |
| 2 | 24 | 45 | 576 | 1080 |
| 3 | 28 | 58 | 784 | 1624 |
| 4 | 32 | 70 | 1024 | 2240 |
| 5 | 36 | 85 | 1296 | 3060 |
| 6 | 40 | 95 | 1600 | 3800 |
| Σ | 180 | 383 | 5680 | 12404 |
\[b_1 = \frac{n \cdot \Sigma XY - \Sigma X \cdot \Sigma Y}{n \cdot \Sigma X^2 - (\Sigma X)^2}\]
\[b_0 = \frac{\Sigma Y - b_1 \cdot \Sigma X}{n}\]
# Sumas necesarias
sum_X <- sum(temperatura)
sum_Y <- sum(ventas)
sum_X2 <- sum(temperatura^2)
sum_XY <- sum(temperatura * ventas)
cat("Sumas:\n")## Sumas:
## ΣX = 180
## ΣY = 383
## ΣX² = 5680
## ΣXY = 12404
## n = 6
# Pendiente b1
numerador_b1 <- n * sum_XY - sum_X * sum_Y
denominador_b1 <- n * sum_X2 - sum_X^2
b1_manual <- numerador_b1 / denominador_b1
cat("Cálculo de b₁:\n")## Cálculo de b₁:
## Numerador: 6 × 12404 − 180 × 383 = 5484
## Denominador: 6 × 5680 − 180 ² = 1680
## b₁ = 3.2643
## Cálculo de b₀:
## b₀ = ( 383 − 3.2643 × 180 ) / 6
## b₀ = -34.0952
lm)# Ajuste del modelo lineal
modelo <- lm(ventas ~ temperatura)
# Extraer coeficientes
b0 <- coef(modelo)[1]
b1 <- coef(modelo)[2]
# Correlación y R²
r <- cor(temperatura, ventas)
r2 <- summary(modelo)$r.squared
cat("=== RESULTADOS DEL MODELO ===\n")## === RESULTADOS DEL MODELO ===
## Pendiente (b₁): 3.2643
## Intercepto (b₀): -34.0952
## Correlación (r): 0.9988
## R² (det.) : 99.76 %
##
## Ecuación: Ŷ = -34.1 + 3.26 · X
##
## Call:
## lm(formula = ventas ~ temperatura)
##
## Residuals:
## 1 2 3 4 5 6
## -1.1905 0.7524 0.6952 -0.3619 1.5810 -1.4762
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -34.0952 2.4799 -13.75 0.000162 ***
## temperatura 3.2643 0.0806 40.50 2.22e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.349 on 4 degrees of freedom
## Multiple R-squared: 0.9976, Adjusted R-squared: 0.997
## F-statistic: 1640 on 1 and 4 DF, p-value: 2.221e-06
| Parámetro | Valor | Interpretación |
|---|---|---|
| Pendiente b₁ | 3.2643 | Por cada grado más de temperatura, se venden ~3.26 helados adicionales |
| Intercepto b₀ | -34.0952 | Valor teórico de Y cuando X = 0 (fuera del rango de los datos) |
| Correlación r | 0.9988 | Relación lineal muy fuerte y positiva entre las variables |
| R² | 99.76% | El 99.76% de la variación en ventas es explicada por la temperatura |
# Valores ajustados y residuales
fitted_vals <- fitted(modelo)
# Gráfico base
plot(temperatura, ventas,
main = "Regresión Lineal: Temperatura vs Ventas de Helados",
xlab = "Temperatura (°C)",
ylab = "Ventas (unidades)",
pch = 16,
col = "steelblue",
cex = 1.5,
las = 1)
# Recta de regresión
abline(modelo, col = "firebrick", lwd = 2)
# Líneas de residuales
for (i in seq_along(temperatura)) {
lines(c(temperatura[i], temperatura[i]),
c(ventas[i], fitted_vals[i]),
col = "tomato", lty = 2, lwd = 1.2)
}
# Leyenda
legend("topleft",
legend = c("Datos reales", "Recta de regresión", "Residuales"),
col = c("steelblue", "firebrick", "tomato"),
pch = c(16, NA, NA),
lty = c(NA, 1, 2),
lwd = 2,
bty = "n")
# Ecuación en el gráfico
eq <- paste0("Ŷ = ", round(b0, 2), " + ", round(b1, 2), " · X R² = ",
round(r2 * 100, 2), "%")
mtext(eq, side = 3, line = 0.3, cex = 0.9, col = "firebrick")residuales <- data.frame(
i = 1:n,
X = temperatura,
Y_real = ventas,
Y_pred = round(fitted_vals, 2),
Residual = round(ventas - fitted_vals, 2),
Res_cuad = round((ventas - fitted_vals)^2, 4)
)
knitr::kable(residuales,
col.names = c("i", "X (°C)", "Y real", "Ŷ pred.", "Residual (e)", "e²"),
caption = "Valores ajustados y residuales",
align = "c")| i | X (°C) | Y real | Ŷ pred. | Residual (e) | e² |
|---|---|---|---|---|---|
| 1 | 20 | 30 | 31.19 | -1.19 | 1.4172 |
| 2 | 24 | 45 | 44.25 | 0.75 | 0.5661 |
| 3 | 28 | 58 | 57.30 | 0.70 | 0.4834 |
| 4 | 32 | 70 | 70.36 | -0.36 | 0.1310 |
| 5 | 36 | 85 | 83.42 | 1.58 | 2.4994 |
| 6 | 40 | 95 | 96.48 | -1.48 | 2.1791 |
##
## Suma de residuales al cuadrado (SCE): 7.2762
# Predecir ventas para nuevas temperaturas
nuevas_temp <- data.frame(temperatura = c(25, 30, 35, 45))
predicciones <- predict(modelo,
newdata = nuevas_temp,
interval = "confidence",
level = 0.95)
resultado <- cbind(nuevas_temp, round(predicciones, 2))
colnames(resultado) <- c("Temperatura (°C)", "Ŷ (predicción)", "IC Inf. 95%", "IC Sup. 95%")
knitr::kable(resultado,
caption = "Predicciones con intervalo de confianza al 95%",
align = "c")| Temperatura (°C) | Ŷ (predicción) | IC Inf. 95% | IC Sup. 95% |
|---|---|---|---|
| 25 | 47.51 | 45.62 | 49.41 |
| 30 | 63.83 | 62.30 | 65.36 |
| 35 | 80.15 | 78.26 | 82.05 |
| 45 | 112.80 | 109.11 | 116.49 |
Nota: Las predicciones son válidas solo dentro del rango de los datos originales (20°C – 40°C). Extrapolar más allá puede generar resultados poco confiables.
Elaborado con R Markdown · Método de Mínimos Cuadrados