Ik moet sommige gegevens omzetten in een ‘normale vorm’ en ik heb gelezen dat Box-Cox de exponent kan identificeren die moet worden gebruikt om de gegevens te transformeren.
Voor wat ik begreep
car::boxCoxVariable(y)
wordt gebruikt voor responsvariabelen in lineaire modellen, en
MASS::boxcox(object)
voor een formule of aangepast modelobject. Dus, omdat mijn gegevens de variabele van een dataframe zijn, is de enige functie die ik kon gebruiken:
car::powerTransform(dataframe$variable, family="bcPower")
Is dat juist? Of mis ik iets?
De tweede vraag gaat over wat ik moet doen nadat ik de
Estimated transformation parameters
dataframe$variable
0.6394806
Moet ik de variabelegewoon vermenigvuldigen met deze waarde?
Dat heb ik gedaan:
aaa = 0.6394806
dataframe$variable2 = (dataframe$variable)*aaa
en dan voer ik de shapiro-wilks-test uit voor normaliteit, maar nogmaals, mijn gegevens lijken geen normale verdeling te volgen:
shapiro.test(dataframe$variable2)
data: dataframe$variable2
W = 0.97508, p-value < 2.2e-16
Antwoord 1, autoriteit 100%
Box en Cox (1964) suggereerden een reeks transformaties die ontworpen waren om de niet-normaliteit van de foutenin een lineair model te verminderen. Het blijkt dat hierdoor vaak ook de niet-lineariteit wordt verminderd.
Hier is een mooie samenvatting van het originele werk en al het werk dat is gedaan sinds: http://www.ime.usp.br/~abe/lista/pdfm9cJKUmFZp.pdf
U zult echter merken dat de log-waarschijnlijkheidsfunctie die de selectie van de lambda-vermogenstransformatie bepaalt, afhankelijk is van de resterende kwadratensom van een onderliggend model (geen LaTeX op SO — zie de referentie), dus geen transformatie kan zonder model worden toegepast.
Een typische toepassing is als volgt:
library(MASS)
# generate some data
set.seed(1)
n <- 100
x <- runif(n, 1, 5)
y <- x^3 + rnorm(n)
# run a linear model
m <- lm(y ~ x)
# run the box-cox transformation
bc <- boxcox(y ~ x)
(lambda <- bc$x[which.max(bc$y)])
[1] 0.4242424
powerTransform <- function(y, lambda1, lambda2 = NULL, method = "boxcox") {
boxcoxTrans <- function(x, lam1, lam2 = NULL) {
# if we set lambda2 to zero, it becomes the one parameter transformation
lam2 <- ifelse(is.null(lam2), 0, lam2)
if (lam1 == 0L) {
log(y + lam2)
} else {
(((y + lam2)^lam1) - 1) / lam1
}
}
switch(method
, boxcox = boxcoxTrans(y, lambda1, lambda2)
, tukey = y^lambda1
)
}
# re-run with transformation
mnew <- lm(powerTransform(y, lambda) ~ x)
# QQ-plot
op <- par(pty = "s", mfrow = c(1, 2))
qqnorm(m$residuals); qqline(m$residuals)
qqnorm(mnew$residuals); qqline(mnew$residuals)
par(op)
Zoals u kunt zien Dit is geen magische kogel – alleen sommige gegevens kunnen effectief worden getransformeerd (meestal een lambda minder dan -2 of groter dan 2 is een teken dat u niet de methode mag gebruiken). Zoals met een statistische methode, gebruik met de nodige voorzichtigheid voordat u uitvoert.
Gebruik de transformatie van de twee parameter-cox-Cox, gebruik de geoR
PAKKET om de lambdas te vinden:
library("geoR")
bc2 <- boxcoxfit(x, y, lambda2 = TRUE)
lambda1 <- bc2$lambda[1]
lambda2 <- bc2$lambda[2]
Bewerkingen: Conflatie van Tukey en Box-COX-implementatie zoals aangegeven door @ Yui-Shiuan Fixed.
Antwoord 2, Autoriteit 50%
Volgens de Box-Cox-transformatieformule in het papier Box, George E. P.; Cox, D.R. (1964). “Een analyse van transformaties” , ik denk dat MÜLEGGE’s post enigszins moet worden bewerkt. De getransformeerde Y zou moeten zijn (y ^ (lambda) -1) / lambda in plaats van y ^ (lambda). (eigenlijk, Y ^ (Lambda) wordt Tukey-transformatie genoemd, wat een andere duidelijke transformatieformule is.)
Dus de code moet zijn:
(trans <- bc$x[which.max(bc$y)])
[1] 0.4242424
# re-run with transformation
mnew <- lm(((y^trans-1)/trans) ~ x) # Instead of mnew <- lm(y^trans ~ x)
Meer informatie
-
Correcte implementatie van Box-Cox Transformation Formule van Boxcox () in R:
https://www.r-bloggers.com/ On-Box-Cox-transform-in-regressiemodellen / -
Een geweldige vergelijking tussen Box-Cox-transformatie en Tukey-transformatie. http://onlinestatbook.com/2/transformations/box-cox.html
-
Je zou de Box-Cox-transformatieformule ook op Wikipedia kunnen vinden:
nl.wikipedia.org/wiki/Power_transform#Box.E2.80.93Cox_transformation
Corrigeer me als ik het verkeerd heb begrepen.
Antwoord 3, autoriteit 10%
Als ik alleen de responsvariabele y wil overbrengen in plaats van een lineair model met x gespecificeerd, bijvoorbeeld als ik een lijst met gegevens wil overdragen/normaliseren, kan ik 1 nemen voor x, dan wordt het object een lineair model:
library(MASS)
y = rf(500,30,30)
hist(y,breaks = 12)
result = boxcox(y~1, lambda = seq(-5,5,0.5))
mylambda = result$x[which.max(result$y)]
mylambda
y2 = (y^mylambda-1)/mylambda
hist(y2)
Antwoord 4, autoriteit 2%
Het toepassen van de BoxCox-transformatie op gegevens, zonder dat er een onderliggend model nodig is, kan momenteel worden gedaan met behulp van het pakket geoR. In het bijzonder kunt u de functie boxcoxfit() gebruiken om de beste parameter te vinden en vervolgens de getransformeerde variabelen voorspellen met de functie BCtransform().