## MAIN EXAMPLE
# Box-Cox Transformation Function
bxcx <- function( xy, rho){
if (rho == 0L) {
log(xy)
} else if(rho == 1L){
xy
} else {
(xy^rho - 1)/rho
}
}
bxcx_inv <- function( xy, rho){
if (rho == 0L) {
exp(xy)
} else if(rho == 1L){
xy
} else {
(xy * rho + 1)^(1/rho)
}
}
# Which Variables
reg <- lm(wage ~ school + exper, data=xy_hat)
X <- xy_hat[, c('school', 'exper')]
y_hat <- xy_hat[, 'wage']
# Simple Grid Search over potential (Rho, Lambda)
rl_df <- expand.grid(rho=seq(-2, 2, by=.5), lambda=seq(-2, 2, by=.5))
# Compute Mean Squared Error
# from OLS on Transformed Data
errors <- apply(rl_df, 1, function(rl){
Xr <- bxcx(X, rl[[1]])
y_trans_hat <- bxcx(y_hat, rl[[2]])
xy_trans_hat <- cbind(wage=y_trans_hat, Xr)
Regr <- lm(wage ~ school + exper, data=xy_trans_hat)
y_fit <- bxcx_inv(predict(Regr), rl[[2]])
e_hat <- (y_hat - y_fit)
return(e_hat)
})
rl_df$mse <- colMeans(errors^2)
# Want Small MSE and Interpretable
layout(matrix(1:2, ncol=2), width=c(3, 1), height=c(1, 1))
par(mar=c(4, 4, 2, 0))
plot(lambda ~ rho, rl_df, cex=8, pch=15,
xlab=expression(rho),
ylab=expression(lambda),
col=hcl.colors(25)[cut(1/rl_df$mse, 25)])
# Which min
rl0 <- rl_df[which.min(rl_df$mse), c('rho', 'lambda')]
points(rl0$rho, rl0$lambda, pch=0, col=rgb(0, 0, 0, .8), cex=8, lwd=2)
# Legend
plot(c(0, 2), c(0, 1), type='n', axes=FALSE,
xlab='', ylab='', cex.main=.8,
main=expression(frac(1, 'Mean Square Error')))
rasterImage(as.raster(matrix(hcl.colors(25), ncol=1)), 0, 0, 1, 1)
text(x=1.5, y=seq(1, 0, l=10), cex=.5,
labels=levels(cut(1/rl_df$mse, 10)))