Decision Tree — Gini ও Entropy
এই পাঠে যা শিখবেন
- Decision Tree-এর কাঠামো — root, internal node, leaf
- Gini impurity ও Entropy — দু'টি impurity পরিমাপ ও তাদের পার্থক্য
- Information Gain — best split বাছার objective function
- Greedy recursive partitioning — কীভাবে গাছ বানানো হয়
- NumPy থেকে scratch একটি tree — sklearn-এর সাথে তুলনা
১ · মানুষ যেভাবে সিদ্ধান্ত নেয়
একজন ব্যাংকার ঋণ দেবে কি না — চিন্তা করেন: "আয় কত? ৫০,০০০-এর বেশি? আগে ঋণ ছিল? পরিশোধ করেছিল?" — একটি প্রশ্নের উত্তর পরবর্তী প্রশ্ন ঠিক করে দেয়। শেষে একটি সিদ্ধান্ত। Decision TreeDecision Treeএকটি tree-structured মডেল — internal node-এ feature test, leaf-এ prediction। recursive binary splitting দিয়ে তৈরি। Interpretable, কিন্তু একা ব্যবহারে overfitting prone। ঠিক এই কাজই করে — কিন্তু প্রতিটি প্রশ্ন ও সীমা ডেটা থেকে শেখে।
১) Root node: সবচেয়ে উপরে — সব ডেটা শুরু এখান থেকে।
২) Internal node: একটি feature-এ একটি condition (যেমন income > 50000)।
৩) Branch: condition-এর true/false উত্তর — পরবর্তী node-এ যায়।
৪) Leaf: চূড়ান্ত prediction (class label বা মান)।
২ · মূল প্রশ্ন — কোন split ভালো?
একটি node-এ ১০০টি sample — ৫০ "approve", ৫০ "reject"। দু'টি possible split:
- Split A:
income > 50000→ বাম [৪৫ approve, ৫ reject], ডান [৫ approve, ৪৫ reject]। - Split B:
age > 30→ বাম [২৫ approve, ২৫ reject], ডান [২৫ approve, ২৫ reject]।
A স্পষ্টতই ভালো — দু'পাশ প্রায় pure। B-তে কিছুই বদলায়নি। আমাদের চাই একটি গাণিতিক পরিমাপ — node "কত মিশ্র" তা বলবে। সেটাই impurityImpurityএকটি node-এ class labels কত মিশ্র — পরিমাপ। ০ মানে সব sample একই class (pure)। সর্বোচ্চ মানে সমান অনুপাত (most mixed)।।
৩ · Gini Impurity
Gini impurityGini Impurityএকটি random sample-কে random class label assign করলে ভুল হওয়ার probability। CART-এর default split criterion। — যদি আমরা random একটি sample বেছে random class label দিই, কত বার ভুল হবে তার probability:
$$G = 1 - \sum_{k=1}^{K} p_k^2$$
$p_k$ — class $k$-এর অনুপাত। উদাহরণ: ৫০-৫০ binary → $G = 1 - (0.5^2 + 0.5^2) = 0.5$। ১০০% pure → $G = 1 - 1 = 0$।
Range: binary-এ $0 \le G \le 0.5$। $K$-class-এ সর্বোচ্চ $1 - 1/K$।
৪ · Entropy ও Information Gain
Information theory থেকে এসেছে — Shannon (১৯৪৮)। EntropyEntropyএকটি distribution-এ গড়ে কত bits তথ্য দরকার একটি sample-এর label বলতে। ID3 ও C4.5 algorithm-এর splitting criterion। Gini-র চেয়ে computationally costly (log)। পরিমাপ করে — গড়ে কত bits দরকার একটি sample-এর label specify করতে:
$$H = - \sum_{k=1}^{K} p_k \log_2 p_k$$
৫০-৫০ → $H = 1$ (১ bit)। ১০০% pure → $H = 0$। কনভেনশন: $0 \log_2 0 = 0$।
Information Gain: split-এর আগে ও পরে impurity-র পার্থক্য:
$$\text{IG}(D, s) = H(D) - \sum_{c \in \text{children}} \frac{|D_c|}{|D|} H(D_c)$$
Greedy algorithm — সব feature-এ সব possible split দেখে — সর্বোচ্চ IG-র split বাছে।
৫ · Gini vs Entropy — পার্থক্য কি?
প্রায়ই দু'টি একই tree বানায়। ছোট পার্থক্য:
- Gini — দ্রুত (no log)। CART-এর default।
- Entropy — তত্ত্বে আরও interpretable (information theory)। ID3, C4.5-এর default।
- Gini "majority class" preserve করতে inclined; Entropy "balanced split"-এ সামান্য বেশি গুরুত্ব।
- প্রায়শই accuracy-তে <১% পার্থক্য — practical purposes-এ interchangeable।
criterion='gini' বা 'entropy' বদলালে validation score significant বদলায় — সম্ভবত কোনো deeper সমস্যা (ছোট data, label noise, leak)। আগে সেগুলো check করুন।
৬ · Recursive Partitioning — পুরো algorithm
- Root-এ পুরো training data রাখুন।
- সব feature ও সব candidate threshold check করুন — সর্বোচ্চ IG (বা সর্বনিম্ন Gini)-র split বাছুন।
- ডেটা দু'টি child-এ ভাগ করুন।
- প্রতিটি child-এ ১-৩ পুনরাবৃত্তি — যতক্ষণ stopping criterion না আসে।
- Leaf-এ পৌঁছালে — সেই subset-এর majority class (বা mean) prediction।
Stopping criteria:
- Node pure (impurity = 0)।
- Sample count threshold-এর নিচে (
min_samples_split)। - Tree depth সর্বোচ্চ-এ পৌঁছেছে (
max_depth)। - আর কোনো split impurity কমাচ্ছে না।
৭ · NumPy দিয়ে — scratch থেকে
সাধারণ binary classification tree — Gini criterion-এ। বুঝতে সরল রাখা।
import numpy as np
def gini(y):
if len(y) == 0:
return 0
p = np.bincount(y) / len(y)
return 1 - np.sum(p**2)
def best_split(X, y):
n, d = X.shape
best_gain, best_feat, best_thr = 0, None, None
parent_g = gini(y)
for f in range(d):
thresholds = np.unique(X[:, f])
for t in thresholds:
left = y[X[:, f] <= t]
right = y[X[:, f] > t]
if len(left) == 0 or len(right) == 0:
continue
g = (len(left)*gini(left) + len(right)*gini(right)) / n
gain = parent_g - g
if gain > best_gain:
best_gain, best_feat, best_thr = gain, f, t
return best_feat, best_thr, best_gain
class Node:
def __init__(self, pred=None, feat=None, thr=None, left=None, right=None):
self.pred, self.feat, self.thr, self.left, self.right = pred, feat, thr, left, right
def build_tree(X, y, depth=0, max_depth=4, min_samples=5):
# leaf condition
if depth >= max_depth or len(y) < min_samples or len(np.unique(y)) == 1:
return Node(pred=np.bincount(y).argmax())
feat, thr, gain = best_split(X, y)
if feat is None or gain == 0:
return Node(pred=np.bincount(y).argmax())
mask = X[:, feat] <= thr
left = build_tree(X[mask], y[mask], depth+1, max_depth, min_samples)
right = build_tree(X[~mask], y[~mask], depth+1, max_depth, min_samples)
return Node(feat=feat, thr=thr, left=left, right=right)
def predict_one(node, x):
if node.pred is not None:
return node.pred
return predict_one(node.left if x[node.feat] <= node.thr else node.right, x)
# Test on simple 2D data
np.random.seed(0)
X = np.vstack([np.random.randn(50, 2),
np.random.randn(50, 2) + np.array([3, 3])])
y = np.array([0]*50 + [1]*50)
tree = build_tree(X, y, max_depth=3)
preds = np.array([predict_one(tree, x) for x in X])
print(f"Train accuracy: {np.mean(preds == y):.4f}")
৮ · sklearn দিয়ে — production version
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.model_selection import cross_val_score
X, y = load_iris(return_X_y=True)
clf = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=0)
clf.fit(X, y)
print("CV accuracy:", cross_val_score(clf, X, y, cv=5).mean())
print(export_text(clf, feature_names=['sl', 'sw', 'pl', 'pw']))
export_text পুরো গাছকে human-readable rule হিসেবে দেখায় — Decision Tree-এর সবচেয়ে বড় শক্তি interpretability।
৯ · কোথায় Decision Tree fail
- Overfitting: পূর্ণ-গভীর tree training-এ ১০০% accurate, test-এ দুর্বল। সমাধান — pruning, max_depth, min_samples_leaf।
- Instability: ছোট data variation — সম্পূর্ণ ভিন্ন tree। Random Forest এর সমাধান।
- Axis-aligned splits: $x_1 + x_2 > 0$-এর মতো diagonal boundary multiple split-এ approximate।
- Continuous targets-এ blocky: Regression tree step-function বানায় — smooth নয়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ Gini ও Entropy দু'টিই impurity পরিমাপ করে — গাণিতিকভাবে এত মিলে কেন? কখন একটি অন্যটির চেয়ে স্পষ্টভাবে ভিন্ন গাছ বানাবে?
Decision tree-র classic intriguing প্রশ্ন। দু'টি function-ই concave, $p = 0.5$-এ maximum, $p = 0$ বা $1$-এ minimum। তাই behavior একই ধরনের।
গাণিতিক সম্পর্ক:
- Binary case-এ Taylor expansion করলে — $H(p) \approx 2 G(p) + O(p^3)$।
- Entropy ≈ ২ × Gini (small region-এ)।
- Scaling factor — split ranking পরিবর্তন প্রায়ই করে না।
ছোট পার্থক্য — কোথায় matter:
(১) Class imbalance প্রতি sensitivity:
- Entropy logarithmic — extreme imbalance-এ probabilities-এ বেশি বদলায়।
- ৯৯-১ split-এ Entropy = 0.08, Gini = 0.02 — relative ratio একই, absolute ভিন্ন।
- Gain calculation-এ subtle ranking পার্থক্য আসতে পারে।
(২) Multi-class behavior:
- ৩-class এ Gini max = ০.৬৭, Entropy max = log₂3 ≈ ১.৫৮।
- Multi-way split-এ Entropy বেশি "balanced" partition prefer।
- Gini "isolate dominant class" tendency।
(৩) Computational:
- Gini শুধু multiplication — দ্রুত।
- Entropy log call — কিছুটা ধীর (modern hardware-এ negligible)।
- CART (sklearn) Gini default — performance reason।
Empirical observation:
- Raileanu & Stoffel (২০০৪) systematic study — শুধু ২% case-এ noticeable difference।
- প্রায় সবসময় final accuracy-তে ০.৫% এর মধ্যে।
- সিদ্ধান্ত — criterion বদলে hyperparameter tune করা better।
কখন একটি বাছবেন:
- Gini: default — দ্রুত, robust।
- Entropy: information-theoretic interpretation দরকার (yardstick communication)।
- Misclassification error: $1 - \max p_k$ — split করতে insensitive (প্রায়ই ০ gain), তাই ব্যবহৃত হয় না।
মূল উপলব্ধি: "Right criterion" ঐশ্বরিক প্রশ্ন না — practical impact tiny। বরং tree depth, min_samples — এই hyperparameter অনেক বেশি determinant। ML pragmatism: যেখানে significant signal আছে সেখানে tune করুন।
প্র ০২ Decision tree axis-aligned split দেয়। কিন্তু decision boundary প্রায়ই diagonal/curved। Tree তাহলে কীভাবে কাজ করে — ও কখন এই limitation severe হয়?
Decision tree-র fundamental geometric limitation। তবু production-এ tree-based ensemble dominate — কেন এই paradox?
Axis-aligned split-এর geometry:
- প্রতিটি split — একটি hyperplane (যা একটি axis-এর perpendicular)।
- Multiple split — staircase boundary।
- $x_1 + x_2 > 0$ — single line, কিন্তু tree অনেক ছোট block দিয়ে approximate।
কেন তবু কাজ করে:
(১) Universal approximator:
- Sufficient depth-এ যেকোনো boundary approximate।
- Step function — যেকোনো continuous function approximate (ε-precision-এ)।
- Theoretical guarantee — practical concern নয়।
(২) Real data মানিয়ে নেয়:
- Most ML problem-এ feature interactions hierarchical।
- "Income high AND credit history good" — exactly tree-এর strength।
- Rare features-এ tree অসাধারণ।
(৩) Ensemble averaging:
- Random Forest — many trees averaged।
- Each tree axis-aligned, কিন্তু average smooth।
- Diagonal boundary effectively recovered।
কখন severe limitation:
- Strong linear relationship: spiral data, perfect line — tree hundreds of splits ব্যবহার করে।
- High-dimensional rotation invariance দরকার: image rotation (raw pixels)।
- Smooth gradient prediction: physics/engineering interpolation।
সমাধান:
- Oblique trees: linear combinations of features — academic, rare প্রায়শই।
- Feature engineering: $x_1 + x_2$, $x_1 / x_2$ — pre-compute করে দিন।
- Linear baseline + tree residual: hybrid model।
- Neural net + tree ensemble: production-এ powerful।
Real-world examples:
- Credit scoring: tree-friendly (income, age, history — discrete thresholds matter)।
- Image classification: tree weak, NN dominant (raw pixels)।
- Tabular data: tree ensembles (XGBoost) অনেক benchmark-এ NN-এর সমান বা বেশি।
- Time series: recent works (LightGBM, NeuralProphet) — both compete।
Geometric intuition:
- Tree — piecewise constant function।
- Linear model — single hyperplane।
- Neural net — composition of nonlinearities।
- Choose by data structure।
মূল উপলব্ধি: "Axis-aligned" শুনতে বড় limitation — practice-এ ensemble + sufficient trees এই issue overcome করে। Tree-based methods Kaggle dominate কারণ tabular data-এ feature interaction hierarchical — exactly যা tree natural। Right tool for right data।
প্র ০৩
একটি tree-কে যত গভীর করা যায়, training accuracy তত বাড়ে। তবু আমরা max_depth বা pruning ব্যবহার করি। Bias-variance lens-এ এই ট্রেডঅফ ব্যাখ্যা করুন।
Decision tree — bias-variance tradeoff-এর textbook example। "Just enough" complexity — ML-এর recurring theme।
Depth বাড়ালে কী হয়:
- Depth = 1 (stump): high bias (under-fit), low variance। Mostly majority class predict।
- Moderate depth (5-10): balanced — good bias, manageable variance।
- Unbounded depth: training-এ ১০০%, কিন্তু variance বিস্ফোরণ।
কেন variance বাড়ে:
- প্রতিটি split — কম sample-এ (depth-এর সাথে exponential drop)।
- Leaf-এ ৩-৫ sample → noise-এ sensitive।
- একটি sample বদলালে — split threshold বদলায় — পুরো sub-tree বদলায়।
- "Memorization" না learning।
Example:
- Iris dataset, ১৫০ samples, ৪ features।
- depth=2 — train 95%, test 92% (good fit)।
- depth=10 — train 100%, test 88% (overfit)।
- train accuracy "flatlined" — কিন্তু test degrade।
Pruning strategies:
(১) Pre-pruning (early stopping):
max_depth— global limit।min_samples_split— split-এর জন্য minimum sample।min_samples_leaf— leaf-এ minimum sample।min_impurity_decrease— minimum gain threshold।- Computationally cheap — early termination।
(২) Post-pruning (cost-complexity):
- Full tree বানিয়ে subtrees prune।
- $\alpha$ — complexity parameter (CART)।
- Cross-validation দিয়ে $\alpha$ tune।
- Better quality — costlier।
(৩) Sample-based:
min_samples_leaf=5— practical default।- Small leaves prevent।
- Robustness improve।
Bias-variance equation:
$$\text{Error} = \text{Bias}^2 + \text{Variance} + \text{Noise}$$
- Shallow tree — high bias term।
- Deep tree — high variance term।
- Optimal — minimize sum।
Validation curve dekhe:
- X-axis: max_depth।
- Y-axis: train + validation accuracy।
- Train monotonic up; validation U-shape।
- Validation peak — sweet spot।
Random Forest — different story:
- Deep tree forest-এ acceptable।
- Bagging variance kill করে।
- Default — fully grown trees।
- Single deep tree-এর problem ensemble-এ vanish।
Boosting — different story:
- Shallow tree (depth 3-6) preferred।
- Boosting bias kill করে — bias starting থেকে কম দরকার নেই।
- Variance — sequential nature controlled।
মূল উপলব্ধি: Single tree fragile। Hyperparameter tune-এ extensive validation। Production-এ — সবসময় ensemble (RF/XGBoost) prefer। Tree-এর শক্তি — interpretability ও speed; weakness — overfitting। ensemble দু'টিকেই handle।
প্র ০৪ আপনি একটি Bangladesh microfinance startup-এ ML lead। Decision Tree-এর interpretability-এর সুযোগ-অসুবিধা — regulator, customer, ও business-এর দৃষ্টিতে।
Tree-র interpretability — Bangladesh-এর regulated financial sector-এ critical। কিন্তু "interpretable" মানে "fair" নয়।
Interpretability-র সুবিধা:
(১) Regulator-এর দৃষ্টি:
- Bangladesh Bank — explainable model demand।
- "কেন এই ঋণ reject?" — clear answer ("income < ৩০,০০০ AND credit history poor")।
- Audit trail — প্রতিটি decision traceable।
- Compliance documentation সহজ।
- Black-box NN — regulatory headache।
(২) Customer-এর দৃষ্টি:
- Right to explanation (GDPR, similar laws coming)।
- "কী করলে approve হবে?" — actionable advice।
- Trust building — transparent process।
- Dispute resolution — clear ground।
(৩) Business-এর দৃষ্টি:
- Domain expert validate করতে পারে — "এই rule কি sensible?"।
- Bug catch — counterintuitive split → data issue উদঘাটন।
- Marketing — "approval criteria" customer-এ communicate।
- Onboarding new ML engineer — সহজ।
Interpretability-র অসুবিধা:
(১) "Interpretable" ≠ "Fair":
- Tree-তে দেখা যায় "district = Rangpur → reject" — explicit bias।
- Black-box-এ লুকানো thaakto — regulatory concern বরং বেশি।
- Visibility সমস্যা solve করে না — fix করার responsibility।
(২) Surface vs deep interpretability:
- "Income > 50K → approve" — surface।
- কিন্তু কেন এই threshold? Training data distribution?
- Demographic bias hidden।
- Feature engineering choice — invisible।
(৩) Accuracy tradeoff:
- Single tree — XGBoost-এর চেয়ে ৫-১০% accuracy কম।
- ৫% mistake — ৫,০০০ wrong loan decisions / ১,০০,০০০।
- Business cost vs explainability tradeoff।
- সমাধান — XGBoost + SHAP (explanation post-hoc)।
(৪) "Gaming" risk:
- Customer rule জানলে — game করতে পারে।
- "Income just above threshold" inflate করে।
- Fraud risk বাড়ে।
- Tree fully transparent করা — adversarial concern।
Bangladesh-specific considerations:
(১) Demographic features-এর handling:
- Religion (ঈদ purchasing pattern from)— direct use sensitive।
- Gender — Grameen Bank-এ historically primary; modern ML-এ careful।
- Geographic — district অনেক proxy hide করে।
(২) Data quality issue:
- Rural data sparse — small leaf statistic unreliable।
- Income unreported / under-reported — feature noisy।
- Tree noise-এ overfit — pruning critical।
(৩) Regulatory landscape:
- Microcredit Regulatory Authority (MRA)।
- Bangladesh Bank prudential rules।
- Personal Data Protection Bill (in pipeline)।
- Documentation prep অগ্রিম।
Recommended hybrid approach:
- Production model: XGBoost (accuracy)।
- Explanation: SHAP per-decision।
- Surrogate: single shallow tree as overall summary।
- Human override: edge case-এ analyst review।
- Audit: monthly fairness check।
মূল উপলব্ধি: Interpretability — necessary, sufficient নয়। Tree starting point — production-এ ensemble + explanation tools। Ethics — model architecture-এ নয়, deployment process-এ।
অনুশীলন
-
হিসাব করুন: একটি node-এ ৬০ "yes", ৪০ "no"। Gini ও Entropy কত?
- $p_{yes} = 0.6, p_{no} = 0.4$।
- Gini = $1 - (0.6^2 + 0.4^2) = 1 - 0.52 = 0.48$।
- Entropy = $-(0.6 \log_2 0.6 + 0.4 \log_2 0.4) \approx 0.971$।
-
Information Gain: উপরের node-এ একটি split — বাম [৫০ yes, ১০ no], ডান [১০ yes, ৩০ no]। IG (Gini-based) কত?
- Parent Gini = ০.৪৮।
- Left Gini = $1 - (50/60)^2 - (10/60)^2 = 1 - 0.694 - 0.028 = 0.278$।
- Right Gini = $1 - (10/40)^2 - (30/40)^2 = 1 - 0.0625 - 0.5625 = 0.375$।
- Weighted = $(60/100) \times 0.278 + (40/100) \times 0.375 = 0.167 + 0.150 = 0.317$।
- IG = $0.48 - 0.317 = 0.163$।
-
NumPy চ্যালেঞ্জ: উপরের
build_tree-এ entropy criterion যোগ করুন। Iris-এ দু'টির accuracy compare করুন।def entropy(y): if len(y) == 0: return 0 p = np.bincount(y) / len(y) p = p[p > 0] return -np.sum(p * np.log2(p)) # best_split-এ gini → entropy সরাসরি replace। # Iris-এ accuracy প্রায় একই (~০.৯৬)।
আরও পড়ুন
- পাঠ ২০ · CART অ্যালগরিদম পরবর্তী পাঠ Breiman-এর binary tree — pruning ও regression tree-এ extension।
- পাঠ ১৮ · Naive Bayes আগের পাঠ Bayesian classification — Decision Tree-এর alternative baseline।
- পাঠ ২১ · Random Forest এই পাঠের সাথে সম্পর্কিত অনেক tree-এর bagging — single tree-এর variance সমস্যার সমাধান।
- সব AI Courses ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps।