A transformação de energia da Yeo-Johnson discutida aqui tem excelentes propriedades projetadas para lidar com zeros e negativos, enquanto constrói os pontos fortes da transformação de energia da Box Cox. É para isso que normalmente vou quando estou lidando com zeros ou dados negativos.
Aqui está um resumo das transformações com prós / contras para ilustrar por que a Yeo-Johnson é preferível.
Registro
Prós: funciona bem com dados positivos.
Contras: Não manipula zeros.
> log(0)
[1] -Inf
Log Plus 1
Prós: O deslocamento mais 1 adiciona a capacidade de lidar com zeros, além de dados positivos.
Contras: falha com dados negativos
> log1p(-1)
[1] -Inf
> log1p(-2)
[1] NaN
Warning message:
In log1p(-2) : NaNs produced
Raiz quadrada
Prós: usa uma transformação de energia que pode lidar com zeros e dados positivos.
Contras: falha com dados negativos
> sqrt(-1)
[1] NaN
Warning message:
In sqrt(-1) : NaNs produced
Box Cox
Código R:
box_cox <- function(x, lambda) {
eps <- 0.00001
if (abs(lambda) < eps)
log(x)
else
(x ^ lambda - 1) / lambda
}
Prós: permite transformações de energia em escala
Contras: sofre de problemas com zeros e negativos (ou seja, pode lidar apenas com dados positivos.
> box_cox(0, lambda = 0)
[1] -Inf
> box_cox(0, lambda = -0.5)
[1] -Inf
> box_cox(-1, lambda = 0.5)
[1] NaN
Yeo Johnson
Código R:
yeo_johnson <- function(x, lambda) {
eps <- .000001
not_neg <- which(x >= 0)
is_neg <- which(x < 0)
not_neg_trans <- function(x, lambda) {
if (abs(lambda) < eps) log(x + 1)
else ((x + 1) ^ lambda - 1) / lambda
}
neg_trans <- function(x, lambda) {
if (abs(lambda - 2) < eps) - log(-x + 1)
else - ((-x + 1) ^ (2 - lambda) - 1) / (2 - lambda)
}
x[not_neg] <- not_neg_trans(x[not_neg], lambda)
x[is_neg] <- neg_trans(x[is_neg], lambda)
return(x)
}
Prós: pode lidar com dados positivos, zero e negativos.
Contras: Nada que eu possa pensar. As propriedades são muito semelhantes ao Box-Cox, mas podem lidar com dados zero e negativos.
> yeo_johnson(0, lambda = 0)
[1] 0
> yeo_johnson(0, lambda = -0.5)
[1] 0
> yeo_johnson(-1, lambda = 0.5)
[1] -1.218951