The Story That Explains Ensemble Learningवह कहानी जो Ensemble Learning समझाती है一个解释 Ensemble Learning 的故事
Now you ask five different experts: a property dealer, a civil engineer, a market analyst, a bank loan officer, and a neighbour who sold his house last month. Their guesses: ₹31.0L, ₹33.0L, ₹31.5L, ₹32.5L, ₹31.8L. Average: ₹31.96 lakh.
Each expert has different knowledge and different blind spots. When their errors are not linked, they cancel out in the average. No single person needs to be perfect. The group is strong.
This is Ensemble Learning. In machine learning, the "experts" are models. Different models make different mistakes. Combine them, and many mistakes cancel.
अब आप पाँच अलग experts से पूछते हैं: एक property dealer, एक civil engineer, एक market analyst, एक bank loan officer, और एक पड़ोसी जिसने पिछले महीने अपना घर बेचा। उनके अनुमान: ₹31.0L, ₹33.0L, ₹31.5L, ₹32.5L, ₹31.8L. औसत: ₹31.96 lakh.
हर expert का ज्ञान अलग है और कमज़ोरियाँ भी अलग हैं। जब उनकी गलतियाँ आपस में जुड़ी नहीं होतीं, तो औसत में वे एक-दूसरे को काट देती हैं। किसी एक को perfect होने की ज़रूरत नहीं। समूह मज़बूत है।
यही Ensemble Learning है। Machine learning में ये "experts" models हैं। अलग models अलग गलतियाँ करते हैं। उन्हें जोड़ें, तो कई गलतियाँ कट जाती हैं।
现在你问五位不同的专家:房产中介、土木工程师、市场分析师、银行贷款员,还有上个月刚卖掉房子的邻居。他们的估价:₹31.0L、₹33.0L、₹31.5L、₹32.5L、₹31.8L。平均:₹31.96 lakh。
每位专家的知识不同,盲点也不同。当他们的错误互不相关时,平均之后就会相互抵消。没有人需要完美,整个团队很强。
这就是 Ensemble Learning。在机器学习中,这些"专家"就是 model。不同的 model 犯不同的错误。把它们组合起来,很多错误就会抵消。
Take N models. Each is right more than half the time (accuracy p > 0.5). Their errors are independent. Then the majority vote gets more accurate as N grows, and it approaches 100%. Even weak models become strong together. The catch: errors must be uncorrelated. Diversity is the secret ingredient. Try it below.
N models लें। हर model आधे से ज़्यादा बार सही है (accuracy p > 0.5)। उनकी गलतियाँ independent हैं। तब N बढ़ने पर majority vote और सटीक होता जाता है और 100% के पास पहुँचता है। कमज़ोर models भी साथ मिलकर मज़बूत बन जाते हैं। शर्त: गलतियाँ uncorrelated होनी चाहिए। Diversity ही असली राज़ है। नीचे खुद आज़माएँ।
取 N 个 model,每个的正确率都超过一半(accuracy p > 0.5),且它们的错误相互独立。那么 N 越大,多数投票越准确,并趋近 100%。弱 model 组合在一起也能变强。前提:错误必须不相关。多样性(diversity)是秘诀。在下面亲自试试。
Each dot is one model voting on a yes/no question. Green = correct, red = wrong. The majority wins. Change the accuracy, the number of models, and how much they copy each other (correlation ρ).
हर dot एक model है जो हाँ/नहीं वाले सवाल पर vote देता है। हरा = सही, लाल = गलत। बहुमत जीतता है। Accuracy, models की संख्या, और वे एक-दूसरे की कितनी नकल करते हैं (correlation ρ) बदलें।
每个圆点是一个对是/否问题投票的 model。绿色 = 正确,红色 = 错误。多数获胜。调整 accuracy、model 数量,以及它们相互复制的程度(correlation ρ)。
The Ensemble Learning LandscapeEnsemble Learning का नक्शाEnsemble Learning 全景
There are three big families of ensemble methods. Each one combines models in a different way. To see why each family exists, we first need the bias–variance tradeoff (Section 03).
Ensemble methods के तीन बड़े परिवार हैं। हर परिवार models को अलग तरीके से जोड़ता है। हर परिवार क्यों है, यह समझने के लिए पहले bias–variance tradeoff समझना होगा (Section 03)।
Ensemble 方法有三大家族,每个家族用不同的方式组合 model。要理解每个家族为什么存在,先要理解 bias–variance tradeoff(第 03 节)。
Bagging trains models in parallel and reduces variance. Boosting trains models one after another and reduces bias. Stacking trains a second model that learns how to combine the first ones.
Bagging models को parallel में train करता है और variance घटाता है। Boosting models को एक के बाद एक train करता है और bias घटाता है। Stacking एक दूसरा model train करता है जो पहले models को जोड़ना सीखता है।
Bagging 并行训练 model,降低 variance。Boosting 逐个顺序训练 model,降低 bias。Stacking 再训练一个 model,学习如何组合前面的 model。
Key Differences at a Glanceमुख्य अंतर एक नज़र में主要区别一览
| Bagging | Boosting | Stacking | |
|---|---|---|---|
| TrainingTraining训练方式 | Parallel (fast)Parallel (तेज़)并行(快) | Sequential (slower)Sequential (धीमा)串行(较慢) | Two levels, uses K-fold CVदो levels, K-fold CV两层,使用 K-fold CV |
| Fixesक्या ठीक करता है解决 | High varianceHigh variance高 variance | High biasHigh bias高 bias | Both, if bases are diverseदोनों, अगर bases diverse हों两者都可以(前提是 base 多样) |
| Data per modelहर model का data每个 model 的数据 | Bootstrap samples (with replacement)Bootstrap samples (with replacement)Bootstrap 样本(有放回) | Re-weighted rows or residualsRe-weighted rows या residuals重新加权的样本或残差 | Out-of-fold predictionsOut-of-fold predictionsOut-of-fold 预测 |
| Base learnerBase learnerBase learner | Deep treesDeep trees深树 | Shallow trees / stumpsShallow trees / stumps浅树 / stump | Any mix of different modelsअलग-अलग models का कोई भी मेल任意不同 model 的组合 |
| Combine byजोड़ने का तरीका组合方式 | Vote / averageVote / average投票 / 平均 | Weighted sumWeighted sum加权求和 | A learned meta-modelएक सीखा हुआ meta-model学出来的 meta-model |
| Exampleउदाहरण例子 | Random Forest | XGBoost, LightGBM | RF + SVM + KNN → LogReg |
Bias–Variance Tradeoff — Why Ensembles ExistBias–Variance Tradeoff — Ensembles क्यों हैंBias–Variance Tradeoff — Ensemble 为什么存在
A model's total error has three parts. Each ensemble family attacks one of them.
किसी model की कुल error के तीन हिस्से होते हैं। हर ensemble परिवार इनमें से एक पर हमला करता है।
model 的总误差由三部分组成。每个 ensemble 家族针对其中一部分。
Variance: error from being too sensitive to the training data (overfitting).
Noise: error in the data itself. No model can remove it.
Variance: training data के प्रति बहुत sensitive होने से error (overfitting)।
Noise: data में ही error. कोई model इसे हटा नहीं सकता।
Variance:对训练数据过于敏感带来的误差(overfitting)。
Noise:数据本身的误差,任何 model 都无法消除。
The centre is the true answer. Each round, N models make a guess. Red dots = one model alone. Green dots = the average of all N. Raise ρ and watch the green cloud stop shrinking.
केंद्र सही जवाब है। हर round में N models अनुमान लगाते हैं। लाल dots = अकेला एक model. हरे dots = सभी N का average. ρ बढ़ाएँ और देखें कि हरा बादल सिकुड़ना बंद कर देता है।
中心是真实答案。每一轮 N 个 model 各给出一个预测。红点 = 单个 model,绿点 = N 个 model 的平均。增大 ρ,看绿色点云不再缩小。
The green curve is the formula. It drops fast, then flattens at the red floor ρσ². More models cannot beat the floor. Only more diversity (lower ρ) can.
हरा curve formula है। यह तेज़ी से गिरता है, फिर लाल floor ρσ² पर सपाट हो जाता है। ज़्यादा models इस floor को नहीं हरा सकते। सिर्फ़ ज़्यादा diversity (कम ρ) ही हरा सकती है।
绿色曲线就是公式。它先快速下降,然后在红色下限 ρσ² 处变平。再多的 model 也突破不了下限,只有更高的多样性(更低的 ρ)才行。
| Problemसमस्या问题 | Causeकारण原因 | Ensemble FixEnsemble समाधानEnsemble 解决办法 | MethodMethod方法 |
|---|---|---|---|
| High Variance | One deep tree memorises noiseएक deep tree noise रट लेता है一棵深树记住了噪声 | Average many different trees, errors cancelकई अलग trees का average, errors कट जाते हैं平均许多不同的树,错误相互抵消 | Bagging / Random Forest |
| High Bias | One shallow tree underfitsएक shallow tree underfit करता है一棵浅树欠拟合 | Add models one by one to fix remaining errorsबची हुई errors ठीक करने के लिए एक-एक करके models जोड़ें逐个添加 model 来修正剩余的错误 | Boosting (AdaBoost / GBM) |
| Bothदोनों两者 | No single model type is best everywhereकोई एक model type हर जगह best नहीं没有一种 model 在所有地方都最好 | Learn the best combination from dataData से सबसे अच्छा मेल सीखें从数据中学习最佳组合 | Stacking / Blending |
Family 1: Bagging — Parallel DiversityFamily 1: Bagging — Parallel Diversity家族 1:Bagging — 并行多样性
So each forecaster builds a different model. Some overfit to heatwaves. Some overfit to coastal patterns. But when all 500 vote, the personal quirks cancel out. The group forecast is very accurate.
This is Bagging (Bootstrap Aggregating): same algorithm, different random data, trained in parallel, then a vote.
इसलिए हर forecaster अलग model बनाता है। कुछ heatwaves पर overfit करते हैं। कुछ समुद्री तट के patterns पर। पर जब सभी 500 vote करते हैं, तो निजी कमियाँ कट जाती हैं। समूह का forecast बहुत सटीक होता है।
यही Bagging (Bootstrap Aggregating) है: वही algorithm, अलग random data, parallel में training, फिर vote.
所以每位预报员建立的 model 都不同。有的对热浪过拟合,有的对沿海模式过拟合。但当 500 人一起投票时,个人偏差相互抵消,集体预报非常准确。
这就是 Bagging(Bootstrap Aggregating):同一种算法,不同的随机数据,并行训练,最后投票。
n_jobs=-1 to use every CPU core.n_jobs=-1 लगाएँ।n_jobs=-1 使用所有 CPU 核心。The dataset has 20 rows. Draw 20 times with replacement. Some rows are picked twice or more (×2). Some are never picked: they become OOB rows (dashed).
Dataset में 20 rows हैं। Replacement के साथ 20 बार निकालें। कुछ rows दो या ज़्यादा बार चुनी जाती हैं (×2)। कुछ कभी नहीं चुनी जातीं: वे OOB rows बन जाती हैं (dashed)।
数据集有 20 行。有放回地抽取 20 次。有些行被抽中两次或更多(×2),有些从未被抽中,成为 OOB 行(虚线)。
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# Noisy dataset: a single deep tree will overfit badly
X, y = make_classification(
n_samples=1000, n_features=20,
n_informative=10, n_redundant=5,
flip_y=0.1, # 10% label noise
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Baseline: one fully grown tree
single_tree = DecisionTreeClassifier(max_depth=None, random_state=42)
single_tree.fit(X_train, y_train)
print(f"Single Tree — Train: {single_tree.score(X_train, y_train):.3f} "
f"Test: {single_tree.score(X_test, y_test):.3f}")
# Bagging: 100 trees, each on its own bootstrap sample
bag = BaggingClassifier(
estimator=DecisionTreeClassifier(max_depth=None),
n_estimators=100, # number of trees
max_samples=0.8, # each bootstrap sample = 80% of the rows
max_features=0.8, # each tree sees 80% of the features
bootstrap=True, # sample rows WITH replacement
oob_score=True, # free validation on out-of-bag rows
n_jobs=-1,
random_state=42
)
bag.fit(X_train, y_train)
print(f"Bagging (100) — Train: {bag.score(X_train, y_train):.3f} "
f"Test: {bag.score(X_test, y_test):.3f} OOB: {bag.oob_score_:.3f}")
The single tree scores 100% on training data but only 73.5% on test data. It memorised the noise. Bagging keeps the same deep trees but averages 100 of them: test accuracy jumps to 88.0%. The OOB score (84.4%) is a fair estimate computed without any test data.
एक अकेला tree training data पर 100% पर test data पर सिर्फ़ 73.5% लाता है। उसने noise रट लिया। Bagging वही deep trees रखता है पर उनमें से 100 का average लेता है: test accuracy 88.0% तक पहुँच जाती है। OOB score (84.4%) बिना किसी test data के निकाला गया एक उचित अनुमान है।
单棵树在训练集上 100%,在测试集上只有 73.5%,它记住了噪声。Bagging 使用同样的深树,但平均了 100 棵:测试 accuracy 跳到 88.0%。OOB 分数(84.4%)是不用任何测试数据得到的合理估计。
Random Forest — The Production StandardRandom Forest — Production का StandardRandom Forest — 生产环境标准
Two noisy "moons". Circles = class 0, squares = class 1. A single deep tree makes jagged islands around noisy points. Switch to Random Forest and press "Grow". Watch the boundary smooth out and test accuracy rise.
दो noisy "moons". Circles = class 0, squares = class 1. एक deep tree noisy points के चारों ओर टेढ़े-मेढ़े टापू बनाता है। Random Forest चुनें और "Grow" दबाएँ। Boundary को smooth होते और test accuracy को बढ़ते देखें।
两个带噪声的"月牙"。圆点 = class 0,方块 = class 1。单棵深树会在噪声点周围形成锯齿状的小岛。切换到 Random Forest 并点击"生长",看边界变平滑、测试 accuracy 上升。
Train accuracy is near 100% for every model here (deep trees). Only the test accuracy tells you which one generalises. Try max_depth = 2 too: now even one tree underfits, and averaging cannot fix bias.
यहाँ हर model की train accuracy लगभग 100% है (deep trees)। सिर्फ़ test accuracy बताती है कि कौन generalise करता है। max_depth = 2 भी आज़माएँ: अब एक tree भी underfit करता है, और averaging bias ठीक नहीं कर सकती।
这里每个 model 的训练 accuracy 都接近 100%(深树)。只有测试 accuracy 能说明谁泛化得好。也试试 max_depth = 2:此时单棵树就欠拟合,而平均无法修正 bias。
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import numpy as np
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
rf = RandomForestClassifier(
n_estimators=300, # number of trees
max_features='sqrt', # sqrt(p) features per split: the key randomness
max_depth=None, # grow fully, so bias stays low
min_samples_leaf=1,
bootstrap=True,
oob_score=True,
n_jobs=-1,
random_state=42
)
rf.fit(X_train, y_train)
print(f"OOB Score : {rf.oob_score_:.4f}")
print(f"Test Score : {rf.score(X_test, y_test):.4f}")
print(classification_report(y_test, rf.predict(X_test),
target_names=cancer.target_names))
# Feature importances (MDI)
importances = rf.feature_importances_
top5 = np.argsort(importances)[::-1][:5]
print("Top-5 features:")
for i in top5:
print(f" {cancer.feature_names[i]:<24} {importances[i]:.4f}")
Look at the output: "worst perimeter" and "worst area" have the same importance (0.1373). They measure almost the same thing, so the forest splits the credit between them. The default MDI importance also favours features with many unique values. For real decisions, use permutation_importance or SHAP.
Output देखें: "worst perimeter" और "worst area" की importance बराबर है (0.1373)। ये लगभग एक ही चीज़ मापते हैं, इसलिए forest credit को दोनों में बाँट देता है। Default MDI importance उन features को भी ज़्यादा महत्व देती है जिनमें कई unique values हों। असली फ़ैसलों के लिए permutation_importance या SHAP इस्तेमाल करें।
看输出:"worst perimeter" 和 "worst area" 的 importance 相同(0.1373)。它们衡量的几乎是同一件事,所以森林把功劳分给了两者。默认的 MDI importance 还偏向取值很多的特征。做实际决策时,请使用 permutation_importance 或 SHAP。
Family 2: Boosting — Sequential Error CorrectionFamily 2: Boosting — एक-एक करके गलतियाँ सुधारना家族 2:Boosting — 逐步纠错
Each round, the student gets better at exactly the problems that were hard before. No time is wasted on topics already mastered.
This is Boosting. Each new model focuses on the examples that the previous models got wrong. Together, the sequence covers every level of difficulty.
हर round में student ठीक उन्हीं सवालों में बेहतर होता है जो पहले कठिन थे। जो topics पहले से आते हैं उन पर समय बर्बाद नहीं होता।
यही Boosting है। हर नया model उन examples पर ध्यान देता है जो पिछले models ने गलत किए। साथ मिलकर यह sequence हर कठिनाई स्तर को cover करता है।
每一轮,学生都恰好在之前不会的题上进步,不会把时间浪费在已经掌握的内容上。
这就是 Boosting。每个新 model 都专注于前面 model 做错的样本。整个序列合起来,覆盖了所有难度。
Bigger orange dots = higher weight. Points that were wrong get more attention in the next round. All boosting methods are sequential, so they cannot be parallelised across rounds like Bagging.
बड़े नारंगी dots = ज़्यादा weight. जो points गलत थे उन्हें अगले round में ज़्यादा ध्यान मिलता है। सभी boosting methods sequential हैं, इसलिए Bagging की तरह rounds को parallel नहीं किया जा सकता।
橙色大点 = 权重更高。上一轮错的点在下一轮得到更多关注。所有 boosting 方法都是串行的,不能像 Bagging 那样在轮次之间并行。
AdaBoost — Adaptive BoostingAdaBoost — Adaptive BoostingAdaBoost — 自适应提升
Squares belong to the circle in the middle; dots are outside. Each round adds one stump (the dashed line). Point size = weight. Red ring = still wrong. The shaded background is the vote of all stumps so far.
Squares बीच वाले घेरे के अंदर हैं; dots बाहर हैं। हर round एक stump (dashed line) जोड़ता है। Point का आकार = weight. लाल घेरा = अभी भी गलत। छायादार पृष्ठभूमि अब तक के सभी stumps का vote है।
方块属于中间的圆形区域,圆点在外面。每一轮加入一个 stump(虚线)。点的大小 = 权重。红圈 = 仍然错误。背景阴影是目前所有 stump 的投票结果。
| RoundRound轮次 | |
| Stump error εStump error εStump 误差 ε | |
| Stump weight αStump weight αStump 权重 α |
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(
n_samples=800, n_features=15, n_informative=8, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# AdaBoost with stumps (depth-1 trees)
ada = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1), # weak learner = stump
n_estimators=200, # sequential rounds
learning_rate=0.5, # shrinks each stump's vote
random_state=42
)
ada.fit(X_train, y_train)
print(f"AdaBoost Test Accuracy: {ada.score(X_test, y_test):.4f}")
# Watch accuracy grow as stumps are added
staged = list(ada.staged_score(X_test, y_test))
for n in [1, 10, 50, 100, 200]:
print(f"Rounds {n:>3}: {staged[n - 1]:.4f}")
Accuracy climbs from 60.6% with one stump to 83.1% with 200. Each stump is weak on its own. Together they are strong.
एक stump के साथ accuracy 60.6% से बढ़कर 200 stumps पर 83.1% हो जाती है। हर stump अकेले कमज़ोर है। साथ मिलकर वे मज़बूत हैं।
accuracy 从 1 个 stump 时的 60.6% 上升到 200 个时的 83.1%。每个 stump 单独都很弱,合起来就很强。
Older tutorials pass algorithm='SAMME' to AdaBoostClassifier. That parameter was deprecated in scikit-learn 1.6 and has since been removed. SAMME is now the only algorithm, so just leave the parameter out.
पुराने tutorials AdaBoostClassifier में algorithm='SAMME' देते हैं। यह parameter scikit-learn 1.6 में deprecated हुआ और अब हटा दिया गया है। अब SAMME ही एकमात्र algorithm है, इसलिए इस parameter को हटा दें।
旧教程会给 AdaBoostClassifier 传入 algorithm='SAMME'。这个参数在 scikit-learn 1.6 中已弃用,之后被移除。现在 SAMME 是唯一的算法,直接省略这个参数即可。
Gradient Boosting Machine (GBM)Gradient Boosting Machine (GBM)Gradient Boosting Machine (GBM)
Filled dots = training data. Hollow dots = validation data. Red lines = residuals. Each round, a small tree fits the residuals and the green curve moves. Below: training error keeps falling, but validation error turns back up. That turning point is where early stopping stops.
भरे dots = training data. खोखले dots = validation data. लाल lines = residuals. हर round में एक छोटा tree residuals fit करता है और हरा curve खिसकता है। नीचे: training error घटता रहता है, पर validation error फिर बढ़ने लगता है। वही मोड़ है जहाँ early stopping रुकता है।
实心点 = 训练数据,空心点 = 验证数据,红线 = 残差。每一轮,一棵小树拟合残差,绿色曲线随之移动。下方:训练误差一直下降,但验证误差会掉头上升。这个转折点就是 early stopping 停下的地方。
Best round so farअब तक का best round目前最佳轮次:
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score
import numpy as np
X, y = make_classification(
n_samples=1000, n_features=20, n_informative=12, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
gb = GradientBoostingClassifier(
n_estimators=300, # number of boosting rounds
learning_rate=0.05, # shrinkage: smaller = safer, needs more trees
max_depth=4, # keep trees small (3-6)
subsample=0.8, # stochastic boosting: 80% rows per tree
max_features='sqrt', # random features per split
min_samples_leaf=5,
random_state=42
)
gb.fit(X_train, y_train)
cv_scores = cross_val_score(gb, X_train, y_train, cv=5, scoring='accuracy')
print(f"CV Accuracy : {cv_scores.mean():.4f} +/- {cv_scores.std():.4f}")
print(f"Test Accuracy: {gb.score(X_test, y_test):.4f}")
top3 = np.argsort(gb.feature_importances_)[::-1][:3]
print("Top-3 feature indices:", top3,
"importances:", gb.feature_importances_[top3].round(4))
XGBoost — The Competition StandardXGBoost — Competitions का StandardXGBoost — 竞赛标准
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Early stopping needs its OWN validation set.
# Never stop on the test set: that leaks test data into training.
X_tr, X_val, y_tr, y_val = train_test_split(
X_train, y_train, test_size=0.2, random_state=42, stratify=y_train
)
dtrain = xgb.DMatrix(X_tr, label=y_tr)
dval = xgb.DMatrix(X_val, label=y_val)
dtest = xgb.DMatrix(X_test)
params = {
'objective': 'binary:logistic',
'eval_metric': 'logloss',
'max_depth': 4,
'learning_rate': 0.05,
'subsample': 0.8,
'colsample_bytree': 0.8, # feature subsampling per tree
'reg_alpha': 0.1, # L1 regularisation
'reg_lambda': 1.0, # L2 regularisation
'seed': 42
}
model = xgb.train(
params, dtrain,
num_boost_round=500,
evals=[(dval, 'val')],
early_stopping_rounds=30, # stop if no improvement for 30 rounds
verbose_eval=50
)
print(f"Best iteration: {model.best_iteration}")
proba = model.predict(dtest, iteration_range=(0, model.best_iteration + 1))
y_pred = (proba > 0.5).astype(int)
print(classification_report(y_test, y_pred, target_names=cancer.target_names))
Early stopping picks the best round by looking at the evaluation data. If that data is your test set, the test score is no longer an honest estimate. The code above splits off a separate validation set from the training data. The test set is used only once, at the end.
Early stopping evaluation data देखकर best round चुनता है। अगर वह data आपका test set है, तो test score अब ईमानदार अनुमान नहीं रहता। ऊपर का code training data से एक अलग validation set निकालता है। Test set सिर्फ़ एक बार, आख़िर में इस्तेमाल होता है।
Early stopping 通过观察评估数据来选择最佳轮次。如果这份数据是测试集,测试分数就不再是诚实的估计。上面的代码从训练数据中另外分出一个验证集,测试集只在最后使用一次。
AdaBoost: simple and fast. Good on clean data. Sensitive to noise and outliers, because wrong points get huge weights (you saw this in the simulator).
GBM: more flexible (any differentiable loss). Handles noise better with subsample. Slower.
XGBoost / LightGBM / HistGradientBoosting: same idea as GBM, built for speed (histogram splits, parallel split search, missing-value handling). The usual first choice for tabular data.
AdaBoost: सरल और तेज़। साफ़ data पर अच्छा। Noise और outliers के प्रति sensitive, क्योंकि गलत points को बहुत बड़ा weight मिलता है (आपने simulator में देखा)।
GBM: ज़्यादा flexible (कोई भी differentiable loss)। subsample से noise को बेहतर संभालता है। धीमा।
XGBoost / LightGBM / HistGradientBoosting: GBM वाला ही विचार, speed के लिए बना (histogram splits, parallel split search, missing values संभालना)। Tabular data के लिए आमतौर पर पहली पसंद।
AdaBoost:简单快速,适合干净数据。对噪声和 outlier 敏感,因为错误的点会得到巨大的权重(你在模拟器里看到了)。
GBM:更灵活(任意可微 loss),用 subsample 更好地处理噪声,速度较慢。
XGBoost / LightGBM / HistGradientBoosting:与 GBM 思想相同,但为速度而设计(直方图分裂、并行寻找分裂点、处理缺失值)。表格数据的常用首选。
Family 3: Stacking — Learning to CombineFamily 3: Stacking — जोड़ना सीखना家族 3:Stacking — 学习如何组合
For unclear heart symptoms, she trusts the cardiologist and the geneticist most. For diabetes, the endocrinologist leads. She does not just count votes. She has learned the best weighting from thousands of past cases.
She is the meta-learner. The specialists are the base learners. The key: her knowledge is learned from data, not written by hand.
अस्पष्ट दिल के लक्षणों में वह cardiologist और geneticist पर सबसे ज़्यादा भरोसा करती है। Diabetes में endocrinologist आगे रहता है। वह सिर्फ़ votes नहीं गिनती। उसने हज़ारों पुराने cases से सबसे अच्छा weighting सीखा है।
वह meta-learner है। Specialists base learners हैं। मुख्य बात: उसका ज्ञान data से सीखा गया है, हाथ से नहीं लिखा गया।
对于不明确的心脏症状,她最相信心脏科和遗传科;对于糖尿病,内分泌科说了算。她不只是数票,而是从成千上万个病例中学到了最佳权重。
她就是 meta-learner,专科医生就是 base learner。关键在于:她的知识是从数据中学来的,不是人工写死的。
Each base learner is trained on K−1 folds and predicts the fold it did not see. These out-of-fold predictions become the meta-features. So the meta-learner never sees a prediction made on a row the base learner was trained on.
हर base learner K−1 folds पर train होता है और उस fold पर predict करता है जो उसने नहीं देखा। ये out-of-fold predictions meta-features बनती हैं। इसलिए meta-learner कभी ऐसा prediction नहीं देखता जो उसी row पर बना हो जिस पर base learner train हुआ था।
每个 base learner 在 K−1 个 fold 上训练,并预测它没见过的那个 fold。这些 out-of-fold 预测就是 meta-feature。因此 meta-learner 永远不会看到 base learner 在自己训练过的行上做出的预测。
10 training rows, 5 folds (2 rows each). Watch each fold take its turn as the held-out part. Then compare with the leaky way.
10 training rows, 5 folds (हर fold में 2 rows)। देखिए हर fold बारी-बारी से held-out हिस्सा बनता है। फिर leaky तरीके से तुलना करें।
10 行训练数据,5 个 fold(每个 2 行)。看每个 fold 轮流作为 held-out 部分。然后与有泄漏的做法对比。
from sklearn.ensemble import StackingClassifier, RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Level 0: diverse base learners (scaling lives inside each Pipeline)
base_learners = [
('rf', RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1)),
('svm', Pipeline([('sc', StandardScaler()),
('svc', SVC(probability=True, C=10, random_state=42))])),
('knn', Pipeline([('sc', StandardScaler()),
('knn', KNeighborsClassifier(n_neighbors=11, weights='distance'))])),
('dt', DecisionTreeClassifier(max_depth=5, random_state=42)),
]
# Level 1: meta-learner learns from the base learners' predictions
stack = StackingClassifier(
estimators=base_learners,
final_estimator=LogisticRegression(max_iter=1000),
cv=5, # 5-fold out-of-fold meta-features (no leakage)
stack_method='predict_proba',
passthrough=False, # meta-learner sees only predictions
n_jobs=-1
)
# Compare each base learner with the stack
for name, model in base_learners + [('stack', stack)]:
model.fit(X_train, y_train)
print(f" {name:<6} Test accuracy: {model.score(X_test, y_test):.4f}")
The stack (98.25%) beats every single base learner, including the best ones (SVM and KNN at 97.37%). It works because the four models are very different: trees, a kernel method and a distance method.
Stack (98.25%) हर एक base learner को हराता है, सबसे अच्छे वालों (SVM और KNN, 97.37%) को भी। यह इसलिए काम करता है क्योंकि चारों models बहुत अलग हैं: trees, एक kernel method और एक distance method.
stack(98.25%)胜过了每一个 base learner,包括最好的 SVM 和 KNN(97.37%)。之所以有效,是因为这四个 model 差别很大:树模型、核方法和基于距离的方法。
Voting Classifier — The Simplest CombinationVoting Classifier — सबसे सरल तरीकाVoting Classifier — 最简单的组合方式
Three models give their probability for class 1. Hard voting counts the votes. Soft voting averages the probabilities. Drag the sliders to find cases where they disagree.
तीन models class 1 के लिए अपनी probability देते हैं। Hard voting votes गिनता है। Soft voting probabilities का average लेता है। Sliders खिसकाकर ऐसे cases ढूँढें जहाँ वे सहमत नहीं हैं।
三个 model 给出 class 1 的概率。Hard voting 数票数,soft voting 对概率取平均。拖动滑块,找到两者结果不同的情况。
from sklearn.ensemble import VotingClassifier, RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(
n_samples=1000, n_features=15, n_informative=10, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
estimators = [
('lr', Pipeline([('sc', StandardScaler()),
('lr', LogisticRegression(max_iter=1000))])),
('svm', Pipeline([('sc', StandardScaler()),
('svm', SVC(probability=True, random_state=42))])),
('rf', RandomForestClassifier(n_estimators=100, random_state=42)),
('knn', Pipeline([('sc', StandardScaler()),
('knn', KNeighborsClassifier(n_neighbors=9))])),
]
# Each model on its own
for name, clf in estimators:
clf.fit(X_train, y_train)
print(f"{name:<12}: {clf.score(X_test, y_test):.4f}")
hard_vote = VotingClassifier(estimators=estimators, voting='hard', n_jobs=-1)
soft_vote = VotingClassifier(estimators=estimators, voting='soft', n_jobs=-1)
for name, clf in [('Hard Voting', hard_vote), ('Soft Voting', soft_vote)]:
clf.fit(X_train, y_train)
print(f"{name:<12}: {clf.score(X_test, y_test):.4f}")
Look closely at the output. KNN alone scores 96.0%. Hard voting (95.0%) and soft voting (95.5%) are both worse than KNN. The weak logistic regression (86.5%) pulls the vote down. Voting gives every model the same say. That is why stacking, which learns the weights, often does better. Always compare the ensemble with its best single member.
Output को ध्यान से देखें। अकेला KNN 96.0% लाता है। Hard voting (95.0%) और soft voting (95.5%) दोनों KNN से बुरे हैं। कमज़ोर logistic regression (86.5%) vote को नीचे खींचता है। Voting हर model को बराबर अधिकार देता है। इसीलिए stacking, जो weights सीखता है, अक्सर बेहतर करता है। Ensemble की तुलना हमेशा उसके सबसे अच्छे अकेले सदस्य से करें।
仔细看输出:KNN 单独就有 96.0%。Hard voting(95.0%)和 soft voting(95.5%)都不如 KNN。较弱的 logistic regression(86.5%)拉低了投票结果。Voting 给每个 model 同样的话语权,这正是会学习权重的 stacking 常常更好的原因。一定要把 ensemble 和它最好的单个成员做比较。
Hard voting: each model gives one vote for a class. Works even if a model has no probabilities.
Soft voting: average the probabilities and pick the highest. It uses confidence, so it is usually a bit better, if the probabilities are well calibrated. SVM probabilities (Platt scaling) and deep-tree probabilities can be poorly calibrated, so test both.
Hard voting: हर model किसी class के लिए एक vote देता है। तब भी काम करता है जब model probability न दे।
Soft voting: probabilities का average लें और सबसे बड़ी चुनें। यह confidence इस्तेमाल करता है, इसलिए आमतौर पर थोड़ा बेहतर है, अगर probabilities अच्छी तरह calibrated हों। SVM probabilities (Platt scaling) और deep-tree probabilities ठीक से calibrated न हों ऐसा हो सकता है, इसलिए दोनों test करें।
Hard voting:每个 model 给某个类别投一票。即使 model 不输出概率也能用。
Soft voting:对概率取平均,选最高的类别。它利用了置信度,所以通常略好一些,前提是概率校准良好。SVM 的概率(Platt scaling)和深树的概率可能校准不佳,所以两种都要测试。
Head-to-Head Comparison — All Methods on the Same Dataआमने-सामने — एक ही Data पर सभी Methods正面对比 — 同一数据上的所有方法
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import (
BaggingClassifier, RandomForestClassifier,
AdaBoostClassifier, GradientBoostingClassifier
)
from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_classification
X, y = make_classification(
n_samples=2000, n_features=20, n_informative=12,
n_redundant=4, flip_y=0.05, random_state=42
)
models = {
'Decision Tree' : DecisionTreeClassifier(random_state=42),
'Bagging' : BaggingClassifier(n_estimators=100, random_state=42, n_jobs=-1),
'Random Forest' : RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1),
'AdaBoost' : AdaBoostClassifier(n_estimators=100, random_state=42),
'Gradient Boost': GradientBoostingClassifier(n_estimators=100, random_state=42),
}
print(f"{'Model':<16} {'CV Mean':>8} {'CV Std':>8}")
print("-" * 34)
for name, model in models.items():
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy', n_jobs=-1)
print(f"{name:<16} {scores.mean():>8.4f} {scores.std():>8.4f}")
Bars start at 70% so the gaps are easy to see. pp = percentage points over the single tree.Bars 70% से शुरू होते हैं ताकि अंतर साफ़ दिखे। pp = एक tree से ज़्यादा percentage points.条形从 70% 开始,便于看清差距。pp = 相对单棵树提升的百分点。
On this data, Random Forest wins (91.1%), and every ensemble beats the single tree. Gradient Boosting here uses default settings (100 trees, no tuning). With tuning it often takes the lead. The lesson: the ranking depends on the data and on tuning. Always test a few methods with cross-validation.
इस data पर Random Forest जीतता है (91.1%), और हर ensemble एक tree को हराता है। यहाँ Gradient Boosting default settings पर है (100 trees, कोई tuning नहीं)। Tuning के साथ यह अक्सर आगे निकल जाता है। सबक: ranking data और tuning पर निर्भर करती है। हमेशा cross-validation से कुछ methods test करें।
在这份数据上,Random Forest 胜出(91.1%),而且每个 ensemble 都胜过单棵树。这里的 Gradient Boosting 使用默认设置(100 棵树,未调参),调参后它常常会领先。结论:排名取决于数据和调参。一定要用交叉验证测试几种方法。
Key Hyperparameters Across All Methodsसभी Methods के मुख्य Hyperparameters各方法的关键超参数
| MethodMethod方法 | Key Parametersमुख्य Parameters关键参数 | What They Controlये क्या नियंत्रित करते हैं控制什么 | Tuning PriorityTuning Priority调参优先级 |
|---|---|---|---|
| Bagging | n_estimators, max_samples, max_features | More trees help, with diminishing returns after ~200. max_samples / max_features control diversity.ज़्यादा trees मदद करते हैं, ~200 के बाद फ़ायदा कम होता जाता है। max_samples / max_features diversity नियंत्रित करते हैं।树越多越好,约 200 棵后收益递减。max_samples / max_features 控制多样性。 | Low — defaults work wellकम — defaults अच्छे हैं低 — 默认值就不错 |
| Random Forest | n_estimators, max_features, min_samples_leaf | max_features='sqrt' for classification. For regression, try 1/3 of the features. Raise min_samples_leaf on noisy data.Classification के लिए max_features='sqrt'. Regression के लिए 1/3 features आज़माएँ। Noisy data पर min_samples_leaf बढ़ाएँ।classification 用 max_features='sqrt';regression 可以试 1/3 的特征。数据噪声大时增大 min_samples_leaf。 | Medium — tune max_features firstमध्यम — पहले max_features tune करें中 — 先调 max_features |
| AdaBoost | n_estimators, learning_rate | learning_rate shrinks each stump's vote. A lower rate needs more estimators.learning_rate हर stump के vote को छोटा करता है। कम rate के लिए ज़्यादा estimators चाहिए।learning_rate 缩小每个 stump 的投票权重。学习率越低,需要的 estimator 越多。 | Medium — tune both togetherमध्यम — दोनों साथ tune करें中 — 两者一起调 |
| GBM / XGBoost | n_estimators, learning_rate, max_depth, subsample | learning_rate × n_estimators is the key tradeoff. Low rate + more trees + early stopping usually wins. max_depth 3–6.learning_rate × n_estimators मुख्य tradeoff है। कम rate + ज़्यादा trees + early stopping आमतौर पर जीतता है। max_depth 3–6.learning_rate × n_estimators 是关键权衡。低学习率 + 更多树 + early stopping 通常最好。max_depth 取 3–6。 | High — use RandomizedSearchCVज़्यादा — RandomizedSearchCV इस्तेमाल करें高 — 使用 RandomizedSearchCV |
| Stacking | Base learner variety, meta-learner, cvBase learners की विविधता, meta-learner, cvbase learner 的多样性、meta-learner、cv | Diverse base learners matter most. Keep the meta-learner simple (LogisticRegression). cv=5 prevents leakage.Diverse base learners सबसे ज़रूरी हैं। Meta-learner को सरल रखें (LogisticRegression)। cv=5 leakage रोकता है।多样的 base learner 最重要。meta-learner 保持简单(LogisticRegression)。cv=5 防止泄漏。 | Medium — choose diverse basesमध्यम — diverse bases चुनें中 — 选多样的 base |
When to Use Each Methodकौन-सा Method कब इस्तेमाल करें何时使用哪种方法
Common Pitfallsआम गलतियाँ常见陷阱
Golden RulesGolden Rules黄金法则
StackingClassifier(cv=5) handles this for you.StackingClassifier(cv=5) यह आपके लिए संभालता है।StackingClassifier(cv=5) 会帮你处理好。n_jobs=-1 on parallel ensembles. Bagging, Random Forest, Voting and Stacking can train their models at the same time. On an 8-core machine this can cut training time several times over. (Plain GradientBoostingClassifier has no n_jobs; XGBoost and LightGBM parallelise inside each tree.)n_jobs=-1 लगाएँ। Bagging, Random Forest, Voting और Stacking अपने models एक साथ train कर सकते हैं। 8-core machine पर इससे training time कई गुना घट सकता है। (साधारण GradientBoostingClassifier में n_jobs नहीं है; XGBoost और LightGBM हर tree के अंदर parallel काम करते हैं।)n_jobs=-1。 Bagging、Random Forest、Voting 和 Stacking 可以同时训练各自的 model。在 8 核机器上,训练时间可以缩短好几倍。(普通的 GradientBoostingClassifier 没有 n_jobs;XGBoost 和 LightGBM 在每棵树内部并行。)