CART (Classification and Regression Trees) › Formula - Classification

Michael BrenndoerferJune 27, 202512 min read
Machine Learning from ScratchAll chapters
Part 5 of 9Tree-Based Models
Chapter 41CART (Classification and Regression Trees) › Formula - Classification
Reading section 2 of 9 · Formula - Classification · 12 minSection 2 of 9 · 12 min

Book contents

Section 2 of 9 · 12 min read

CART (Classification and Regression Trees) › Formula - ClassificationOne section · Sections in this chapter2 / 9 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

The mathematical foundation of CART revolves around finding the optimal split that minimizes impurity for classification or variance for regression. Let's walk through these concepts step by step.

Gini Impurity

For classification problems, CART uses the Gini impurity measure to evaluate the quality of a split. The Gini impurity measures how often a randomly chosen element would be incorrectly labeled if it were randomly labeled according to the distribution of labels in the subset.

We start with the basic Gini impurity formula for a node:

Gini(S)=1−∑i=1cpi2Gini(S) = 1 - \sum_{i=1}^{c} p_i^2

where:

  • Gini(S)Gini(S) is the Gini impurity for node SS (a measure of impurity ranging from 0 for pure nodes to a maximum value when classes are evenly distributed)
  • SS represents the set of samples at the current node (the subset of training data that reaches this node)
  • cc is the number of classes (total number of distinct class labels in the classification problem)
  • pip_i is the proportion of samples belonging to class ii in the set SS (calculated as pi=ni∣S∣p_i = \frac{n_i}{|S|} where nin_i is the number of samples of class ii and ∣S∣|S| is the total number of samples in node SS)
  • ii is the class index (ranging from 1 to cc)

The reason we square the probabilities is to penalize nodes where the class distribution is mixed. When all samples belong to the same class (complete purity), pi=1p_i = 1 for one class and pi=0p_i = 0 for all others, making Gini(S)=1−12=0Gini(S) = 1 - 1^2 = 0. When classes are evenly distributed, the Gini impurity reaches its maximum.

To find the best split, we calculate the weighted average of the Gini impurities of the resulting child nodes:

Ginisplit(S)=∣SL∣∣S∣⋅Gini(SL)+∣SR∣∣S∣⋅Gini(SR)Gini_{split}(S) = \frac{|S_L|}{|S|} \cdot Gini(S_L) + \frac{|S_R|}{|S|} \cdot Gini(S_R)

where:

  • Ginisplit(S)Gini_{split}(S) is the weighted Gini impurity after splitting node SS (the combined impurity of both child nodes, weighted by their sizes)
  • SLS_L is the left child node after the split (the subset of samples that satisfy the split condition)
  • SRS_R is the right child node after the split (the subset of samples that do not satisfy the split condition)
  • ∣S∣|S| is the number of samples in the parent node SS (total samples before splitting)
  • ∣SL∣|S_L| is the number of samples in the left child node (samples satisfying the split condition)
  • ∣SR∣|S_R| is the number of samples in the right child node (samples not satisfying the split condition, where ∣SL∣+∣SR∣=∣S∣|S_L| + |S_R| = |S|)
  • ∣SL∣∣S∣\frac{|S_L|}{|S|} and ∣SR∣∣S∣\frac{|S_R|}{|S|} are the weights (proportions of samples going to each child node, so larger child nodes have more influence on the overall impurity measure)

The algorithm selects the split that minimizes this weighted Gini impurity. This makes intuitive sense: we want splits that create child nodes with as pure class distributions as possible.

Out[2]:
Visualization
Quadratic curve showing Gini impurity reaching maximum value of 0.5 when classes are equally balanced and minimum value of 0 as nodes become pure with one dominant class.
Gini Impurity as a Function of Class Probability: This plot shows how Gini impurity varies with the probability of one class in a binary classification problem. When p=0 or p=1 (pure nodes with all samples belonging to one class), the Gini impurity is 0. The maximum impurity of 0.5 occurs when classes are perfectly balanced (p=0.5). The curve demonstrates why the Gini measure penalizes mixed nodes and rewards pure splits.

Regression: Mean Squared Error

For regression problems, CART minimizes the variance (or equivalently, the mean squared error) of the target variable within each leaf node. The variance for a node is calculated as:

Var(S)=1∣S∣∑i∈S(yi−yˉ)2Var(S) = \frac{1}{|S|} \sum_{i \in S} (y_i - \bar{y})^2

where:

  • Var(S)Var(S) is the variance of the target variable in node SS (a measure of how spread out the target values are around their mean)
  • ∣S∣|S| is the number of samples in node SS (total count of data points in this node)
  • yiy_i is the target value for sample ii (the actual observed response value for the ii-th sample in node SS)
  • yˉ\bar{y} is the mean target value in the node (the average of all target values in node SS)
  • i∈Si \in S indicates summation over all samples in node SS

The mean target value yˉ\bar{y} is calculated as:

yˉ=1∣S∣∑i∈Syi\bar{y} = \frac{1}{|S|} \sum_{i \in S} y_i

where:

  • yˉ\bar{y} is the mean target value (the arithmetic average of all target values in node SS, which becomes the prediction for this node)
  • 1∣S∣\frac{1}{|S|} is the normalization factor (ensures we compute the average rather than the sum)
  • ∑i∈Syi\sum_{i \in S} y_i is the sum of all target values in node SS

The mean squared error is essentially the same as variance, just without the division by ∣S∣|S|:

MSE(S)=∑i∈S(yi−yˉ)2MSE(S) = \sum_{i \in S} (y_i - \bar{y})^2

