Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Boruta is a supervised feature-selection method for finding all relevant predictors—not necessarily the smallest or fastest set. It repeatedly compares real features with shuffled copies (“shadow features”) using a model’s importance scores, then labels each feature Confirmed, Rejected, or Tentative. The result is conditional on the data, target, importance model, and settings; it is not a causal finding or a promise of better test performance.

What Boruta does—and what it does not do

A usual importance ranking tells you which predictors scored highest for one fitted model. Boruta asks a different question: is a predictor consistently more informative than randomized copies of the available predictors? This makes it useful when you want a broad relevance screen, including predictors that overlap with stronger ones.

Boruta is a wrapper: it repeatedly fits an importance-producing supervised model as part of feature selection. The original R package uses a Random Forest-based importance provider by default. The method and package are described in the CRAN Boruta documentation and the Journal of Statistical Software paper.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“Important” here means judged relevant under the chosen supervised model and comparison procedure. It does not mean classically statistically significant, causally influential, or essential to every later model.

How the shadow comparison works

  1. Boruta starts with the active real predictors and shuffles each predictor’s values to create shadow features.
  2. It appends the shadows to the real predictors and fits the importance model.
  3. It compares each real feature’s importance with a threshold derived from shadow-feature importance. The original comparison typically uses the maximum shadow importance.
  4. It records evidence for each feature as more relevant or less relevant than the shadow benchmark, applies its configured testing and correction procedure, and updates feature decisions.
  5. It creates new shadows and repeats until features are decided or the iteration limit is reached.

The shadows are recreated during iterations, so the reference is not one fixed noise column. Still, a result is tied to the supplied data and sampling design, target, importance model and hyperparameters, random seed, iteration limit, multiple-testing correction, and shadow threshold. The CRAN reference manual documents the R implementation.

All-relevant is not minimal-optimal

Goal What it means
All-relevant selection Retain predictors that carry useful predictive information, including potentially redundant ones. This is Boruta’s aim.
Minimal-optimal selection Find a compact subset that performs as well as possible for a specified model. Boruta does not promise this.
Causal discovery Determine whether a variable causes an outcome. Boruta is not a causal-inference procedure.
Production efficiency Reduce prediction cost by using fewer inputs. Boruta may retain more variables than needed; a separate reduction and validation step may be appropriate.

For a compact subset, consider methods such as recursive feature elimination with cross-validation or sparse L1-based models. The appropriate choice depends on whether the priority is broad discovery, predictive performance, or a parsimonious model.

When Boruta is a good fit

  • You have a labeled classification, regression, or compatible survival-analysis task and want to screen for a broad set of relevant predictors.
  • Nonlinearities or interactions may matter, and the chosen importance model can represent them.
  • You can afford repeated model fitting and have enough data to assess selection stability.
  • Keeping several overlapping signals is useful for scientific exploration or downstream review.

The R interface supports classification and numeric regression, and survival objects when the selected importance adapter supports them. Predictors can be numeric, binary, or encoded categorical variables; the estimator and adapter must accept their representation. High-dimensional problems are possible, but added shadow columns and repeated fits can make runtime and memory substantial. See the R reference manual for supported interfaces.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For Python, BorutaPy expects a supervised estimator exposing fit and feature_importances_; higher absolute importance is treated as more important. In R, a custom getImp function can be supplied, but it must return one numeric score per predictor in the correct order. The result remains dependent on that importance source.

Prepare data without leakage

Split the data before learning feature-selection decisions. Fit Boruta only on the training data, or separately inside every cross-validation training fold. If the test set influences which variables are selected, it is no longer an untouched estimate of generalization performance.

Define predictors and the target

  • Exclude the target from the predictor matrix.
  • Remove post-outcome fields, identifiers that encode the outcome, timestamps unavailable at prediction time, and aggregates that use future observations.
  • Check for duplicate or near-duplicate records across train and test partitions.

Choose a split that matches deployment

Use group-aware splitting when rows share a customer, patient, subject, device, or household. For forecasting or temporal deployment, use time-aware validation and, where appropriate, a held-out future period. Random splitting can overstate performance when observations are dependent.

Encode categories and handle missing values

The importance estimator must consume the representation given to it. For Python Random Forest estimators, categorical columns commonly need numeric encoding, such as one-hot encoding, unless the estimator natively supports categories. Boruta then judges one-hot columns separately, so one logical category may have some dummy columns selected and others rejected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Impute missing values using statistics learned only from training data, or use a compatible estimator. If missingness itself may carry predictive information, preserve a missingness indicator deliberately. Apply encoding and imputation within the training fold rather than fitting them once on all rows.

Configure the importance model for the task

