Train both models on the same dataset, compare metrics (Accuracy/F1), inspect overfitting, and review feature importance.
Use a tabular, multi-class dataset like Iris or Breast Cancer (binary). Below uses Iris.
# Imports
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score, classification_report
import numpy as np
# Data & split (same split for both)
X, y = load_iris(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# Models
dt = DecisionTreeClassifier(max_depth=None, random_state=42)
rf = RandomForestClassifier(n_estimators=200, max_depth=None, random_state=42, n_jobs=-1)
# Fit
dt.fit(X_tr, y_tr)
rf.fit(X_tr, y_tr)
# Train & Test metrics
def metrics(name, model):
yhat_tr = model.predict(X_tr)
yhat_te = model.predict(X_te)
print(f"== {name} ==")
print("Train Acc:", round(accuracy_score(y_tr, yhat_tr), 3),
" Test Acc:", round(accuracy_score(y_te, yhat_te), 3))
print("Train F1:", round(f1_score(y_tr, yhat_tr, average='macro'), 3),
" Test F1:", round(f1_score(y_te, yhat_te, average='macro'), 3))
print()
metrics("Decision Tree", dt)
metrics("Random Forest", rf)
# Feature importance (Random Forest)
importances = rf.feature_importances_
rank = np.argsort(importances)[::-1]
print("Feature importance (RF):")
for i in rank:
print(f" x{i} -> {importances[i]:.3f}")
# Optional: classification report
print("\\nRandom Forest report:")
print(classification_report(y_te, rf.predict(X_te)))
Interpretation: If the Decision Tree shows very high train score but lower test score relative to Random Forest, that’s a sign of overfitting. RF usually generalizes better.
max_depth – limit depth to reduce variancemin_samples_leaf – smooth leaf predictionscriterion – gini vs entropyn_estimators – more trees → stabler scoresmax_depth, min_samples_leaf – control overfittingmax_features – randomness per split (e.g., sqrt)oob_score=True – quick internal validationmax_depth for DT and n_estimators/max_features for RF.