Почему рецепты в 20 раз медленнее, чем ручная предварительная обработка при обучении модели карета? - PullRequest
2 голосов
/ 25 апреля 2019

Чтобы построить модель стекирования, я обучил много базовых моделей, используя различные предварительные обработки в одном наборе данных. Чтобы отслеживать способ построения матриц дизайна, я использовал пакет рецептов и определил свои собственные шаги. Но использование рецепта с пользовательским шагом в модели тренировки карета оказалось в 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 ().

1 Ответ

0 голосов
/ 25 апреля 2019

train выполняет правильную предварительную обработку путем повторного выполнения рецепта в каждом повторном примере . Это необходимо, когда ваш метод предварительной обработки выдает некоторую оценку или статистику из данных для применения предварительной обработки. PCA, вменение и другие методы должны применяться таким образом, иначе вы получите очень оптимистичное представление о производительности.

Для некоторых методов, таких как пространственный знак, нет ничего, что можно было бы оценить, и это можно было бы сделать до повторной выборки. В противном случае, он должен идти внутрь (именно поэтому мы делаем это).

...