12-bo‘lim
Qaror daraxti va Random Forest
Daraxtlar qanday qaror qabul qiladi, Gini va entropiya, ansambl usullari va belgilar muhimligi.
Ushbu bo‘lim mundarijasi
Qaror daraxti - inson mantiqiga eng yaqin algoritm. U ketma-ket savollar berib javobga keladi, xuddi shifokor kabi.
Qaror daraxti nima? #
Birinchi daraxt #
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
iris = load_iris()
X, y = iris.data, iris.target
X_o, X_s, y_o, y_s = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
daraxt = DecisionTreeClassifier(max_depth=3, random_state=42)
daraxt.fit(X_o, y_o)
print(f"O'qitish: {daraxt.score(X_o, y_o):.3f}")
print(f"Sinov: {daraxt.score(X_s, y_s):.3f}")
O'qitish: 0.981
Sinov: 0.978
Daraxt faqat "bu qiymat chegaradan kattami?" deb so'raydi. Belgilar qanday birlikda o'lchanganining ahamiyati yo'q.
Bu daraxtlarning katta amaliy afzalligi.
Daraxtni ko'rish #
plt.figure(figsize=(16, 9))
plot_tree(
daraxt,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True,
rounded=True,
fontsize=10,
)
plt.show()
from sklearn.tree import export_text
print(export_text(daraxt, feature_names=iris.feature_names))
|--- petal length (cm) <= 2.45
| |--- class: setosa
|--- petal length (cm) > 2.45
| |--- petal width (cm) <= 1.75
| | |--- petal length (cm) <= 4.95
| | | |--- class: versicolor
| | |--- petal length (cm) > 4.95
| | | |--- class: virginica
| |--- petal width (cm) > 1.75
| | |--- class: virginica
def bashorat(barg_uzunligi, barg_kengligi):
if barg_uzunligi <= 2.45:
return "setosa"
if barg_kengligi <= 1.75:
return "versicolor" if barg_uzunligi <= 4.95 else "virginica"
return "virginica"
Hech qanday kutubxona kerak emas. Bu daraxtlarning tushuntirilishi naqadar yaxshi ekanini ko'rsatadi.
Bo'linish qanday tanlanadi? #
Daraxt har bir qadamda eng yaxshi ajratuvchi savolni qidiradi.
def gini(sinflar):
_, sonlar = np.unique(sinflar, return_counts=True)
ehtimolliklar = sonlar / len(sinflar)
return 1 - np.sum(ehtimolliklar ** 2)
print(gini([0, 0, 0, 0, 0])) # 0.0
print(gini([0, 0, 0, 0, 1])) # 0.32
print(gini([0, 0, 0, 1, 1])) # 0.48
print(gini([0, 1, 0, 1, 0, 1])) # 0.5
| Mezon | Formula | Xususiyat |
|---|---|---|
| Gini | 1 - Σp² | Tezroq hisoblanadi, standart |
| Entropiya | -Σp·log2(p) | Nazariy asosli, biroz sekinroq |
DecisionTreeClassifier(criterion="gini") # standart
DecisionTreeClassifier(criterion="entropy")
Gini va entropiya deyarli har doim bir xil daraxt quradi. Gini tezroq bo'lgani uchun standart qilib tanlangan.
Qayta o'qitish - daraxtlarning asosiy muammosi #
daraxt_cheksiz = DecisionTreeClassifier(random_state=42)
daraxt_cheksiz.fit(X_o, y_o)
print(f"O'qitish: {daraxt_cheksiz.score(X_o, y_o):.3f}")
print(f"Sinov: {daraxt_cheksiz.score(X_s, y_s):.3f}")
print(f"Chuqurlik: {daraxt_cheksiz.get_depth()}")
print(f"Barglar: {daraxt_cheksiz.get_n_leaves()}")
O'qitish: 1.000
Sinov: 0.933
Chuqurlik: 5
Barglar: 9
Agar chuqurlik cheklanmasa, daraxt har bir namuna uchun alohida barg yaratishi mumkin - ya'ni butun ma'lumotni yodlab oladi.
Bu qayta o'qitishning eng aniq ko'rinishi.
Cheklovlar #
daraxt = DecisionTreeClassifier(
max_depth=4, # maksimal chuqurlik
min_samples_split=20, # bo'linish uchun minimal namuna
min_samples_leaf=10, # bargdagi minimal namuna
max_leaf_nodes=15, # maksimal barglar soni
min_impurity_decrease=0.01,
random_state=42,
)
| Parametr | Ta'siri |
|---|---|
max_depth | Eng muhim - daraxt balandligi |
min_samples_split | Kichik guruhlarni bo'lishni taqiqlaydi |
min_samples_leaf | Bargda kamida shuncha namuna bo'lsin |
max_leaf_nodes | Umumiy murakkablikni cheklaydi |
ccp_alpha | Kesish (pruning) kuchi |
print("Chuqurlik O'qitish Sinov")
for chuqurlik in [1, 2, 3, 5, 10, None]:
d = DecisionTreeClassifier(max_depth=chuqurlik, random_state=42).fit(X_o, y_o)
nom = str(chuqurlik) if chuqurlik else "cheksiz"
print(f"{nom:>9} {d.score(X_o, y_o):8.3f} {d.score(X_s, y_s):.3f}")
Chuqurlik O'qitish Sinov
1 0.667 0.667
2 0.962 0.978
3 0.981 0.978
5 1.000 0.933
10 1.000 0.933
cheksiz 1.000 0.933
Chuqurlik 2-3 - eng yaxshi. Undan keyin sinov natijasi tushadi.
Belgilar muhimligi #
import pandas as pd
daraxt = DecisionTreeClassifier(max_depth=3, random_state=42).fit(X_o, y_o)
muhimlik = pd.Series(
daraxt.feature_importances_,
index=iris.feature_names,
).sort_values(ascending=False)
print(muhimlik.round(3))
petal width (cm) 0.573
petal length (cm) 0.427
sepal length (cm) 0.000
sepal width (cm) 0.000
Daraxt ikkita belgini umuman ishlatmagan - ular ortiqcha.
Bu bilim boshqa modellar uchun ham foydali: kerakli belgilarni daraxt yordamida topib, keyin ularni logistik regressiyaga bering.
feature_importances_ cheklovlari- Korrelyatsiyalangan belgilar orasida muhimlik tasodifan taqsimlanadi
- Ko'p noyob qiymatli belgilar sun'iy ravishda muhimroq ko'rinadi
Ishonchliroq usul - permutatsiya muhimligi:
from sklearn.inspection import permutation_importance
natija = permutation_importance(daraxt, X_s, y_s, n_repeats=10, random_state=42)
Random Forest #
Bitta daraxt beqaror. Yechim - ko'p daraxt qurib, ovoz berish.
Ikki tasodifiylik manbai:
- Bootstrap - har bir daraxt ma'lumotning tasodifiy qismida o'qiydi
- Belgi tasodifiyligi - har bir bo'linishda faqat belgilarning bir qismi ko'rib chiqiladi
from sklearn.ensemble import RandomForestClassifier
orman = RandomForestClassifier(
n_estimators=200,
max_depth=None,
max_features="sqrt",
n_jobs=-1,
random_state=42,
)
orman.fit(X_o, y_o)
print(f"Bitta daraxt: {daraxt_cheksiz.score(X_s, y_s):.3f}")
print(f"Random Forest: {orman.score(X_s, y_s):.3f}")
Bitta daraxt: 0.933
Random Forest: 0.978
Tasavvur qiling: 100 kishi tanga tashlab bashorat qiladi va har biri 55% to'g'ri javob beradi.
Ularning ko'pchilik ovozi 99% dan yuqori aniqlik beradi - agar ular mustaqil xato qilsa.
Random Forest aynan shuni ta'minlaydi: har bir daraxt boshqa ma'lumot va boshqa belgilarni ko'radi, shuning uchun ular turlicha xato qiladi.
Muhim parametrlar #
| Parametr | Tavsiya |
|---|---|
n_estimators | 100-500; ko'proq har doim yaxshiroq, lekin sekinroq |
max_features | "sqrt" klassifikatsiya, 1.0 regressiya uchun |
max_depth | None odatda yaxshi (ansambl qayta o'qitishni kamaytiradi) |
min_samples_leaf | 1-5; shovqinli ma'lumotda oshiring |
n_jobs | -1 - barcha yadrolarni ishlatadi |
class_weight | Nomutanosib sinflarda "balanced" |
n_estimators ni oshirish xavfsizDaraxtlar sonini oshirish qayta o'qitishga olib kelmaydi - u faqat natijani barqarorlashtiradi.
Ma'lum bir nuqtadan keyin yaxshilanish to'xtaydi, lekin yomonlashmaydi.
OOB baholash #
orman = RandomForestClassifier(
n_estimators=200, oob_score=True, random_state=42, n_jobs=-1,
)
orman.fit(X_o, y_o)
print(f"OOB aniqlik: {orman.oob_score_:.3f}")
print(f"Sinov aniqlik: {orman.score(X_s, y_s):.3f}")
OOB aniqlik: 0.962
Sinov aniqlik: 0.978
Bootstrap da har bir daraxt namunalarning ~63 foizini ko'radi. Qolgan ~37 foiz - out-of-bag (OOB).
Har bir namuna uni ko'rmagan daraxtlar bilan baholanadi. Bu kross-validatsiyaga o'xshash natija beradi, lekin qo'shimcha hisob talab qilmaydi.
Gradient Boosting #
Random Forest daraxtlarni parallel quradi. Boosting esa ketma-ket: har bir yangi daraxt oldingilarining xatolarini tuzatadi.
from sklearn.ensemble import GradientBoostingClassifier, HistGradientBoostingClassifier
gb = GradientBoostingClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
random_state=42,
)
gb.fit(X_o, y_o)
print(f"Gradient Boosting: {gb.score(X_s, y_s):.3f}")
# Katta ma'lumot uchun ancha tezroq
hgb = HistGradientBoostingClassifier(random_state=42).fit(X_o, y_o)
print(f"HistGradientBoosting: {hgb.score(X_s, y_s):.3f}")
| Random Forest | Gradient Boosting | |
|---|---|---|
| Daraxtlar | Parallel, mustaqil | Ketma-ket, bog'liq |
| Har bir daraxt | To'liq o'sadi | Sayoz (2-5 chuqurlik) |
| Qayta o'qitish | Kam | Ko'proq xavf |
| Sozlash | Oson | Ko'proq e'tibor talab qiladi |
| Odatiy natija | Yaxshi | Ko'pincha eng yaxshi |
| Tezlik | Parallel, tez | Sekinroq |
Kaggle musobaqalarida jadval ma'lumoti bilan g'olib chiqadigan yechimlarning katta qismi XGBoost, LightGBM yoki CatBoost ishlatadi.
pip install xgboost lightgbm catboost
Neyron tarmoqlar rasm, matn va ovozda ustun; jadvalda esa boosting odatda yaxshiroq ishlaydi.
Regressiya uchun #
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_estimators=200, n_jobs=-1, random_state=42)
model.fit(X_o, y_o)
Uy narxlarini 40-150 m2 oralig'ida o'rgangan daraxt, 300 m2 uy uchun o'zi ko'rgan eng katta qiymatni qaytaradi.
Chiziqli regressiya esa chiziqni davom ettirib, mantiqiy javob beradi.
Bashorat o'qitish oralig'idan tashqarida bo'lsa - daraxtlarga ishonmang.
- Iris ma'lumotida
max_depth=2bilan daraxt quring. export_textbilan qoidalarni chop eting.- Ularni qo'lda Python funksiyasiga aylantiring.
plot_treebilan daraxtni chizing.- Chuqurlikni 1 dan 15 gacha o'zgartirib jadval tuzing.
feature_importances_ni chiqaring va grafikda ko'rsating.RandomForestClassifierbilan solishtiring.n_estimatorsni 1, 10, 100, 500 qilib natijani kuzating.oob_score=Trueqo'shing va sinov natijasi bilan solishtiring.GradientBoostingClassifierbilan ham sinang - qaysi biri yaxshiroq?
Xulosa #
- Qaror daraxti ketma-ket savollar berib javobga keladi.
- Masshtablash kerak emas - bu katta amaliy afzallik.
- Gini yoki entropiya guruh qanchalik aralashligini o'lchaydi.
- Cheklanmagan daraxt ma'lumotni yodlab oladi -
max_depthni cheklang. feature_importances_qaysi belgilar muhimligini ko'rsatadi.- Random Forest ko'p daraxt qurib, ularning ovozini oladi.
- Ikki tasodifiylik: bootstrap namunalar va tasodifiy belgilar.
n_estimatorsni oshirish xavfsiz - qayta o'qitishga olib kelmaydi.- OOB bepul validatsiya beradi.
- Gradient Boosting ketma-ket xatolarni tuzatadi - jadval ma'lumotida ko'pincha eng yaxshi natija.
- Daraxtlar ekstrapolyatsiya qila olmaydi.
Keyingi bo'limda SVM va Naive Bayes ni ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.