Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Qoldiqqa moslash
- 2.2. Funksional gradient tushish
- 2.3. Yo'qotish funksiyalari
- 2.4. learning_rate va n_estimators
- 2.5. subsample
- 2.6. HistGradientBoosting
- 2.7. Tuzoqlar
- 2.8. Qoldiqqa qarab o'sish
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Qo'lda gradient boosting
- Misol 2 — Yo'qotish funksiyalari
- Misol 3 — Giperparametrlar
- Misol 4 — HistGradientBoosting
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
15.8-dars: Gradient boosting
15-QISM — DARAXTLAR VA ANSAMBLLAR · 8-dars
1. Kirish va motivatsiya
Gradient boosting — AdaBoost g'oyasining umumlashmasi: og'irliklarni yangilash o'rniga har qadamda qoldiqqa (aniqrog'i, yo'qotish funksiyasining manfiy gradientiga) daraxt moslanadi. Bu kichik o'zgarish algoritmni istalgan yo'qotish funksiyasi bilan ishlashga imkon beradi.
Natija — jadval ma'lumotlari uchun eng kuchli modellar oilasi. Kaggle musobaqalarining katta qismi gradient boosting (XGBoost, LightGBM, CatBoost) bilan yutilgan va sanoatdagi ko'p tavsiya, narx va risk modellari shu asosda qurilgan.
Bu darsda: gradient tushish va funksional fazo, qoldiq ga moslash, yo'qotish funksiyalari (squared_error, absolute_error, huber, log_loss), learning_rate, subsample, max_depth va HistGradientBoosting.
Real vaziyat. Sug'urta zararini bashorat qilishda squared_error bilan model katta da'volarga haddan ortiq e'tibor berardi — bir nechta 100 mln lik hodisa butun modelni tortib ketgan edi. loss="huber" ga o'tilgach, o'rtacha mutlaq xato 22% ga yaxshilandi. Yo'qotish funksiyasini almashtirish — gradient boosting ning asosiy afzalligi.
Bu darsda gradient boosting ni o'rganamiz.
Bu darsda:
- Qoldiqqa moslash
- Funksional gradient tushish
- Yo'qotish funksiyalari
- learning_rate va n_estimators
- subsample
- HistGradientBoosting
- Tuzoqlar
- Amaliy: qo'lda boosting
ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Qoldiqqa moslash
Eng sodda ko'rinish (regressiya, squared_error):
1. F_0(x) = y ning o'rtachasi
2. m = 1..M uchun:
a. qoldiq: r_i = y_i - F_{m-1}(x_i)
b. qoldiqqa daraxt moslanadi: h_m ~ r
c. F_m(x) = F_{m-1}(x) + eta * h_m(x)
3. Yakuniy: F_M(x)
Ya'ni har daraxt OLDINGI modelning XATOSINI bashorat qiladi Bu — gradient boosting ning eng tushunarli ko'rinishi: har daraxt qoldiqni bashorat qiladi. squared_error da qoldiq aynan manfiy gradientga teng, shuning uchun bu sodda tasvir to'g'ri ishlaydi.
2.2. Funksional gradient tushish
Umumiy holat: qoldiq emas, MANFIY GRADIENT
g_i = -dL(y_i, F(x_i)) / dF(x_i)
squared_error: g_i = y_i - F(x_i) (qoldiq)
absolute_error: g_i = sign(y_i - F(x_i)) (faqat belgi)
log_loss: g_i = y_i - p_i (ehtimollik xatosi)
Daraxt g ga moslanadi -> bu funksiyalar fazosida gradient tushish 13.6-bob
Har barg uchun optimal qiymat alohida hisoblanadi (line search) Funksional fazoda gradient tushish — Friedman ning asosiy g'oyasi (2001): parametrlar bo'yicha emas, funksiya bo'yicha optimallashtirish. Har qadam eta uzunlikdagi qadam tashlaydi, daraxt esa yo'nalishni beradi.
2.3. Yo'qotish funksiyalari
Regressiya:
squared_error — standart; chetlangan qiymatlarga sezgir
absolute_error — medianaga moslaydi; chidamli, sekinroq
huber — ikkalasining o'rtasi (alpha bilan)
quantile — kvantil regressiya (alpha bilan) - 13.11
Klassifikatsiya:
log_loss — standart (ehtimollik)
exponential — AdaBoost bilan bir xil
sklearn: GradientBoostingRegressor(loss="huber", alpha=0.9) Yo'qotish funksiyasini almashtirish — gradient boosting ning AdaBoost dan asosiy afzalligi. Chetlangan qiymatlar bo'lgan ma'lumotda huber yoki absolute_error ko'pincha sezilarli yaxshilanish beradi.
2.4. learning_rate va n_estimators
F_M(x) = F_0 + eta * sum(h_m(x))
eta kichik -> har qadam kichik -> ko'p daraxt kerak, yaxshi umumlashtirish
eta katta -> tez o'qiydi -> overfitting xavfi
AMALIY QOIDA:
eta = 0.05..0.1 qo'ying
n_estimators ni ERTA TO'XTATISH bilan toping 15.9-bob
eta ni 2x kamaytirsangiz, n_estimators ni ~2x oshiring Boosting da n_estimators overfitting beradi — bu bagging dan asosiy farq 15.4-bob. Uni CV yoki validatsiya to'plami bilan albatta tanlang.
2.5. subsample
subsample < 1.0 -> Stochastic Gradient Boosting (Friedman, 2002)
har qadamda ma'lumotning tasodifiy qismi ishlatiladi
+ regulyarizatsiya (overfitting kamayadi)
+ tezlik
+ OOB baho imkoniyati (sklearn: oob_improvement_)
Odatiy qiymat: 0.5 - 0.8
max_features ham qo'llaniladi (RF dagi kabi) subsample=0.8 — deyarli bepul yaxshilanish: u tezlikni ham oshiradi, overfitting ni ham kamaytiradi. Ko'p amaliyotchilar uni standart sifatida qo'yadi.
2.6. HistGradientBoosting
HistGradientBoostingClassifier / Regressor (sklearn 0.21+)
belgilarni 255 ta "savat" (bin) ga bo'ladi -> bo'linish qidiruvi juda tez
LightGBM g'oyasiga asoslangan
10-100x TEZROQ (katta ma'lumotda)
NaN ni o'zi boshqaradi
categorical_features bilan kategoriyalarni to'g'ridan-to'g'ri qabul qiladi
early_stopping="auto" (n > 10000 bo'lsa avtomatik)
Eski GradientBoosting* — kichik ma'lumot va staged_* uchun HistGradientBoosting* — sklearn dagi zamonaviy tanlov: eski GradientBoosting* ni faqat kichik ma'lumotlarda yoki staged_predict kerak bo'lganda ishlating. Tezlik farqi 10 000 qatordan boshlab sezilarli.
2.7. Tuzoqlar
Asosiy tuzoqlar: n_estimators ni sozlamaslik; learning_rate=1.0 bilan ishlatish; chuqur daraxtlar (max_depth > 8) qo'yish; chetlangan qiymatlarda squared_error da qolish; katta ma'lumotda eski GradientBoosting* ni ishlatish; subsample ni unutish; erta to'xtatishni test to'plamida qilish (12.9 — leakage); boosting ni shovqinli ma'lumotda sozlamasdan qo'llash.
2.8. Qoldiqqa qarab o'sish
Gradient boosting har qadamda yo'qotish funksiyasining manfiy gradientiga (eng sodda holatda — qoldiqqa) daraxt moslaydi va uni eta bilan qo'shadi. Bu funksional fazoda gradient tushish va u istalgan yo'qotish funksiyasi bilan ishlaydi (huber, quantile, log_loss). learning_rate kichik, n_estimators erta to'xtatish bilan, max_depth 3-6, subsample 0.5-0.8 — odatiy retsept. Katta ma'lumotda HistGradientBoosting*. Keyingi dars — sozlash va erta to'xtatish.
3. Tez ma'lumotnoma
from sklearn.ensemble import (GradientBoostingClassifier, GradientBoostingRegressor,
HistGradientBoostingClassifier,
HistGradientBoostingRegressor)
g = GradientBoostingRegressor(loss="huber", alpha=0.9, learning_rate=0.05,
n_estimators=500, max_depth=3, subsample=0.8,
random_state=0).fit(X, y)
list(g.staged_predict(Xte)) # bosqichma-bosqich
g.train_score_, g.oob_improvement_ # subsample < 1 bo'lsa
h = HistGradientBoostingClassifier(learning_rate=0.05, max_iter=500,
early_stopping=True, validation_fraction=0.1,
random_state=0).fit(X, y)
h.n_iter_ # erta to'xtagan qadam
QOIDA: eta kichik · n_estimators ni erta to'xtatish bilan ·
max_depth 3-6 · subsample 0.8 · katta ma'lumotda Hist*Gradient boosting xulosasi
Har daraxt manfiy gradientga (qoldiqqa) moslanadi
F_m = F_{m-1} + eta * h_m; funksional gradient tushish
Istalgan yo'qotish: squared/absolute/huber/quantile/log_loss
eta 0.05-0.1, max_depth 3-6, subsample 0.8, n_estimators - erta to'xtatish4. Batafsil misollar
Misollar real numpy/pandas/sklearn bilan (Python 3.14).
Misol 1 — Qo'lda gradient boosting
"""Qoldiqqa moslashni noldan qurish (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
def yarat(seed: int = 5, n: int = 1500):
rng = np.random.default_rng(seed)
X = rng.uniform(-3, 3, (n, 4))
f = (np.sin(1.5 * X[:, 0]) + 0.6 * X[:, 1] - 0.3 * X[:, 2] ** 2
+ 0.5 * X[:, 3])
return X, f + rng.normal(0, 0.5, n), f
def main() -> None:
X, y, f = yarat()
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0)
print("=== 1. Boshlang'ich model ===")
F_tr = np.full(len(ytr), ytr.mean())
F_te = np.full(len(yte), ytr.mean())
print(f" F_0 = o'rtacha = {ytr.mean():.4f}")
print(f" test MSE: {mean_squared_error(yte, F_te):.4f}")
print("\n=== 2. Qo'lda 100 qadam (eta = 0.1) ===")
eta = 0.1
print(f" {'qadam':>6} {'qoldiq std':>12} {'o_quv MSE':>11} {'test MSE':>10}")
for m in range(100):
qoldiq = ytr - F_tr
h = DecisionTreeRegressor(max_depth=3, random_state=0).fit(Xtr, qoldiq)
F_tr = F_tr + eta * h.predict(Xtr)
F_te = F_te + eta * h.predict(Xte)
if m in [0, 4, 19, 49, 99]:
print(f" {m + 1:>6} {qoldiq.std():>12.4f} "
f"{mean_squared_error(ytr, F_tr):>11.4f} "
f"{mean_squared_error(yte, F_te):>10.4f}")
print("\n=== 3. sklearn bilan solishtirish ===")
g = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1,
max_depth=3, random_state=0).fit(Xtr, ytr)
print(f" qo'lda: test MSE {mean_squared_error(yte, F_te):.4f}")
print(f" sklearn: test MSE "
f"{mean_squared_error(yte, g.predict(Xte)):.4f}")
print(f" (sklearn har bargda optimal qiymatni alohida hisoblaydi)")
print("\n=== 4. eta ning ta'siri ===")
print(f" {'eta':>6} {'50 qadam':>10} {'100 qadam':>11} {'400 qadam':>11}")
for e in [0.5, 0.2, 0.1, 0.03]:
qator = []
for ne in [50, 100, 400]:
gm = GradientBoostingRegressor(n_estimators=ne, learning_rate=e,
max_depth=3,
random_state=0).fit(Xtr, ytr)
qator.append(mean_squared_error(yte, gm.predict(Xte)))
print(f" {e:>6.2f} " + " ".join(f"{v:>10.4f}" for v in qator))
print(" ⭐ Kichik eta ko'p qadam talab qiladi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Boshlang'ich model ===
F_0 = o'rtacha = -0.9358
test MSE: 2.9935
=== 2. Qo'lda 100 qadam (eta = 0.1) ===
qadam qoldiq std o_quv MSE test MSE
1 1.7534 2.7566 2.6997
5 1.4422 1.9184 1.8969
20 0.9233 0.7947 0.9111
50 0.5479 0.2954 0.4343
100 0.4163 0.1724 0.3228
=== 3. sklearn bilan solishtirish ===
qo'lda: test MSE 0.3228
sklearn: test MSE 0.3235
(sklearn har bargda optimal qiymatni alohida hisoblaydi)
=== 4. eta ning ta'siri ===
eta 50 qadam 100 qadam 400 qadam
0.50 0.4573 0.4562 0.4939
0.20 0.3420 0.3369 0.3683
0.10 0.4348 0.3235 0.3311
0.03 1.1816 0.6862 0.3290
⭐ Kichik eta ko'p qadam talab qiladiNima ko'rsatdi: 2.1, 2.4-bo'limlar.
Misol 2 — Yo'qotish funksiyalari
"""Chetlangan qiymatlarda qaysi yo'qotish yaxshiroq (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.model_selection import train_test_split
def yarat(seed: int = 7, n: int = 2000, chetlangan: float = 0.03):
rng = np.random.default_rng(seed)
X = rng.uniform(-3, 3, (n, 4))
f = np.sin(1.5 * X[:, 0]) + 0.7 * X[:, 1] - 0.3 * X[:, 2] ** 2
y = f + rng.normal(0, 0.5, n)
buzuq = rng.random(n) < chetlangan
y[buzuq] += rng.normal(0, 15, buzuq.sum()) # katta chetlanishlar
return X, y, f, buzuq
def main() -> None:
X, y, f, buzuq = yarat()
itr, ite = train_test_split(np.arange(len(X)), test_size=0.3,
random_state=0)
Xtr, Xte, ytr, yte = X[itr], X[ite], y[itr], y[ite]
fte = f[ite]
print("=== 1. Ma'lumot ===")
print(f" {len(X)} namuna, chetlangan {buzuq.sum()} ta "
f"({buzuq.mean():.1%})")
print(f" y diapazoni: {y.min():.1f} .. {y.max():.1f}")
print("\n=== 2. Yo'qotish funksiyalari (toza signalga nisbatan) ===")
print(f" {'loss':<18} {'MAE(f)':>9} {'RMSE(f)':>10} {'MAE(y)':>9}")
for nom, parametrlar in [("squared_error", {"loss": "squared_error"}),
("absolute_error", {"loss": "absolute_error"}),
("huber 0.9-bob", {"loss": "huber", "alpha": 0.9}),
("huber 0.7-bob", {"loss": "huber", "alpha": 0.7})]:
g = GradientBoostingRegressor(n_estimators=300, learning_rate=0.05,
max_depth=3, subsample=0.8,
random_state=0, **parametrlar).fit(Xtr, ytr)
pred = g.predict(Xte)
print(f" {nom:<18} {mean_absolute_error(fte, pred):>9.4f} "
f"{np.sqrt(mean_squared_error(fte, pred)):>10.4f} "
f"{mean_absolute_error(yte, pred):>9.4f}")
print("\n=== 3. Chetlanish ulushi bo'yicha ===")
print(f" {'ulush':>7} {'squared':>10} {'huber':>10} {'absolute':>10}")
for ch in [0.0, 0.01, 0.05, 0.10]:
Xn, yn, fn, _ = yarat(chetlangan=ch)
ia, ib = train_test_split(np.arange(len(Xn)), test_size=0.3,
random_state=0)
qator = []
for parametrlar in [{"loss": "squared_error"},
{"loss": "huber", "alpha": 0.9},
{"loss": "absolute_error"}]:
g = GradientBoostingRegressor(n_estimators=200, learning_rate=0.05,
max_depth=3, subsample=0.8,
random_state=0,
**parametrlar).fit(Xn[ia], yn[ia])
qator.append(mean_absolute_error(fn[ib], g.predict(Xn[ib])))
print(f" {ch:>7.2f} " + " ".join(f"{v:>10.4f}" for v in qator))
print("\n=== 4. Kvantil regressiya ===")
print(f" {'kvantil':>8} {'qoplash %':>11} {'nazariy %':>11}")
modellar = {}
for q in [0.1, 0.5, 0.9]:
g = GradientBoostingRegressor(loss="quantile", alpha=q,
n_estimators=200, learning_rate=0.05,
max_depth=3,
random_state=0).fit(Xtr, ytr)
modellar[q] = g.predict(Xte)
qoplash = (yte <= modellar[q]).mean()
print(f" {q:>8.1f} {qoplash:>10.1%} {q:>10.1%}")
kenglik = (modellar[0.9] - modellar[0.1])
ichida = ((yte >= modellar[0.1]) & (yte <= modellar[0.9])).mean()
print(f" 80% oraliq: qoplash {ichida:.1%}, "
f"o'rtacha kenglik {kenglik.mean():.3f}")
print(" ⭐ Yo'qotish funksiyasini almashtirish - asosiy afzallik")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Ma'lumot ===
2000 namuna, chetlangan 51 ta (2.5%)
y diapazoni: -41.0 .. 27.5
=== 2. Yo'qotish funksiyalari (toza signalga nisbatan) ===
loss MAE(f) RMSE(f) MAE(y)
squared_error 0.5403 1.2319 1.0901
absolute_error 0.1860 0.2375 0.7893
huber 0.9-bob 0.1919 0.3302 0.8081
huber 0.7-bob 0.1822 0.2466 0.7940
=== 3. Chetlanish ulushi bo'yicha ===
ulush squared huber absolute
0.00 0.1700 0.1741 0.2022
0.01 0.2767 0.1701 0.2010
0.05 0.6518 0.2477 0.2172
0.10 0.9967 0.2722 0.2107
=== 4. Kvantil regressiya ===
kvantil qoplash % nazariy %
0.1 13.0% 10.0%
0.5 52.8% 50.0%
0.9 87.8% 90.0%
80% oraliq: qoplash 74.8%, o'rtacha kenglik 1.474
⭐ Yo'qotish funksiyasini almashtirish - asosiy afzallikNima ko'rsatdi: 2.3-bo'lim.
Misol 3 — Giperparametrlar
"""max_depth, subsample va n_estimators (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
def yarat(seed: int = 11, n: int = 4000, p: int = 12, shovqin: float = 0.10):
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, p))
qoida = (((X[:, 0] > 0.2) & (X[:, 1] < 0.3))
| ((X[:, 2] > 0.4) & (X[:, 3] > -0.1))
| (X[:, 4] < -1.0))
y = qoida.astype(int)
alm = rng.random(n) < shovqin
y[alm] = 1 - y[alm]
return X, y
def main() -> None:
X, y = yarat()
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0,
stratify=y)
print("=== 1. max_depth ===")
print(f" {'max_depth':>10} {'o_quv AUC':>11} {'test AUC':>10} "
f"{'farq':>8}")
for chuqurlik in [1, 2, 3, 5, 8]:
g = GradientBoostingClassifier(n_estimators=200, learning_rate=0.1,
max_depth=chuqurlik,
random_state=0).fit(Xtr, ytr)
a1 = roc_auc_score(ytr, g.predict_proba(Xtr)[:, 1])
a2 = roc_auc_score(yte, g.predict_proba(Xte)[:, 1])
print(f" {chuqurlik:>10} {a1:>11.4f} {a2:>10.4f} {a1 - a2:>8.4f}")
print("\n=== 2. subsample ===")
print(f" {'subsample':>10} {'test AUC':>10}")
for ss in [1.0, 0.8, 0.5, 0.3]:
g = GradientBoostingClassifier(n_estimators=200, learning_rate=0.1,
max_depth=3, subsample=ss,
random_state=0).fit(Xtr, ytr)
print(f" {ss:>10.1f} "
f"{roc_auc_score(yte, g.predict_proba(Xte)[:, 1]):>10.4f}")
print("\n=== 3. n_estimators overfitting beradimi ===")
g = GradientBoostingClassifier(n_estimators=600, learning_rate=0.2,
max_depth=5, random_state=0).fit(Xtr, ytr)
bosqichlar = list(g.staged_predict_proba(Xte))
test_auc = [roc_auc_score(yte, p[:, 1]) for p in bosqichlar]
oquv = list(g.staged_predict_proba(Xtr))
oquv_auc = [roc_auc_score(ytr, p[:, 1]) for p in oquv]
print(f" {'qadam':>6} {'o_quv AUC':>11} {'test AUC':>10}")
for i in [9, 49, 99, 299, 599]:
print(f" {i + 1:>6} {oquv_auc[i]:>11.4f} {test_auc[i]:>10.4f}")
eng = int(np.argmax(test_auc))
print(f" eng yaxshi: {eng + 1}-qadam ({test_auc[eng]:.4f}), "
f"oxirida {test_auc[-1]:.4f}")
print(" (bagging dan farqli: ko'p daraxt ZARAR qilishi mumkin)")
print("\n=== 4. learning_rate va n_estimators bog'liqligi ===")
print(f" {'eta':>6} {'eng yaxshi qadam':>18} {'test AUC':>10}")
for e in [0.3, 0.1, 0.05, 0.02]:
g = GradientBoostingClassifier(n_estimators=500, learning_rate=e,
max_depth=3, subsample=0.8,
random_state=0).fit(Xtr, ytr)
auc = [roc_auc_score(yte, p[:, 1])
for p in g.staged_predict_proba(Xte)]
eng = int(np.argmax(auc))
print(f" {e:>6.2f} {eng + 1:>18} {auc[eng]:>10.4f}")
print(" ⭐ eta kichrayganda kerakli qadamlar soni oshadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. max_depth ===
max_depth o_quv AUC test AUC farq
1 0.8872 0.8830 0.0042
2 0.9422 0.9101 0.0322
3 0.9777 0.9113 0.0664
5 0.9996 0.9123 0.0874
8 1.0000 0.9204 0.0796
=== 2. subsample ===
subsample test AUC
1.0 0.9113
0.8 0.9139
0.5 0.9129
0.3 0.9127
=== 3. n_estimators overfitting beradimi ===
qadam o_quv AUC test AUC
10 0.9520 0.9124
50 0.9939 0.9126
100 0.9997 0.9130
300 1.0000 0.9143
600 1.0000 0.9165
eng yaxshi: 567-qadam 0.9165-bob, oxirida 0.9165
(bagging dan farqli: ko'p daraxt ZARAR qilishi mumkin)
=== 4. learning_rate va n_estimators bog'liqligi ===
eta eng yaxshi qadam test AUC
0.30 9 0.9187
0.10 9 0.9194
0.05 21 0.9193
0.02 54 0.9184
⭐ eta kichrayganda kerakli qadamlar soni oshadiNima ko'rsatdi: 2.4, 2.5-bo'limlar.
Misol 4 — HistGradientBoosting
"""Zamonaviy sklearn implementatsiyasi (real numpy/pandas/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.ensemble import (GradientBoostingClassifier,
HistGradientBoostingClassifier,
RandomForestClassifier)
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
def yarat(seed: int = 2, n: int = 20000) -> pd.DataFrame:
rng = np.random.default_rng(seed)
hudud = rng.choice(["toshkent", "samarqand", "buxoro", "fargona"], n,
p=[0.4, 0.25, 0.2, 0.15])
tur = rng.choice(["oddiy", "tezkor", "yirik"], n, p=[0.6, 0.3, 0.1])
masofa = rng.gamma(3, 60, n)
ogirlik = rng.gamma(2, 4, n)
soat = rng.integers(0, 24, n).astype(float)
hq = pd.Series(hudud).map({"toshkent": 0.0, "samarqand": 0.4,
"buxoro": 0.8, "fargona": 0.5}).to_numpy()
tt = pd.Series(tur).map({"oddiy": 0.0, "tezkor": -0.9,
"yirik": 1.0}).to_numpy()
kuch = (-3.0 + 0.006 * masofa + 0.05 * ogirlik + hq + tt
+ 1.0 * ((soat >= 7) & (soat <= 10)))
y = (rng.random(n) < 1 / (1 + np.exp(-kuch))).astype(int)
df = pd.DataFrame({"hudud": pd.Categorical(hudud),
"tur": pd.Categorical(tur), "masofa": masofa,
"ogirlik": ogirlik, "soat": soat, "kechikdi": y})
# 3% yo'qolgan qiymat
yoq = rng.random(n) < 0.03
df.loc[yoq, "ogirlik"] = np.nan
return df
def main() -> None:
df = yarat()
X = df.drop(columns="kechikdi")
y = df["kechikdi"]
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0,
stratify=y)
print("=== 1. Ma'lumot ===")
print(f" {len(df)} qator, kechikish {y.mean():.2%}")
print(f" yo'qolgan qiymatlar: {int(df['ogirlik'].isna().sum())}")
print(f" kategoriyali: hudud, tur")
print("\n=== 2. HistGradientBoosting (NaN va kategoriya avtomatik) ===")
h = HistGradientBoostingClassifier(learning_rate=0.1, max_iter=400,
early_stopping=True,
validation_fraction=0.15,
categorical_features="from_dtype",
random_state=0).fit(Xtr, ytr)
ph = h.predict_proba(Xte)[:, 1]
print(f" erta to'xtagan qadam: {h.n_iter_} (max 400)")
print(f" test ROC AUC: {roc_auc_score(yte, ph):.4f}")
print("\n=== 3. Boshqa modellar bilan solishtirish ===")
# eski GradientBoosting NaN va kategoriyani qabul qilmaydi
Xtr2 = pd.get_dummies(Xtr, columns=["hudud", "tur"]).fillna(-1)
Xte2 = pd.get_dummies(Xte, columns=["hudud", "tur"]).fillna(-1)
Xte2 = Xte2.reindex(columns=Xtr2.columns, fill_value=0)
g = GradientBoostingClassifier(n_estimators=200, learning_rate=0.1,
max_depth=3, subsample=0.8,
random_state=0).fit(Xtr2, ytr)
r = RandomForestClassifier(n_estimators=300, random_state=0,
n_jobs=1).fit(Xtr2, ytr)
print(f" HistGradientBoosting: {roc_auc_score(yte, ph):.4f}")
print(f" GradientBoosting: "
f"{roc_auc_score(yte, g.predict_proba(Xte2)[:, 1]):.4f}")
print(f" RandomForest: "
f"{roc_auc_score(yte, r.predict_proba(Xte2)[:, 1]):.4f}")
print("\n=== 4. Model hajmi va qadamlar ===")
print(f" Hist: {h.n_iter_} qadam, "
f"max_leaf_nodes={h.max_leaf_nodes}")
tugunlar = sum(e.tree_.node_count for e in r.estimators_)
print(f" RF: {len(r.estimators_)} daraxt, jami {tugunlar:,} tugun")
gb_tugun = sum(t[0].tree_.node_count for t in g.estimators_)
print(f" GB: {len(g.estimators_)} daraxt, jami {gb_tugun:,} tugun")
print(" ⭐ Hist* - katta ma'lumot uchun standart tanlov")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Ma'lumot ===
20000 qator, kechikish 26.85%
yo'qolgan qiymatlar: 594
kategoriyali: hudud, tur
=== 2. HistGradientBoosting (NaN va kategoriya avtomatik) ===
erta to'xtagan qadam: 43 (max 400)
test ROC AUC: 0.7388
=== 3. Boshqa modellar bilan solishtirish ===
HistGradientBoosting: 0.7388
GradientBoosting: 0.7393
RandomForest: 0.6970
=== 4. Model hajmi va qadamlar ===
Hist: 43 qadam, max_leaf_nodes=31
RF: 300 daraxt, jami 1,778,356 tugun
GB: 200 daraxt, jami 2,974 tugun
⭐ Hist* - katta ma'lumot uchun standart tanlovNima ko'rsatdi: 2.6-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Boosting har doim qoldiqqa moslanadi" | Manfiy gradientga |
| "n_estimators ko'p bo'lsa yaxshi" | Overfitting beradi |
| "squared_error har doim mos" | Chetlanishda huber |
| "max_depth katta bo'lsin" | 3-6 |
| "subsample sifatni buzadi" | Ko'pincha yaxshilaydi |
| "GradientBoosting va Hist* bir xil" | Hist* 10-100x tez |
| "GB masshtablash talab qiladi" | Yo'q |
| "GB ehtimolliklari kalibrlangan" | Odatda yaxshi, lekin tekshiring |
6. Keng tarqalgan xatolar va yechimlari
1. n_estimators ni sozlamaslik
GradientBoostingClassifier(n_estimators=2000) # ⚠️
# staged_* yoki early_stopping bilan toping 15.9-bob # ✅2. learning_rate=1.0
GradientBoostingRegressor(learning_rate=1.0) # ⚠️
GradientBoostingRegressor(learning_rate=0.05, n_estimators=500) # ✅3. Chuqur daraxtlar
GradientBoostingClassifier(max_depth=15) # ⚠️
GradientBoostingClassifier(max_depth=3) # ✅4. Chetlanishda squared_error
GradientBoostingRegressor() # chetlangan qiymatlar bor # ⚠️
GradientBoostingRegressor(loss="huber", alpha=0.9) # ✅5. Katta ma'lumotda eski implementatsiya
GradientBoostingClassifier(n_estimators=500) # 500k qator # ⚠️
HistGradientBoostingClassifier(max_iter=500) # ✅6. subsample ni unutish
GradientBoostingClassifier(n_estimators=500) # ⚠️
GradientBoostingClassifier(n_estimators=500, subsample=0.8) # ✅7. Testda erta to'xtatish
# staged_score(Xte, yte) bo'yicha qadam tanlash # ⚠️
# validation_fraction yoki alohida validatsiya to'plami # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 15.7-dars (o'tilgan): Boosting g'oyasi
- 13.6-dars (o'tilgan): Gradient tushish
- 15.9-dars: Sozlash va erta to'xtatish
- 15.10-dars: XGBoost va LightGBM
- 13.11-dars (o'tilgan): Kvantil regressiya
8. Eng yaxshi amaliyotlar
learning_rate ni kichik qo'ying.
n_estimators ni erta to'xtatish bilan toping.
max_depth 3-6.
subsample 0.8 qo'ying.
Yo'qotish funksiyasini vazifaga moslang.
Katta ma'lumotda Hist ishlating.*
Validatsiyani ajrating.
RF bilan taqqoslang.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # gradient boosting nimaga moslanadi?
2. # squared_error da gradient nima?
3. # F_0 nima?
4. # yangilash formulasi?
5. # loss variantlari (regressiya)?
6. # huber nima uchun?
7. # quantile nima beradi?
8. # max_depth odatiy?
9. # subsample odatiy?
10. # n_estimators overfitting beradimi?
11. # eta va n_estimators bog'liqmi?
12. # Hist* qachon?Javoblar
- Manfiy gradientga
- Qoldiq (y - F)
- O'rtacha (yoki log-odds)
- F_m = F_{m-1} + eta·h_m
- squared/absolute/huber/quantile
- Chetlangan qiymatlar
- Bashorat oralig'i
- 3-6
- 0.5-0.8
- Ha
- Ha, teskari
- Katta ma'lumotda
Vazifa 2: Xatolarni tuzating
1. GradientBoostingClassifier(n_estimators=3000)
2. GradientBoostingRegressor(learning_rate=1.0)
3. GradientBoostingClassifier(max_depth=20)
4. GradientBoostingRegressor() # chetlangan qiymatlar bor
5. GradientBoostingClassifier() # 1 mln qatorJavoblar
1. # early_stopping / staged_* bilan qadamni toping
2. GradientBoostingRegressor(learning_rate=0.05, n_estimators=500)
3. GradientBoostingClassifier(max_depth=3)
4. GradientBoostingRegressor(loss="huber", alpha=0.9)
5. HistGradientBoostingClassifier(max_iter=500)Vazifa 3: Qo'lda boosting
Modellang:
- F_0
- 100 qadam
- sklearn
- eta
Vazifa 4: Yo'qotish
Modellang:
- Ma'lumot
- To'rt loss
- Chetlanish ulushi
- Kvantil
Vazifa 5: Giperparametrlar
Modellang:
- max_depth
- subsample
- n_estimators
- eta bog'liqligi
Vazifa 6: Hist
Modellang:
- Ma'lumot
- Hist
- Solishtirish
- Hajm
Vazifa 7: O'ylash
Gradient boosting da har daraxt oldingilarning xatosini tuzatadi. Nega u holda bitta katta, chuqur daraxt qurib qo'ya qolmaymiz — u ham barcha xatolarni tuzatadi-ku?
Javob
Qisqa javob: chuqur daraxt xatolarni yodlash orqali tuzatadi, boosting esa ularni bosqichma-bosqich va regulyarizatsiya bilan tuzatadi. Farq — qanday tuzatilishida, tuzatilish faktida emas.
1. Ikki yo'lning farqi
| Jihat | Bitta chuqur daraxt | Boosting |
|---|---|---|
| Har bo'linish | Butun ma'lumotni ko'radi | Qoldiqqa qaraydi |
| Qadam kattaligi | Cheklanmagan | eta bilan kichraytirilgan |
| Regulyarizatsiya | Faqat pruning | eta, subsample, chuqurlik, n_est |
| Xatoni tuzatish | Yodlash | Umumiy naqshni topish |
2. eta ning roli
Boosting har qadamda xatoning butunini emas, eta qismini tuzatadi. Bu:
- Bitta daraxtning tasodifiy qarorini yumshatadi
- Keyingi daraxtlarga tuzatish imkonini qoldiradi
- Ko'p daraxt bir naqshni "tasdiqlashi" kerak bo'ladi
Shovqin bunday tasdiqni ololmaydi — faqat haqiqiy naqsh oladi.
3. Qo'shimcha model ustunligi
- Chuqur daraxt: bitta bo'lakli doimiy funksiya, qo'pol chegaralar
- Boosting: yuzlab sayoz daraxt yig'indisi -> silliqroq funksiya
- Natijada bir xil murakkablikda umumlashtirish yaxshiroq
4. Empirik tasdiq
Misol 3 da max_depth=8 bilan boosting max_depth=3 dan yomonroq natija berdi — chuqurroq daraxt bu yerda ham zarar keltiradi.
5. Xulosa
- Muhimi — xatoni tuzatish emas, uni QANDAY tuzatish
etakichik qadamlar orqali regulyarizatsiya qiladi- Ko'p sayoz daraxt bitta chuqur daraxtdan silliqroq
- Shuning uchun boosting da
max_depthkichik
Nimani mustahkamlaydi: 2.1, 2.4-bo'limlar.
Xulosa
Bu darsda gradient boosting ni o'rgandik.
Eng muhim uch fikr:
Har daraxt qoldiqqa (gradientga) moslanadi.
F_m = F_{m-1} + eta * h_m, bundah_myo'qotish funksiyasining manfiy gradientiga moslanadi.squared_errorda bu aynan qoldiq,log_lossda —y - p. Bu funksional fazoda gradient tushish 13.6-bob va u AdaBoost ni istalgan yo'qotish funksiyasiga umumlashtiradi.Yo'qotish funksiyasini almashtirish mumkin. Chetlangan qiymatlarda
huberyokiabsolute_error, bashorat oralig'i kerak bo'lsaquantile13.11-bob, klassifikatsiyadalog_loss. Bu — gradient boosting ning AdaBoost dan asosiy amaliy afzalligi.Odatiy retsept: kichik qadam, sayoz daraxt.
learning_rate0.05-0.1,max_depth3-6,subsample0.5-0.8,n_estimatorsesa erta to'xtatish bilan tanlanadi — u bagging dagidek bepul emas va overfitting beradi. Katta ma'lumotdaHistGradientBoosting*(10-100x tez, NaN va kategoriyalarni o'zi boshqaradi).
Keyingi darsda boosting ni sozlash va erta to'xtatishni o'rganamiz: qaysi parametrni qaysi tartibda va qanday tanlash kerak.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!