Problem with rBayesianOptimization when used with the caret package

51 Views Asked by At

I have been trying to do the hyperparameter tuning of the caret models by using some libraries such as rBayesianOptimization. I started off with some simple models (such as svmLinear or glmnet) and it worked perfectly. When I wanted to try out some models with more hyperparameters (such as xgbTree or mlpWeightDecayML), the tuning process started causing exceptions after around 10 rounds.

I have been following the tutorial from this website on how to combine these two packages.

The basic code:

# Function used in BayesianOptimization
eval_function_mlpWeightDecayML <- function(layer1, layer2, layer3, decay) {
    message("Running the eval 'mlpWeightDecayML' function...")

    dataFrame = caretTrainObject$trainingData
    index = caret::createDataPartition(dataFrame[, ncol(dataFrame)], p = 0.8, list = FALSE)

    trainData = dataFrame[index, ]
    testData = dataFrame[-index, ]

    model <- suppressWarnings(caret::train(
        x = trainData[, -ncol(dataFrame)],
        y = trainData[, ncol(dataFrame)],
        metric = caretTrainObject$metric,
        method = "mlpWeightDecayML",
        trControl = caret::trainControl(method = "none"),
        verbose = FALSE, 
        tuneGrid = expand.grid(
            layer1 = layer1,
            layer2 = layer2,
            layer3 = layer3,
            decay = decay
        )
    ))
    message("Finished this evaluation! Getting the results ready..")
    return(list(Score = calculate_specific_metric(model, testData, caretTrainObject$metric), Pred = 0))
}

calculate_specific_metric <- function(model, testData, metricName){
    predictions = stats::predict(model, newdata = testData)
    actual = testData[, ncol(testData)]

    if(is_classification_model(model)){
        matrix = caret::confusionMatrix(predictions, actual)
        metrics = matrix$overall
    } else {
        # Negative because MAE, Rsquared and RMSE all are errors and should be minimized
        metrics = -caret::postResample(pred = predictions, obs = actual)
    }

    if(metricName %in% names(metrics)){
        return(metrics[metricName])
    } else {
        stop("Metric not found or not applicable for this model.")
    }
}

tune.bayesian_optimization <- function(caretTrainObject){
    dataFrame = caretTrainObject$trainingData

    func = eval_function_mlpWeightDecayML 
    bounds = list(
        layer1 = c(0L, 20L),
        layer2 = c(0L, 20L),
        layer3 = c(0L, 20L),
        decay = c(0.0001, 0.9)
    )

    bayesianModel = rBayesianOptimization::BayesianOptimization(
        func,
        bounds = bounds,
        n_iter = 5,
        init_points = 10,
        verbose = TRUE
    )
    bestPar = bayesianModel$Best_Par
}

caretTrainObject <- suppressWarnings(caret::train(
  x = iris[, -ncol(iris)], 
  y = iris[, ncol(iris)], 
  method = "mlpWeightDecayML",
  trControl = caret::trainControl(method = "cv"),
  verbose = FALSE,
  tuneGrid = expand.grid( # Grid not relevant
    layer1 = c(3, 4),
    layer2 = c(3, 4),
    layer3 = c(3, 4),
    decay = c(0.3, 0.4)
  )
))

a = tune.bayesian_optimization(caretTrainObject)

The exception, after 10 rounds is:

... elapsed = 0.20 Round = 9 layer1 = 15.0000 layer2 = 0.0000 layer3 = 0.0000 decay = 0.2070436 Value = 0.4452055 Running the eval 'mlpWeightDecayML' function... Finished this evaluation! Getting the results ready.. elapsed = 0.16 Round = 10 layer1 = 7.0000 layer2 = 0.0000 layer3 = 0.0000 decay = 0.2733959 Value = 0.5547945 Error in if ((min(X) < 0) | (max(X) > 1) | ((max(X) - min(X)) <= 0.5)) { : missing value where TRUE/FALSE needed

I have tried with different datasets, still the same issue. The interesting part that this exact code, when run with caret models such as glmnet, runs perfectly fine. I debugged a bit and found out that the line number 168 in the rBayesianOptimization package causes an issue.

The same error is caused by both mlpWeightDecayML and xgbTree models (from what I tested).

0

There are 0 best solutions below