পাঠ ২২ · ৪৫-এর মধ্যে · মডিউল ৩
Home / AI Courses / Machine Learning / OOB Error

Out-of-Bag Error

OOB error — built-in validation for RF
৬ মিনিট পড়া মাঝারি · Intermediate NumPy + sklearn

এই পাঠে যা শিখবেন

  • Bootstrap sampling math — কেন ~৩৭% OOB
  • OOB prediction পদ্ধতি — কোন trees vote-এ অংশ নেয়
  • OOB vs cross-validation — কখন interchangeable, কখন না
  • OOB error দিয়ে hyperparameter tune
  • OOB-এর সীমাবদ্ধতা ও alternative

১ · Bootstrap-এর সাইড-এফেক্ট

$n$ samples থেকে with replacement $n$ draw — কিছু sample একাধিকবার আসবে, কিছু একবারও না।

একটি specific sample $i$ একবার draw-এ choose না হওয়ার probability $(1 - 1/n)$। $n$ draws-এ — none chose probability:

$$P(i \notin \text{bootstrap}) = \left(1 - \frac{1}{n}\right)^n \xrightarrow{n \to \infty} \frac{1}{e} \approx 0.368$$

অর্থাৎ প্রায় $0.368 n$ sample প্রতি bootstrap-এ "out" থাকে। এদের বলে Out-of-Bag samplesOut-of-Bag (OOB)একটি tree-এর bootstrap sample-এ যেসব sample নেই — সেই tree-এর জন্য effectively held-out। প্রায় ৩৭% data per tree, যা free validation দেয়।।

Free validation

$n = 1000$ → প্রায় ৩৭০ samples প্রতি bootstrap-এ নেই। সেই tree তাদের কখনো দেখেনি — তাদের prediction-এ tree biased নয়। অর্থাৎ — সেই tree-এর জন্য validation set।

২ · OOB prediction — কীভাবে

একটি sample $i$-এর OOB prediction:

  1. সব $B$ trees-এর মধ্যে — যেগুলোর bootstrap-এ $i$ নেই — সেই trees বাছুন (প্রায় ০.৩৭ $B$টি)।
  2. সেই trees-এ $i$ predict — vote (classification) বা average (regression)।
  3. এটাই $i$-এর OOB prediction।

OOB error: সব sample-এ OOB prediction ও true label-এর মধ্যে error rate।

প্রতিটি sample — সম্পূর্ণ ভিন্ন trees-এর সংমিশ্রণে predict — tiny "personal validation set"। সব মিলে — OOB error ≈ test error।

৩ · OOB কেন test error-এর কাছাকাছি

  • প্রতিটি OOB prediction — sample-কে train-এ দেখেনি এমন trees দিয়ে।
  • "Held-out"-এর মতো — কিন্তু explicitly held-out নয়, bootstrap থেকে naturally।
  • বহু $B$-এ — প্রতি sample প্রায় $0.37 B$ trees-এ unseen — robust prediction।
  • Big-data limit-এ — OOB error → true generalization error।
Theorem (asymptotic): $B \to \infty$ এবং $n$ বড়, OOB error converge করে — যেন একটি 0.632-train / 0.368-test split-এর সাথে। কিছু paper বলে "0.632 estimator" — Efron-Tibshirani-এর extensive study আছে।

৪ · OOB vs Cross-validation

দিক OOB 5-fold CV
Compute Free (training-এর সাথেই) ৫× retraining
Validation set size ৩৭% per tree (effective) ২০% per fold
Bias Slightly pessimistic (০.৬৩ data train) Slightly optimistic (০.৮ data train)
Variance কম (প্রতি sample সব data ব্যবহৃত) Moderate (folds variability)
Use case RF, bagging only Universal

Practical rule: RF-এ OOB sufficient; অন্য model (XGBoost, NN)-এ CV use করুন।

OOB — প্রতি sample প্রায় ৩৭% trees-এ unseen Samples s1 s2 s3 s4 s5 Bootstrap membership (in / out) Tree 1 in OOB in in OOB Tree 2 OOB in in OOB in Tree 3 in in OOB in OOB OOB Prediction — sample s2 s2 OOB-এ → Tree 1 s2 in-bag → Tree 2 (skip) s2 in-bag → Tree 3 (skip) → vote only on Tree 1 প্রকৃতপক্ষে — ৩৭% trees-এ vote average → robust estimate OOB error = average error over all OOB predictions ≈ test error, no extra split needed
প্রতি sample-এর জন্য — শুধু সেই trees-এ vote যেগুলো তাকে train-এ দেখেনি। সব samples-এ aggregate → OOB error।

