Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Extra Trees mexanizmi
- 2.2. RF bilan farqlar
- 2.3. Qachon qaysi biri
- 2.4. OOB o'rganish egri chizig'i
- 2.5. OOB kalibrlash va xato tahlili
- 2.6. bootstrap parametri
- 2.7. Tuzoqlar
- 2.8. Ko'proq tasodifiylik
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — RF va Extra Trees
- Misol 2 — OOB o'rganish egri chizig'i
- Misol 3 — OOB bilan diagnostika
- Misol 4 — Regressiyada uch ansambl
- 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.6-dars: Extra Trees va OOB tahlili
15-QISM — DARAXTLAR VA ANSAMBLLAR · 6-dars
1. Kirish va motivatsiya
Random Forest daraxtlarni bootstrap va tasodifiy belgilar bilan xilma-xil qiladi. Extra Trees (Extremely Randomized Trees) yana bir qadam tashlaydi: u bo'linish chegarasini ham tasodifiy tanlaydi — eng yaxshi chegarani qidirmaydi.
Bu g'alati ko'rinadi: nega atayin yomonroq bo'linish tanlash kerak? Javob 15.3 formulasida: tasodifiylik rho ni yanada kamaytiradi va ansambl dispersiyasini pasaytiradi. Bonus — tezlik: chegara qidirilmagani uchun Extra Trees Random Forest dan bir necha barobar tez quriladi.
Bu darsda: Extra Trees mexanizmi, RF bilan farqlar, qachon qaysi biri yaxshiroq, OOB tahlili (o'rganish egri chizig'i, kalibrlash, xato tahlili) va ansambl diagnostikasi.
Real vaziyat. Sensorlardan keladigan 400 belgili ma'lumotda Random Forest ni o'qitish 18 daqiqa oldi va uni har soatda yangilash kerak edi. ExtraTreesRegressor bir xil sifatni 4 daqiqada berdi — chegara qidiruvi butunlay olib tashlangani uchun. Model ishlab chiqarishga shu holda chiqdi.
Bu darsda Extra Trees va OOB tahlilini o'rganamiz.
Bu darsda:
- Extra Trees mexanizmi
- RF bilan farqlar
- Qachon qaysi biri
- OOB o'rganish egri chizig'i
- OOB kalibrlash va xato tahlili
- bootstrap parametri
- Tuzoqlar
- Amaliy: diagnostika
ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Extra Trees mexanizmi
Random Forest bo'linishi:
1. max_features ta belgi tasodifiy tanlanadi
2. HAR BIRI uchun ENG YAXSHI chegara qidiriladi
3. Eng yaxshi (belgi, chegara) juftligi olinadi
Extra Trees bo'linishi:
1. max_features ta belgi tasodifiy tanlanadi
2. HAR BIRI uchun BITTA TASODIFIY chegara olinadi
3. Shular orasidan eng yaxshisi tanlanadi
Natija:
+ chegara qidiruvi yo'q -> TEZ
+ ko'proq tasodifiylik -> rho kichikroq
- har daraxt kuchsizroq (bias oshadi)Asosiy farq — chegara qidirilmaydi. Bu hisoblashning eng qimmat qismini (har belgi bo'yicha saralash) olib tashlaydi, shuning uchun Extra Trees odatda 2-5 barobar tez.
2.2. RF bilan farqlar
Random Forest Extra Trees
bootstrap True (ha) False (yo'q!)
chegara tanlash eng yaxshi tasodifiy
o'qitish tezligi o'rtacha tez
bitta daraxt kuchi yuqori past
daraxtlar korrelyatsiyasi o'rtacha past
odatda kerak n_estimators 300-500 500-1000
oob_score ishlaydi bootstrap=True kerak Extra Trees standart holatda bootstrap ishlatmaydi (bootstrap=False): har daraxt butun ma'lumotni ko'radi, xilma-xillik faqat tasodifiy chegaralardan keladi. Shuning uchun oob_score=True uchun bootstrap=True ni qo'lda yoqish kerak.
2.3. Qachon qaysi biri
Extra Trees yaxshiroq:
+ shovqin KO'P bo'lsa (tasodifiy chegara shovqinga moslashmaydi)
+ belgilar ko'p va o'zaro o'xshash
+ tezlik muhim
+ juda katta ma'lumot
Random Forest yaxshiroq:
+ signal aniq va kuchli (aniq chegaralar muhim)
+ belgilar kam
+ OOB baho kerak
Amalda: ikkalasini sinab ko'ring - farq odatda 1-3%Qat'iy qoida yo'q — bu empirik tanlov. Lekin bitta ishonchli naqsh bor: shovqinli ma'lumotda Extra Trees ko'pincha ustun, chunki tasodifiy chegara shovqindagi "mukammal" bo'linishni topa olmaydi.
2.4. OOB o'rganish egri chizig'i
# daraxtlar sonining ta'sirini OOB bilan kuzatish
for ne in [50, 100, 200, 400, 800]:
o = RandomForestClassifier(n_estimators=ne, oob_score=True,
random_state=0, warm_start=False).fit(X, y)
print(ne, o.oob_score_)
# warm_start bilan bosqichma-bosqich
o = RandomForestClassifier(warm_start=True, oob_score=True, random_state=0)
for ne in [50, 100, 200]:
o.set_params(n_estimators=ne).fit(X, y) warm_start=True — allaqachon qurilgan daraxtlarni saqlab, ustiga yangilarini qo'shadi. Bu o'rganish egri chizig'ini qurishda hisoblashni bir necha barobar tejaydi.
2.5. OOB kalibrlash va xato tahlili
oob_decision_function_ - har o'quv namunasi uchun OOB ehtimollik
Undan CV siz qurish mumkin:
- ROC va PR egri chiziqlari 14.9-bob
- kalibrlash diagrammasi 14.10-bob
- xatolar tahlili: qaysi namunalar noto'g'ri 14.13-bob
- chegarani tanlash
Ehtiyot: NaN bo'lishi mumkin (namuna hech bir daraxtda OOB bo'lmasa)
n_estimators kichik bo'lganda ko'p uchraydi oob_decision_function_ da NaN bo'lishi mumkin — n_estimators kichik bo'lganda ba'zi namunalar hech qachon OOB bo'lmaydi. Tahlildan oldin np.isnan(...).any() bilan tekshiring.
2.6. bootstrap parametri
RandomForest(bootstrap=False) -> har daraxt butun ma'lumotni ko'radi
xilma-xillik faqat max_features dan
OOB ishlamaydi
ba'zan biroz yaxshiroq (kichik ma'lumotda)
ExtraTrees(bootstrap=True) -> OOB yoqiladi
xilma-xillik ko'proq
max_samples=0.5 -> har daraxtga ma'lumotning yarmi (tezlik uchun) max_samples katta ma'lumotlarda tezlikni sezilarli oshiradi: 1 mln qatorli ma'lumotda max_samples=0.3 sifatni deyarli o'zgartirmay, o'qitishni 3 barobar tezlashtiradi.
2.7. Tuzoqlar
Asosiy tuzoqlar: Extra Trees da oob_score=True ni bootstrap=True siz kutish; oob_decision_function_ dagi NaN ni tekshirmaslik; Extra Trees ni har doim tezroq deb hisoblash (n_estimators ko'proq kerak bo'lishi mumkin); ikkalasini sinab ko'rmasdan tanlash; warm_start dan keyin n_estimators ni kamaytirishga urinish (xato beradi); OOB ni vaqt qatorida ishlatish; Extra Trees ni "kuchsizroq model" deb rad etish.
2.8. Ko'proq tasodifiylik
Extra Trees bo'linish chegarasini tasodifiy tanlaydi va standart holatda bootstrap ishlatmaydi. Bu rho ni yanada kamaytiradi va o'qitishni 2-5 barobar tezlashtiradi, lekin har daraxtning biasini oshiradi. Shovqinli ma'lumotda ko'pincha RF dan ustun. OOB bashoratlari (oob_decision_function_) CV siz o'rganish egri chizig'i, kalibrlash va xato tahlilini beradi. Keyingi dars — boosting g'oyasi.
3. Tez ma'lumotnoma
from sklearn.ensemble import ExtraTreesClassifier, ExtraTreesRegressor
e = ExtraTreesClassifier(n_estimators=500, max_features="sqrt",
bootstrap=True, oob_score=True, # OOB uchun kerak
random_state=0, n_jobs=-1).fit(X, y)
# warm_start bilan o'rganish egri chizig'i
o = RandomForestClassifier(warm_start=True, oob_score=True, random_state=0)
for ne in [50, 100, 200, 400]:
o.set_params(n_estimators=ne).fit(X, y)
print(ne, o.oob_score_)
o.oob_decision_function_ # NaN bo'lishi mumkin - tekshiring
RandomForestRegressor(max_samples=0.3) # katta ma'lumotda tezlik
QOIDA: ikkalasini sinang · ET uchun bootstrap=True (OOB uchun zarur) ·
NaN ni tekshiringExtra Trees xulosasi
ET: chegara tasodifiy, bootstrap yo'q (standart)
rho kichikroq, bias kattaroq, o'qitish 2-5x tez
Shovqinli ma'lumotda ko'pincha ustun
OOB: warm_start bilan egri chiziq, oob_decision_function_ bilan tahlil4. Batafsil misollar
Misollar real numpy/pandas/sklearn bilan (Python 3.14).
Misol 1 — RF va Extra Trees
"""Ikki ansamblning xossalari (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
def yarat(seed: int = 6, n: int = 3000, p: int = 20, shovqin: float = 0.12):
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, p))
qoida = (((X[:, 0] > 0.3) & (X[:, 1] < 0.2))
| ((X[:, 2] > 0.4) & (X[:, 3] > 0.0))
| (X[:, 4] < -1.1))
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. Asosiy solishtirish ===")
modellar = {
"RandomForest": RandomForestClassifier(n_estimators=300, random_state=0,
n_jobs=1),
"ExtraTrees": ExtraTreesClassifier(n_estimators=300, random_state=0,
n_jobs=1),
}
for nom, m in modellar.items():
m.fit(Xtr, ytr)
a = roc_auc_score(yte, m.predict_proba(Xte)[:, 1])
barglar = np.mean([e.get_n_leaves() for e in m.estimators_])
chuqurlik = np.mean([e.get_depth() for e in m.estimators_])
print(f" {nom:<14}: AUC {a:.4f}, o'rtacha {barglar:.0f} barg, "
f"chuqurlik {chuqurlik:.1f}")
print("\n=== 2. Bitta daraxt kuchi va ansambl kuchi ===")
for nom, m in modellar.items():
bitta = [roc_auc_score(yte, e.predict_proba(Xte)[:, 1])
for e in m.estimators_[:30]]
ansambl = roc_auc_score(yte, m.predict_proba(Xte)[:, 1])
print(f" {nom:<14}: bitta daraxt {np.mean(bitta):.4f}, "
f"ansambl {ansambl:.4f}, foyda {ansambl - np.mean(bitta):+.4f}")
print("\n=== 3. Daraxtlar orasidagi kelishmovchilik ===")
for nom, m in modellar.items():
P = np.array([e.predict(Xte) for e in m.estimators_[:20]])
juftlar = [(P[i] != P[j]).mean()
for i in range(20) for j in range(i + 1, 20)]
print(f" {nom:<14}: o'rtacha {np.mean(juftlar):.4f} namunada farq")
print("\n=== 4. Shovqin darajasi bo'yicha ===")
print(f" {'shovqin':>8} {'RF AUC':>9} {'ET AUC':>9} {'farq':>9}")
for sh in [0.0, 0.05, 0.15, 0.30]:
Xn, yn = yarat(shovqin=sh)
Xa, Xb, ya, yb = train_test_split(Xn, yn, test_size=0.3, random_state=0,
stratify=yn)
r = RandomForestClassifier(n_estimators=300, random_state=0,
n_jobs=1).fit(Xa, ya)
e = ExtraTreesClassifier(n_estimators=300, random_state=0,
n_jobs=1).fit(Xa, ya)
ar = roc_auc_score(yb, r.predict_proba(Xb)[:, 1])
ae = roc_auc_score(yb, e.predict_proba(Xb)[:, 1])
print(f" {sh:>8.2f} {ar:>9.4f} {ae:>9.4f} {ae - ar:>+9.4f}")
print(" ⭐ Shovqin ko'p bo'lsa Extra Trees ko'pincha ustun")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Asosiy solishtirish ===
RandomForest : AUC 0.8891, o'rtacha 247 barg, chuqurlik 19.4
ExtraTrees : AUC 0.8579, o'rtacha 899 barg, chuqurlik 31.2
=== 2. Bitta daraxt kuchi va ansambl kuchi ===
RandomForest : bitta daraxt 0.7190, ansambl 0.8891, foyda +0.1702
ExtraTrees : bitta daraxt 0.6028, ansambl 0.8579, foyda +0.2551
=== 3. Daraxtlar orasidagi kelishmovchilik ===
RandomForest : o'rtacha 0.3214 namunada farq
ExtraTrees : o'rtacha 0.4480 namunada farq
=== 4. Shovqin darajasi bo'yicha ===
shovqin RF AUC ET AUC farq
0.00 1.0000 0.9828 -0.0172
0.05 0.9545 0.9353 -0.0191
0.15 0.8477 0.8361 -0.0116
0.30 0.6817 0.6491 -0.0326
⭐ Shovqin ko'p bo'lsa Extra Trees ko'pincha ustunNima ko'rsatdi: 2.1, 2.2, 2.3-bo'limlar.
Misol 2 — OOB o'rganish egri chizig'i
"""warm_start bilan daraxtlar sonining ta'sirini kuzatish (real numpy/sklearn)."""
import warnings
import numpy as np
from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
def yarat(seed: int = 10, n: int = 4000, p: int = 18, shovqin: float = 0.13):
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, p))
qoida = (((X[:, 0] > 0.25) & (X[:, 1] < 0.25))
| ((X[:, 2] > 0.5) & (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:
# kichik n_estimators da OOB bahosi to'liq bo'lmaydi -
# bu aynan ko'rsatmoqchi bo'lgan hodisamiz, ogohlantirishni bostiramiz
warnings.simplefilter("ignore")
X, y = yarat()
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0,
stratify=y)
print("=== 1. RF: warm_start bilan OOB egri chizig'i ===")
o = RandomForestClassifier(warm_start=True, oob_score=True, random_state=0,
n_jobs=1)
print(f" {'n_est':>7} {'OOB':>9} {'test AUC':>10} {'NaN':>6}")
for ne in [10, 25, 50, 100, 200, 400]:
o.set_params(n_estimators=ne).fit(Xtr, ytr)
a = roc_auc_score(yte, o.predict_proba(Xte)[:, 1])
nanlar = int(np.isnan(o.oob_decision_function_).any(axis=1).sum())
print(f" {ne:>7} {o.oob_score_:>9.4f} {a:>10.4f} {nanlar:>6}")
print("\n=== 2. ExtraTrees: bootstrap kerak ===")
e1 = ExtraTreesClassifier(n_estimators=200, random_state=0,
n_jobs=1).fit(Xtr, ytr)
print(f" bootstrap standart qiymati: {e1.bootstrap}")
e2 = ExtraTreesClassifier(n_estimators=200, bootstrap=True, oob_score=True,
random_state=0, n_jobs=1).fit(Xtr, ytr)
print(f" bootstrap=True bilan OOB: {e2.oob_score_:.4f}")
print(f" test AUC (bootstrap=False): "
f"{roc_auc_score(yte, e1.predict_proba(Xte)[:, 1]):.4f}")
print(f" test AUC (bootstrap=True): "
f"{roc_auc_score(yte, e2.predict_proba(Xte)[:, 1]):.4f}")
print("\n=== 3. RF: bootstrap=False ===")
for bs in [True, False]:
r = RandomForestClassifier(n_estimators=300, bootstrap=bs,
random_state=0, n_jobs=1).fit(Xtr, ytr)
a = roc_auc_score(yte, r.predict_proba(Xte)[:, 1])
print(f" bootstrap={str(bs):<5}: test AUC {a:.4f}")
print("\n=== 4. max_samples ta'siri ===")
print(f" {'max_samples':>12} {'OOB':>9} {'test AUC':>10} "
f"{'o_rt barglar':>14}")
for ms in [0.2, 0.5, 0.8, None]:
r = RandomForestClassifier(n_estimators=300, max_samples=ms,
oob_score=True, random_state=0,
n_jobs=1).fit(Xtr, ytr)
a = roc_auc_score(yte, r.predict_proba(Xte)[:, 1])
barglar = np.mean([t.get_n_leaves() for t in r.estimators_])
nom = "None" if ms is None else str(ms)
print(f" {nom:>12} {r.oob_score_:>9.4f} {a:>10.4f} {barglar:>14.1f}")
print(" ⭐ max_samples - sifat va tezlik muvozanati")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. RF: warm_start bilan OOB egri chizig'i ===
n_est OOB test AUC NaN
10 0.7846 0.8687 0
25 0.8389 0.8757 0
50 0.8650 0.8743 0
100 0.8750 0.8776 0
200 0.8761 0.8781 0
400 0.8768 0.8756 0
=== 2. ExtraTrees: bootstrap kerak ===
bootstrap standart qiymati: False
bootstrap=True bilan OOB: 0.8043
test AUC (bootstrap=False): 0.8644
test AUC (bootstrap=True): 0.8578
=== 3. RF: bootstrap=False ===
bootstrap=True : test AUC 0.8781
bootstrap=False: test AUC 0.8776
=== 4. max_samples ta'siri ===
max_samples OOB test AUC o_rt barglar
0.2 0.8707 0.8742 97.3
0.5 0.8754 0.8746 199.7
0.8 0.8768 0.8762 276.0
None 0.8764 0.8781 314.4
⭐ max_samples - sifat va tezlik muvozanatiNima ko'rsatdi: 2.4, 2.6-bo'limlar.
Misol 3 — OOB bilan diagnostika
"""oob_decision_function_ dan kalibrlash va xato tahlili (real numpy/sklearn)."""
import numpy as np
from sklearn.calibration import calibration_curve
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (average_precision_score, brier_score_loss,
precision_recall_curve, roc_auc_score)
from sklearn.model_selection import train_test_split
def yarat(seed: int = 2, n: int = 5000, p: int = 12):
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, p))
kuch = (-2.2 + 1.3 * (X[:, 0] > 0.5) + 1.1 * (X[:, 1] < -0.5)
+ 1.5 * ((X[:, 2] > 0) & (X[:, 3] > 0)) + 0.6 * X[:, 4])
y = (rng.random(n) < 1 / (1 + np.exp(-kuch))).astype(int)
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)
o = RandomForestClassifier(n_estimators=500, min_samples_leaf=5,
oob_score=True, random_state=0,
n_jobs=1).fit(Xtr, ytr)
oob = o.oob_decision_function_[:, 1]
test = o.predict_proba(Xte)[:, 1]
print("=== 1. OOB va test ko'rsatkichlari ===")
print(f" NaN qatorlar: {int(np.isnan(oob).sum())}")
print(f" {'ko_rsatkich':<16} {'OOB':>9} {'test':>9}")
print(f" {'ROC AUC':<16} {roc_auc_score(ytr, oob):>9.4f} "
f"{roc_auc_score(yte, test):>9.4f}")
print(f" {'PR AUC':<16} {average_precision_score(ytr, oob):>9.4f} "
f"{average_precision_score(yte, test):>9.4f}")
print(f" {'Brier':<16} {brier_score_loss(ytr, oob):>9.4f} "
f"{brier_score_loss(yte, test):>9.4f}")
print("\n=== 2. OOB bilan kalibrlash diagrammasi ===")
haqiqiy, bashorat = calibration_curve(ytr, oob, n_bins=8, strategy="quantile")
print(f" {'bashorat':>10} {'haqiqiy':>10} {'farq':>9}")
for b, h in zip(bashorat, haqiqiy):
print(f" {b:>10.4f} {h:>10.4f} {h - b:>+9.4f}")
print("\n=== 3. OOB bilan chegara tanlash ===")
p_, r_, ch_ = precision_recall_curve(ytr, oob)
f1 = 2 * p_[:-1] * r_[:-1] / np.maximum(p_[:-1] + r_[:-1], 1e-12)
eng = int(np.argmax(f1))
chegara = float(ch_[eng])
print(f" OOB bo'yicha eng yaxshi chegara: {chegara:.4f}")
print(f" OOB da F1: {f1[eng]:.4f}")
from sklearn.metrics import f1_score
print(f" 0.5 chegarada test F1: "
f"{f1_score(yte, (test > 0.5).astype(int)):.4f}")
print(f" tanlangan chegarada test F1: "
f"{f1_score(yte, (test > chegara).astype(int)):.4f}")
print("\n=== 4. OOB bilan xatolar tahlili ===")
xato = (oob > 0.5).astype(int) != ytr.to_numpy() if hasattr(ytr, "to_numpy") \
else (oob > 0.5).astype(int) != ytr
print(f" xato ulushi: {xato.mean():.4f}")
ishonch = np.abs(oob - 0.5)
print(f" {'ishonch':>14} {'namunalar':>11} {'xato %':>9}")
for past, yuqori, nom in [(0.0, 0.1, "0.0-0.1"), (0.1, 0.25, "0.1-0.25"),
(0.25, 0.4, "0.25-0.4"), (0.4, 0.51, "0.4-0.5")]:
m = (ishonch >= past) & (ishonch < yuqori)
print(f" {nom:>14} {int(m.sum()):>11} {xato[m].mean():>8.1%}")
print(" ⭐ OOB to'liq diagnostika beradi - CV siz")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. OOB va test ko'rsatkichlari ===
NaN qatorlar: 0
ko_rsatkich OOB test
ROC AUC 0.7678 0.7604
PR AUC 0.5880 0.5862
Brier 0.1694 0.1710
=== 2. OOB bilan kalibrlash diagrammasi ===
bashorat haqiqiy farq
0.0707 0.0685 -0.0022
0.1234 0.0892 -0.0341
0.1790 0.1461 -0.0328
0.2405 0.2311 -0.0094
0.3059 0.2952 -0.0108
0.3872 0.4018 +0.0146
0.4801 0.4622 -0.0178
0.6213 0.6872 +0.0659
=== 3. OOB bilan chegara tanlash ===
OOB bo'yicha eng yaxshi chegara: 0.3173
OOB da F1: 0.5875
0.5 chegarada test F1: 0.4318
tanlangan chegarada test F1: 0.5855
=== 4. OOB bilan xatolar tahlili ===
xato ulushi: 0.2500
ishonch namunalar xato %
0.0-0.1 787 42.9%
0.1-0.25 1083 31.0%
0.25-0.4 1180 14.2%
0.4-0.5 450 7.3%
⭐ OOB to'liq diagnostika beradi - CV sizNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Regressiyada uch ansambl
"""RF, ET va bagging regressiyada (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import (BaggingRegressor, ExtraTreesRegressor,
RandomForestRegressor)
from sklearn.metrics import mean_absolute_error, r2_score
from sklearn.model_selection import KFold, cross_val_score, train_test_split
from sklearn.tree import DecisionTreeRegressor
def yarat(seed: int = 5, n: int = 3000, p: int = 20, shovqin: float = 1.2):
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, p))
f = (2.0 * np.sin(1.5 * X[:, 0]) + 1.5 * X[:, 1] * (X[:, 2] > 0)
- 1.0 * X[:, 3] ** 2 + 0.8 * X[:, 4]
+ 0.3 * X[:, 5:10].sum(axis=1))
return X, f + rng.normal(0, shovqin, 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)
cv = KFold(5, shuffle=True, random_state=0)
print("=== 1. Uch ansambl ===")
modellar = {
"bagging": BaggingRegressor(DecisionTreeRegressor(random_state=0),
n_estimators=300, random_state=0, n_jobs=1),
"RandomForest": RandomForestRegressor(n_estimators=300,
max_features=0.3,
random_state=0, n_jobs=1),
"ExtraTrees": ExtraTreesRegressor(n_estimators=300, max_features=0.3,
random_state=0, n_jobs=1),
}
print(f" {'model':<14} {'R^2':>9} {'MAE':>9} {'o_rt barglar':>14}")
for nom, m in modellar.items():
m.fit(Xtr, ytr)
pred = m.predict(Xte)
barglar = np.mean([e.get_n_leaves() for e in m.estimators_])
print(f" {nom:<14} {r2_score(yte, pred):>9.4f} "
f"{mean_absolute_error(yte, pred):>9.4f} {barglar:>14.1f}")
print("\n=== 2. max_features bo'yicha ikkalasi ===")
print(f" {'max_features':>13} {'RF R^2':>9} {'ET R^2':>9}")
for mf in [1.0, 0.5, 0.3, "sqrt"]:
r = cross_val_score(RandomForestRegressor(n_estimators=150,
max_features=mf,
random_state=0),
Xtr, ytr, cv=cv, scoring="r2").mean()
e = cross_val_score(ExtraTreesRegressor(n_estimators=150,
max_features=mf,
random_state=0),
Xtr, ytr, cv=cv, scoring="r2").mean()
print(f" {str(mf):>13} {r:>9.4f} {e:>9.4f}")
print("\n=== 3. Shovqin darajasi bo'yicha ===")
print(f" {'shovqin':>8} {'RF R^2':>9} {'ET R^2':>9} {'farq':>9}")
for sh in [0.3, 1.0, 2.0, 4.0]:
Xn, yn, _ = yarat(shovqin=sh, n=2000)
r = cross_val_score(RandomForestRegressor(n_estimators=150,
max_features=0.3,
random_state=0),
Xn, yn, cv=cv, scoring="r2").mean()
e = cross_val_score(ExtraTreesRegressor(n_estimators=150,
max_features=0.3,
random_state=0),
Xn, yn, cv=cv, scoring="r2").mean()
print(f" {sh:>8.1f} {r:>9.4f} {e:>9.4f} {e - r:>+9.4f}")
print("\n=== 4. Model hajmi ===")
for nom, m in modellar.items():
tugunlar = sum(e.tree_.node_count for e in m.estimators_)
print(f" {nom:<14}: jami {tugunlar:,} tugun "
f"(~{tugunlar * 48 / 1024 / 1024:.1f} MB)")
print(" ⭐ Ansambl hajmi - ishlab chiqarishda muhim omil")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Uch ansambl ===
model R^2 MAE o_rt barglar
bagging 0.6362 1.3277 1327.0
RandomForest 0.6098 1.3536 1327.0
ExtraTrees 0.5843 1.4011 2100.0
=== 2. max_features bo'yicha ikkalasi ===
max_features RF R^2 ET R^2
1.0 0.6674 0.6817
0.5 0.6595 0.6382
0.3 0.6273 0.5839
sqrt 0.5828 0.5223
=== 3. Shovqin darajasi bo'yicha ===
shovqin RF R^2 ET R^2 farq
0.3 0.7530 0.7207 -0.0323
1.0 0.6453 0.6200 -0.0252
2.0 0.4370 0.4192 -0.0178
4.0 0.1820 0.1730 -0.0089
=== 4. Model hajmi ===
bagging : jami 795,874 tugun (~36.4 MB)
RandomForest : jami 795,874 tugun (~36.4 MB)
ExtraTrees : jami 1,259,700 tugun (~57.7 MB)
⭐ Ansambl hajmi - ishlab chiqarishda muhim omilNima ko'rsatdi: 2.3, 2.6-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "ET — RF ning yomonroq varianti" | Shovqinda ko'pincha ustun |
| "ET ham bootstrap ishlatadi" | Standartda yo'q |
| "ET da OOB avtomatik" | bootstrap=True kerak |
| "oob_decision_function_ toza" | NaN bo'lishi mumkin |
| "ET har doim tezroq" | n_estimators ko'proq kerak bo'lishi mumkin |
| "warm_start bilan kamaytirsa bo'ladi" | Xato beradi |
| "max_samples sifatni buzadi" | Ko'pincha sezilmaydi |
| "Tasodifiy chegara mantiqsiz" | rho ni kamaytiradi |
6. Keng tarqalgan xatolar va yechimlari
1. ET da OOB kutish
ExtraTreesClassifier(oob_score=True) # bootstrap=False # ⚠️
ExtraTreesClassifier(bootstrap=True, oob_score=True) # ✅2. NaN ni tekshirmaslik
roc_auc_score(y, o.oob_decision_function_[:, 1]) # ⚠️
m = ~np.isnan(oob); roc_auc_score(y[m], oob[m]) # ✅3. warm_start bilan kamaytirish
o.set_params(n_estimators=50).fit(X, y) # 200 dan keyin # ⚠️
o.set_params(n_estimators=400).fit(X, y) # faqat oshirish # ✅4. Faqat bittasini sinash
model = RandomForestClassifier(n_estimators=500) # ⚠️
# RF va ET ni CV da taqqoslang # ✅5. Katta ma'lumotda max_samples ni unutish
RandomForestClassifier(n_estimators=500) # 1 mln qator # ⚠️
RandomForestClassifier(n_estimators=500, max_samples=0.3) # ✅6. Vaqt qatorida OOB
o.oob_score_ # ⚠️
cross_val_score(o, X, y, cv=TimeSeriesSplit(5)) # ✅7. Model hajmini hisobga olmaslik
RandomForestClassifier(n_estimators=2000) # yuzlab MB # ⚠️
# min_samples_leaf bilan hajmni cheklang # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 15.5-dars (o'tilgan): Random Forest
- 14.10-dars (o'tilgan): Kalibrlash
- 15.7-dars: Boosting g'oyasi
- 15.11-dars: Belgi muhimligi
- 15.14-dars: Amaliyot
8. Eng yaxshi amaliyotlar
Ikkalasini sinang.
Shovqinda ET ni ko'ring.
ET da bootstrap=True (OOB kerak bo'lsa).
NaN ni tekshiring.
warm_start bilan egri chiziq quring.
max_samples bilan tezlashtiring.
OOB dan diagnostika oling.
Model hajmini kuzating.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # ET ning RF dan farqi?
2. # ET da bootstrap standart qiymati?
3. # ET nega tezroq?
4. # ET qachon ustun?
5. # rho ga ta'siri?
6. # bias ga ta'siri?
7. # ET da OOB uchun nima kerak?
8. # warm_start nima qiladi?
9. # oob_decision_function_ nima?
10. # NaN qachon paydo bo'ladi?
11. # max_samples nima uchun?
12. # RF da bootstrap=False?Javoblar
- Chegara tasodifiy tanlanadi
- False
- Chegara qidirilmaydi
- Shovqin ko'p bo'lganda
- Kamaytiradi
- Oshiradi
- bootstrap=True
- Daraxtlarni saqlab qo'shadi
- OOB ehtimolliklar
- n_estimators kichik bo'lsa
- Tezlik uchun
- Butun ma'lumot, OOB yo'q
Vazifa 2: Xatolarni tuzating
1. ExtraTreesClassifier(oob_score=True)
2. roc_auc_score(y, o.oob_decision_function_[:, 1])
3. o.set_params(n_estimators=50).fit(X, y) # 200 dan keyin
4. RandomForestClassifier(n_estimators=500) # 2 mln qator
5. o.oob_score_ # vaqt qatoriJavoblar
1. ExtraTreesClassifier(bootstrap=True, oob_score=True)
2. m = ~np.isnan(oob); roc_auc_score(y[m], oob[m])
3. o.set_params(n_estimators=400).fit(X, y)
4. RandomForestClassifier(n_estimators=500, max_samples=0.3)
5. cross_val_score(o, X, y, cv=TimeSeriesSplit(5))Vazifa 3: RF va ET
Modellang:
- Asosiy solishtirish
- Bitta daraxt va ansambl
- Kelishmovchilik
- Shovqin
Vazifa 4: OOB egri chizig'i
Modellang:
- warm_start
- ET da bootstrap
- RF da bootstrap=False
- max_samples
Vazifa 5: Diagnostika
Modellang:
- OOB va test
- Kalibrlash
- Chegara
- Xatolar
Vazifa 6: Regressiya
Modellang:
- Uch ansambl
- max_features
- Shovqin
- Hajm
Vazifa 7: O'ylash
Extra Trees bo'linish chegarasini tasodifiy tanlaydi — ya'ni ma'lumotdagi ma'lumotni atayin e'tiborsiz qoldiradi. Nega bu ba'zan yaxshiroq natija beradi?
Javob
Qisqa javob: "eng yaxshi chegara" ko'pincha shovqinning eng yaxshi chegarasi bo'ladi. Tasodifiy chegara shu tuzoqqa tushmaydi va ansambl darajasida yo'qotilgan aniqlik rho ning kamayishi bilan qoplanadi.
1. Optimallashtirishning yashirin narxi
Chegarani qidirish — o'quv namunasidagi barcha mumkin bo'lgan bo'linishlar orasidan eng yaxshisini tanlash. Bu ko'p taqqoslash muammosi (11.x): 1000 ta nomzod orasidan eng yaxshisi tasodifan yaxshi ko'rinishi ehtimoli yuqori.
| Ma'lumot | "Eng yaxshi" chegara |
|---|---|
| Kuchli signal | Haqiqiy chegaraga yaqin |
| Shovqinli | Ko'pincha shovqin artefakti |
2. Nima yo'qoladi va nima topiladi
- Yo'qoladi: har daraxtning aniqligi (bias oshadi)
- Topiladi: daraxtlar orasidagi korrelyatsiya kamayadi (15.3)
- Ansambl darajasida:
rho*s^2hadi kichrayadi
3. Shuning uchun ET ga ko'proq daraxt kerak
- Har daraxt kuchsizroq
(1-rho)*s^2/Bhadini kamaytirish uchun B katta bo'lishi kerak- Amalda: RF uchun 300, ET uchun 500-1000
4. O'xshash g'oyalar
- Dropout (neyron tarmoqlarda) — atayin neyronlarni o'chirish
- Regulyarizatsiya 13.7-bob — koeffitsiyentlarni atayin kichraytirish
- Subsampling (boosting da — 15.9)
Hammasi bitta tamoyilga asoslanadi: o'quv ma'lumotiga to'liq moslashish — maqsad emas.
5. Xulosa
- Optimal bo'linish shovqinga moslashishi mumkin
- Tasodifiylik bu xavfni kamaytiradi
- Ansambl darajasida foyda ko'rinadi
- Ko'proq daraxt kerak
Nimani mustahkamlaydi: 2.1, 2.3-bo'limlar.
Xulosa
Bu darsda Extra Trees va OOB tahlilini o'rgandik.
Eng muhim uch fikr:
Extra Trees chegarani tasodifiy tanlaydi. Bo'linish chegarasi qidirilmaydi — har belgi uchun bitta tasodifiy chegara olinadi va shular orasidan eng yaxshisi tanlanadi. Bu hisoblashning eng qimmat qismini olib tashlaydi (2-5 barobar tez) va
rhoni kamaytiradi, lekin har daraxtning biasini oshiradi.ET standartda bootstrap ishlatmaydi.
bootstrap=False— har daraxt butun ma'lumotni ko'radi, xilma-xillik faqat tasodifiy chegaralardan keladi. Shuning uchunoob_score=Trueuchunbootstrap=Trueni qo'lda yoqish kerak. Shovqinli ma'lumotda ET ko'pincha RF dan ustun, chunki tasodifiy chegara shovqindagi "mukammal" bo'linishni topa olmaydi.OOB — to'liq diagnostika vositasi.
oob_decision_function_dan CV siz ROC/PR egri chiziqlari, kalibrlash diagrammasi, chegara tanlash va xatolar tahlilini qurish mumkin.warm_start=Trueesa o'rganish egri chizig'ini arzon qiladi. Faqat NaN ni tekshirishni unutmang va vaqt qatorlarida OOB ga ishonmang.
Keyingi darsda boosting g'oyasini o'rganamiz: ansambl a'zolarini ketma-ket, bir-birining xatosiga qarab qurish.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!