Select mtry and nodesize for a supervised random forest using holdout or out-of-bag (OOB) prediction error. tune() searches over both parameters; tune.nodesize() searches over nodesize only. Both functions offer grid and golden-section search and fit the tuning forests with rfsrc.fast.

# S3 method for class 'rfsrc'
tune(formula, data,
  mtry.start = ncol(data) / 2,
  nodesize.try = c(1:9, seq(10, 100, by = 5)), ntree.try = 100,
  sampsize = function(x) { min(x * .632, max(150, x^(3/4))) },
  nsplit = 1, step.factor = 1.25, improve = 1e-3, strikeout = 3, max.iter = 25,
  method = c("grid", "golden"),
  final.window = 5, reps.initial = 2, reps.final = 3,
  trace = FALSE, do.best = TRUE, seed = NULL, ...)

# S3 method for class 'rfsrc'
tune.nodesize(formula, data,
  nodesize.try = c(1:9, seq(10, 150, by = 5)), ntree.try = 100,
  sampsize = function(x) { min(x * .632, max(150, x^(4/5))) },
  nsplit = 1, method = c("grid", "golden"),
  final.window = 5, reps.initial = 2, reps.final = 3, max.iter = 50,
  trace = TRUE, seed = NULL, ...)

Arguments

formula

A model formula specifying the response and predictors.

data

A data frame containing the response and predictors.

mtry.start

Starting value of mtry for tune().

nodesize.try

Candidate terminal-node sizes for grid search, subject to the limits in Note. Not used for golden search.

ntree.try

Number of trees in each tuning forest, excluding the final forest returned by tune().

sampsize

Per-tree sample size, supplied as a function of the sample size or as a number. For a numeric vector, such as class-specific sizes, the total is used during tuning.

nsplit

Number of random split points considered at each node.

step.factor

Factor for increasing or decreasing mtry during grid search in tune(). Must be greater than one.

improve

Relative-error reduction threshold for tune(). Must be nonnegative; 1e-3 corresponds to a 0.1 percent decrease.

strikeout

Number of additional steps allowed after error increases in grid search, counted across each search direction. For golden search in tune(), the number of consecutive alternating-search iterations without sufficient improvement before stopping.

max.iter

Maximum iterations per search direction (grid) or per one-dimensional search (golden). For tune() with golden search, also limits the number of alternating searches.

method

Search method: "grid" (default) or "golden". See Details.

final.window

Target interval width for golden search. Also sets the distance searched on either side of the best value from the initial small-value comparisons.

reps.initial

Number of replicate forests per setting during golden-section search; their errors are averaged.

reps.final

Number of replicate forests per setting in the final integer comparisons for golden search; their errors are averaged.

trace

If TRUE, print tuning progress and errors.

do.best

If TRUE, tune() also fits a forest on all available data using the selected settings.

seed

Optional integer seed for reproducible tuning, including the holdout sample when used.

...

Additional options for rfsrc.fast, such as splitrule and perf.type. In tune(), ntree, mtry, nodesize, forest, and save.memory are controlled by the tuner; values supplied here are ignored.

Details

Tuning compares forest settings to find those with the lowest prediction error. The parameter mtry controls how many predictors are considered at each split, and nodesize controls terminal-node size. A forest is grown for each candidate setting and its prediction error is calculated. The selected setting has the smallest error in the returned results table.

Choosing a search method

method = "grid":

For each eligible nodesize.try value, tune() starts at mtry.start and searches toward smaller and larger mtry values. step.factor sets the spacing; improve, strikeout, and max.iter control when to stop. The grid specifies nodesize values, while mtry values are chosen during the search. tune.nodesize() evaluates the nodesize.try grid directly, subject to the sample-size limit in Note.

method = "golden":

Comparisons within an interval progressively narrow the search toward values with smaller error. tune() alternates between searching over nodesize with mtry fixed and searching over mtry with nodesize fixed. tune.nodesize() searches over nodesize only.

Each one-dimensional search also checks 1:9 within its limits. It finishes with individual integer comparisons near the best small value or within the remaining interval. Averaging replicate forests, controlled by reps.initial and reps.final, reduces the effect of random variation in forest fits. nodesize.try and step.factor are not used.

Comparing prediction errors

Both functions use one per-tree sample size, ssize, throughout tuning. Let n be the sample size after preprocessing. When 2 * ssize < n, a random holdout of ssize observations is set aside. Forests are grown on the remaining data, and all candidates are evaluated on this same holdout. Otherwise, forests use all available data and are evaluated by OOB error.