৫ · NumPy দিয়ে — OOB calculation

Python · NumPy
import numpy as np
from sklearn.tree import DecisionTreeClassifier

class RFWithOOB:
    def __init__(self, n_trees=100, seed=0):
        self.n_trees = n_trees
        self.rng = np.random.RandomState(seed)

    def fit(self, X, y):
        n = len(X)
        self.trees, self.in_bag = [], []
        for _ in range(self.n_trees):
            idx = self.rng.choice(n, size=n, replace=True)
            in_bag = np.zeros(n, dtype=bool)
            in_bag[idx] = True
            t = DecisionTreeClassifier(max_features='sqrt',
                                       random_state=self.rng.randint(1e6))
            t.fit(X[idx], y[idx])
            self.trees.append(t)
            self.in_bag.append(in_bag)
        # OOB prediction
        n_classes = len(np.unique(y))
        votes = np.zeros((n, n_classes))
        counts = np.zeros(n)
        for t, in_bag in zip(self.trees, self.in_bag):
            oob = ~in_bag
            preds = t.predict(X[oob])
            for j, p in zip(np.where(oob)[0], preds):
                votes[j, p] += 1
                counts[j] += 1
        self.oob_pred = np.argmax(votes, axis=1)
        valid = counts > 0
        self.oob_score_ = (self.oob_pred[valid] == y[valid]).mean()
        return self

# Test
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)

rf = RFWithOOB(n_trees=200).fit(X, y)
print(f"OOB score: {rf.oob_score_:.4f}")

    
প্রতি sample-এর জন্য — শুধু সেই trees votes-এ অংশ নেয় যেগুলো এটাকে train-এ দেখেনি। ২০০ trees-এ — প্রতি sample প্রায় ৭৫টি trees vote করে। Robust।

৬ · sklearn — easy mode

Python · scikit-learn
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

rf = RandomForestClassifier(
    n_estimators=300,
    oob_score=True,
    n_jobs=-1,
    random_state=0
).fit(X, y)

print(f"OOB score:        {rf.oob_score_:.4f}")
print(f"OOB error:        {1 - rf.oob_score_:.4f}")

# Compare with held-out test
from sklearn.model_selection import train_test_split
Xt, Xv, yt, yv = train_test_split(X, y, test_size=0.3, random_state=0)
rf2 = RandomForestClassifier(n_estimators=300, n_jobs=-1, random_state=0).fit(Xt, yt)
print(f"Held-out test:    {rf2.score(Xv, yv):.4f}")

    
OOB ও held-out test প্রায়ই ১% এর মধ্যে। OOB-র সুবিধা — পুরো data train-এ ব্যবহৃত, আবার free validation-ও পাওয়া যায়।

৭ · OOB-এর সীমাবদ্ধতা

  • শুধু bagging-based mডেলে: RF, Extra Trees কাজ করে। Boosting (XGB, LightGBM)-এ নেই — কারণ trees independent না।
  • Small $n$-এ slightly biased: ০.৬৩২-fraction effect — Efron-Tibshirani correction (০.৬৩২+ estimator)।
  • $B$ ছোট হলে variance: $B = 50$-এ — কিছু sample হয়তো শুধু ৫টি trees-এ OOB, vote noisy।
  • Stratification নেই: CV-তে stratified split — class imbalance-এ better; OOB random।
  • Time series-এ inappropriate: bootstrap temporal order ভাঙে। walk-forward CV needed।
Production-এ — OOB শুধু "first read"। Critical decision-এর আগে — held-out test বা k-fold CV verify করুন। OOB ও CV-এর gap — data leak / temporal issue-এর signal।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ OOB error ও true test error-এর সম্পর্ক — কতটা reliable? Empirical evidence ও theoretical guarantee আলাদা করে আলোচনা করুন।

OOB-test relationship — extensive research। Practical reliability strong, কিন্তু caveats আছে।

Theoretical foundation:

  • Breiman (১৯৯৬) — bagging context-এ OOB consistent estimator।
  • $n \to \infty$, $B \to \infty$ — OOB error → true generalization error।
  • Bias term $O(1/n)$ — small data-এ visible।

