Özellik mühendisliği gerçek hayatta çok önemli olmasına rağmen, ağaçlar (ve rastgele ormanlar) formun etkileşim terimlerini bulmada çok iyidir x*y
. İşte iki yönlü etkileşimli bir regresyona oyuncak. Saf bir doğrusal model, bir ağaç ve bir torba ağaçla karşılaştırılır (bu, rastgele bir ormana daha basit bir alternatiftir).
Gördüğünüz gibi, ağaç kendi başına etkileşimi bulmakta oldukça iyidir, ancak bu örnekte doğrusal model iyi değildir.
# fake data
x <- rnorm(1000, sd=3)
y <- rnorm(1000, sd=3)
z <- x + y + 10*x*y + rnorm(1000, 0, 0.2)
dat <- data.frame(x, y, z)
# test and train split
test <- sample(1:nrow(dat), 200)
train <- (1:1000)[-test]
# bag of trees model function
boot_tree <- function(formula, dat, N=100){
models <- list()
for (i in 1:N){
models[[i]] <- rpart(formula, dat[sample(nrow(dat), nrow(dat), replace=T), ])
}
class(models) <- "boot_tree"
models
}
# prediction function for bag of trees
predict.boot_tree <- function(models, newdat){
preds <- matrix(0, nc=length(models), nr=nrow(newdat))
for (i in 1:length(models)){
preds[,i] <- predict(models[[i]], newdat)
}
apply(preds, 1, function(x) mean(x, trim=0.1))
}
## Fit models and predict:
# linear model
model1 <- lm(z ~ x + y, data=dat[train,])
pred1 <- predict(model1, dat[test,])
# tree
require(rpart)
model2 <- rpart(z ~ x + y, data=dat[train,])
pred2 <- predict(model2, dat[test,])
# bag of trees
model3 <- boot_tree("z ~ x+y", dat)
pred3 <- predict(model3, dat[test,])
ylim = range(c(pred1, pred2, pred3))
# plot predictions and true z
plot(dat$z[test], predict(model1, dat[test,]), pch=19, xlab="Actual z",
ylab="Predicted z", ylim=ylim)
points(dat$z[test], predict(model2, dat[test,]), col="green", pch=19)
points(dat$z[test], predict(model3, dat[test,]), col="blue", pch=19)
abline(0, 1, lwd=3, col="orange")
legend("topleft", pch=rep(19,3), col=c("black", "green", "blue"),
legend=c("Linear", "Tree", "Forest"))