Supply perf.type to choose the tuning error measure. tune() averages the available errors from get.mv.error with standardize = TRUE: regression errors are divided by the response variance, and errors for multivariate responses are averaged.

Fitting the final forest

With do.best = TRUE, tune() fits a new forest on all available data, using the selected mtry and nodesize, the original sampsize argument, and the specified nsplit. The forest is returned as rf.

This final fit uses the default tree count and performance measure of rfsrc.fast. To choose these yourself, set do.best = FALSE and fit a forest separately with the returned optimal values. tune.nodesize() returns its selected node size and error table without a final forest fit.

Value

tune() returns a list with components:

results

A numeric matrix with columns nodesize, mtry, and err (prediction error). For golden search, this table contains the final integer comparisons; repeated parameter pairs are combined by averaging their errors.

optimal

A named numeric vector giving the nodesize and mtry with the smallest error in results.

rf

The final fitted forest when do.best = TRUE; otherwise NULL.

tune.nodesize() returns a list with components:

nsize.opt

The selected nodesize.

err

A data frame with columns nodesize and err, giving the candidate values and their prediction errors.

Note

The tuning sample size ssize is obtained by evaluating sampsize(n), using a numeric scalar directly, or summing a numeric vector. In tune(), it is rounded and bounded between 2 and n.

For tune(), mtry ranges from 1 to the number of predictors, and the upper nodesize limit is max(10, floor(ssize / 2)). Grid values above this limit are excluded. For tune.nodesize(), the upper grid limit is half the per-tree sample size, rounded down.

Author

Hemant Ishwaran and Udaya B. Kogalur

Examples

# \donttest{
## ------------------------------------------------------------
## White wine classification example
## ------------------------------------------------------------
data(wine, package = "randomForestSRC")
wine$quality <- factor(wine$quality)

## Fixed seed makes tuning reproducible
set.seed(1)

## Full tuner over nodesize and mtry (grid)
o1 <- tune(quality ~ ., wine, sampsize = 100, method = "grid")
print(o1$optimal)

## Golden search alternative
o2 <- tune(quality ~ ., wine, sampsize = 100, method = "golden",
           reps.initial = 2, reps.final = 3, seed = 1)
print(o2$optimal)

## visualize the nodesize/mtry surface
if (library("interp", logical.return = TRUE)) {

  plot.tune <- function(o, linear = TRUE) {
    x <- o$results[, 1]
    y <- o$results[, 2]
    z <- o$results[, 3]
    so <- interp(x = x, y = y, z = z, linear = linear)
    idx <- which.min(z)
    x0 <- x[idx]; y0 <- y[idx]
    filled.contour(x = so$x, y = so$y, z = so$z,
                   xlim = range(so$x, finite = TRUE) + c(-2, 2),
                   ylim = range(so$y, finite = TRUE) + c(-2, 2),
                   color.palette = colorRampPalette(c("yellow", "red")),
                   xlab = "nodesize", ylab = "mtry",
                   main = "error rate for nodesize and mtry",
                   key.title = title(main = "Tuning error", cex.main = 1),
                   plot.axes = {
                     axis(1); axis(2)
                     points(x0, y0, pch = "x", cex = 1, font = 2)
                     points(x, y, pch = 16, cex = .25)
                   })
  }

  plot.tune(o1)
  plot.tune(o2)
}

## ------------------------------------------------------------
## nodesize only: grid vs golden
## ------------------------------------------------------------
o3 <- tune.nodesize(quality ~ ., wine, sampsize = 100, method = "grid",
                    trace = TRUE, seed = 1)
o4 <- tune.nodesize(quality ~ ., wine, sampsize = 100, method = "golden",
                    reps.initial = 2, reps.final = 3, trace = TRUE, seed = 1)
plot(o3$err, type = "s", xlab = "nodesize", ylab = "error")

## ------------------------------------------------------------
## Tuning for class imbalance (rfq with geometric mean performance)
## ------------------------------------------------------------
data(breast, package = "randomForestSRC")
breast <- na.omit(breast)
o5 <- tune(status ~ ., data = breast, rfq = TRUE, perf.type = "gmean",
           method = "golden", seed = 1)
print(o5$optimal)

## ------------------------------------------------------------
## Competing risks example (nodesize only)
## ------------------------------------------------------------
data(wihs, package = "randomForestSRC")
plot(tune.nodesize(Surv(time, status) ~ ., wihs, trace = TRUE)$err, type = "s")
# }