Empirical validation:

  • Bylander (২০০২) — extensive UCI benchmark।
  • OOB ও 10-fold CV correlation 0.99+।
  • Bias প্রায় শূন্য (random direction)।
  • RMSE difference <1%।

Bias direction — slightly pessimistic:

  • OOB এ — প্রতি tree ০.৬৩ data train।
  • Final model ১.০ data train।
  • OOB কম-data model approximate।
  • Pessimism small (1-2%)।

0.632 estimator — Efron correction:

  • Pessimism counteract করে।
  • $\hat{\text{err}}_{0.632} = 0.368 \cdot \text{err}_{\text{train}} + 0.632 \cdot \text{err}_{\text{OOB}}$।
  • 0.632+ — overfit-aware version।
  • Modern RF-এ rarely used; raw OOB ভাল enough।

কখন OOB unreliable:

(১) Small dataset:

  • $n < 100$ — OOB high variance।
  • প্রতি sample শুধু ৩৭ trees-এ OOB।
  • Vote noisy।
  • Repeated CV বেশি stable।

(২) Class imbalance:

  • Minority class — OOB-এ underrepresented।
  • Per-class metric noisy।
  • Stratified CV preferred।

(৩) Temporal data:

  • Bootstrap order ignore।
  • Time-correlated samples — leak।
  • OOB optimistic — past predict past।
  • Walk-forward validation দরকার।

(৪) Group structure:

  • Multiple samples per patient/user।
  • Bootstrap patient-level group ভাঙে।
  • Solution: GroupKFold।

Empirical case studies:

  • Genomic data: small $n$, large $p$ — OOB stable।
  • Image: RF rarely used, irrelevant।
  • Tabular finance: OOB excellent।
  • Time series: OOB misleading।

Best practice:

  • OOB — primary monitor (free)।
  • CV — confirmation (slower)।
  • Held-out test — final validation।
  • Production — long-term performance tracking।

OOB diagnostic value:

  • Train accuracy ১০০%, OOB ৯০% — typical RF।
  • Train ১০০%, OOB ৬০% — overfit warning।
  • OOB plateau — $B$ enough।

মূল উপলব্ধি: OOB — practical "free lunch"। ৯৫% RF use case-এ sufficient। Edge case-এ — supplement, replace।

প্র ০২ OOB error দিয়ে hyperparameter tune করা যাবে? Cross-validation-এর সাথে কীভাবে compare?

Hyperparameter selection — OOB practical workhorse, কিন্তু subtle considerations আছে।

OOB-based tuning workflow:

  • Different hyperparameter সেট — RF train।
  • প্রতিটির OOB score record।
  • Best OOB score-এর hyperparameter বাছুন।
  • Final model — সম্পূর্ণ data-এ retrain।

সুবিধা:

(১) Computational saving:

  • 5-fold CV — ৫× retraining।
  • OOB — single training।
  • Grid search-এ ৫× speedup।

(২) Full data usage:

  • CV — fold-এ ৮০% data train।
  • OOB — সব data-এ train, ৩৭% per-tree validation।
  • Larger effective training।

(৩) Variance lower:

  • প্রতি sample-এ many trees vote।
  • CV — fold-এ once test।
  • OOB smoother estimate।

সমস্যা:

(১) Hyperparameter scope limited:

  • OOB শুধু RF-এ — bagging-only।
  • Boosting (XGBoost), neural net — CV/early stopping।

(২) $B$ depend:

  • Small $B$ — OOB noisy।
  • $n\_estimators$ tune করতে — OOB ব্যবহার করলে cyclic dependency।
  • $B$ fixed করে অন্য parameter tune।

(৩) Class imbalance:

  • OOB stratified না।
  • Minority class metric noisy।
  • StratifiedKFold preferred।

(৪) Search space coverage:

  • OOB — fast, broader search সম্ভব।
  • CV — costly, careful selection।
  • OOB-CV combined — broad OOB, focused CV।

Compare with CV:

  • OOB: ১× cost, slightly pessimistic।
  • 5-fold CV: ৫× cost, bias direction unbiased।
  • 10-fold CV: ১০× cost, lowest variance।
  • Repeated CV: N×k× cost, gold standard।

Practical strategy:

  • (১) Initial search: wide, OOB।
  • (২) Refine: narrow, 5-fold CV।
  • (৩) Final: held-out test।
  • Computational ও statistical balance।

