Die hier diskutierte Yeo-Johnson-Leistungstransformation weist hervorragende Eigenschaften auf, um Nullen und Negative zu verarbeiten und gleichzeitig auf den Stärken der Box-Cox-Leistungstransformation aufzubauen. Dies ist, was ich normalerweise gehe, wenn ich mit Nullen oder negativen Daten zu tun habe.
Hier ist eine Zusammenfassung der Transformationen mit Vor- und Nachteilen, um zu veranschaulichen, warum Yeo-Johnson vorzuziehen ist.
Log
Vorteile: Geht gut mit positiven Daten um.
Nachteile: Behandelt keine Nullen.
> log(0)
[1] -Inf
Log Plus 1
Vorteile: Mit dem Plus-1-Offset können zusätzlich zu positiven Daten auch Nullen verarbeitet werden.
Nachteile: Fehler bei negativen Daten
> log1p(-1)
[1] -Inf
> log1p(-2)
[1] NaN
Warning message:
In log1p(-2) : NaNs produced
Quadratwurzel
Vorteile: Verwendet eine Leistungstransformation, die mit Nullen und positiven Daten umgehen kann.
Nachteile: Fehler bei negativen Daten
> sqrt(-1)
[1] NaN
Warning message:
In sqrt(-1) : NaNs produced
Box Cox
R-Code:
box_cox <- function(x, lambda) {
eps <- 0.00001
if (abs(lambda) < eps)
log(x)
else
(x ^ lambda - 1) / lambda
}
Vorteile: Ermöglicht skalierte Leistungstransformationen
Nachteile: Leiden unter Problemen mit Nullen und Negativen (dh können nur positive Daten verarbeiten.
> 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
R-Code:
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)
}
Vorteile: Kann mit positiven, Null- und negativen Daten umgehen.
Nachteile: Keine, an die ich denken kann. Die Eigenschaften sind denen von Box-Cox sehr ähnlich, können jedoch mit Nulldaten und negativen Daten umgehen.
> yeo_johnson(0, lambda = 0)
[1] 0
> yeo_johnson(0, lambda = -0.5)
[1] 0
> yeo_johnson(-1, lambda = 0.5)
[1] -1.218951