Apéndice II: Transformaciones
En ocasiones es conveniente transformar los datos para el análisis, el objetivo de transformar es simplificar la interpretación y el análisis al eliminar fuentes de variación conocidas, cuando simplificamos los patrones en los datos suele ser más fácil modelar y predecir.
Algunos ejemplos donde eliminamos efectos conocidos:
Cuando analizamos el precio de venta de las casas podemos eliminar la variación debida al tamaño de las casas al pasar de precio de venta a precio de venta por metro cuadrado. De manera similar al analizar las propinas puede convenir considerar la propina como porcentaje de la cuenta.
En series de tiempo cuando los datos están relacionados con el tamaño de la población podemos ajustar a mediciones per capita (por ejemplo en series de tiempo PIB). También es común ajustar por inflación, o poner cantidades monetarias en valor presente.
<- global_economy |>
dat filter(Code == "MEX" | Code == "ARG" | Code == "BRA")
<- ggplot(dat, aes(x = Year, y = GDP / 1e6, color = Code)) +
pib geom_line() +
labs(color = "")
<- ggplot(dat, aes(x = Year, y = GDP / Population, color = Code)) +
pib_pc geom_line() +
labs(color = "")
/ pib_pc pib
Adicionalmente podemos recurrir a otras transformaciones matemáticas (e.g. logaritmo o raíz cuadrada) que simplifiquen el patrón en los datos y la interpretación.
Comenzamos con una serie de tiempo del número de pasajeros de avión entre 1949 y 1960. Cuando los datos muestran variación que se incrementa con el valor de los datos, como en este ejemplo, suele ser apropiado hacer una transformación para simplificar el patrón, Una familia de transformaciones es la de transformaciones Box-Cox que incluye logaritmo y potencias.
En este ejemplo notemos que al aplicar el logaritmo la variación estacional a lo largo de toda la serie es de tamaño similar, resultando en un patrón más sencillo de describir:
<- read_csv("data/AirPassengers.csv") |>
dat mutate(year_month = ym(Month))
<- ggplot(dat, aes(x = year_month, y = `#Passengers`)) +
p1 geom_path()
<- ggplot(dat, aes(x = year_month, y = log(`#Passengers`))) +
p2 geom_path()
/ p2 p1
Ahora veamos los datos Animals con información de peso corporal promedio y peso cerebral promedio para 28 especies. Buscamos entender la relación entre estas dos variables, e inspeccionar que especies se desvían (residuales) del esperado. Comenzamos con un diagrama de dispersión usando las unidades originales
<- as_tibble(Animals, rownames = "animal")
animals_tbl
<- ggplot(animals_tbl, aes(x = body, y = brain, label = animal)) +
p1 geom_point() +
labs(subtitle = "Unidades originales")
<- ggplot(animals_tbl, aes(x = body, y = brain, label = animal)) +
p2 geom_point() + xlim(0, 500) + ylim(0, 1500) +
geom_text_repel() +
labs(subtitle = "Unidades originales, eliminando 'grandes'")
+ p2) (p1
Incluso cuando nos limitamos a especies de menos de 500 kg de masa corporal, la relación no es fácil de descrubir.En la suguiente gráfica hacemos la transformación logaritmo y obtenemos una gráfica más fácil de leer, además los datos se modelarán con más facilidad.
<- ggplot(animals_tbl, aes(x = log(body), y = log(brain), label = animal)) +
p3 geom_smooth(method = "lm", se = FALSE, color = "red") +
geom_point() +
geom_text_repel() +
stat_poly_eq(use_label(c("eq")))
p3
## `geom_smooth()` using formula = 'y ~ x'
La transformación logaritmo tiene además ventajas en interpretación, para diferencias chicas en escala log, las diferencias corresponden a diferencias porcentuales en la escala original, por ejempo consideremos la diferencia entre el peso en escala log de humano y borrego: 4.13 - 4.02 = 0.11. Confirmamos que el humano es aproximadamente 11% más pesado que el borrego en la escala original: 62/55.5 - 1 = 0.12
Esta interpretación es además mas narural para algunos conjuntos de datos donde es más natural considerar efectos multiplicativos. Notemos que en los pesos cerebrales 1 y 1.9 (hamster y rata), la cantidad importante es que la rata tiene un cerebro con un peso casi del doble que el hamster, las dos especies varían mucho más que un mono y un cerdo cuyos pesos cerebrales difieren en aproximadamente la misma cantidad (179 y 180) pero donde el cerebro del cerdo es menos de 1% mas pesado. En escala log, diferencias iguales equivalen a factores multiplicativos iguales.
<- animals_tbl |>
animals_tbl mutate(log_body = log(body),
log_brain = log(brain))
|>
animals_tbl filter(animal == "Human" | animal == "Sheep") |>
arrange(body) |>
::gt() |>
gt::fmt_number() gt
animal | body | brain | log_body | log_brain |
---|---|---|---|---|
Sheep | 55.50 | 175.00 | 4.02 | 5.16 |
Human | 62.00 | 1,320.00 | 4.13 | 7.19 |
Y podemos usarlo también para interpretar la recta de referencia \(y = 2.55 + 0.5 x\), para cambios chicos: Un incremento de 10% en masa total corresponde en un incremento de 5% en masa cerebral.
El coeficiente de la regresión log-log, en nuestro ejemplo 0.5, es la elasticidad y es un concepto común en economía.
Justificación
Para entender la interpretación como cambio porcentual recordemos primero que la representación con series de Taylor de la función exponencial es:
\[e^x = \sum_{n=0}^\infty \frac{x^n}{n!}\]
Más aún podemos tener una aproximación usando polinomios de Taylor, en el caso de la exponencial el \(k\)-ésimo polinomio de Taylor está dado por:
\[e^\delta \approx 1 + \delta + \frac{1}{2!}\delta^2 + \dots + \frac{1}{k!}\delta^k\]
y si \(\delta\) es chica (digamos menor a 0.15), entonces la aproximación de primer grado es razonable y tenemos:
\[Ae^{\delta} \approx A(1+\delta)\]
<- tibble(delta = seq(0, 1, 0.01), exp_delta = exp(delta), uno_mas_delta = 1 + delta)
dat
ggplot(dat, aes(x = uno_mas_delta, y = exp_delta)) +
geom_line() +
geom_abline(color = "red") +
annotate("text", x = 1.50, y = 1.18, label = "y = x", color = "red", size = 6)