Specific hyperparameter:

  • $n\_estimators$: OOB plateau দেখুন। ১০০-৫০০ usually।
  • $max\_depth$: OOB sweep — overfit detect।
  • $min\_samples\_leaf$: OOB validate noise robustness।
  • $max\_features$: sqrt vs log2 vs fraction — OOB compare।

Code pattern:

best_params = None
best_oob = 0
for max_depth in [5, 10, 15, None]:
    for max_features in ['sqrt', 'log2', 0.3]:
        rf = RandomForestClassifier(
            n_estimators=200,
            max_depth=max_depth,
            max_features=max_features,
            oob_score=True,
            random_state=0,
            n_jobs=-1
        ).fit(X, y)
        if rf.oob_score_ > best_oob:
            best_oob = rf.oob_score_
            best_params = (max_depth, max_features)

মূল উপলব্ধি: OOB tuning — RF-এ practical। CV — universal। Hybrid often best।

প্র ০৩ "Bootstrap-এর ৩৭%" — এই magic number কোথা থেকে এলো? এর গণিতিক ভিত্তি ও practical implications কী?

০.৩৬৮ — bootstrap statistics-এর iconic number। এর গণিত elegant এবং deep।

Derivation:

  • $n$ samples-এ একটি specific sample।
  • প্রতি draw-এ — চয়ন না-হওয়ার probability $1 - 1/n$।
  • $n$ independent draws — none chose probability $(1 - 1/n)^n$।

Limit:

$$\lim_{n \to \infty} \left(1 - \frac{1}{n}\right)^n = \frac{1}{e} \approx 0.3679$$

  • $e$ — Euler's number, mathematically deep।
  • Compound interest, decay process — সব পরিচিত।

Convergence rate:

  • $n = 10$ — $0.349$।
  • $n = 100$ — $0.366$।
  • $n = 1000$ — $0.368$।
  • $n = 10000$ — $0.368$।
  • $n = 50$+ — limit-এর ১% within।

Why $1/e$?

  • $e^x$-এর Taylor expansion।
  • $(1 - 1/n)^n = \exp(n \log(1 - 1/n)) \approx \exp(-1) = 1/e$।
  • Probability theory's Poisson distribution-এর সাথে সম্পর্কিত।

Practical implications:

(১) OOB samples ~৩৭%:

  • Per tree — ৩৭% data unseen।
  • Sufficient validation set।
  • "Free" CV-like effect।

(২) Effective training set:

  • Per tree — ৬৩% unique samples।
  • Some samples 2x, 3x, 4x repeated।
  • Diversity yet adequate signal।

(৩) Bias-variance:

  • ৬৩% data-এ trained tree — slightly more bias।
  • OOB error pessimistic (slight)।
  • 0.632 estimator correction।

(৪) Diversity engineering:

  • Different bootstraps — ভিন্ন ৬৩% samples।
  • Trees see different "world"।
  • Decorrelation natural।

Connection to other ML:

  • Stochastic Gradient Descent: mini-batch sampling — bootstrap analog।
  • Dropout: ৫০% activation drop — similar diversity idea।
  • Bayesian inference: bootstrap → posterior approximation।

Variants:

  • Subsampling: without replacement, fixed fraction।
  • Bayesian bootstrap: Dirichlet weights।
  • Block bootstrap: time series-এ।
  • Stratified bootstrap: class imbalance।

OOB sample size:

  • $n = 1000$ → ~৩৭০ OOB per tree।
  • ৫০০ trees → প্রতি sample ~১৮৫ trees-এ OOB।
  • Robust prediction।
  • Statistical confidence।

Historical note:

  • Efron (১৯৭৯) — bootstrap-এর introduction।
  • Originally — confidence interval estimation।
  • Breiman (১৯৯৬) — bagging-এ extension।
  • Modern RF — direct application।

মূল উপলব্ধি: $1/e$ — coincidence নয়। Bootstrap-এর core mathematical structure। Understanding গভীর করে practitioner-কে।

প্র ০৪ আপনার কাছে ১০০ টি rare disease cases-এর data — class imbalance। OOB কি reliable? Alternative কী?

Class imbalance — medical/finance ML-এর recurring scenario। OOB strength ও weakness দু'টোই বের।

Class imbalance OOB-এ — challenges:

(১) Bootstrap class proportion:

  • Original — ১% disease, ৯৯% healthy।
  • Bootstrap — same ratio (random)।
  • Per-tree — ১% disease (~১ disease, ~১০০ healthy in 100 sample)।
  • Tree learn — predict majority always।