A tree ensemble can capture nonlinearities and interactions, but poor hyperparameters can produce unstable importance rankings. The selector’s model need not match the final model, yet relevance under a Random Forest does not necessarily transfer to a linear model, neural network, or time-series model. Validate with the actual downstream model.

For imbalanced classes, consider class weighting or a sampling strategy applied only within training folds, and evaluate with a metric suited to the task rather than accuracy alone.

Run Boruta in R

The CRAN package index identified Boruta version 8.0.0 on August 18, 2026; check the installed package documentation for the version and arguments available in your environment. Install the package with:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
install.packages("Boruta")
library(Boruta)

Basic classification example

set.seed(42)
data(iris)

boruta_fit <- Boruta(
  Species ~ .,
  data = iris,
  doTrace = 1
)

print(boruta_fit)
getSelectedAttributes(boruta_fit)
plotImpHistory(boruta_fit)

To inspect all decisions and sort the summary by mean importance:

decision <- attStats(boruta_fit)
decision[order(decision$meanImp, decreasing = TRUE), ]
boruta_fit$finalDecision

The formula interface can also name predictors explicitly, for example target ~ age + income + account_age + prior_events. If using separate predictor and response objects, keep the target out of x:

x <- train_data[, setdiff(names(train_data), "target")]
y <- train_data$target

boruta_fit <- Boruta(
  x = x,
  y = y,
  maxRuns = 200,
  pValue = 0.01,
  mcAdj = TRUE
)

Documented R defaults include pValue = 0.01, mcAdj = TRUE, maxRuns = 100, and getImp = getImpRfZ. The current package documentation describes the default as a Random Forest-based importance path using ranger. These are implementation defaults, not universal settings that guarantee a good selection.

Handle unresolved variables in R

TentativeRoughFix is an optional, weaker follow-up test—not equivalent to reaching a decisive result through the main run:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
boruta_fixed <- TentativeRoughFix(boruta_fit)
getSelectedAttributes(boruta_fixed)

You can instead leave unresolved variables tentative and report them separately. If you supply a custom getImp, it must fit an appropriate model and return one numeric importance value per input predictor while preserving column order.

Run BorutaPy in Python

BorutaPy is a scikit-learn-style Python implementation that aims to mimic the R package, but it has implementation-specific parameters and defaults. Its API and guidance are in the BorutaPy repository and implementation source.

Install it with:

python -m pip install boruta

This classification example assumes train_df has already been split and its predictors encoded and imputed appropriately for the estimator:

from sklearn.ensemble import RandomForestClassifier
from boruta import BorutaPy

X = train_df.drop(columns="target")
y = train_df["target"]

estimator = RandomForestClassifier(
    n_estimators=1000,
    n_jobs=-1,
    class_weight="balanced",
    max_depth=7,
    random_state=42
)

selector = BorutaPy(
    estimator=estimator,
    n_estimators="auto",
    verbose=2,
    random_state=42,
    max_iter=100
)

selector.fit(X.to_numpy(), y.to_numpy())

confirmed_columns = X.columns[selector.support_]
tentative_columns = X.columns[selector.support_weak_]
X_confirmed = selector.transform(X.to_numpy())

BorutaPy documents support_ as the confirmed-feature mask and support_weak_ as the tentative-feature mask. ranking_ assigns confirmed variables rank 1 and tentative variables rank 2. Use transform to apply the learned confirmed-feature mask. Keep the original column names alongside the transformed array so you can audit which predictors are retained.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Important BorutaPy settings

Parameter Documented default Effect
n_estimators 1000 Number of trees, or use "auto" as in the example.
perc 100 Uses the maximum shadow importance; a lower percentile generally makes the comparison less strict.
alpha 0.05 Significance setting used by the implementation’s decision procedure.
two_step True Enables BorutaPy’s two-step correction procedure. With perc=100, two_step=False is documented as closer to the original R-style correction.
max_iter 100 Maximum selection iterations.
early_stopping Not stated here When enabled, can reduce runtime but may stop before tentative variables are adequately resolved.

The BorutaPy implementation guidance recommends pruned trees with depth between 3 and 7; treat this as that project’s recommendation, not a rule for every dataset or final model. R and Python defaults differ, so record the package, version, estimator, settings, and seed rather than assuming the two implementations produce interchangeable results.

Evaluate the selected variables on untouched data

After selection, transform validation or test data with the selector learned on training data, then fit and assess the final model. Compare its performance with a baseline using all eligible predictors under the same split and evaluation procedure. Boruta may reduce inputs or support interpretation, but it does not guarantee better predictive performance.

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from boruta import BorutaPy

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)

selector = BorutaPy(
    RandomForestClassifier(
        n_estimators=1000,
        n_jobs=-1,
        random_state=42,
        max_depth=7
    ),
    n_estimators="auto",
    random_state=42,
    max_iter=100
)
selector.fit(X_train.to_numpy(), y_train.to_numpy())

