Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

scikit-learn Decision Tree: DecisionTreeClassifier Step by Step

Fit a scikit-learn decision tree with DecisionTreeClassifier: parameters, export_text output, pruning, NaN handling and a methods-section checklist.

Written and maintained by CASRAI Editorial Board

Last updated

Short answer: in scikit-learn, a decision tree classifier is the class DecisionTreeClassifier in the sklearn.tree module. You create it, call fit(X, y) on a numeric feature matrix and class labels, then call predict or score. This guide follows the scikit-learn 1.9.1 documentation (read 2026-11-08) and covers the settings that matter for research work: depth limits, cost-complexity pruning, missing values, categorical features and reporting.

Who this is for: researchers and analysts working in Python who need to fit a classification tree, read its rules, control overfitting and report the model reproducibly.

What DecisionTreeClassifier is used for in research

The scikit-learn User Guide describes decision trees as a non-parametric supervised learning method that learns simple if-then decision rules from the data, giving a piecewise-constant prediction. The same page lists the practical reasons researchers use them: they are simple to interpret and visualize, need little data preparation, have a prediction cost logarithmic in the number of training points, handle multi-output problems and are a white-box model whose rules can be read directly.

The same page also lists the limitations you should state in a methods section: trees can overfit and create over-complex trees, small changes in data can produce a very different tree, predictions are not smooth and extrapolate poorly, and the learning algorithm is greedy, so it does not guarantee a globally optimal tree. Trees can also be biased toward dominant classes, so the guide recommends balancing the data set (or using sample weights) before fitting.

The names sklearn decision tree, decision tree sklearn, decision trees sklearn, sklearn decision tree classifier, decision tree classifier sklearn and sklearn DecisionTreeClassifier all refer to this one class. For a numeric outcome the matching class is DecisionTreeRegressor.

Install or access

scikit-learn is free, open-source software installed from the official installation page (scikit-learn installation instructions, read 2026-11-08). The documented routes are:

  1. pip: pip install -U scikit-learn
  2. conda: conda create -n sklearn-env -c conda-forge scikit-learn, then conda activate sklearn-env
  3. An isolated virtual environment first: python -m venv sklearn-env, activated with sklearn-envScriptsactivate on Windows or source sklearn-env/bin/activate on macOS and Linux, then the pip command above.

Record the installed version (import sklearn; print(sklearn.__version__)) in your methods notes, because defaults and features differ between releases.

Step by step: fit, predict and score a decision tree

  1. Prepare a numeric feature matrix. scikit-learn’s tree implementation does not support categorical variables natively, so encode them numerically (for example one-hot or ordinal encoding) before fitting. Trees use np.float32 internally; sparse input should be csc_matrix for fitting and csr_matrix for prediction.
  2. Split the data. Hold out a test set so the reported score is not computed on training rows. See train-test split in Python.
  3. Create the classifier with a fixed seed.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

clf = DecisionTreeClassifier(max_depth=3, random_state=0)
clf.fit(X_train, y_train)
print(clf.predict(X_test[:5]))
print(clf.score(X_test, y_test))
  1. Predict and score. predict returns class labels, predict_proba returns class probabilities and score returns mean accuracy on the data you give it.
  2. Cross-validate. The official class page example uses DecisionTreeClassifier(random_state=0) and cross_val_score(clf, iris.data, iris.target, cv=10) on the iris data. See cross-validation in statistics for the logic of repeated resampling.

The User Guide’s own tips: start with max_depth=3 and increase it, because the number of samples needed to populate the tree roughly doubles for each added level, and try min_samples_leaf=5 as an initial value. Use min_weight_fraction_leaf instead of min_samples_split when you pass sample weights, since min_samples_split ignores them.

Key parameters of DecisionTreeClassifier

All parameters are keyword-only in the 1.9.1 signature. The defaults below are as listed on the official class page.

Parameter Default What it does (per the documentation)
criterion 'gini' Split-quality measure: 'gini', 'entropy' or 'log_loss'.
splitter 'best' Strategy used to choose the split at each node.
max_depth None With None, nodes expand until leaves are pure or contain fewer than min_samples_split samples.
min_samples_split 2 Minimum samples required to split an internal node.
min_samples_leaf 1 Minimum samples required at a leaf node.
min_weight_fraction_leaf 0.0 Minimum weighted fraction of the input sample weights required at a leaf.
max_features None Number of features considered when looking for the best split.
random_state None Features are randomly permuted at each split even with splitter='best'; set an integer for a deterministic fit.
max_leaf_nodes None Grow the tree best-first up to this number of leaves.
min_impurity_decrease 0.0 A split happens only if it decreases impurity by at least this amount.
class_weight None A dictionary, or 'balanced' to weight classes inversely to their frequencies.
ccp_alpha 0.0 Complexity parameter for Minimal Cost-Complexity Pruning; 0.0 means no pruning.
monotonic_cst None Optional monotonicity constraints on features.

Output and how to read it

Print the rules with export_text

The text rules are usually the clearest thing to put in a supplement:

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, export_text