(২) OOB minority underrepresentation:

  • Disease ১০০ — OOB-এ ~৩৭ disease per tree।
  • Sufficient validation কিন্তু noisy।
  • Per-class metric high variance।

(৩) Accuracy misleading:

  • OOB accuracy ৯৯% — predict all healthy।
  • Disease detection ০%।
  • "Good model" appearance, useless reality।

OOB কি reliable — answer: depends:

(ক) Overall metric — reliable:

  • Accuracy, AUC — OOB-এ unbiased।
  • Trend (improving/degrading) — clear।

(খ) Per-class — unreliable:

  • Recall (sensitivity) noisy।
  • Precision noisy।
  • Confidence interval wide।
  • Stratified validation দরকার।

Alternatives ও solutions:

(১) Stratified Cross-Validation:

  • StratifiedKFold — class proportion preserve।
  • Per-fold reliable minority metric।
  • $5 \times$ cost, but worth।

(২) Class weights:

  • class_weight='balanced' — sklearn।
  • Loss function — minority weighted up।
  • Tree split — minority focus।

(৩) Balanced bagging:

  • BalancedRandomForestClassifier (imblearn)।
  • Each bootstrap — equal class proportion।
  • Better minority learning।

(৪) SMOTE / oversampling:

  • Synthetic minority generation।
  • Pre-RF preprocessing।
  • Bootstrap diversity preserve।
  • Pipeline-এ integrate।

(৫) Threshold tuning:

  • Default ০.৫ — accuracy-based।
  • F1 / cost-aware threshold।
  • OOB probability calibration check।

(৬) Anomaly detection framework:

  • Isolation Forest — bagging variant।
  • One-class SVM।
  • Rare event modeling।

(৭) Ensemble of ensembles:

  • RF + balanced approach + cost-sensitive।
  • Multiple model averaging।
  • Robust।

Recommended workflow:

  • (১) EDA: imbalance ratio quantify।
  • (২) Stratified split: train/test/holdout।
  • (৩) Class weights / SMOTE: training pipeline।
  • (৪) Stratified CV: validation।
  • (৫) Per-class metrics: precision, recall, F1, AUC।
  • (৬) Cost-aware threshold: business cost integrate।
  • (৭) OOB: overall trend monitoring।

Bangladesh medical ML scenario:

  • Cancer screening — ১% prevalence।
  • Sepsis detection — ৫% prevalence।
  • Diabetic retinopathy — ১০-২০% prevalence।
  • Each different strategy।

Specific advice:

  • Recall (sensitivity) primary — false negative critical।
  • Precision secondary — false positive — additional test।
  • F2 score — recall weighted।
  • Decision threshold — clinician input।

Validation rigor:

  • Multi-site validation।
  • Temporal validation (different seasons, years)।
  • Subgroup analysis (age, gender, district)।
  • Calibration check।

মূল উপলব্ধি: Class imbalance — algorithm only-এর বিষয় নয়, end-to-end pipeline। OOB diagnostic, not silver bullet। Domain-aware metric selection critical।

অনুশীলন

  1. হিসাব করুন: $n = 100$ samples, $B = 200$ trees। Average-এ একটি sample কতটি tree-এ OOB-এ থাকবে?
    • প্রতি tree-এ OOB probability ~০.৩৭।
    • $200 \times 0.37 = 74$ trees।
    • প্রতিটি sample প্রায় ৭৪ trees-এর majority vote পায়।
  2. sklearn: Same dataset-এ OOB score ও 5-fold CV score compare করুন।
    rf = RandomForestClassifier(n_estimators=300, oob_score=True, random_state=0).fit(X, y)
    print("OOB:", rf.oob_score_)
    
    from sklearn.model_selection import cross_val_score
    print("5-fold CV:", cross_val_score(rf, X, y, cv=5).mean())
    # সাধারণত ১% এর মধ্যে।
  3. চিন্তা: Time series data-এ OOB কেন reliable নয়? কী alternative?

    Bootstrap temporal order ভাঙে — past predict past hয়। Realistic future prediction-এর সাথে mismatch। Solution: walk-forward / rolling window CV; OOB skip।

আরও পড়ুন

কোড রানার কাজ না করলে? Google Colab ব্যবহার করুন।
পূর্ববর্তী পাঠ
পাঠ ২১ · Random Forest