De la regresión a la predicción, y cómo evaluarla
Dpto. de Fundamentos del Análisis Económico. Universidad de Alicante
En los temas anteriores hemos descrito los datos. Ahora vamos a modelizar
Modelizar es aproximar con métodos estadísticos la relación sistemática entre variables
Una cadena ha encuestado a 404 clientes elegidos al azar. Cada fila de tienda.csv es un cliente:
ventas) y renta mensual (renta)edad, mujer (1 si es mujer) y años de estudios (educ)zona (pueblo, ciudad o capital) y descuento (1 si lo recibió)El año pasado la cadena dio un descuento a algunos clientes, elegidos a mano
Dirección plantea cuatro preguntas: (1) de qué depende el gasto, (2) con qué precisión lo sabemos, (3) cuánto gastará un cliente nuevo y (4) a quién dar el descuento
Como en el Tema 04, los datos se preparan antes de analizarlos: zona es cualitativa, así que se guarda como factor con sus categorías ordenadas
Importante
El ejercicio del tema se hace durante estas clases: Tema 05 - Ejercicios del tema. Sus tres entregas corresponden a las cuatro PRÁCTICAS.
La precisión de la media la mide su distribución muestral: cómo varía \(\bar Y\) de una muestra a otra
Con una sola muestra no se observa, y se deriva de supuestos:
En los dos casos:
Las dos vías dependen de un supuesto: normalidad o muestra grande
El bootstrap aproxima la distribución muestral sin ellos. Sirve cuando se duda del supuesto o cuando no hay una expresión analítica
Si pudiéramos repetir la encuesta infinitas veces, veríamos directamente cómo varía la media. No podemos, pero tenemos lo más parecido a la población: la propia muestra
El bootstrap usa la muestra como si fuera la población y saca de ella muchas remuestras:
Con una muestra de cinco clientes:
| Remuestra | Gasto de los cinco clientes | Media |
|---|---|---|
| 1 | 7000, 1000, 7000, 1000, 4000 | 4.000 |
| 2 | 7000, 1000, 2000, 3000, 1000 | 2.800 |
| 3 | 3000, 2000, 3000, 1000, 1000 | 2.000 |
fornumeric(1000): mil huecos donde guardar, creados antes del buclefor (b in 1:1000) { ... }: repite lo de las llaves con b = 1, 2, …, 1000medias[b] <- ...: guarda la media b en el hueco bVuelta a vuelta: con b = 1, una remuestra y su media, 4.000, va a medias[1]; con b = 2, otra, y 2.800 va a medias[2]; y así hasta mil
De las mil medias sale lo que buscábamos:
sd(medias), 948 eurosquantile(medias, c(0.025, 0.975)), de 1.800 a 5.400 eurosCon tienda$ventas y vuestro DNI como semilla:
Con la fórmula: el error estándar de la media y su intervalo al 95%. Dirección quiere un error estándar de 20 euros: ¿a cuántos clientes hay que encuestar?
Con el bootstrap: el error estándar y el intervalo de la media. Comparadlos con los del punto 1. ¿Por qué salen casi iguales?
La mediana no tiene una fórmula sencilla: su error estándar e intervalo al 95% por bootstrap. ¿Es más o menos precisa que la media?
¿Gastan más las mujeres? La diferencia de gasto medio entre mujeres y hombres, con su error estándar e intervalo por bootstrap, remuestreando cada grupo por separado. ¿Puede ser cero?
Repetid el bootstrap de la mediana quitando replace = TRUE. ¿Qué sale y por qué?
Nota
Ahora el ejercicio: entrega 1, apartados a) y b). Son estos puntos.
Con tienda y vuestro DNI como semilla:
Estimad modelo_z <- lm(ventas ~ renta + descuento + zona, data = tienda). Con summary(), leed en euros los coeficientes de renta y descuento, y el \(R^2\)
Predecid el gasto de un cliente de pueblo con renta 1.500 y sin descuento, y el de uno de capital con renta 3.000 y con descuento
predict(modelo_z, newdata = nuevos) predice para nuevos, una tabla con las mismas columnas que usa el modeloAdaptad el bucle del bootstrap al coeficiente de renta:
filas <- sample(nrow(tienda), replace = TRUE)tienda[filas, ] y guardad coef(m_b)["renta"]summary() y confint(modelo_z)En el mismo bucle, guardad la varianza del error, var(residuals(m_b)). ¿Cuál es su error estándar y su intervalo al 95%? ¿Cuánto se desvía un cliente típico de lo que predice el modelo?
Nota
Ahora el ejercicio: entrega 1, apartados c) a e). Son estos puntos.
ggplot(tienda, aes(edad, ventas)) + geom_point() +
geom_smooth(method = "lm", se = FALSE) + geom_smooth(se = FALSE)
tienda |> group_by(educ) |> summarize(ventas = mean(ventas)) |>
ggplot(aes(educ, ventas)) + geom_point() + geom_step()
ggplot(tienda, aes(renta, ventas, colour = factor(mujer))) +
geom_point(shape = 1) + geom_smooth(method = "lm", se = FALSE)El modelo lineal supone que el efecto de cada \(X\) es el mismo número siempre: \(\partial\, \text{ventas} / \partial X_j = \beta_j\). Los datos dicen otra cosa:
El gasto sube y luego baja con la edad: la recta gris dice que no cambia
Con los estudios, el gasto va a saltos que suben y bajan
La pendiente de la renta es distinta para mujeres y hombres
En economía esto es la norma: rendimientos decrecientes, umbrales, efectos distintos por grupo
El modelo lineal lo captura transformando las variables
Un euro más de renta importa menos cuanto más renta se tiene: rendimientos decrecientes
En logaritmos, lo constante es el efecto de un 1% más de renta
Tres lecturas, según dónde esté el logaritmo:
\(y \sim \log(x)\): \(\beta/100\) es el cambio de \(y\) por un 1% más de \(x\). Aquí \(\hat\beta\) = 1.150: 11,5 euros más de gasto por un 1% más de renta
\(\log(y) \sim \log(x)\): \(\beta\) es la elasticidad: un 1% más de renta, un \(\beta\)% más de gasto. Aquí 0,28
\(\log(y) \sim x\): \(100\beta\) es el cambio porcentual de \(y\) por una unidad más de \(x\)
Frente a la recta, donde 100 euros de renta son siempre 49 de gasto, en logaritmos:
log() va dentro de la fórmula. Solo con valores positivos: log(0) es -Inf y esas filas desaparecen del modelo
\[ \small \text{ventas} = \beta_0 + \beta_1\,\text{edad} + \beta_2\,\text{edad}^2 + u \]
I() avisa a la fórmula de que edad^2 es una operación aritmética
poly(edad, g) añade de una vez los grados 1 a g: predice lo mismo, con los coeficientes en otra escala
El efecto de un año más ya depende de la edad: \(\partial\, \text{ventas} / \partial\, \text{edad} = \beta_1 + 2\beta_2\, \text{edad}\)
Con \(\hat\beta_1\) = 313 y \(\hat\beta_2\) = -3,40:
cut() crea el factor y el modelo lo trata como a zona| (Intercept) | (30,40] | (40,50] | (50,60] | (60,70] |
|---|---|---|---|---|
| 3057 | 1276 | 1515 | 1199 | 249 |
(40,50] son los clientes de más de 40 y hasta 50 años. Cada coeficiente compara su tramo con el de 20 a 30, la referencia:
Añadir mujer desplaza la recta: distinta altura para mujeres y hombres, con la misma pendiente
Una interacción, el producto de las dos variables, da a cada grupo su pendiente:
\(\small \text{ventas} = \beta_0 + \beta_1\,\text{renta} + \beta_2\,\text{mujer} + \beta_3\,\text{renta} \cdot \text{mujer} + u\)
(Intercept) renta mujer renta:mujer
2961 0.079 285 0.594
Partiendo de ventas ~ renta + descuento + zona, anotad el \(R^2\) de cada modelo con seis decimales, summary(m)$r.squared:
Polinomios: añadid edad, y después, de uno en uno, I(edad^2), I(edad^3) e I(edad^4)
Tramos de edad, en lugar del polinomio: de 20 en 20 años (cut(edad, c(20, 40, 60, 70), include.lowest = TRUE)), de 10 en 10 (seq(20, 70, by = 10)) y de 5 en 5
Interacciones: partiendo de la parábola, añadid educ, y después, de una en una, renta * mujer, educ * mujer y edad * mujer
Nota
Ahora el ejercicio: entrega 2, apartados a) a c). Son estos tres puntos.
| Variables | renta |
+ descuento |
+ zona |
+ mujer |
+ edad |
+ educ |
+ z1 + z2 + z3 |
|---|---|---|---|---|---|---|---|
| \(R^2\) | 0,14995 | 0,15803 | 0,17366 | 0,61601 | 0,61715 | 0,62855 | 0,62921 |
z1, z2 y z3 son números aleatorios y también suben el \(R^2\)
descuento pasa de 110,1 a 110,6, y el de renta de 0,0389 a 0,0391set.seed(1)
tienda <- tienda |>
mutate(z1 = rnorm(404), z2 = rnorm(404), z3 = rnorm(404))
m1 <- lm(ventas ~ renta, data = tienda)
m6 <- lm(ventas ~ renta + descuento + zona + mujer + edad + educ,
data = tienda)
m9 <- lm(ventas ~ renta + descuento + zona + mujer + edad + educ +
z1 + z2 + z3, data = tienda)
summary(m1)$r.squared
summary(m6)$r.squared
summary(m9)$r.squared
summary(m6)$coefficients[, "Std. Error"]
summary(m9)$coefficients[, "Std. Error"]Dejar fuera una variable relevante cambia los coeficientes de las que quedan
El descuento, con y sin la renta en el modelo:
| Modelo | Coef. de descuento |
Error estándar |
|---|---|---|
ventas ~ descuento |
-97 | 170 |
ventas ~ descuento + log(renta) |
+409 | 167 |
| modelo completo | +500 | 48 |
A solas, el descuento parece no servir
El sesgo por omisión sigue la regla del signo: (efecto de la omitida sobre \(Y\)) × (su correlación con la \(X\) que queda). Aquí, positivo × negativo: hacia abajo
Elegir modelo tiene dos riesgos: incluir demasiado, que ajusta el ruido, y omitir lo relevante, que mezcla efectos
lm(ventas ~ descuento, data = tienda)
lm(ventas ~ descuento + log(renta), data = tienda)
tramos <- c(0, 10, 12, 14, 16, 20)
lm(ventas ~ log(renta) * mujer + edad + I(edad^2) +
cut(educ, tramos, include.lowest = TRUE) +
descuento + zona, data = tienda)
tienda |> group_by(descuento) |> summarize(renta = mean(renta))La pregunta 3 de la tienda es cuánto gastará un cliente nuevo, así que el modelo se juzga por cómo predice esos casos
Una función de pérdida \(L(y, \hat{y})\) asigna un coste a cada error de predicción, y el modelo se evalúa por la pérdida media:
MSE (error cuadrático medio): \((1/n)\sum (y_i - \hat{y}_i)^2\). Penaliza más los errores grandes
RMSE: \(\sqrt{\text{MSE}}\), en las unidades de \(y\)
MAE (error absoluto medio): \((1/n)\sum |y_i - \hat{y}_i|\). Cada euro de error pesa lo mismo
Son pérdidas simétricas: pasarse y quedarse corto cuestan lo mismo
En una pérdida asimétrica, un lado cuesta más: quedarse sin existencias frente a tener de sobra
\(R^2 = 1 - \text{SCR}/\text{SCT}\) es el MSE relativo a la varianza de \(y\): compara modelos de la misma \(y\) en los mismos datos
Estos datos los hemos simulado, y por eso conocemos la relación verdadera: la curva negra discontinua es \(f(\text{edad})\)
Cada punto es \(f(\text{edad})\) más un error \(u\) propio de cada muestra. Su media es cero: unas veces cae por encima de la curva y otras por debajo
Ajustamos tres modelos a dos muestras:
El cliente marcado queda por encima de la curva en A y por debajo en B, y el grado 12 se va tras él
f <- function(edad) 3900 - 2.5 * (edad - 45)^2
edad <- seq(20, 70, length.out = 30)
set.seed(57)
A <- tibble(edad, ventas = f(edad) + rnorm(30, sd = 350))
B <- tibble(edad, ventas = f(edad) + rnorm(30, sd = 350))
A$ventas[13] <- f(edad[13]) + 900
B$ventas[13] <- f(edad[13]) - 900
ggplot(A, aes(edad, ventas)) + geom_point(colour = "grey55", size = 2) +
geom_function(fun = f) +
geom_smooth(method = "lm", se = FALSE) +
geom_smooth(method = "lm", formula = y ~ poly(x, 2), se = FALSE) +
geom_smooth(method = "lm", formula = y ~ poly(x, 12), se = FALSE)rnorm(30, sd = 350) es el error: 30 números aleatorios de media cero.
La curva de grado 12 estimada en A es la que más se acerca al cliente marcado
En una muestra nueva, la B, ese cliente cae lejos: el error es mayor que el de la recta y la parábola
Con todos los clientes pasa lo mismo: el grado 12 tiene el menor MSE en A, y en B es peor que la parábola
| Curva estimada con A | Error, cliente marcado en A | Error, cliente marcado en B | MSE en A (miles) | MSE en B (miles) |
|---|---|---|---|---|
| recta | 1.342 | 458 | 435 | 333 |
| parábola | 886 | 914 | 237 | 157 |
| grado 12 | 347 | 1.453 | 81 | 391 |
La tienda solo tiene una muestra, así que los clientes nuevos hay que conseguirlos de ella: se divide al azar en dos partes y una se aparta
Con tienda, el error de entrenamiento baja siempre al subir el grado, y el de prueba cae hasta el grado 2 y luego apenas cambia. Elegiríamos un grado bajo
El error de prueba estima cómo predecirá el modelo clientes nuevos, a costa de estimar con menos datos
Pregunta 4 de la tienda: ¿a quién dar el descuento? descuento es una variable 0/1, así que es un problema de clasificación
Con una variable 0/1, la media condicional es una probabilidad:
\[ \small E[\text{descuento} \mid \text{renta}] = \Pr(\text{descuento} = 1 \mid \text{renta}) \]
Se puede ajustar una recta: lm(descuento ~ renta)
Pendiente -0,00010: cada 1.000 euros de renta, 10 puntos menos de probabilidad
Problema: la recta sale de \([0, 1]\). Para 35 clientes predice una probabilidad negativa
La función logística lleva cualquier índice \(z = \beta_0 + \beta_1 x_1 + \ldots\) al intervalo \([0, 1]\): \(\Lambda(z) = e^z/(1 + e^z)\)
El modelo: \(\Pr(\text{descuento} = 1 \mid X) = \Lambda(\beta_0 + \beta_1\,\text{renta} + \ldots)\)
glm(), como lm() más el argumento family:type = "response" da probabilidades. Con newdata, las de clientes nuevosLos coeficientes ya no son cambios en la probabilidad: el efecto de un euro de renta depende de dónde esté la curva
Sí se interpretan el signo y la significatividad: renta -0,0015 (z = -5,8); edad, nada
La regresión logística se generaliza a una variable con \(C\) categorías, como el producto elegido o el tipo de contrato: es el logit multinomial
Hay un índice lineal por clase, y cada probabilidad es:
\[ \Pr(Y = c \mid X) = \genfrac{}{}{1.2pt}{0}{e^{z_c}}{\sum_{l = 1}^{C} e^{z_l}}, \qquad z_c = \beta_{0c} + \beta_{1c} x_1 + \ldots \]
Un modelo de clasificación predice la probabilidad de que una observación pertenezca a cada categoría
La clase predicha es la de mayor probabilidad. Con dos clases, eso es superar un umbral de 0,5, y se pueden probar otros valores:
Las clases son categorías: no tiene sentido restarlas, así que no se puede calcular el MSE ni medidas similares
Se comparan con la matriz de confusión, que tabula las clases observadas frente a las predichas:
| Observado 1 | Observado 0 | |
|---|---|---|
| Predicho 1 | verdadero positivo (VP) | falso positivo (FP) |
| Predicho 0 | falso negativo (FN) | verdadero negativo (VN) |
La medida natural es la exactitud, la tasa de observaciones bien clasificadas, \(\color{blue}{(VP + VN)/(VP + FP + VN + FN)}\)
Pero no informa con clases infrecuentes (datos desequilibrados): con un 1% de fraude, predecir que nunca hay fraude da una exactitud del 99% y no detecta ninguno
Por eso se mira cada clase por separado, como en una prueba diagnóstica:
| Medida | En una prueba diagnóstica | Fórmula |
|---|---|---|
| Sensibilidad | de los enfermos, cuántos detecta | \(\color{blue}{VP/(VP + FN)}\) |
| Especificidad | de los sanos, cuántos descarta | \(\color{blue}{VN/(VN + FP)}\) |
| Tasa de falsos positivos | de los sanos, a cuántos da por enfermos | \(\color{blue}{1 - \text{especificidad}}\) |
Las dos tiran en sentido contrario: bajar el umbral detecta más positivos, y también da por positivos a más negativos
Más métricas en el anexo
La tienda quiere una regla para dar el descuento a clientes nuevos. Con descuento como variable a explicar y renta, edad y zona como regresores:
Estimad el logit y obtened la probabilidad predicha de cada cliente. ¿Entre qué valores está? ¿Cuántos pasan de 0,5?
Con umbral 0,5, construid la matriz de confusión. Calculad exactitud, sensibilidad y especificidad
Repetid con umbral 0,25 y con 0,10. Una tabla de tres filas: umbral, exactitud, sensibilidad, especificidad, clientes contactados
La tienda dice que no dar el descuento a quien lo habría recibido cuesta diez veces más que dárselo a quien no lo necesitaba. Calculad el coste de cada umbral: \(10 \cdot FN + FP\). ¿Cuál elegís?
Nota
Ahora el ejercicio: entrega 3, apartados a) a d). Son estos cuatro puntos.
Cada umbral da un punto: la tasa de falsos positivos en horizontal y la sensibilidad en vertical. La curva ROC une los puntos de todos los umbrales
Sus extremos:
Bajar el umbral nos mueve hacia arriba y a la derecha: más verdaderos positivos y más falsos positivos
Un clasificador perfecto llega a la esquina (0, 1), y uno al azar sigue la diagonal: cuanto más cerca de la esquina, mejor
El AUC es el área bajo la curva ROC: resume todos los umbrales en un número. En la tienda, 0,78
Va de 0,5 (clasificador aleatorio) a 1 (clasificador perfecto):
Si dos curvas se cruzan, ninguna gana con todos los umbrales, y el área las compara con un solo número
El AUC compara modelos sin fijar umbral; el umbral lo fija el coste de cada error, como en la práctica. Más en el anexo
Con una sola partición, el error de prueba depende de qué observaciones cayeron en prueba
La validación cruzada de K bloques usa todas las observaciones para estimar y para evaluar, aunque nunca a la vez:
Se aplica a regresión (con el MSE) y a clasificación (con la exactitud o el AUC)
Con K = 5: cada fila es una iteración, y el bloque naranja es el apartado
Variantes en el anexo
Dirección hace dos preguntas que suenan igual y no lo son:
“¿Cuánto gastará un cliente con descuento?” → predecir. Vale cualquier modelo que acierte en prueba; el coeficiente del descuento solo tiene que ayudar a acertar
“¿Cuánto más gastaría un cliente si le diéramos el descuento?” → un efecto. Hay que comparar al mismo cliente con y sin descuento, y eso no está en los datos
A solas, el descuento resta 97 euros; con la renta, suma 320; con el modelo completo, 500
Con la renta dentro, el +320 compara clientes con la misma renta observada
Regla del curso: “esta variable es importante” significa “el modelo la usa para predecir”, y nada más
Selección, contrafactual y experimentos en el anexo