X_train_selected = selector.transform(X_train.to_numpy())
X_test_selected = selector.transform(X_test.to_numpy())

final_model = RandomForestClassifier(
    n_estimators=1000,
    n_jobs=-1,
    random_state=42,
    max_depth=7
)
final_model.fit(X_train_selected, y_train)
test_score = final_model.score(X_test_selected, y_test)

This is a holdout illustration; use a task-appropriate score and compare against an all-feature model. For cross-validation or hyperparameter tuning, selection and preprocessing must be learned within each training fold. scikit-learn explains how pipelines chain transformations with an estimator to help avoid leakage, and its feature-selection guidance covers selector use. BorutaPy may not behave as a drop-in native scikit-learn pipeline transformer in every installed version, so verify the exact integration or fit the selector explicitly inside each fold.

If the project is selecting variables and tuning a final model, use nested cross-validation or a separate final test set so choices made during model selection do not contaminate the final estimate. Repeat selection across resamples when stability matters, and report how often each variable is selected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Interpret Confirmed, Rejected, and Tentative

Confirmed

A confirmed variable has sufficient evidence, under the configured test and correction procedure, to be more relevant than the shadow benchmark. This does not prove causality, unique contribution after deployment, stability in another population, or necessity for every downstream model.

Rejected

A rejected variable was judged less informative than the shadow benchmark in this run. That is not proof it has no relationship with the target in every model, population, or subgroup.

Tentative

A tentative variable remains unresolved when the run stops. Do not silently treat it as selected or discarded. In Python, report support_weak_ separately; in R, consider more iterations only after checking data and model stability, or use the weaker TentativeRoughFix while labeling that choice clearly.

Correlated features, stability, and common results

Correlated predictors can both be confirmed

When predictors overlap, Boruta may confirm several because each can carry predictive information. A confirmed feature need not add unique information beyond its correlated group, and tree importance can be distributed unevenly so a weaker but useful feature becomes tentative or rejected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For interpretation or simplification, cluster highly correlated variables, then choose representatives using domain meaning, measurement quality, cost, or missingness. Compare group-level performance and, where suitable, examine conditional permutation importance. Treat this as a follow-up question about incremental value, not as a reinterpretation of Boruta’s all-relevant decision.

All or none confirmed

If every feature is confirmed, that may reflect dense signal, interactions, correlated signals, a permissive configuration, leakage, an informative identifier, or too little data to distinguish weak signal from noise. If none is confirmed, check target encoding, signal strength, sample size, missingness, estimator configuration, train/test mismatch, target corruption, threshold strictness, and whether enough iterations ran. Neither outcome alone establishes that the algorithm failed.

Small samples, high dimensionality, and runtime

Small datasets can yield unstable repeated importance comparisons; report selection frequencies across resamples rather than treating one run as definitive. With very wide data, Boruta’s shadows and repeated estimator fits can consume substantial time and memory. One practical compromise is to remove constants and obvious data-quality failures, apply a cheap leakage-safe preliminary filter, then run Boruta and validate the resulting shortlist with nested cross-validation. That preliminary filter can discard weak, interaction-only, or redundant-but-relevant variables before Boruta sees them.

Alternatives when the objective differs

Method Best suited to Important distinction
Random Forest importance Fast ranking or rough screening. Simpler and usually faster, but it ranks scores rather than testing real features against shadow-feature benchmarks.
Permutation importance Post-fit interpretation of a model on relevant evaluation data. Measures score degradation after shuffling a feature; it depends on the fitted model and evaluation data. See scikit-learn’s documentation.
RFE or RFECV A compact subset, especially when the number of retained features should be chosen by cross-validation. Recursively removes weaker predictors; scikit-learn’s feature-selection documentation describes RFECV.
L1 regularization Sparse linear or generalized linear models with coefficient-based selection. Correlated predictors can compete, leaving one selected and another discarded; sparse recovery depends on design-matrix correlation.
Mutual information or univariate tests Cheap preliminary screening or independent-feature baselines. Univariate methods can miss interaction-only signals; mutual-information estimation is nonparametric and needs sufficient data.

The choice depends on the question: Boruta for broad relevance, a compact selector for parsimony, permutation importance for a fitted model’s reliance on features, or causal methods for causal claims.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What to report for a reproducible result

  • Package name and version, importance estimator, and its hyperparameters.
  • Random seed, iteration limit, significance and correction settings, and shadow threshold setting where configurable.
  • Counts and identities of confirmed, rejected, and tentative variables, with an explicit treatment of tentative results.
  • Data split or cross-validation design, including group or time structure and preprocessing performed within folds.
  • Selection stability across resamples and final-model performance compared with an all-eligible-feature baseline on untouched data.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.