iris = load_iris()
decision_tree = DecisionTreeClassifier(random_state=0, max_depth=2)
decision_tree = decision_tree.fit(iris.data, iris.target)
print(export_text(decision_tree, feature_names=iris['feature_names']))

The User Guide shows this output for the iris data:

|--- petal width (cm) <= 0.80
|   |--- class: 0
|--- petal width (cm) >  0.80
|   |--- petal width (cm) <= 1.75
|   |   |--- class: 1
|   |--- petal width (cm) >  1.75
|   |   |--- class: 2

Read it top to bottom: each indented line is a split condition, and a line that ends in class: n is a leaf that predicts class n.

Draw the tree

from sklearn import tree then tree.plot_tree(clf) draws the fitted tree with matplotlib. export_graphviz writes a Graphviz file and needs both the Graphviz binaries and the graphviz Python package; it accepts feature_names, class_names, filled, rounded and special_characters.

Other fitted attributes and methods

  • feature_importances_: array of shape (n_features,), one importance per input feature.
  • classes_, n_classes_, n_features_in_, and feature_names_in_ (defined only when all feature names in X are strings).
  • get_depth() and get_n_leaves(): report the size of the fitted tree.
  • apply and decision_path: return the leaf reached and the nodes traversed for each sample.

For classification quality beyond accuracy, see the scikit-learn confusion matrix.

Pruning and overfitting

With the default max_depth=None the tree keeps growing until its leaves are pure, which is the usual route to overfitting. The User Guide names three controls: limit depth, raise min_samples_leaf, or prune. Minimal Cost-Complexity Pruning minimizes Rα(T) = R(T) + α|T̃|, where |T̃| is the number of terminal nodes; the weakest link (smallest effective α) is pruned first, and a larger ccp_alpha gives a smaller tree. The documentation attributes the method to Breiman et al., Classification and Regression Trees (1984), chapter 3.

path = clf.cost_complexity_pruning_path(X_train, y_train)
alphas = path.ccp_alphas      # candidate ccp_alpha values
impurities = path.impurities

Refit one tree per candidate ccp_alpha and choose the value by cross-validation on the training data, not on the test set.

Missing values and categorical features

Per the User Guide, DecisionTreeClassifier with splitter='best' supports missing values (NaN): at each candidate threshold it tries sending the missing samples all left or all right, and at prediction time a sample follows the direction learned in training; if no missing values were seen during training for a feature, they go to the child with the most samples. The documented example fits X = [nan, -1, nan, 1] (reshaped to one column) with y = [0, 0, 1, 1] and max_depth=1, and predict([[nan]]) returns array([1]).

Categorical features are the opposite case: the implementation does not support them directly, so encode them as numbers before fitting.

Troubleshooting

  • Training accuracy is near perfect but test accuracy is low. The tree is overgrown. Set max_depth, raise min_samples_leaf, or use ccp_alpha.
  • The tree changes between runs. Features are permuted at random at each split. Set random_state to an integer.
  • An error when fitting columns of text labels. Categorical strings are not supported; encode them numerically first.
  • Rare classes are never predicted. Trees favour dominant classes. Balance the data, pass sample weights, or set class_weight='balanced'.
  • Poor results with many features and few samples. The User Guide notes this ratio overfits; consider dimensionality reduction (PCA, ICA) or feature selection first.
  • Scripts copied from older tutorials fail on imports. Use the import paths shown on the current official pages (from sklearn.tree import ...).
  • Trees cannot learn some concepts compactly. The User Guide lists XOR, parity and multiplexer problems as hard for trees.

Reporting checklist for a methods section

  • scikit-learn and Python versions.
  • Every non-default parameter, plus random_state.
  • How categorical variables were encoded and how missing values were handled.
  • How the split or cross-validation folds were made, and the metric used.
  • Tree size from get_depth() and get_n_leaves(), and the pruning value if used.

Free alternatives

Option What it is See
DecisionTreeRegressor (scikit-learn) The same tree algorithm for a continuous outcome. User Guide: Decision Trees
Random forests in R An ensemble of many trees, in R rather than Python. Random forests in R
XGBoost Gradient-boosted trees. What is XGBoost
Logistic regression (scikit-learn) A linear classifier when a readable coefficient table suits the question better than rules. scikit-learn logistic regression

FAQ

How do I use a decision tree in sklearn?

Import DecisionTreeClassifier from sklearn.tree, create it with a random_state, call fit(X_train, y_train) on numeric data, then predict or score on held-out data.

What is the difference between DecisionTreeClassifier and DecisionTreeRegressor?

The classifier predicts class labels; the regressor predicts a continuous value. Both are in sklearn.tree.

Does sklearn’s decision tree handle categorical variables?

No, not natively. Encode categories numerically before fitting.

Does it handle missing values?

Yes, DecisionTreeClassifier with splitter='best' supports NaN, as described above.

How do I stop a decision tree overfitting?

Limit max_depth, raise min_samples_leaf, or prune with ccp_alpha, and check the choice by cross-validation.

Which criterion should I use?

The class accepts 'gini' (default), 'entropy' and 'log_loss'; treat the choice as a tunable setting and compare by cross-validation.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about scikit-learn Decision Tree: DecisionTreeClassifier Step by Step

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →