Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Daraxt tuzilishi
- 2.2. Bo'linishni tanlash
- 2.3. Gini va entropiya farqi
- 2.4. Regressiya daraxti
- 2.5. Induktiv siljish
- 2.6. sklearn amaliyoti
- 2.7. Tuzoqlar
- 2.8. Sodda, tushunarli, kuchsiz
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Bo'linishni qo'lda hisoblash
- Misol 2 — Daraxtni o'qish
- Misol 3 — Induktiv siljish: o'qlarga parallel chegaralar
- Misol 4 — Regressiya daraxti va ekstrapolyatsiya
- 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.1-dars: Qaror daraxti
15-QISM — DARAXTLAR VA ANSAMBLLAR · 1-dars
1. Kirish va motivatsiya
Qaror daraxti — ML dagi eng tushunarli model: u ketma-ket savollar beradi ("daromad 5 mln dan kattami?", "kechikish bo'lganmi?") va javoblarga qarab bashoratga keladi. Bu — insonning tabiiy qaror qabul qilish usuli, shuning uchun daraxtni har qanday mutaxassisga tushuntirish mumkin.
Lekin daraxtlarning asosiy qiymati boshqa joyda: ular ansambllar (Random Forest, gradient boosting) uchun qurilish bloki bo'lib, jadval ma'lumotidagi eng kuchli modellarni hosil qiladi. Bitta daraxt kuchsiz, yuzlab daraxt esa deyarli har doim eng yaxshi natijani beradi.
Bu darsda: daraxt tuzilishi va bashorat jarayoni, bo'linish qanday tanlanadi (Gini, entropiya), nopoklik kamayishi (impurity decrease), daraxtning induktiv siljishi (o'qlarga parallel chegaralar — 14.7), regressiya daraxti va sklearn amaliyoti.
Real vaziyat. Sug'urta kompaniyasida da'volarni tekshirish qoidalari 15 yil davomida qo'lda yozilgan: 200 dan ortiq shart. Ma'lumotdan o'qitilgan 6 darajali daraxt shu qoidalarning 80% ini takrorladi va 12 ta yangi naqsh topdi. Eng muhimi: daraxt chizib ko'rsatildi va tekshiruvchilar uni tasdiqladi — qora quti bo'lganda bu imkonsiz edi.
Bu darsda qaror daraxtini o'rganamiz.
Bu darsda:
- Daraxt tuzilishi
- Bo'linishni tanlash: Gini va entropiya
- Nopoklik kamayishi
- Regressiya daraxti
- Daraxtning induktiv siljishi
- sklearn amaliyoti
- Tuzoqlar
- Amaliy: daraxtni o'qish
ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Daraxt tuzilishi
ILDIZ (root) — birinchi savol, butun ma'lumot
TUGUN (node) — savol: belgi <= chegara?
BARG (leaf) — bashorat (sinf yoki son)
Bashorat: ildizdan boshlab savollarga javob berib, bargga yetish
barg bashorati = shu bargdagi o'quv namunalarining ko'pchilik sinfi
(regressiyada — o'rtachasi)
Chuqurlik (depth) — ildizdan bargga eng uzun yo'l
Barglar soni — model murakkabligining o'lchoviDaraxt — bo'lakli doimiy funksiya: u belgilar fazosini to'rtburchaklarga bo'ladi va har to'rtburchakda doimiy bashorat beradi. Har bashorat uchun aniq yo'l mavjud — shuning uchun daraxt "nega bunday qaror qildi?" degan savolga to'liq javob beradi.
2.2. Bo'linishni tanlash
Har tugunda: barcha belgi va chegaralarni sinab, ENG YAXSHI bo'linish tanlanadi
NOPOKLIK (impurity) — tugundagi sinflar aralashganlik darajasi:
Gini: 1 - sum(p_k^2) 0 (toza) .. 0.5 (ikki sinf teng)
Entropiya: -sum(p_k * log2(p_k)) 0 (toza) .. 1.0 (ikki sinf teng)
Bo'linish sifati = NOPOKLIK KAMAYISHI:
kamayish = nopoklik(ota) - [n_chap/n * nopoklik(chap) + n_ong/n * nopoklik(ong)]
Eng katta kamayish beradigan bo'linish tanlanadi (ochko'z algoritm)Daraxt ochko'z (greedy) quriladi: har qadamda mahalliy eng yaxshi bo'linish tanlanadi, global optimal daraxt izlanmaydi (bu NP-qiyin masala). Shuning uchun daraxt "eng yaxshi" emas, "yetarlicha yaxshi" bo'ladi — va bu ansambllar uchun aynan kerak.
2.3. Gini va entropiya farqi
Gini = 1 - sum(p^2) — tezroq (logarifm yo'q), sklearn standarti
Entropiya = -sum(p * log2(p)) — informatsiya nazariyasidan
Amalda natija DEYARLI BIR XIL (daraxtlar 1-2% farq qiladi)
Gini biroz ko'proq "sof" bo'linishlarni afzal ko'radi
Entropiya biroz muvozanatli bo'linishlarni
log_loss (sklearn 1.1+) — entropiya bilan bir xil criterion tanlovi kamdan-kam ahamiyatli: uni sozlashga vaqt sarflamang. Muhimroq giperparametrlar — chuqurlik va bargdagi minimal namunalar 15.2-bob. Bu — yangi boshlanuvchilar ko'p vaqt yo'qotadigan joy.
2.4. Regressiya daraxti
Nopoklik o'rniga: MSE yoki MAE
MSE bo'linishi: sum((y - o'rtacha)^2) ni minimallashtirish
barg bashorati: shu bargdagi o'rtacha (MAE da — mediana)
criterion="squared_error" (standart), "absolute_error", "friedman_mse", "poisson"
Natija: bo'lakli DOIMIY funksiya — daraxt ekstrapolyatsiya QILMAYDI
o'quv diapazonidan tashqarida eng chekka bargning qiymatini qaytaradiDaraxt ekstrapolyatsiya qilmaydi — bu chiziqli modeldan 13.1-bob asosiy farq va jiddiy cheklov: trend bo'lgan vaqt qatorlarida daraxt kelajakni bashorat qila olmaydi. Yechim: trendni alohida modellab, qoldiqni daraxt bilan (yoki belgi sifatida "vaqt" o'rniga "o'zgarish" berish).
2.5. Induktiv siljish
Daraxt chegarasi — O'QLARGA PARALLEL to'rtburchaklar 14.7-bob
Oson: "daromad > X VA yosh < Y" kabi shartlar, o'zaro ta'sirlar
Qiyin: diagonal chegara (zinapoya bilan taqriblanadi — ko'p bo'linish kerak)
silliq egri chiziqlar
Shuning uchun: daraxt MASSHTABLASHNI TALAB QILMAYDI
(har belgi alohida ko'riladi, masofa hisoblanmaydi) Masshtablash kerak emasligi — daraxtlarning katta amaliy afzalligi (KNN va SVM dan farqli — 14.2, 14.5). Shuningdek, ular monoton transformatsiyalarga befarq: log(x) qo'shish daraxt natijasini umuman o'zgartirmaydi (bo'linish tartibi bir xil qoladi).
2.6. sklearn amaliyoti
from sklearn.tree import DecisionTreeClassifier, export_text, plot_tree
daraxt = DecisionTreeClassifier(max_depth=4, min_samples_leaf=20,
random_state=0).fit(X, y)
print(export_text(daraxt, feature_names=nomlar))
daraxt.tree_.node_count, daraxt.get_depth(), daraxt.get_n_leaves()
daraxt.feature_importances_ # nopoklik kamayishi (15.11 — ehtiyot)
daraxt.decision_path(X[:1]) # bitta namunaning yo'li export_text — daraxtni matn sifatida ko'rish: hisobot va tekshiruv uchun eng qulay. random_state majburiy: teng sifatli bo'linishlarda tanlov tasodifiy bo'ladi, shuning uchun usiz natija takrorlanmaydi.
2.7. Tuzoqlar
Asosiy tuzoqlar: chuqurlikni cheklamaslik (daraxt o'quvni yodlaydi — 15.2); random_state ni qo'ymaslik; criterion ni sozlashga vaqt sarflash; daraxtdan ekstrapolyatsiya kutish; feature_importances_ ni sababiy talqin qilish 15.11-bob; bitta daraxtga barqaror deb qarash (ma'lumot biroz o'zgarsa tuzilma butunlay o'zgaradi); masshtablash qilish (keraksiz, lekin zararsiz); chuqur daraxtni "talqin qilinadigan" deb hisoblash.
2.8. Sodda, tushunarli, kuchsiz
Qaror daraxti ma'lumotni ketma-ket savollar bilan bo'laklarga ajratadi; har tugunda nopoklik kamayishi (Gini yoki entropiya) eng katta bo'lgan bo'linish ochko'z tanlanadi. Chegara — o'qlarga parallel to'rtburchaklar, shuning uchun masshtablash kerak emas va monoton transformatsiyalar natijani o'zgartirmaydi. Regressiyada barg o'rtachani qaytaradi va daraxt ekstrapolyatsiya qilmaydi. Bitta daraxt kuchsiz va beqaror — lekin u ansambllarning qurilish bloki 15.4-bob. Keyingi dars — daraxt o'sishi va to'xtash shartlari.
3. Tez ma'lumotnoma
import numpy as np
from sklearn.tree import (DecisionTreeClassifier, DecisionTreeRegressor,
export_text, plot_tree)
d = DecisionTreeClassifier(criterion="gini", max_depth=4, min_samples_leaf=20,
random_state=0).fit(X, y)
print(export_text(d, feature_names=list(nomlar)))
d.get_depth(), d.get_n_leaves(), d.tree_.node_count
# tugun ma'lumotlari
d.tree_.feature, d.tree_.threshold, d.tree_.impurity, d.tree_.value
# regressiya
DecisionTreeRegressor(max_depth=5, min_samples_leaf=10, random_state=0)
QOIDA: chuqurlikni chekla · random_state qo'y · masshtablash shart emas ·
ekstrapolyatsiya yo'qDaraxt xulosasi
Tugun = savol, barg = bashorat; bashorat = ildizdan bargga yo'l
Gini = 1 - sum(p^2), entropiya = -sum(p log2 p); farqi kichik
Bo'linish = nopoklik kamayishi eng katta bo'lgan joy (ochko'z)
Chegara o'qlarga parallel; masshtablash keraksiz; ekstrapolyatsiya yo'q4. Batafsil misollar
Misollar real numpy/pandas/sklearn bilan (Python 3.14).
Misol 1 — Bo'linishni qo'lda hisoblash
"""Gini, entropiya va nopoklik kamayishi (real numpy/sklearn)."""
import numpy as np
from sklearn.tree import DecisionTreeClassifier
def gini(y) -> float:
if len(y) == 0:
return 0.0
p = np.bincount(y, minlength=2) / len(y)
return float(1 - (p ** 2).sum())
def entropiya(y) -> float:
if len(y) == 0:
return 0.0
p = np.bincount(y, minlength=2) / len(y)
p = p[p > 0]
return float(-(p * np.log2(p)).sum() + 0.0) # -0.0 ni 0.0 ga
def main() -> None:
rng = np.random.default_rng(3)
n = 400
x = rng.uniform(0, 10, n)
y = ((x > 6.2) ^ (rng.random(n) < 0.08)).astype(int) # 8% shovqin
print("=== 1. Nopoklik o'lchovlari ===")
for nom, taqsimot in [("toza (0/100)", np.zeros(100, dtype=int)),
("90/10", np.array([0] * 90 + [1] * 10)),
("70/30", np.array([0] * 70 + [1] * 30)),
("50/50", np.array([0] * 50 + [1] * 50))]:
print(f" {nom:<14}: Gini {gini(taqsimot):.4f}, "
f"entropiya {entropiya(taqsimot):.4f}")
print("\n=== 2. Chegara bo'yicha nopoklik kamayishi ===")
asosiy = gini(y)
print(f" ildiz Gini = {asosiy:.4f} (musbat sinf {y.mean():.2%})")
print(f" {'chegara':>8} {'chap n':>7} {'ong n':>7} {'kamayish':>10}")
eng_kamayish, eng_chegara = -1.0, None
for chegara in [2.0, 4.0, 5.0, 6.0, 6.2, 7.0, 8.0]:
chap, ong = y[x <= chegara], y[x > chegara]
kamayish = asosiy - (len(chap) / n * gini(chap)
+ len(ong) / n * gini(ong))
if kamayish > eng_kamayish:
eng_kamayish, eng_chegara = kamayish, chegara
print(f" {chegara:>8.1f} {len(chap):>7} {len(ong):>7} {kamayish:>10.4f}")
print(f" eng yaxshi chegara: {eng_chegara} (kamayish {eng_kamayish:.4f})")
print("\n=== 3. sklearn bilan tekshirish ===")
d = DecisionTreeClassifier(max_depth=1, random_state=0).fit(x.reshape(-1, 1), y)
print(f" sklearn tanlagan chegara: {d.tree_.threshold[0]:.4f}")
print(f" ildiz nopokligi: {d.tree_.impurity[0]:.4f}")
print(f" bolalar nopokligi: {d.tree_.impurity[1]:.4f} va "
f"{d.tree_.impurity[2]:.4f}")
print(f" haqiqiy chegara: 6.2")
print("\n=== 4. Gini va entropiya bir xil natija beradimi ===")
for kriteriy in ["gini", "entropy"]:
d = DecisionTreeClassifier(criterion=kriteriy, max_depth=3,
random_state=0).fit(x.reshape(-1, 1), y)
chegaralar = sorted(d.tree_.threshold[d.tree_.feature >= 0]
.round(3).tolist())
print(f" {kriteriy:<8}: {d.get_n_leaves()} barg, "
f"chegaralar {chegaralar}")
print(" ⭐ Bo'linish — nopoklik kamayishini maksimallashtirish")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Nopoklik o'lchovlari ===
toza (0/100) : Gini 0.0000, entropiya 0.0000
90/10 : Gini 0.1800, entropiya 0.4690
70/30 : Gini 0.4200, entropiya 0.8813
50/50 : Gini 0.5000, entropiya 1.0000
=== 2. Chegara bo'yicha nopoklik kamayishi ===
ildiz Gini = 0.4916 (musbat sinf 43.50%)
chegara chap n ong n kamayish
2.0 73 327 0.0556
4.0 152 248 0.1129
5.0 191 209 0.1931
6.0 235 165 0.2842
6.2 244 156 0.3046
7.0 282 118 0.1930
8.0 326 74 0.1123
eng yaxshi chegara: 6.2 (kamayish 0.3046)
=== 3. sklearn bilan tekshirish ===
sklearn tanlagan chegara: 6.1556
ildiz nopokligi: 0.4916
bolalar nopokligi: 0.2046 va 0.1404
haqiqiy chegara: 6.2
=== 4. Gini va entropiya bir xil natija beradimi ===
gini : 7 barg, chegaralar [1.034, 1.685, 1.714, 6.156, 8.892, 8.98]
entropy : 7 barg, chegaralar [1.034, 1.685, 1.714, 6.156, 8.892, 8.98]
⭐ Bo'linish — nopoklik kamayishini maksimallashtirishNima ko'rsatdi: 2.2, 2.3-bo'limlar.
Misol 2 — Daraxtni o'qish
"""export_text va qaror yo'li (real pandas/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_text
def yarat(seed: int = 7, n: int = 4000) -> pd.DataFrame:
"""Kredit: qoidalar aniq (daraxt ularni topishi kerak)."""
rng = np.random.default_rng(seed)
daromad = rng.lognormal(14.6, 0.5, n)
kechikish = rng.poisson(0.5, n).astype(float)
muddat = rng.integers(3, 48, n).astype(float)
yosh = rng.integers(21, 65, n).astype(float)
# haqiqiy qoida: past daromad VA kechikish -> xavfli
xavf = ((daromad < 2.5e6) & (kechikish >= 1)) | (kechikish >= 3)
y = np.where(rng.random(n) < np.where(xavf, 0.75, 0.10), 1, 0)
return pd.DataFrame({"daromad": daromad, "kechikish": kechikish,
"muddat": muddat, "yosh": yosh, "qaytarmadi": y})
def main() -> None:
df = yarat()
nomlar = ["daromad", "kechikish", "muddat", "yosh"]
X, y = df[nomlar], df["qaytarmadi"]
print("=== 1. Ma'lumot ===")
print(f" {len(df)} ariza, xavfli ulush {y.mean():.2%}")
print("\n=== 2. Kichik daraxt (max_depth=3) ===")
d = DecisionTreeClassifier(max_depth=3, min_samples_leaf=50,
random_state=0).fit(X, y)
matn = export_text(d, feature_names=nomlar, decimals=0)
for qator in matn.splitlines():
print(" " + qator)
print("\n=== 3. Daraxt o'lchami ===")
print(f" chuqurlik {d.get_depth()}, barglar {d.get_n_leaves()}, "
f"tugunlar {d.tree_.node_count}")
print(f" o'quv aniqligi {d.score(X, y):.4f}")
print("\n=== 4. Bitta arizaning yo'li ===")
ariza = X.iloc[[0]]
yol = d.decision_path(ariza).indices
for tugun in yol:
if d.tree_.feature[tugun] >= 0:
belgi = nomlar[d.tree_.feature[tugun]]
chegara = d.tree_.threshold[tugun]
qiymat = float(ariza.iloc[0][belgi])
yonalish = "chap (<=)" if qiymat <= chegara else "o'ng (>)"
print(f" tugun {tugun}: {belgi} = {qiymat:.0f} vs "
f"{chegara:.0f} -> {yonalish}")
else:
sanoq = d.tree_.value[tugun][0]
print(f" barg {tugun}: sinf ulushlari {sanoq.round(3)}, "
f"bashorat {int(np.argmax(sanoq))}")
print(" ⭐ Har bashorat uchun to'liq tushuntirish mavjud")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Ma'lumot ===
4000 ariza, xavfli ulush 27.45%
=== 2. Kichik daraxt (max_depth=3) ===
|--- kechikish <= 0
| |--- yosh <= 40
| | |--- muddat <= 8
| | | |--- class: 0
| | |--- muddat > 8
| | | |--- class: 0
| |--- yosh > 40
| | |--- muddat <= 40
| | | |--- class: 0
| | |--- muddat > 40
| | | |--- class: 0
|--- kechikish > 0
| |--- daromad <= 2510131
| | |--- daromad <= 1669333
| | | |--- class: 1
| | |--- daromad > 1669333
| | | |--- class: 1
| |--- daromad > 2510131
| | |--- kechikish <= 2
| | | |--- class: 0
| | |--- kechikish > 2
| | | |--- class: 0
=== 3. Daraxt o'lchami ===
chuqurlik 3, barglar 8, tugunlar 15
o'quv aniqligi 0.8598
=== 4. Bitta arizaning yo'li ===
tugun 0: kechikish = 0 vs 0 -> chap (<=)
tugun 1: yosh = 44 vs 40 -> o'ng (>)
tugun 5: muddat = 18 vs 40 -> chap (<=)
barg 6: sinf ulushlari [0.927 0.073], bashorat 0
⭐ Har bashorat uchun to'liq tushuntirish mavjudNima ko'rsatdi: 2.1, 2.6-bo'limlar.
Misol 3 — Induktiv siljish: o'qlarga parallel chegaralar
"""Daraxt qanday shakllarni oson, qaysilarini qiyin topadi (real numpy/sklearn)."""
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier
def yarat(tur: str, seed: int = 5, n: int = 2000):
rng = np.random.default_rng(seed)
X = rng.uniform(-3, 3, (n, 2))
if tur == "oq bo'yicha":
y = ((X[:, 0] > 0.5) & (X[:, 1] < 1.0)).astype(int)
elif tur == "diagonal":
y = (X[:, 0] + X[:, 1] > 0).astype(int)
else: # "doira"
y = (X[:, 0] ** 2 + X[:, 1] ** 2 < 4.0).astype(int)
alm = rng.random(n) < 0.03
y[alm] = 1 - y[alm]
return X, y
def main() -> None:
cv = StratifiedKFold(5, shuffle=True, random_state=0)
print("=== 1. Uch shakl uchun CV aniqligi ===")
print(f" {'shakl':<13} {'daraxt(4)':>11} {'daraxt(10)':>12} {'LogReg':>9}")
for tur in ["oq bo'yicha", "diagonal", "doira"]:
X, y = yarat(tur)
d4 = cross_val_score(DecisionTreeClassifier(max_depth=4, random_state=0),
X, y, cv=cv).mean()
d10 = cross_val_score(DecisionTreeClassifier(max_depth=10,
min_samples_leaf=10,
random_state=0),
X, y, cv=cv).mean()
lr = cross_val_score(Pipeline([("sc", StandardScaler()),
("m", LogisticRegression(max_iter=2000))]),
X, y, cv=cv).mean()
print(f" {tur:<13} {d4:>11.4f} {d10:>12.4f} {lr:>9.4f}")
print("\n=== 2. Diagonal chegara uchun nechta barg kerak ===")
X, y = yarat("diagonal")
for chuqurlik in [2, 4, 6, 8, 12]:
d = DecisionTreeClassifier(max_depth=chuqurlik, random_state=0).fit(X, y)
b = cross_val_score(DecisionTreeClassifier(max_depth=chuqurlik,
random_state=0),
X, y, cv=cv).mean()
print(f" chuqurlik {chuqurlik:>2}: {d.get_n_leaves():>4} barg, "
f"CV {b:.4f}")
print(" (diagonal chiziq zinapoya bilan taqriblanadi)")
print("\n=== 3. Masshtablash daraxtga ta'sir qiladimi ===")
X, y = yarat("oq bo'yicha")
X2 = X.copy()
X2[:, 0] *= 1000
d1 = DecisionTreeClassifier(max_depth=5, random_state=0).fit(X, y)
d2 = DecisionTreeClassifier(max_depth=5, random_state=0).fit(X2, y)
print(f" asl: {d1.get_n_leaves()} barg, o'quv aniqligi "
f"{d1.score(X, y):.4f}")
print(f" 1000x: {d2.get_n_leaves()} barg, o'quv aniqligi "
f"{d2.score(X2, y):.4f}")
print(f" bashoratlar bir xil: {np.array_equal(d1.predict(X), d2.predict(X2))}")
print("\n=== 4. Monoton transformatsiya ===")
X3 = X.copy()
X3[:, 0] = np.exp(X3[:, 0]) # monoton o'suvchi
d3 = DecisionTreeClassifier(max_depth=5, random_state=0).fit(X3, y)
print(f" exp(x1) bilan: {d3.get_n_leaves()} barg, "
f"bashoratlar bir xil: {np.array_equal(d1.predict(X), d3.predict(X3))}")
print(" ⭐ Daraxt tartibga qaraydi, qiymatga emas")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Uch shakl uchun CV aniqligi ===
shakl daraxt(4) daraxt(10) LogReg
oq bo'yicha 0.9655 0.9665 0.8830
diagonal 0.9160 0.9345 0.9655
doira 0.9040 0.9340 0.6380
=== 2. Diagonal chegara uchun nechta barg kerak ===
chuqurlik 2: 4 barg, CV 0.8320
chuqurlik 4: 16 barg, CV 0.9160
chuqurlik 6: 56 barg, CV 0.9360
chuqurlik 8: 108 barg, CV 0.9315
chuqurlik 12: 143 barg, CV 0.9250
(diagonal chiziq zinapoya bilan taqriblanadi)
=== 3. Masshtablash daraxtga ta'sir qiladimi ===
asl: 22 barg, o'quv aniqligi 0.9735
1000x: 22 barg, o'quv aniqligi 0.9735
bashoratlar bir xil: True
=== 4. Monoton transformatsiya ===
exp(x1) bilan: 22 barg, bashoratlar bir xil: True
⭐ Daraxt tartibga qaraydi, qiymatga emasNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Regressiya daraxti va ekstrapolyatsiya
"""Bo'lakli doimiy bashorat va uning cheklovi (real numpy/sklearn)."""
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
from sklearn.tree import DecisionTreeRegressor
def main() -> None:
rng = np.random.default_rng(9)
n = 600
x = rng.uniform(0, 10, n)
y = 3 + 1.8 * x + 4 * np.sin(x) + rng.normal(0, 1.0, n)
X = x.reshape(-1, 1)
print("=== 1. Daraxt va chiziqli model (o'quv diapazoni) ===")
ichki_x = np.linspace(0.5, 9.5, 300).reshape(-1, 1)
ichki_y = 3 + 1.8 * ichki_x[:, 0] + 4 * np.sin(ichki_x[:, 0])
modellar = {
"daraxt(3)": DecisionTreeRegressor(max_depth=3, random_state=0),
"daraxt(6)": DecisionTreeRegressor(max_depth=6, random_state=0),
"chiziqli": LinearRegression(),
}
for nom, m in modellar.items():
m.fit(X, y)
print(f" {nom:<10}: ichki MAE "
f"{mean_absolute_error(ichki_y, m.predict(ichki_x)):.3f}")
print("\n=== 2. Bo'lakli doimiy bashorat ===")
d = DecisionTreeRegressor(max_depth=3, random_state=0).fit(X, y)
sinov = np.array([[1.0], [1.5], [2.0], [2.5], [3.0]])
print(f" x qiymatlari: {sinov[:, 0]}")
print(f" bashoratlar: {d.predict(sinov).round(3)}")
print(f" (bir bargdagi nuqtalar BIR XIL bashorat oladi)")
print(f" barglar soni: {d.get_n_leaves()}, "
f"noyob bashoratlar: {len(np.unique(d.predict(X)))}")
print("\n=== 3. Ekstrapolyatsiya ===")
tash = np.array([[10.5], [12.0], [15.0], [30.0]])
haqiqiy = 3 + 1.8 * tash[:, 0] + 4 * np.sin(tash[:, 0])
for nom, m in modellar.items():
print(f" {nom:<10}: {m.predict(tash).round(1)}")
print(f" haqiqiy: {haqiqiy.round(1)}")
print(" (daraxt eng chekka bargning qiymatida QOTIB QOLADI)")
print("\n=== 4. Trend bo'lsa nima qilish kerak ===")
# trendni chiziqli model bilan, qoldiqni daraxt bilan
chiziqli = LinearRegression().fit(X, y)
qoldiq = y - chiziqli.predict(X)
qoldiq_daraxt = DecisionTreeRegressor(max_depth=4,
random_state=0).fit(X, qoldiq)
birlashgan_tash = chiziqli.predict(tash) + qoldiq_daraxt.predict(tash)
print(f" chiziqli + daraxt(qoldiq): {birlashgan_tash.round(1)}")
print(f" haqiqiy: {haqiqiy.round(1)}")
ichki_birlashgan = chiziqli.predict(ichki_x) + qoldiq_daraxt.predict(ichki_x)
print(f" ichki MAE: {mean_absolute_error(ichki_y, ichki_birlashgan):.3f}")
print(" ⭐ Trend chiziqli modelga, qoldiq daraxtga")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Daraxt va chiziqli model (o'quv diapazoni) ===
daraxt(3) : ichki MAE 0.839
daraxt(6) : ichki MAE 0.339
chiziqli : ichki MAE 2.426
=== 2. Bo'lakli doimiy bashorat ===
x qiymatlari: [1. 1.5 2. 2.5 3. ]
bashoratlar: [8.53 8.53 8.53 8.53 8.53]
(bir bargdagi nuqtalar BIR XIL bashorat oladi)
barglar soni: 8, noyob bashoratlar: 8
=== 3. Ekstrapolyatsiya ===
daraxt(3) : [19.6 19.6 19.6 19.6]
daraxt(6) : [19.7 19.7 19.7 19.7]
chiziqli : [22.8 25.5 30.9 58. ]
haqiqiy: [18.4 22.5 32.6 53. ]
(daraxt eng chekka bargning qiymatida QOTIB QOLADI)
=== 4. Trend bo'lsa nima qilish kerak ===
chiziqli + daraxt(qoldiq): [20.1 22.9 28.3 55.4]
haqiqiy: [18.4 22.5 32.6 53. ]
ichki MAE: 0.467
⭐ Trend chiziqli modelga, qoldiq daraxtgaNima ko'rsatdi: 2.4-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Daraxt eng yaxshi bo'linishni topadi" | Ochko'z, mahalliy optimal |
| "Gini va entropiya katta farq qiladi" | Farq 1-2% |
| "Daraxtni masshtablash kerak" | Kerak emas |
| "log(x) daraxtga yordam beradi" | Natija o'zgarmaydi |
| "Daraxt ekstrapolyatsiya qiladi" | Yo'q, qotib qoladi |
| "Chuqur daraxt tushunarli" | 50 barg — tushunarsiz |
| "Daraxt barqaror" | Ma'lumot o'zgarsa tuzilma o'zgaradi |
| "Bitta daraxt yetarli" | Ansambl ancha kuchli |
6. Keng tarqalgan xatolar va yechimlari
1. Chuqurlikni cheklamaslik
DecisionTreeClassifier().fit(X, y) # o'quvda 100% # ⚠️
DecisionTreeClassifier(max_depth=5, min_samples_leaf=20) # ✅2. random_state yo'q
DecisionTreeClassifier(max_depth=4) # takrorlanmaydi # ⚠️
DecisionTreeClassifier(max_depth=4, random_state=0) # ✅3. criterion ni sozlashga vaqt sarflash
GridSearchCV(d, {"criterion": ["gini", "entropy"]}) # ⚠️
GridSearchCV(d, {"max_depth": [3, 5, 8], "min_samples_leaf": [5, 20]}) # ✅4. Daraxtdan ekstrapolyatsiya kutish
daraxt.predict([[kelajakdagi_sana]]) # ⚠️
# trendni chiziqli model bilan, qoldiqni daraxt bilan # ✅5. Chuqur daraxtni "talqin qilinadigan" deb hisoblash
# 200 bargli daraxtni hisobotga qo'yish # ⚠️
# max_depth=3-4 (talqin uchun) yoki ansambl + SHAP (aniqlik uchun) # ✅6. Bitta daraxtga tayanish
model = DecisionTreeClassifier().fit(X, y) # ⚠️
RandomForestClassifier(n_estimators=300) # 15.5 # ✅7. Keraksiz masshtablash
Pipeline([("sc", StandardScaler()), ("m", DecisionTreeClassifier())]) # ⚠️
DecisionTreeClassifier(max_depth=5, random_state=0) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 14.7-dars (o'tilgan): Qaror chegaralari
- 15.2-dars: O'sish va to'xtash shartlari
- 15.4-15.5-darslar: Bagging va Random Forest
- 15.8-dars: Gradient boosting
- 15.11-dars: Belgi muhimligi
8. Eng yaxshi amaliyotlar
Chuqurlikni cheklang.
random_state qo'ying.
criterion ni sozlamang.
Masshtablamang (keraksiz).
Talqin uchun kichik daraxt oling.
Aniqlik uchun ansamblga o'ting.
Ekstrapolyatsiyani tekshiring.
export_text bilan ko'rib chiqing.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # daraxt tuzilishi elementlari?
2. # barg bashorati qanday?
3. # Gini formulasi?
4. # entropiya formulasi?
5. # bo'linish qanday tanlanadi?
6. # ochko'z nima degani?
7. # Gini va entropiya farqi?
8. # regressiyada barg nima qaytaradi?
9. # daraxt ekstrapolyatsiya qiladimi?
10. # chegara shakli?
11. # masshtablash kerakmi?
12. # log(x) natijani o'zgartiradimi?Javoblar
- Ildiz, tugun, barg
- Ko'pchilik sinf (yoki o'rtacha)
- 1 - sum(p^2)
- -sum(p*log2 p)
- Nopoklik kamayishi eng katta
- Mahalliy eng yaxshi, global emas
- Deyarli yo'q (1-2%)
- O'rtacha (yoki mediana)
- Yo'q
- O'qlarga parallel to'rtburchak
- Yo'q
- Yo'q (monoton)
Vazifa 2: Xatolarni tuzating
1. DecisionTreeClassifier().fit(X, y)
2. DecisionTreeClassifier(max_depth=4) # takrorlanmaydi
3. GridSearchCV(d, {"criterion": ["gini", "entropy"]})
4. Pipeline([("sc", StandardScaler()), ("m", DecisionTreeClassifier())])
5. daraxt.predict([[2027]]) # o'quvda 2020-2024Javoblar
1. DecisionTreeClassifier(max_depth=5, min_samples_leaf=20, random_state=0)
2. DecisionTreeClassifier(max_depth=4, random_state=0)
3. GridSearchCV(d, {"max_depth": [3, 5, 8]})
4. DecisionTreeClassifier(max_depth=5, random_state=0)
5. # trendni chiziqli model bilan modellangVazifa 3: Bo'linish
Modellang:
- Gini va entropiya
- Chegaralar bo'yicha kamayish
- sklearn bilan tekshirish
- Ikki kriteriy
Vazifa 4: Daraxtni o'qish
Modellang:
- Kichik daraxt
- export_text
- Bitta yo'l
- Xulosa
Vazifa 5: Induktiv siljish
Modellang:
- Uch shakl
- Diagonal chegara
- Masshtab
- Monoton transformatsiya
Vazifa 6: Regressiya daraxti
Modellang:
- Bo'lakli doimiy
- Ekstrapolyatsiya
- Trend muammosi
- Gibrid yechim
Vazifa 7: O'ylash
Qaror daraxti "talqin qilinadigan model" sifatida targ'ib qilinadi va shu sababli tibbiyot va moliyada afzal ko'riladi. Lekin bu da'vo qanchalik asosli?
Javob
Qisqa javob: kichik daraxt (3-4 daraja) haqiqatan tushunarli, lekin u kamdan-kam aniq. Aniq bo'lgan daraxt (20+ daraja, yuzlab barg) esa amalda qora quti — undan ma'no chiqarish chiziqli model koeffitsiyentlaridan ham qiyin.
1. Talqin qilinishning ikki darajasi
| Daraja | Daraxt |
|---|---|
| Bitta bashorat (lokal) | Yaxshi — aniq yo'l bor |
| Butun model (global) | Faqat kichik daraxtda |
2. Yashirin muammo: beqarorlik
- Ma'lumotning 5% i o'zgarsa, daraxt tuzilmasi butunlay o'zgarishi mumkin
- Ikki teng sifatli bo'linishdan biri tasodifiy tanlanadi
- "Bu qoida muhim" degan xulosa takrorlanmaydi
- Shuning uchun daraxt tuzilmasini bilim sifatida e'lon qilish xavfli
3. Amaliy yondashuv
- Talqin uchun:
max_depth=3-4,min_samples_leafkatta - Barqarorlikni tekshirish: bir nechta bootstrap namunada daraxt qurib, tuzilmani solishtirish
- Aniqlik uchun: ansambl + SHAP/permutation (15.11)
- Qoidalar kerak bo'lsa: daraxtdan qoida chiqarib, ularni alohida tasdiqlash
4. Muqobil talqin vositalari
- Chiziqli model koeffitsiyentlari 13.3-bob — barqarorroq
- Monotonlik cheklovlari bilan boosting
- Qoidalar ro'yxati (RuleFit, skope-rules)
5. Xulosa
- Talqin qilinish — daraxt chuqurligiga bog'liq
- Kichik daraxt tushunarli, lekin kuchsiz
- Beqarorlik talqinni shubha ostiga qo'yadi
- Lokal tushuntirish (yo'l) — eng ishonchli qism
Nimani mustahkamlaydi: 2.1, 2.7-bo'limlar.
Xulosa
Bu darsda qaror daraxtini o'rgandik.
Eng muhim uch fikr:
Bo'linish — nopoklik kamayishi. Har tugunda barcha belgi va chegaralar sinaladi va eng katta nopoklik kamayishi beradigani tanlanadi (
Gini = 1 - sum(p^2)yokientropiya = -sum(p*log2 p)— farqi 1-2%). Algoritm ochko'z: mahalliy eng yaxshi bo'linish tanlanadi, global optimal daraxt izlanmaydi.Chegara o'qlarga parallel. Bu induktiv siljish ikki muhim oqibatga ega: masshtablash kerak emas va monoton transformatsiyalar (log, exp) natijani umuman o'zgartirmaydi — daraxt qiymatga emas, tartibga qaraydi. Diagonal chegaralarni esa u zinapoya bilan taqriblaydi (ko'p barg talab qiladi).
Ekstrapolyatsiya yo'q. Regressiya daraxti barglarda o'rtachani qaytaradi, shuning uchun o'quv diapazonidan tashqarida eng chekka bargning qiymatida qotib qoladi — trendli ma'lumotda bu jiddiy cheklov (yechim: trendni chiziqli model bilan, qoldiqni daraxt bilan). Bitta daraxt kuchsiz va beqaror; uning asosiy qiymati — ansambllar uchun qurilish bloki bo'lishi.
Keyingi darsda daraxt o'sishi va to'xtash shartlarini o'rganamiz: chuqurlik, minimal namunalar, pruning va overfitting nazorati.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!