Transformación Yeo-Johnson

Prep

Transformación Yeo-Johnson

Creado: Última actualización: Tiempo de lectura: 2 min

La transformación Yeo-Johnson es una transformación de potencia tipo Box-Cox que ayuda a reducir la asimetría y estabilizar la varianza de un rasgo numérico, aun cuando el conjunto de datos contiene ceros o valores negativos.

Definición #

Para una observación (y) y un parámetro de potencia (\lambda), la transformación Yeo-Johnson (T_\lambda(y)) se define por tramos:

$$ T_\lambda(y)= \begin{cases} \dfrac{(y + 1)^\lambda - 1}{\lambda}, & y \ge 0,\ \lambda \ne 0,\\ \log(y + 1), & y \ge 0,\ \lambda = 0,\\ -\dfrac{(1 - y)^{2 - \lambda} - 1}{2 - \lambda}, & y < 0,\ \lambda \ne 2,\\ -\log(1 - y), & y < 0,\ \lambda = 2. \end{cases} $$

  • Con (\lambda = 1) se recupera el valor original.
  • Para (y \ge 0) el comportamiento coincide con una transformación Box-Cox sobre (y + 1).
  • Los valores negativos se reflejan alrededor de cero, por lo que la transformación sigue siendo monótona incluso cuando cambia el signo.
  • La trasformación inversa se obtiene resolviendo cada caso para (y); SciPy la ofrece en scipy.stats.yeojohnson_inverse.

Normalmente (\lambda) se estima maximizando la verosimilitud bajo el supuesto de normalidad después de transformar los datos. SciPy implementa este estimador mediante yeojohnson_normmax.

I. Yeo y R. A. Johnson, “A New Family of Power Transformations to Improve Normality or Symmetry”, Biometrika 87(4), 2000.

Ejemplo práctico #

from scipy import stats
import matplotlib.pyplot as plt

x = stats.loggamma.rvs(1, size=1_000) - 0.5
plt.hist(x, bins=30)
plt.axvline(x=0, color="r")
plt.title("Distribución original (con valores negativos)")
plt.show()

Ejemplo práctico (figura)

from scipy.stats import yeojohnson, yeojohnson_normmax

lmbda = yeojohnson_normmax(x)  # estimación de máxima verosimilitud
print(f"λ estimado: {lmbda:.3f}")

x_trans = yeojohnson(x, lmbda=lmbda)
plt.hist(x_trans, bins=30)
plt.title("Después de Yeo-Johnson")
plt.show()

Ejemplo práctico (figura)

Tras la transformación la distribución es mucho más simétrica. Debido a que fijamos (\lambda), podemos reutilizar el mismo valor en otros subconjuntos del conjunto de datos:

X_train_trans = yeojohnson(X_train, lmbda=lmbda)
X_valid_trans = yeojohnson(X_valid, lmbda=lmbda)  # reutilizar λ

Consejos prácticos #

  • Si el modelo espera variables centradas y escaladas, normaliza después de aplicar Yeo-Johnson (StandardScaler, por ejemplo).
  • Calcula (\lambda) únicamente con el conjunto de entrenamiento y reutilízalo en validación o prueba para evitar fugas de información.
  • Cuando aún existan colas pesadas, combina la transformación con escalados robustos (RobustScaler) para mitigar el impacto de los outliers.

La transformación Yeo-Johnson es un sustituto directo de Box-Cox en pipelines de preprocesamiento que no pueden asumir datos estrictamente positivos.