ML Notes
Master decision tree classification with entropy, information gain, Gini impurity, pruning techniques, and complete sklearn implementation guide.
If you have ever played the game "20 Questions" — where you narrow down possibilities by asking yes/no questions — you already understand the intuition behind decision trees. A decision tree classifier works by asking a series of questions about the input features, with each question splitting the data into smaller, more homogeneous groups until it reaches a prediction. Among all machine learning algorithms, decision trees are arguably the most human-readable and interpretable, making them a favorite in industries where you need to explain why a model made a certain prediction.
The Intuition: Thinking Like a Doctor
Imagine a doctor diagnosing whether a patient has the flu. The doctor does not run every possible test simultaneously. Instead, they ask sequential questions: "Do you have a fever?" If yes, "Is it above 101°F?" If yes, "Do you have body aches?" Each answer narrows down the diagnosis. A decision tree does exactly this — it learns which questions to ask and in what order by analyzing training data.
The beauty of this approach is that the resulting model is a flowchart that anyone can follow. No linear algebra, no probability theory needed to understand the prediction — just follow the branches from root to leaf.
How Decision Trees Split Data
The core challenge in building a decision tree is deciding which feature to split on at each node. The algorithm needs a way to measure which split creates the most "pure" child nodes — groups where most data points belong to the same class.
Entropy and Information Gain
Entropy measures the disorder or impurity in a group. A group with all same-class examples has zero entropy (perfectly pure). A group with 50-50 split has maximum entropy (maximum uncertainty).
The mathematical formula for entropy is:
| All spam | H = -1×log₂(1) = 0 (pure) |
| 50/50 split | H = -0.5×log₂(0.5) - 0.5×log₂(0.5) = 1.0 (maximum impurity) |
| 90/10 split | H = -0.9×log₂(0.9) - 0.1×log₂(0.1) = 0.47 (mostly pure) |
Information Gain measures how much entropy decreases after splitting on a particular feature. The feature with the highest information gain is chosen for the split:
The intuition behind this is simple: we want each split to reduce uncertainty as much as possible. If splitting on "age > 50" separates your data into one group that is 95 percent positive and another that is 90 percent negative, that is an excellent split because both children are nearly pure.
Gini Impurity — The Practical Alternative
While entropy uses logarithms, Gini impurity achieves similar results with simpler computation:
| All one class | Gini = 1 - 1² = 0 (pure) |
| 50/50 split | Gini = 1 - 0.5² - 0.5² = 0.5 (maximum impurity) |
| 90/10 split | Gini = 1 - 0.9² - 0.1² = 0.18 (mostly pure) |
Scikit-learn uses Gini by default because it is computationally cheaper and produces similar trees to entropy in practice. The key insight is that both metrics agree on what constitutes a good split — they just measure purity slightly differently.
The CART Algorithm: Building Trees Step by Step
The Classification and Regression Trees (CART) algorithm builds decision trees using a greedy, top-down approach:
- Start with all training data at the root node
- For each feature, find the best split threshold (the value that maximizes information gain or minimizes Gini impurity)
- Select the feature and threshold that produces the best split overall
- Create two child nodes — one for data points satisfying the condition, one for the rest
- Recursively repeat for each child until a stopping criterion is met
- Assign the majority class of training examples at each leaf as the prediction
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
# Load the Iris dataset (classic multi-class problem)
iris = load_iris()
X, y = iris.data, iris.target
feature_names = iris.feature_names
class_names = iris.target_names
# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Train a decision tree
tree_clf = DecisionTreeClassifier(
criterion='gini', # or 'entropy'
max_depth=4, # limit tree depth to prevent overfitting
min_samples_split=5, # minimum samples needed to split a node
min_samples_leaf=2, # minimum samples in a leaf node
random_state=42
)
tree_clf.fit(X_train, y_train)
# Evaluate
y_pred = tree_clf.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(classification_report(y_test, y_pred, target_names=class_names))
# Print the tree structure — this is the beauty of decision trees!
print("\nDecision Tree Rules:")
print(export_text(tree_clf, feature_names=feature_names, class_names=list(class_names)))The Overfitting Problem and Pruning
Here is the critical weakness of decision trees: without constraints, they will keep splitting until every leaf contains a single training example, perfectly memorizing the training data but failing miserably on new data. This is severe overfitting.
Pre-Pruning (Limiting Growth)
Stop the tree from growing too deep in the first place:
max_depth: Maximum number of levels from root to leafmin_samples_split: Minimum examples needed before a node can splitmin_samples_leaf: Minimum examples required in each leafmax_features: Only consider a random subset of features at each split
Post-Pruning (Cost-Complexity Pruning)
Grow the full tree first, then trim branches that do not improve validation performance. Scikit-learn implements this via the ccp_alpha parameter — higher alpha means more aggressive pruning.
Advantages and Limitations
Strengths: Decision trees require no feature scaling, handle both numerical and categorical data naturally, provide built-in feature importance rankings, produce interpretable models that non-technical stakeholders can understand, and serve as building blocks for powerful ensemble methods like Random Forest and Gradient Boosting.
Weaknesses: Single decision trees are prone to overfitting, unstable (small data changes can produce very different trees), biased toward features with many levels, and typically less accurate than ensemble methods. They create axis-aligned splits only, struggling with diagonal decision boundaries.
Real-World Applications
Decision trees shine in scenarios requiring interpretability: credit approval decisions (banks must explain why), medical triage protocols, fraud detection rule systems, and customer segmentation. They are also the foundation of Random Forest and Gradient Boosting — the most successful algorithms in structured data competitions.
Key Takeaways
Decision trees learn by asking optimal yes/no questions that maximize information gain at each split. They are wonderfully interpretable but prone to overfitting without proper pruning. Use max_depth, min_samples_leaf, and cross-validated ccp_alpha to control complexity. While a single tree rarely wins competitions, understanding trees deeply is essential because ensemble methods (Random Forest, XGBoost) are simply collections of decision trees working together. Master the single tree, and you have the foundation for the most powerful algorithms in tabular data machine learning.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Decision Trees.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Machine Learning topic.
Search Terms
machine-learning, machine learning, machine, learning, classification, decision, trees, decision trees
Related Machine Learning Topics