Random Forests with ranger
Train random forest models, tune mtry and ntrees, and assess OOB error.
Random Forests with ranger is a free R Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is a Random Forest?
A random forest builds many decision trees on bootstrapped samples of the data, then averages their predictions (regression) or takes a majority vote (classification). Two sources of randomness give the ensemble its name: bootstrap sampling of rows, and random feature selection at each split.
library(ranger)
# Minimal random forest: 500 trees, auto mtry
rf <- ranger(
medv ~ .,
data = MASS::Boston,
num.trees = 500
)
print(rf)The mtry Parameter
mtry is the number of features randomly considered at each split. Using fewer features than the total decorrelates the trees, reducing variance. The rule of thumb is mtry = sqrt(p) for classification and mtry = p/3 for regression, where p is the number of predictors.
p <- ncol(MASS::Boston) - 1 # number of predictors
rf_class <- ranger(
Species ~ ., data = iris,
num.trees = 500,
mtry = floor(sqrt(4)) # sqrt(p) for classification
)
rf_reg <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 500,
mtry = floor(p / 3) # p/3 for regression
)
cat('Classification OOB Error:', rf_class$prediction.error)
cat('Regression OOB RMSE:', sqrt(rf_reg$prediction.error))OOB Error — Free Validation
Because each tree is trained on a bootstrap sample, roughly one-third of observations are left out (out-of-bag, OOB). These OOB samples act as a built-in validation set for each tree. The aggregate OOB error is a nearly unbiased estimate of test error — no separate validation set required.
rf <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 500,
mtry = 4
)
# OOB MSE
cat('OOB MSE:', rf$prediction.error)
# OOB RMSE
cat('OOB RMSE:', sqrt(rf$prediction.error))
# For classification: OOB error rate
rf_cl <- ranger(Species ~ ., data = iris)
cat('OOB Error Rate:', rf_cl$prediction.error)Variable Importance
Setting importance = 'impurity' records the total decrease in node impurity (Gini or MSE) for each feature across all trees. Setting importance = 'permutation' measures accuracy loss when each feature is randomly shuffled — this is more reliable but slower.
rf_imp <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 500,
importance = 'impurity'
)
# Sorted importance scores
imp <- sort(rf_imp$variable.importance, decreasing = TRUE)
print(imp)
# Quick plot
barplot(imp, las = 2, col = 'steelblue',
main = 'Random Forest Variable Importance')Predictions with ranger
Use predict(rf, data = test) to generate predictions. The result is a list; access the predictions with $predictions. For classification, predictions are factor levels by default.
set.seed(1)
idx <- sample(nrow(MASS::Boston), 400)
train <- MASS::Boston[idx, ]
test <- MASS::Boston[-idx, ]
rf <- ranger(medv ~ ., data = train, num.trees = 500)
pred <- predict(rf, data = test)
test_rmse <- sqrt(mean((pred$predictions - test$medv)^2))
cat('Test RMSE:', round(test_rmse, 3))Confusion Matrix Concept
For classification, a confusion matrix cross-tabulates actual vs predicted classes. Key metrics derived from it include accuracy, precision (TP / (TP + FP)), recall (TP / (TP + FN)), and F1 score. ranger provides OOB confusion matrix directly.
rf_cl <- ranger(
Species ~ ., data = iris,
num.trees = 500,
mtry = 2
)
# OOB confusion matrix
print(rf_cl$confusion.matrix)
# OOB error rate
cat('OOB Error Rate:', rf_cl$prediction.error)
# Manual accuracy on OOB predictions
# (1 - error rate)
cat('OOB Accuracy:', 1 - rf_cl$prediction.error)Tuning mtry and num.trees
More trees always reduce variance (until diminishing returns around 300-500). The mtry parameter has a sweet spot. A simple tuning loop evaluates OOB error across a grid of mtry values to find the optimal value without cross-validation.
mtry_vals <- c(2, 4, 6, 8, 10)
oob_errors <- sapply(mtry_vals, function(m) {
rf <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 300, mtry = m
)
rf$prediction.error
})
best_mtry <- mtry_vals[which.min(oob_errors)]
cat('Best mtry:', best_mtry)
plot(mtry_vals, sqrt(oob_errors), type = 'b',
xlab = 'mtry', ylab = 'OOB RMSE')ranger for Classification
For classification, set probability = TRUE to get class probability predictions instead of hard labels. This is necessary for ROC curve computation and calibrated probability estimates, and matches the output format expected by yardstick metrics.
# Ensure the target is a factor
iris$Species <- as.factor(iris$Species)
rf_prob <- ranger(
Species ~ ., data = iris,
num.trees = 300,
probability = TRUE # output class probabilities
)
# Predictions are a matrix of probabilities
pred_prob <- predict(rf_prob, data = iris[1:5, ])
print(pred_prob$predictions)Parallelism in ranger
ranger is designed for speed and parallelism. Set num.threads to use all available CPU cores. This can produce dramatic speedups over the older randomForest package, especially for large datasets with many trees.
# Use all available cores
rf_fast <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 1000,
mtry = 4,
num.threads = parallel::detectCores()
)
cat('Trees:', rf_fast$num.trees)
cat('Threads used:', rf_fast$num.threads)
cat('OOB RMSE:', sqrt(rf_fast$prediction.error))ranger via tidymodels
You can use ranger through the tidymodels interface, which provides consistent syntax and integrates with workflows, cross-validation, and tuning. Specify the engine as 'ranger' and pass engine-specific arguments with set_engine().
library(parsnip)
library(workflows)
rf_spec <- rand_forest(
mtry = tune(),
trees = 500,
min_n = tune()
) |>
set_engine('ranger', importance = 'impurity') |>
set_mode('regression')
wf <- workflow() |>
add_recipe(rec) |>
add_model(rf_spec)
print(wf)Interpreting ranger Output
The printed ranger model shows: number of trees, target variable, number of features used, OOB prediction error, and R-squared (for regression). Always check OOB error as a quick sanity check — if it is extremely low on a large dataset, suspect data leakage.
rf <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 500, mtry = 4,
importance = 'impurity'
)
# Key output fields
cat('OOB MSE: ', rf$prediction.error, '\n')
cat('OOB RMSE: ', sqrt(rf$prediction.error), '\n')
cat('R-squared: ', rf$r.squared, '\n')
cat('Num trees: ', rf$num.trees, '\n')
cat('Num features: ', rf$num.independent.variables, '\n')Quick Check
In a random forest built with ranger, what does the OOB (out-of-bag) error estimate?
Random Forests Recap
Key takeaways from Random Forests with ranger:
- Random forests combine many trees built on bootstrapped samples with random feature selection at each split.
mtry: sqrt(p) for classification, p/3 for regression; tune this parameter.- OOB error provides a free, nearly unbiased validation estimate.
importance = 'impurity'or'permutation'gives variable importance scores.- Set
probability = TRUEfor class probability outputs in classification. - ranger is highly parallelised; use
num.threadsfor large datasets. - Integrate with tidymodels via
rand_forest() |> set_engine('ranger').
rf <- ranger(
medv ~ ., data = MASS::Boston,
num.trees = 500,
mtry = 4,
importance = 'impurity',
num.threads = parallel::detectCores()
)
cat('OOB RMSE:', sqrt(rf$prediction.error))
cat('R2:', rf$r.squared)
print(sort(rf$variable.importance, decreasing = TRUE))Frequently asked questions
Is the “Random Forests with ranger” lesson free?
Yes — the full text of “Random Forests with ranger” is free to read here on the web, and the R Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the R Academy course, upgrade to CoddyKit PRO.
What will I learn in “Random Forests with ranger”?
Train random forest models, tune mtry and ntrees, and assess OOB error. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start R Academy?
No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Random Forests with ranger” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this R Academy lesson?
Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.