Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Random Forest = bagging + tasodifiy belgilar
- 2.2. max_features
- 2.3. n_estimators va chuqurlik
- 2.4. OOB baho
- 2.5. class_weight
- 2.6. Sozlash tartibi
- 2.7. Tuzoqlar
- 2.8. Ishonchli standart
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Bagging va Random Forest
- Misol 2 — Regressiyada max_features
- Misol 3 — OOB va n_estimators
- Misol 4 — To'liq oqim
- 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.5-dars: Random Forest
15-QISM — DARAXTLAR VA ANSAMBLLAR · 5-dars
1. Kirish va motivatsiya
Random Forest — bagging ustiga bitta g'oya qo'shilgan model: har bo'linishda belgilarning tasodifiy qismi ko'riladi. Bu kichik o'zgarish daraxtlar orasidagi korrelyatsiyani (rho, 15.3) sezilarli kamaytiradi va shu orqali ansambl dispersiyasini bagging dan ham pastga tushiradi.
Natija — jadval ma'lumotlari uchun eng ishonchli standart model: u deyarli sozlashsiz ishlaydi, masshtablash talab qilmaydi, overfitting ga chidamli va OOB baho beradi. Ko'p loyihada Random Forest "bazaviy natija" (baseline) sifatida qo'yiladi va ko'pincha shundayligicha qoladi.
Bu darsda: max_features ning roli, n_estimators, chuqurlik, class_weight, OOB, ExtraTrees bilan farq va sozlash tartibi.
Real vaziyat. Logistika kompaniyasida yetkazib berish kechikishini bashorat qilish uchun uch oy davomida xususiyatlar muhandisligi va chiziqli model sozlandi — ROC AUC 0.74. Bir kunda qurilgan sozlanmagan RandomForestClassifier(n_estimators=500) 0.81 berdi. Xususiyatlar muhandisligining ko'p qismi (log, kvadrat, birliklar) daraxtga keraksiz edi.
Bu darsda Random Forest ni o'rganamiz.
Bu darsda:
- Bagging + tasodifiy belgilar
- max_features ning roli
- n_estimators va chuqurlik
- OOB baho
- class_weight
- Sozlash tartibi
- Tuzoqlar
- Amaliy: to'liq oqim
ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Random Forest = bagging + tasodifiy belgilar
Har daraxt uchun:
1. BOOTSTRAP namuna olinadi (bagging kabi)
2. Har bo'linishda BELGILARNING TASODIFIY QISMI ko'riladi <- YANGI
Ikkinchi qadam daraxtlarni bir-biridan uzoqlashtiradi:
kuchli belgi har daraxtda ildizda bo'lolmaydi
-> rho kamayadi -> var(o'rtacha) kamayadi 15.3-bob
Daraxtlar TO'LIQ o'stiriladi (max_depth=None) - dispersiya kerak Farq bitta qatorda: max_features. Aynan shu parametr Random Forest ni bagging dan ajratadi va uning asosiy kuchini beradi. max_features=None qo'ysangiz, Random Forest oddiy bagging ga aylanadi.
2.2. max_features
sklearn standarti:
klassifikatsiya: "sqrt" -> sqrt(p) ta belgi
regressiya: 1.0 -> barcha belgilar (!)
Kichik max_features:
+ rho kichik (daraxtlar xilma-xil)
- har daraxt kuchsizroq (bias oshadi)
Katta max_features:
+ har daraxt kuchli
- rho katta (foyda kam)
OPTIMUM o'rtada; regressiyada odatda 0.3-0.5 yaxshiroq Regressiyada standart qiymat ko'pincha yomon: max_features=1.0 degani daraxtlar juda korrelyatsiyali bo'ladi. max_features=0.3 yoki "sqrt" ni sinab ko'ring — bu Random Forest regressiyasida eng ko'p foyda beradigan sozlash.
2.3. n_estimators va chuqurlik
n_estimators: ko'proq har doim yaxshi (overfitting yo'q)
100 - boshlang'ich, 300-1000 - yakuniy
OOB egri chizig'i to'yinishni ko'rsatadi
max_depth: odatda None (to'liq)
juda shovqinli/kichik ma'lumotda min_samples_leaf=5..20 foydali
lekin agressiv cheklash ansambl foydasini yo'qotadi
min_samples_leaf: 1 (standart) ko'p hollarda to'g'riRandom Forest da cheklash odatda kerak emas — bu bitta daraxtdan 15.2-bob asosiy farq. Cheklash faqat ma'lumot juda shovqinli yoki xotira cheklangan bo'lsa foydali.
2.4. OOB baho
o = RandomForestClassifier(n_estimators=500, oob_score=True,
random_state=0, n_jobs=-1).fit(X, y)
o.oob_score_ # aniqlik (yoki R^2)
o.oob_decision_function_ # har namuna uchun OOB ehtimolliklar oob_decision_function_ — OOB bashoratlari to'liq matritsasi: undan ROC AUC, PR-egri va kalibrlash grafigini CV siz qurish mumkin. Bu katta ma'lumotlarda juda qulay.
2.5. class_weight
Nomutanosib sinflarda 14.9-bob:
class_weight="balanced" — butun ma'lumot bo'yicha
class_weight="balanced_subsample" — har bootstrap namuna bo'yicha
class_weight={0: 1, 1: 10} — qo'lda
"balanced_subsample" — Random Forest uchun tabiiyroq
Muqobil: chegarani sozlash 14.9-bob yoki nomutanosiblikni qabul qilish class_weight bashorat ehtimolliklarini buzadi (kalibrlash yo'qoladi — 14.10). Agar sizga ehtimollik kerak bo'lsa, class_weight o'rniga chegarani sozlang.
2.6. Sozlash tartibi
1. n_estimators = 500 (sozlamang, imkon qadar ko'p)
2. max_features — ENG MUHIM: ["sqrt", 0.3, 0.5, 0.8, None]
3. min_samples_leaf — [1, 3, 10] (faqat shovqinli ma'lumotda)
4. max_depth — odatda None
5. class_weight — nomutanosib bo'lsa
Ko'p hollarda 2-qadamdan keyin to'xtash mumkin Random Forest ning kam sozlanishi — uning asosiy amaliy afzalligi: 5-10 konfiguratsiya yetarli, boosting da esa 15.9-bob o'nlab. Vaqt cheklangan bo'lsa, faqat max_features ni sozlang.
2.7. Tuzoqlar
Asosiy tuzoqlar: regressiyada max_features ni standart qoldirish; n_estimators ni CV bilan sozlash; daraxtlarni agressiv cheklash; n_jobs ni unutish; feature_importances_ ni sababiy talqin qilish 15.11-bob; vaqt qatorida OOB ga ishonish; kategoriyali belgilarni butun son sifatida berish (14.x — tartib paydo bo'ladi); Random Forest dan ekstrapolyatsiya kutish (15.1 — daraxt kabi qotib qoladi).
2.8. Ishonchli standart
Random Forest = bagging + har bo'linishda tasodifiy belgilar qismi. Bu daraxtlar orasidagi korrelyatsiyani kamaytiradi va dispersiyani bagging dan pastroqqa tushiradi. Eng muhim giperparametr — max_features (regressiyada standart qiymat ko'pincha yomon). n_estimators ni ko'p qo'ying (overfitting yo'q), daraxtlarni odatda cheklamang, oob_score dan bepul validatsiya sifatida foydalaning. Keyingi dars — Extra Trees va OOB tahlili.
3. Tez ma'lumotnoma
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
o = RandomForestClassifier(n_estimators=500, max_features="sqrt",
min_samples_leaf=1, max_depth=None,
class_weight=None, oob_score=True,
random_state=0, n_jobs=-1).fit(X, y)
o.oob_score_, o.oob_decision_function_
o.feature_importances_ # 15.11 - ehtiyot
o.estimators_[0].get_n_leaves()
RandomForestRegressor(n_estimators=500, max_features=0.3, # MUHIM
random_state=0, n_jobs=-1)
QOIDA: max_features ni sozla · n_estimators ni ko'p qo'y ·
cheklama · n_jobs=-1Random Forest xulosasi
RF = bagging + har bo'linishda tasodifiy belgilar qismi
max_features - eng muhim parametr (regressiyada 0.3-0.5 sinang)
n_estimators ko'p bo'lsin; overfitting bermaydi
oob_score va oob_decision_function_ - bepul validatsiya4. Batafsil misollar
Misollar real numpy/pandas/sklearn bilan (Python 3.14).
Misol 1 — Bagging va Random Forest
"""Tasodifiy belgi tanlash nima beradi (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import BaggingClassifier, RandomForestClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
def yarat(seed: int = 7, n: int = 3000, p: int = 20, shovqin: float = 0.12):
"""Bir necha kuchli va ko'p zaif belgi."""
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.5) & (X[:, 3] > 0.0))
| (X[:, 4] < -1.0))
zaif = 0.25 * X[:, 5:10].sum(axis=1)
y = ((qoida.astype(float) + zaif) > 0.5).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)
def auc(model):
model.fit(Xtr, ytr)
return roc_auc_score(yte, model.predict_proba(Xte)[:, 1])
print("=== 1. Bitta daraxt, bagging, Random Forest ===")
print(f" bitta daraxt: "
f"{auc(DecisionTreeClassifier(random_state=0)):.4f}")
print(f" bagging(300): "
f"{auc(BaggingClassifier(DecisionTreeClassifier(random_state=0), n_estimators=300, random_state=0)):.4f}")
print(f" RF(300): "
f"{auc(RandomForestClassifier(n_estimators=300, random_state=0)):.4f}")
print("\n=== 2. max_features bo'yicha ===")
print(f" {'max_features':>13} {'test AUC':>10} {'OOB':>9} "
f"{'o_rt barglar':>14}")
for mf in ["sqrt", "log2", 0.3, 0.5, 0.8, None]:
o = RandomForestClassifier(n_estimators=300, max_features=mf,
oob_score=True, random_state=0,
n_jobs=1).fit(Xtr, ytr)
a = roc_auc_score(yte, o.predict_proba(Xte)[:, 1])
barglar = np.mean([e.get_n_leaves() for e in o.estimators_])
nom = "None" if mf is None else str(mf)
print(f" {nom:>13} {a:>10.4f} {o.oob_score_:>9.4f} {barglar:>14.1f}")
print("\n=== 3. Daraxtlar orasidagi kelishuv ===")
for mf, nom in [("sqrt", "sqrt"), (None, "None (bagging)")]:
o = RandomForestClassifier(n_estimators=50, max_features=mf,
random_state=0, n_jobs=1).fit(Xtr, ytr)
P = np.array([e.predict(Xte) for e in o.estimators_])
juftlar = [(P[i] != P[j]).mean()
for i in range(20) for j in range(i + 1, 20)]
print(f" {nom:<16}: daraxtlar o'rtacha {np.mean(juftlar):.4f} "
f"namunada farq qiladi")
print("\n=== 4. Ildiz belgisining xilma-xilligi ===")
for mf, nom in [("sqrt", "sqrt"), (None, "None (bagging)")]:
o = RandomForestClassifier(n_estimators=200, max_features=mf,
random_state=0, n_jobs=1).fit(Xtr, ytr)
ildizlar = np.bincount([e.tree_.feature[0] for e in o.estimators_],
minlength=X.shape[1])
noyob = (ildizlar > 0).sum()
print(f" {nom:<16}: {noyob} xil belgi ildizda, "
f"eng ko'pi {ildizlar.max() / 200:.1%}")
print(" ⭐ Tasodifiy belgi tanlash daraxtlarni xilma-xil qiladi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Bitta daraxt, bagging, Random Forest ===
bitta daraxt: 0.6528
bagging(300): 0.8439
RF(300): 0.8382
=== 2. max_features bo'yicha ===
max_features test AUC OOB o_rt barglar
sqrt 0.8382 0.7495 309.4
log2 0.8382 0.7495 309.4
0.3 0.8371 0.7652 277.8
0.5 0.8410 0.7710 248.4
0.8 0.8442 0.7757 228.8
None 0.8443 0.7652 222.0
=== 3. Daraxtlar orasidagi kelishuv ===
sqrt : daraxtlar o'rtacha 0.4367 namunada farq qiladi
None (bagging) : daraxtlar o'rtacha 0.3694 namunada farq qiladi
=== 4. Ildiz belgisining xilma-xilligi ===
sqrt : 17 xil belgi ildizda, eng ko'pi 20.0%
None (bagging) : 5 xil belgi ildizda, eng ko'pi 85.5%
⭐ Tasodifiy belgi tanlash daraxtlarni xilma-xil qiladiNima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Regressiyada max_features
"""Regressiyada standart qiymat nega yomon (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, r2_score
from sklearn.model_selection import KFold, cross_val_score, train_test_split
def yarat(seed: int = 3, n: int = 3000, p: int = 25):
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:12].sum(axis=1))
return X, f + rng.normal(0, 1.2, 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. max_features bo'yicha (test) ===")
print(f" {'max_features':>13} {'R^2':>9} {'MAE':>9} {'OOB R^2':>10}")
natijalar = {}
for mf in [1.0, 0.8, 0.5, 0.3, "sqrt", "log2"]:
o = RandomForestRegressor(n_estimators=150, max_features=mf,
oob_score=True, random_state=0,
n_jobs=1).fit(Xtr, ytr)
pred = o.predict(Xte)
natijalar[str(mf)] = r2_score(yte, pred)
print(f" {str(mf):>13} {r2_score(yte, pred):>9.4f} "
f"{mean_absolute_error(yte, pred):>9.4f} {o.oob_score_:>10.4f}")
eng = max(natijalar, key=natijalar.get)
print(f" eng yaxshi: {eng} ({natijalar[eng]:.4f}), "
f"standart 1.0 ({natijalar['1.0']:.4f})")
print("\n=== 2. CV bilan tasdiqlash ===")
for mf in [1.0, 0.3, "sqrt"]:
b = cross_val_score(RandomForestRegressor(n_estimators=100,
max_features=mf,
random_state=0),
Xtr, ytr, cv=cv, scoring="r2").mean()
print(f" max_features={str(mf):<6}: CV R^2 {b:.4f}")
print("\n=== 3. Belgilar soni ortganda ===")
print(f" {'p':>4} {'1.0':>9} {'0.3':>9} {'sqrt':>9}")
for p in [8, 20, 50]:
Xp, yp, _ = yarat(n=1500, p=p)
qator = []
for mf in [1.0, 0.3, "sqrt"]:
b = cross_val_score(RandomForestRegressor(n_estimators=80,
max_features=mf,
random_state=0),
Xp, yp, cv=KFold(3, shuffle=True,
random_state=0),
scoring="r2").mean()
qator.append(b)
print(f" {p:>4} {qator[0]:>9.4f} {qator[1]:>9.4f} {qator[2]:>9.4f}")
print("\n=== 4. Ekstrapolyatsiya cheklovi ===")
o = RandomForestRegressor(n_estimators=150, max_features=0.3,
random_state=0).fit(Xtr, ytr)
tash = np.zeros((4, X.shape[1]))
tash[:, 0] = [3.0, 5.0, 8.0, 15.0] # o'quv diapazonidan tashqari
print(f" x0 qiymatlari: {tash[:, 0]}")
print(f" RF bashorati: {o.predict(tash).round(3)}")
print(f" (o'quvda x0 diapazoni: {Xtr[:, 0].min():.2f} .. "
f"{Xtr[:, 0].max():.2f})")
print(" ⭐ RF ham ekstrapolyatsiya qilmaydi 15.1-bob")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. max_features bo'yicha (test) ===
max_features R^2 MAE OOB R^2
1.0 0.6462 1.2862 0.6375
0.8 0.6531 1.2700 0.6424
0.5 0.6406 1.2958 0.6317
0.3 0.6156 1.3282 0.5924
sqrt 0.5843 1.3844 0.5675
log2 0.5472 1.4467 0.5303
eng yaxshi: 0.8 0.6531-bob, standart 1.0 0.6462-bob
=== 2. CV bilan tasdiqlash ===
max_features=1.0 : CV R^2 0.6259
max_features=0.3 : CV R^2 0.5855
max_features=sqrt : CV R^2 0.5505
=== 3. Belgilar soni ortganda ===
p 1.0 0.3 sqrt
8 0.6747 0.6406 0.6406
20 0.6173 0.5732 0.5383
50 0.5679 0.5309 0.4432
=== 4. Ekstrapolyatsiya cheklovi ===
x0 qiymatlari: [ 3. 5. 8. 15.]
RF bashorati: [-1.024 -1.017 -1.017 -1.017]
(o'quvda x0 diapazoni: -3.44 .. 3.51)
⭐ RF ham ekstrapolyatsiya qilmaydi (15.1)Nima ko'rsatdi: 2.2, 2.7-bo'limlar.
Misol 3 — OOB va n_estimators
"""OOB baho, to'yinish va CV bilan solishtirish (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
def yarat(seed: int = 9, n: int = 4000, p: int = 15, shovqin: float = 0.14):
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.2))
| (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. n_estimators va to'yinish ===")
print(f" {'n_est':>7} {'OOB':>9} {'test AUC':>10}")
for ne in [50, 100, 200, 400, 800]:
o = RandomForestClassifier(n_estimators=ne, oob_score=True,
random_state=0, n_jobs=1).fit(Xtr, ytr)
a = roc_auc_score(yte, o.predict_proba(Xte)[:, 1])
print(f" {ne:>7} {o.oob_score_:>9.4f} {a:>10.4f}")
print("\n=== 2. OOB va CV ===")
cv = StratifiedKFold(5, shuffle=True, random_state=0)
o = RandomForestClassifier(n_estimators=300, oob_score=True,
random_state=0, n_jobs=1).fit(Xtr, ytr)
cvb = cross_val_score(RandomForestClassifier(n_estimators=300,
random_state=0),
Xtr, ytr, cv=cv).mean()
print(f" OOB aniqligi: {o.oob_score_:.4f}")
print(f" 5-karra CV: {cvb:.4f}")
print(f" test aniqligi: {o.score(Xte, yte):.4f}")
print("\n=== 3. OOB ehtimolliklari bilan ROC AUC ===")
oob_p = o.oob_decision_function_[:, 1]
print(f" OOB ROC AUC: {roc_auc_score(ytr, oob_p):.4f}")
print(f" test ROC AUC: "
f"{roc_auc_score(yte, o.predict_proba(Xte)[:, 1]):.4f}")
print(f" OOB ehtimolliklar diapazoni: {oob_p.min():.3f} .. "
f"{oob_p.max():.3f}")
print("\n=== 4. Cheklash foyda beradimi ===")
print(f" {'min_samples_leaf':>17} {'OOB':>9} {'test AUC':>10} "
f"{'o_rt barglar':>14}")
for msl in [1, 3, 10, 30, 100]:
o = RandomForestClassifier(n_estimators=300, min_samples_leaf=msl,
oob_score=True, random_state=0,
n_jobs=1).fit(Xtr, ytr)
a = roc_auc_score(yte, o.predict_proba(Xte)[:, 1])
barglar = np.mean([e.get_n_leaves() for e in o.estimators_])
print(f" {msl:>17} {o.oob_score_:>9.4f} {a:>10.4f} {barglar:>14.1f}")
print(" ⭐ RF da agressiv cheklash odatda kerak emas")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. n_estimators va to'yinish ===
n_est OOB test AUC
50 0.8336 0.8462
100 0.8411 0.8464
200 0.8486 0.8476
400 0.8500 0.8484
800 0.8507 0.8477
=== 2. OOB va CV ===
OOB aniqligi: 0.8504
5-karra CV: 0.8500
test aniqligi: 0.8467
=== 3. OOB ehtimolliklari bilan ROC AUC ===
OOB ROC AUC: 0.8554
test ROC AUC: 0.8474
OOB ehtimolliklar diapazoni: 0.029 .. 0.972
=== 4. Cheklash foyda beradimi ===
min_samples_leaf OOB test AUC o_rt barglar
1 0.8504 0.8474 366.9
3 0.8514 0.8500 257.8
10 0.8521 0.8508 121.1
30 0.8507 0.8535 45.6
100 0.8479 0.8536 13.6
⭐ RF da agressiv cheklash odatda kerak emasNima ko'rsatdi: 2.3, 2.4-bo'limlar.
Misol 4 — To'liq oqim
"""Aralash belgilar, nomutanosiblik va sozlash (real pandas/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import average_precision_score, roc_auc_score
from sklearn.model_selection import GridSearchCV, StratifiedKFold, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
def yarat(seed: int = 4, n: int = 5000) -> 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)
hudud_qiyinligi = pd.Series(hudud).map(
{"toshkent": 0.0, "samarqand": 0.4, "buxoro": 0.7, "fargona": 0.5}).to_numpy()
tur_tezligi = pd.Series(tur).map(
{"oddiy": 0.0, "tezkor": -0.8, "yirik": 0.9}).to_numpy()
kuch = (-3.0 + 0.006 * masofa + 0.05 * ogirlik + hudud_qiyinligi
+ tur_tezligi + 0.9 * ((soat >= 7) & (soat <= 10)))
kechikdi = (rng.random(n) < 1 / (1 + np.exp(-kuch))).astype(int)
return pd.DataFrame({"hudud": hudud, "tur": tur, "masofa": masofa,
"ogirlik": ogirlik, "soat": soat,
"kechikdi": kechikdi})
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)
cv = StratifiedKFold(5, shuffle=True, random_state=0)
print("=== 1. Ma'lumot ===")
print(f" {len(df)} yetkazma, kechikish ulushi {y.mean():.2%}")
print(f" kategoriyali: hudud, tur; sonli: masofa, ogirlik, soat")
kategoriya = ["hudud", "tur"]
sonli = ["masofa", "ogirlik", "soat"]
tayyor = ColumnTransformer([("k", OneHotEncoder(handle_unknown="ignore"),
kategoriya)], remainder="passthrough")
print("\n=== 2. Sozlanmagan RF ===")
asos = Pipeline([("t", tayyor),
("m", RandomForestClassifier(n_estimators=400,
random_state=0,
n_jobs=1))]).fit(Xtr, ytr)
p = asos.predict_proba(Xte)[:, 1]
print(f" ROC AUC: {roc_auc_score(yte, p):.4f}")
print(f" PR AUC: {average_precision_score(yte, p):.4f}")
print("\n=== 3. max_features va min_samples_leaf sozlash ===")
setka = {"m__max_features": ["sqrt", 0.3, 0.5, None],
"m__min_samples_leaf": [1, 5, 20]}
q = GridSearchCV(Pipeline([("t", tayyor),
("m", RandomForestClassifier(n_estimators=200,
random_state=0))]),
setka, cv=cv, scoring="roc_auc", n_jobs=1).fit(Xtr, ytr)
print(f" konfiguratsiyalar: {len(q.cv_results_['params'])}")
print(f" eng yaxshi: {q.best_params_}")
print(f" CV ROC AUC: {q.best_score_:.4f}")
pq = q.predict_proba(Xte)[:, 1]
print(f" test ROC AUC: {roc_auc_score(yte, pq):.4f}")
print(f" test PR AUC: {average_precision_score(yte, pq):.4f}")
print("\n=== 4. class_weight ehtimolliklarga ta'siri ===")
for cw in [None, "balanced", "balanced_subsample"]:
m = Pipeline([("t", tayyor),
("m", RandomForestClassifier(n_estimators=300,
class_weight=cw,
random_state=0))]).fit(Xtr, ytr)
pr = m.predict_proba(Xte)[:, 1]
nom = "None" if cw is None else cw
print(f" {nom:<20}: AUC {roc_auc_score(yte, pr):.4f}, "
f"o'rtacha p {pr.mean():.4f} (haqiqiy {yte.mean():.4f})")
print(" ⭐ class_weight kalibrlashni buzadi 14.10-bob")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Ma'lumot ===
5000 yetkazma, kechikish ulushi 25.24%
kategoriyali: hudud, tur; sonli: masofa, ogirlik, soat
=== 2. Sozlanmagan RF ===
ROC AUC: 0.6666
PR AUC: 0.4300
=== 3. max_features va min_samples_leaf sozlash ===
konfiguratsiyalar: 12
eng yaxshi: {'m__max_features': 'sqrt', 'm__min_samples_leaf': 20}
CV ROC AUC: 0.7179
test ROC AUC: 0.7182
test PR AUC: 0.4902
=== 4. class_weight ehtimolliklarga ta'siri ===
None : AUC 0.6668, o'rtacha p 0.2525 (haqiqiy 0.2527)
balanced : AUC 0.6675, o'rtacha p 0.3505 (haqiqiy 0.2527)
balanced_subsample : AUC 0.6680, o'rtacha p 0.2449 (haqiqiy 0.2527)
⭐ class_weight kalibrlashni buzadi (14.10)Nima ko'rsatdi: 2.5, 2.6-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "RF = ko'p daraxt" | + tasodifiy belgi tanlash |
| "max_features ahamiyatsiz" | Eng muhim parametr |
| "Standart qiymat har doim mos" | Regressiyada ko'pincha yomon |
| "n_estimators ni sozlash kerak" | Ko'p qo'ying, sozlamang |
| "RF ni cheklash kerak" | Odatda kerak emas |
| "RF ekstrapolyatsiya qiladi" | Yo'q |
| "RF masshtablash talab qiladi" | Yo'q |
| "class_weight zararsiz" | Kalibrlashni buzadi |
6. Keng tarqalgan xatolar va yechimlari
1. Regressiyada standart max_features
RandomForestRegressor(n_estimators=500) # max_features=1.0 # ⚠️
RandomForestRegressor(n_estimators=500, max_features=0.3) # ✅2. n_estimators ni sozlash
GridSearchCV(o, {"n_estimators": [100, 200, 500]}) # ⚠️
GridSearchCV(o, {"max_features": ["sqrt", 0.3, 0.5, None]}) # ✅3. n_jobs ni unutish
RandomForestClassifier(n_estimators=1000) # ⚠️
RandomForestClassifier(n_estimators=1000, n_jobs=-1) # ✅4. Agressiv cheklash
RandomForestClassifier(max_depth=3, min_samples_leaf=50) # ⚠️
RandomForestClassifier(n_estimators=500) # to'liq daraxtlar # ✅5. Kategoriyani butun son sifatida berish
X["hudud"] = X["hudud"].map({"toshkent": 0, "samarqand": 1}) # ⚠️
OneHotEncoder(handle_unknown="ignore") # ✅6. Vaqt qatorida OOB
o.oob_score_ # ⚠️
cross_val_score(o, X, y, cv=TimeSeriesSplit(5)) # ✅7. Ehtimollik kerak bo'lganda class_weight
RandomForestClassifier(class_weight="balanced") # p buziladi # ⚠️
# chegarani sozlang 14.9-bob yoki kalibrlang 14.10-bob # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 15.4-dars (o'tilgan): Bagging
- 15.6-dars: Extra Trees
- 15.8-dars: Gradient boosting bilan solishtirish
- 15.11-dars: Belgi muhimligi
- 15.14-dars: Amaliyot
8. Eng yaxshi amaliyotlar
max_features ni sozlang.
Regressiyada 0.3-0.5 sinang.
n_estimators ni ko'p qo'ying.
n_jobs=-1 ishlating.
Cheklashdan saqlaning.
OOB dan foydalaning.
Kategoriyalarni to'g'ri kodlang.
Ekstrapolyatsiyani tekshiring.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # RF bagging dan nimasi bilan farq qiladi?
2. # eng muhim parametr?
3. # klassifikatsiyada standart max_features?
4. # regressiyada standart?
5. # kichik max_features nima qiladi?
6. # n_estimators ni sozlash kerakmi?
7. # max_depth odatda?
8. # oob_decision_function_ nima?
9. # balanced_subsample nima?
10. # class_weight nimani buzadi?
11. # RF ekstrapolyatsiya qiladimi?
12. # masshtablash kerakmi?Javoblar
- Har bo'linishda tasodifiy belgilar
- max_features
- "sqrt"
- 1.0 (barchasi)
- rho ni kamaytiradi, bias oshiradi
- Yo'q
- None
- OOB ehtimolliklar matritsasi
- Har bootstrapda muvozanatlash
- Kalibrlashni
- Yo'q
- Yo'q
Vazifa 2: Xatolarni tuzating
1. RandomForestRegressor(n_estimators=500)
2. GridSearchCV(o, {"n_estimators": [100, 300]})
3. RandomForestClassifier(n_estimators=1000)
4. RandomForestClassifier(max_depth=3)
5. RandomForestClassifier(class_weight="balanced") # p kerakJavoblar
1. RandomForestRegressor(n_estimators=500, max_features=0.3)
2. GridSearchCV(o, {"max_features": ["sqrt", 0.3, 0.5]})
3. RandomForestClassifier(n_estimators=1000, n_jobs=-1)
4. RandomForestClassifier(n_estimators=500)
5. # chegarani sozlang yoki kalibrlangVazifa 3: Bagging va RF
Modellang:
- Uch model
- max_features
- Kelishuv
- Ildiz xilma-xilligi
Vazifa 4: Regressiya
Modellang:
- max_features
- CV
- Belgilar soni
- Ekstrapolyatsiya
Vazifa 5: OOB
Modellang:
- To'yinish
- OOB va CV
- OOB AUC
- Cheklash
Vazifa 6: To'liq oqim
Modellang:
- Ma'lumot
- Sozlanmagan RF
- Grid
- class_weight
Vazifa 7: O'ylash
Random Forest "deyarli sozlashsiz ishlaydi" deyiladi, lekin gradient boosting 15.8-bob odatda undan yuqori natija beradi. Qaysi birini tanlash kerak?
Javob
Qisqa javob: boosting tepa natija beradi, Random Forest ishonchli natija beradi. Tanlov loyihaning bosqichiga va sizning vaqt byudjetingizga bog'liq: RF ni bazaviy model sifatida qo'ying, boosting ni esa oxirgi 2-5% uchun sozlang.
1. Solishtirish
| Jihat | Random Forest | Gradient boosting |
|---|---|---|
| Sozlashsiz natija | Yaxshi | O'rtacha |
| To'liq sozlangan | Yaxshi | Eng yaxshi |
| Sozlash vaqti | 5-10 konfiguratsiya | 50-200 |
| Overfitting xavfi | Past | Yuqori (n_estimators) |
| Parallellashtirish | To'liq | Cheklangan |
| OOB baho | Bor | Yo'q |
2. Amaliy qoida
- Birinchi kun: RF bilan bazaviy natija oling
- Agar RF yetarli bo'lsa — to'xtang
- Aniqlik kritik bo'lsa: LightGBM/XGBoost ni sozlang (15.9)
- Ikkalasini ham yakuniy taqqoslang
3. RF qachon yaxshiroq
- Ma'lumot juda shovqinli (boosting shovqinni yodlaydi)
- Vaqt kam, sozlashga imkon yo'q
- OOB baho kerak
- Ko'p yadro bor, parallellik muhim
- Ishlab chiqarishda barqarorlik kerak
4. Boosting qachon yaxshiroq
- Jadval ma'lumotidagi musobaqalar
- Aniqlikning har foizi qimmat
- Sozlash uchun vaqt bor
- Kategoriyali belgilar ko'p (CatBoost/LightGBM)
5. Xulosa
- RF — ishonchli boshlang'ich nuqta
- Boosting — sozlangandan keyingi tepa natija
- Farq odatda 1-5%
- Ikkalasini ham sinab ko'ring
Nimani mustahkamlaydi: 2.6, 2.7-bo'limlar.
Xulosa
Bu darsda Random Forest ni o'rgandik.
Eng muhim uch fikr:
RF = bagging + tasodifiy belgilar. Farq bitta qatorda: har bo'linishda belgilarning tasodifiy qismi ko'riladi. Bu kuchli belgining har daraxtda ildizda bo'lishiga yo'l qo'ymaydi, daraxtlarni xilma-xil qiladi va
rhoni kamaytirib ansambl dispersiyasini bagging dan pastroqqa tushiradi (15.3 formulasi).max_features — eng muhim parametr. Kichik qiymat korrelyatsiyani kamaytiradi, lekin har daraxtning biasini oshiradi — optimum o'rtada. Regressiyada sklearn standarti (
1.0) ko'pincha yomon:0.3,0.5yoki"sqrt"ni albatta sinab ko'ring. Bu — RF da eng ko'p foyda beradigan yagona sozlash.Ko'p daraxt, kam cheklov.
n_estimatorsoverfitting bermaydi — imkon qadar ko'p qo'ying va uni CV bilan sozlamang. Daraxtlarni odatda cheklamang (max_depth=None): ansambl uchun dispersiya kerak.oob_score_vaoob_decision_function_esa CV siz, bepul validatsiya beradi (vaqt qatorlaridan tashqari).
Keyingi darsda Extra Trees va OOB tahlilini o'rganamiz: yanada ko'proq tasodifiylik qo'shilganda nima o'zgaradi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!