where:

  • MSE(S)MSE(S) is the mean squared error for node SS (the sum of squared deviations from the mean, used as an alternative to variance)
  • (yi−yˉ)2(y_i - \bar{y})^2 is the squared deviation of sample ii from the mean (measures how far each sample's target value is from the node's average)

For a split, we calculate the weighted sum of the MSEs of the child nodes:

MSEsplit(S)=MSE(SL)+MSE(SR)MSE_{split}(S) = MSE(S_L) + MSE(S_R)

where:

  • MSEsplit(S)MSE_{split}(S) is the total mean squared error after splitting node SS (the sum of MSEs from both child nodes)
  • MSE(SL)MSE(S_L) is the mean squared error of the left child node (calculated as ∑i∈SL(yi−yˉL)2\sum_{i \in S_L} (y_i - \bar{y}_L)^2)
  • MSE(SR)MSE(S_R) is the mean squared error of the right child node (calculated as ∑i∈SR(yi−yˉR)2\sum_{i \in S_R} (y_i - \bar{y}_R)^2)

This is equivalent to the weighted variance approach used in classification, but since we're dealing with continuous values, we use the sum of squared deviations from the mean.

Split Selection Process

The algorithm evaluates all possible splits for each feature and selects the one that provides the maximum reduction in impurity or variance. For a continuous feature with values x1,x2,...,xnx_1, x_2, ..., x_n, we consider splits of the form x≤tx \leq t for all possible thresholds tt. For categorical features, we consider all possible subsets of categories.

The information gain (or variance reduction) for a split is:

Gain=Impurityparent−ImpuritysplitGain = Impurity_{parent} - Impurity_{split}

where:

  • GainGain is the information gain (the reduction in impurity achieved by the split, with higher values indicating better splits)
  • ImpurityparentImpurity_{parent} is the impurity of the parent node before splitting (either Gini impurity for classification or variance for regression)
  • ImpuritysplitImpurity_{split} is the weighted impurity after splitting (the combined impurity of both child nodes)

For classification, this becomes:

Gain=Gini(S)−Ginisplit(S)Gain = Gini(S) - Gini_{split}(S)

where:

  • Gini(S)Gini(S) is the Gini impurity of the parent node SS before splitting
  • Ginisplit(S)Gini_{split}(S) is the weighted Gini impurity after splitting (calculated as ∣SL∣∣S∣⋅Gini(SL)+∣SR∣∣S∣⋅Gini(SR)\frac{|S_L|}{|S|} \cdot Gini(S_L) + \frac{|S_R|}{|S|} \cdot Gini(S_R))

For regression, this becomes:

Gain=Var(S)−∣SL∣∣S∣⋅Var(SL)−∣SR∣∣S∣⋅Var(SR)Gain = Var(S) - \frac{|S_L|}{|S|} \cdot Var(S_L) - \frac{|S_R|}{|S|} \cdot Var(S_R)

where:

  • Var(S)Var(S) is the variance of the parent node SS before splitting
  • ∣SL∣∣S∣⋅Var(SL)\frac{|S_L|}{|S|} \cdot Var(S_L) is the weighted variance of the left child node
  • ∣SR∣∣S∣⋅Var(SR)\frac{|S_R|}{|S|} \cdot Var(S_R) is the weighted variance of the right child node

The algorithm selects the split with the maximum gain.

Out[3]:
Visualization
Combined scatter plot and bar chart showing data points colored by class with vertical lines marking split thresholds and corresponding information gain values.
Split Selection Process: This visualization demonstrates how CART evaluates different split points on a feature to find the optimal split. The scatter plot shows data points colored by class, with vertical dashed lines representing candidate split thresholds. The bar chart below shows the information gain for each candidate split, with the optimal split (maximum gain) highlighted in teal. This illustrates the greedy search process that CART uses to select the best split at each node.

Mathematical Properties

The Gini impurity and variance measures are monotonically decreasing as we make better splits. This property ensures that the algorithm chooses splits that improve the overall model quality.

The impurity functions are convex, meaning that the weighted average of impurities from child nodes is less than or equal to the parent node's impurity. This ensures that splitting does not increase the overall impurity.

For each feature, the algorithm must evaluate all possible split points. For continuous features with nn unique values, this requires O(n)O(n) evaluations. For categorical features with kk categories, it requires evaluating 2k−1−12^{k-1} - 1 possible splits, making it computationally expensive for high-cardinality categorical features.

where:

  • nn is the number of unique values for a continuous feature (the distinct values that could serve as split thresholds)
  • O(n)O(n) represents linear computational complexity (evaluating each unique value as a potential split point)
  • kk is the number of categories for a categorical feature (the distinct category labels)
  • 2k−1−12^{k-1} - 1 is the number of possible binary partitions of kk categories (exponential growth with the number of categories)
Computational Complexity

The computational complexity of CART grows significantly with the number of features and their cardinality. For a dataset with pp features and nn samples, the worst-case time complexity is O(p⋅nlog⁡n)O(p \cdot n \log n) for continuous features, but can be much higher for categorical features with many categories.

where:

  • pp is the number of features (predictor variables in the dataset)
  • nn is the number of samples (data points in the training set)
  • O(p⋅nlog⁡n)O(p \cdot n \log n) represents the computational complexity (the algorithm must evaluate pp features, and for each feature with nn samples, sorting takes O(nlog⁡n)O(n \log n) time)

This is why preprocessing steps like feature selection or categorical encoding are often necessary for large-scale applications.