为了构建堆叠模型,我在同一数据集上使用不同的预处理训练了许多基础模型。为了跟踪构建设计矩阵的方式,我使用了 recipes 包并定义了自己的步骤。但是,在插入符号训练模型中使用带有自定义步骤的配方显示比应用相同的预处理并使用手工设计矩阵训练插入符号模型要慢 20 倍。知道为什么以及如何改进吗?
我在下面提供了一个可重现的示例:
# Loading libraries
packs <- c("tidyverse", "caret", "e1071", "wavelets", "recipes")
InstIfNec<-function (pack) {
if (!do.call(require,as.list(pack))) {
do.call(install.packages,as.list(pack)) }
do.call(require,as.list(pack)) }
lapply(packs, InstIfNec)
# Getting data
data(biomass)
biomass <- select(biomass,-dataset,-sample)
# Defining custom pretreatment algorithm
HaarTransform <- function(DF1) {
w <- function(k) {
s1 = dwt(k, filter = "haar")
return (s1@V[[1]])
}
Smt = as.matrix(DF1)
Smt = t(base::apply(Smt, 1, w))
return (data.frame(Smt))
}
# Creating the custom step function
step_Haar_new <- function(terms, role, trained, skip, columns, id) {
step(subclass = "Haar", terms = terms, role = role,
trained = trained, skip = skip, columns = columns, id = id)
}
step_Haar<-function(recipe, ..., role="predictor", trained=FALSE, skip=FALSE,
columns=NULL, id=rand_id("Harr")) {
terms=ellipse_check(...)
add_step(recipe, step_Haar_new(terms=terms, role=role, trained=trained,
skip=skip, columns=columns, id=id))
}
prep.step_Haar <- function(x, training, info = NULL, ...) {
col_names <- terms_select(terms = x$terms, info = info)
step_Haar_new(terms = x$terms, role = x$role, trained = TRUE,
skip = x$skip, columns = col_names, id = x$id)
}
bake.step_Haar <- function(object, new_data, ...) {
predictors <- HaarTransform(dplyr::select(new_data, object$columns))
new_data[, object$columns] <- NULL
bind_cols(new_data, predictors)
}
# Fiting the caret model using recipe
system.time({
Haar_recipe<-recipe(carbon ~ ., biomass) %>%
step_Haar(all_predictors())
set.seed(1)
fit <- caret::train(Haar_recipe, data = biomass, method = "svmLinear")
})
# Fiting the caret model with hand made pretreatment
system.time({
df<-HaarTransform(biomass[,-1])
set.seed(1)
fit2<-caret::train(x=df, y=biomass[, 1], method="svmLinear")
})
# Comparing results
fit; fit2
# Both way provide the same result but the recipes way take ~20 seconds while hand made pretreatment take ~1.5 seconds
使用 profvis,看起来配方方式进行了多次尝试(即 27 次)使用不同运行的 try() 和 eval() 函数来完成相同的工作。