Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. O'rganish egri chizig'i
- 2.2. Uch asosiy naqsh
- 2.3. Validatsiya egri chizig'i
- 2.4. Ko'proq ma'lumot yordam beradimi
- 2.5. Bias va dispersiyani ajratish
- 2.6. Amaliy qarorlar
- 2.7. Tuzoqlar
- 2.8. Diagnostika, sozlash emas
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Uch asosiy naqsh
- Misol 2 — Ko'proq ma'lumot yordam beradimi
- Misol 3 — Validatsiya egri chizig'i
- Misol 4 — Egri chiziqdan qarorga
- 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
18.8-dars: O'rganish egri chiziqlari
18-QISM — MODEL BAHOLASH VA SOZLASH · 8-dars
1. Kirish va motivatsiya
Model CV da 0.78 beradi va sizga 0.85 kerak. Endi nima qilish kerak — ko'proq ma'lumot yig'ishmi, murakkabroq model olishmi, yoki yangi belgilar o'ylab topishmi?
Bu savolga taxmin bilan javob berish qimmat: ma'lumot yig'ish oylar oladi, murakkabroq model esa foyda bermasligi mumkin. O'rganish egri chizig'i (learning curve) shu savolga o'lchov bilan javob beradi: u o'quv hajmi ortgani sari o'quv va validatsiya ballari qanday o'zgarishini ko'rsatadi.
Ikkinchi vosita — validatsiya egri chizig'i (validation curve): bitta giperparametr bo'yicha o'quv va validatsiya ballari. U underfitting va overfitting hududlarini ko'rsatadi.
Bu darsda: learning_curve va validation_curve ishlashi, egri chiziqlarni o'qish, yuqori bias va yuqori dispersiya naqshlari, "ko'proq ma'lumot yordam beradimi?" savoliga javob va amaliy qarorlar.
Real vaziyat. Jamoa uch oy davomida yangi ma'lumot yig'ish loyihasini rejalashtirdi (taxminiy narx 40 000 dollar). O'rganish egri chizig'i chizilganda ma'lum bo'ldiki, validatsiya balli 20 000 qatordan keyin tekislanib qolgan — ko'proq ma'lumot foyda bermasdi. Byudjet belgi muhandisligiga yo'naltirildi va +0.04 berdi.
Bu darsda o'rganish egri chiziqlarini o'rganamiz.
Bu darsda:
- O'rganish egri chizig'i
- Uch asosiy naqsh
- Validatsiya egri chizig'i
- Ko'proq ma'lumot yordam beradimi
- Bias va dispersiyani ajratish
- Amaliy qarorlar
- Tuzoqlar
- Amaliy: diagnostika
ℹ Misollar real numpy/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. O'rganish egri chizig'i
learning_curve(model, X, y, train_sizes=[...], cv=cv, scoring=...)
Har o'quv hajmi uchun:
o'quv to'plamidan shu qadar qator olinadi
model o'rgatiladi
O'QUV ballari va VALIDATSIYA ballari qaytariladi
NATIJA: ikki egri chiziq
o'quv balli - odatda pastga tushadi (ko'p ma'lumot = qiyinroq)
validatsiya balli - odatda yuqoriga chiqadi va tekislanadi
MUHIM: validatsiya to'plami HAR DOIM to'liq (CV dan)
faqat o'quv hajmi o'zgaradiIkki egri chiziq orasidagi masofa — dispersiya (overfitting) o'lchovi; validatsiya egri chizig'ining darajasi — bias o'lchovi.
2.2. Uch asosiy naqsh
1. YUQORI BIAS (underfitting)
o'quv balli PAST, validatsiya balli unga YAQIN
ikkalasi ham tez tekislanadi
-> ko'proq ma'lumot YORDAM BERMAYDI
-> murakkabroq model, yangi belgilar kerak
2. YUQORI DISPERSIYA (overfitting)
o'quv balli YUQORI, validatsiya balli PAST
orasida katta bo'shliq, bo'shliq sekin kamayadi
-> ko'proq ma'lumot YORDAM BERADI
-> yoki regularizatsiya, soddaroq model
3. YAXSHI MUVOZANAT
ikki egri chiziq yaqin va yuqori darajada tekislangan
-> model ma'lumotdan olishi mumkin bo'lgan narsani olgan
-> yangi BELGILAR yoki boshqa ma'lumot manbai kerakBo'shliq va daraja — ikki alohida savol: bo'shliq katta bo'lsa ma'lumot, daraja past bo'lsa model yoki belgilar.
2.3. Validatsiya egri chizig'i
validation_curve(model, X, y, param_name=..., param_range=[...],
cv=cv, scoring=...)
Bitta giperparametr bo'yicha o'quv va validatsiya ballari.
O'QISH:
chap tomon (sodda model): ikkalasi past -> underfitting
o'rta: validatsiya eng yuqori -> optimum
o'ng tomon (murakkab): o'quv yuqori, validatsiya tushadi
-> overfitting
DIQQAT: bu 1D kesim - boshqa parametrlar qat'iy
bog'liq parametrlar bo'lsa yanglishtirishi mumkinValidatsiya egri chizig'i — 1D kesim: u optimal qiymatni emas, shakl va yo'nalishni ko'rsatadi.
2.4. Ko'proq ma'lumot yordam beradimi
QARORNI SHUNDAY QABUL QILING:
1. Oxirgi uch nuqtaga qarang (eng katta o'quv hajmlari)
2. Validatsiya balli hali o'sayaptimi?
ha -> ma'lumot qo'shish FOYDALI
yo'q -> tekislangan, ma'lumot yordam bermaydi
3. Qancha foyda? oxirgi ikki nuqta farqini ekstrapolyatsiya qiling
(odatda log-chiziqli: hajm 2x -> o'sish deyarli bir xil)
4. Narxni solishtiring:
"10 000 qator qo'shish +0.004 beradi, narxi 5000 dollar"
"yangi belgi guruhi +0.02 berishi mumkin, narxi 1 hafta"Ekstrapolyatsiya qiling: "hajmni ikki barobar oshirsak, qancha olamiz?" degan savolga egri chiziq taxminiy javob beradi.
2.5. Bias va dispersiyani ajratish
o'quv ball valid. ball bo'shliq
yuqori bias past past kichik
yuqori dispersiya yuqori past KATTA
ikkalasi o'rta past o'rta
yaxshi yuqori yuqori kichik
DIQQAT: "past" va "yuqori" MUTLAQ emas, VAZIFAGA nisbatan
shovqinli vazifada 0.75 - yaxshi natija bo'lishi mumkin
CHEGARA (Bayes xatosi):
hech bir model o'ta olmaydigan daraja
shovqin (flip_y), belgilar yetishmasligiMutlaq raqamlar aldaydi: vazifaning chegarasi (erishish mumkin bo'lgan eng yaxshi natija) noma'lum bo'lsa, "past" nima ekanini bilmaysiz.
2.6. Amaliy qarorlar
EGRI CHIZIQ QAROR
bo'shliq katta, valid o'sib -> ko'proq ma'lumot
bo'shliq katta, valid tekis -> regularizatsiya/soddalashtirish
bo'shliq kichik, daraja past -> murakkabroq model, YANGI BELGILAR
ikkalasi yuqori, tekis -> tayyor; belgilar/ma'lumot manbai
QO'SHIMCHA TEKSHIRUV:
- eng kichik hajmda ham natija yaxshi bo'lsa -> leakage?
- egri chiziq tebransa -> CV shovqinli, takrorlang
- o'quv balli 1.0 bo'lsa -> to'liq yodlab olganO'quv balli 1.0 va validatsiya past — klassik overfitting; o'quv balli ham past — model vazifani umuman yecha olmayapti.
2.7. Tuzoqlar
Asosiy tuzoqlar: egri chiziqni bitta bo'linishda chizish (shovqinli); train_sizes ni chiziqli olish (log masshtab yaxshiroq); o'quv ballini e'tiborsiz qoldirish; validatsiya egri chizig'ini ko'p o'lchovli qaror uchun ishlatish; tekislanganini "model yomon" deb talqin qilish; shuffle siz learning_curve (sukut bo'yicha KFold tartibni saqlaydi); egri chiziqni tayyorlashsiz (masshtablashsiz) chizish.
2.8. Diagnostika, sozlash emas
O'rganish egri chizig'i sozlash vositasi emas, diagnostika vositasi. U ikki savolga javob beradi: bo'shliq (o'quv va validatsiya orasidagi masofa) — ko'proq ma'lumot kerakmi; daraja (validatsiya balli qayerda tekislandi) — model yoki belgilar kerakmi. Qaror qabul qilishdan oldin egri chiziqni chizing: bu bir necha daqiqa, lekin oylik ishni tejashi mumkin.
3. Tez ma'lumotnoma
import numpy as np
from sklearn.model_selection import (StratifiedKFold, learning_curve,
validation_curve)
hajmlar, oquv, valid = learning_curve(
quvur, X, y, train_sizes=np.logspace(-1.3, 0, 8),
cv=StratifiedKFold(5, shuffle=True, random_state=0),
scoring="roc_auc", n_jobs=1)
print(oquv.mean(axis=1).round(3), valid.mean(axis=1).round(3))
oquv, valid = validation_curve(
quvur, X, y, param_name="m__max_leaf_nodes",
param_range=[4, 8, 16, 32, 64], cv=cv, scoring="roc_auc")
bo_shliq = oquv.mean(axis=1) - valid.mean(axis=1)
QOIDA: bo'shliq -> ma'lumot · daraja -> model/belgilar ·
log train_sizes · Pipeline ichidaO'rganish egri chiziqlari xulosasi
Yuqori bias: ikkalasi past, bo'shliq kichik -> model/belgilar
Yuqori dispersiya: bo'shliq katta -> ma'lumot/regularizatsiya
Tekislangan: ma'lumot qo'shish foydasiz
validation_curve: bitta parametr bo'yicha 1D kesim4. Batafsil misollar
Misollar real numpy/sklearn bilan (Python 3.14).
Misol 1 — Uch asosiy naqsh
"""Bias, dispersiya va muvozanat egri chiziqlari (real numpy/sklearn)."""
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, learning_curve
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
def egri(model, X, y, cv):
hajmlar, oquv, valid = learning_curve(
model, X, y, train_sizes=np.logspace(-1.5, 0, 7),
cv=cv, scoring="roc_auc", n_jobs=1, shuffle=True, random_state=0)
return hajmlar, oquv.mean(axis=1), valid.mean(axis=1)
def main() -> None:
# nochiziqli vazifa: chiziqli model uchun yuqori bias
rng = np.random.default_rng(0)
n = 4000
X = rng.normal(0, 1, (n, 8))
kuch = (1.6 * (X[:, 0] * X[:, 1] > 0) + 1.4 * (X[:, 2] ** 2 - 1)
+ 0.8 * X[:, 3] - 1.0)
y = (rng.random(n) < 1 / (1 + np.exp(-kuch))).astype(int)
cv = StratifiedKFold(4, shuffle=True, random_state=0)
modellar = {
"chiziqli (yuqori bias)": make_pipeline(
StandardScaler(), LogisticRegression(max_iter=2000)),
"RF cheklanmagan (dispersiya)": RandomForestClassifier(
n_estimators=150, min_samples_leaf=1, random_state=0, n_jobs=1),
"RF sozlangan (muvozanat)": RandomForestClassifier(
n_estimators=150, min_samples_leaf=15, max_features=0.5,
random_state=0, n_jobs=1),
}
for nom, m in modellar.items():
hajmlar, oquv, valid = egri(m, X, y, cv)
print(f"=== {nom} ===")
print(f" {'hajm':>7} {'o_quv':>8} {'valid':>8} {'bo_shliq':>10}")
for h, o, v in zip(hajmlar, oquv, valid):
print(f" {int(h):>7} {o:>8.4f} {v:>8.4f} {o - v:>10.4f}")
print(f" yakuniy bo'shliq: {oquv[-1] - valid[-1]:.4f}")
print(f" oxirgi ikki nuqtada valid o'sishi: "
f"{valid[-1] - valid[-2]:+.4f}")
print()
print("=== Talqin ===")
print(f" {'model':<30} {'daraja':>8} {'bo_shliq':>10} {'xulosa':<28}")
for nom, m in modellar.items():
_, oquv, valid = egri(m, X, y, cv)
bosh = oquv[-1] - valid[-1]
if bosh > 0.05:
xulosa = "ko'proq ma'lumot / reg."
elif valid[-1] < 0.72:
xulosa = "murakkabroq model/belgilar"
else:
xulosa = "muvozanat"
print(f" {nom:<30} {valid[-1]:>8.4f} {bosh:>10.4f} {xulosa:<28}")
print(" ⭐ Bo'shliq va daraja - ikki alohida savol")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== chiziqli (yuqori bias) ===
hajm o_quv valid bo_shliq
94 0.6929 0.5816 0.1114
168 0.6684 0.6024 0.0661
300 0.6754 0.6161 0.0594
533 0.6619 0.6217 0.0402
948 0.6532 0.6253 0.0278
1687 0.6449 0.6331 0.0118
3000 0.6391 0.6355 0.0036
yakuniy bo'shliq: 0.0036
oxirgi ikki nuqtada valid o'sishi: +0.0024
=== RF cheklanmagan (dispersiya) ===
hajm o_quv valid bo_shliq
94 1.0000 0.7475 0.2525
168 1.0000 0.7749 0.2251
300 1.0000 0.7886 0.2114
533 1.0000 0.7971 0.2029
948 1.0000 0.8032 0.1968
1687 1.0000 0.8147 0.1853
3000 1.0000 0.8240 0.1760
yakuniy bo'shliq: 0.1760
oxirgi ikki nuqtada valid o'sishi: +0.0093
=== RF sozlangan (muvozanat) ===
hajm o_quv valid bo_shliq
94 0.8545 0.6743 0.1801
168 0.9050 0.7716 0.1335
300 0.9221 0.7978 0.1243
533 0.9163 0.8042 0.1121
948 0.9199 0.8139 0.1060
1687 0.9230 0.8197 0.1033
3000 0.9251 0.8280 0.0970
yakuniy bo'shliq: 0.0970
oxirgi ikki nuqtada valid o'sishi: +0.0083
=== Talqin ===
model daraja bo_shliq xulosa
chiziqli (yuqori bias) 0.6355 0.0036 murakkabroq model/belgilar
RF cheklanmagan (dispersiya) 0.8240 0.1760 ko'proq ma'lumot / reg.
RF sozlangan (muvozanat) 0.8280 0.0970 ko'proq ma'lumot / reg.
⭐ Bo'shliq va daraja - ikki alohida savolNima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Ko'proq ma'lumot yordam beradimi
"""Egri chiziqdan ekstrapolyatsiya (real numpy/sklearn)."""
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.model_selection import StratifiedKFold, learning_curve
def main() -> None:
# ikki vazifa: biri shovqinli (chegara past), biri toza
vazifalar = {
"shovqinli (flip_y=0.30)": make_classification(
n_samples=24000, n_features=20, n_informative=6, n_redundant=4,
flip_y=0.30, class_sep=0.9, random_state=0),
"toza (flip_y=0.02)": make_classification(
n_samples=24000, n_features=20, n_informative=6, n_redundant=4,
flip_y=0.02, class_sep=0.9, random_state=0),
}
cv = StratifiedKFold(3, shuffle=True, random_state=0)
for nom, (X, y) in vazifalar.items():
model = HistGradientBoostingClassifier(learning_rate=0.1,
max_iter=200,
early_stopping=False,
random_state=0)
hajmlar, oquv, valid = learning_curve(
model, X, y, train_sizes=np.logspace(-2.4, 0, 7), cv=cv,
scoring="roc_auc", n_jobs=1, shuffle=True, random_state=0)
o, v = oquv.mean(axis=1), valid.mean(axis=1)
print(f"=== {nom} ===")
print(f" {'hajm':>7} {'o_quv':>8} {'valid':>8} "
f"{'oldingidan o_sish':>19}")
oldingi = None
for h, oo, vv in zip(hajmlar, o, v):
osish = "-" if oldingi is None else f"{vv - oldingi:+.4f}"
print(f" {int(h):>7} {oo:>8.4f} {vv:>8.4f} {osish:>19}")
oldingi = vv
# log-chiziqli ekstrapolyatsiya: hajm 2x -> so'nggi o'sish
songgi = v[-1] - v[-2]
nisbat = hajmlar[-1] / hajmlar[-2]
bir_ikki = songgi * np.log(2) / np.log(nisbat)
print(f" hajmni 2x oshirsak taxminan: {bir_ikki:+.4f}")
print(f" hajmni 10x oshirsak taxminan: "
f"{bir_ikki * np.log(10) / np.log(2):+.4f}")
print()
print("=== Qaror ===")
print(f" {'vazifa':<26} {'yakuniy':>9} {'2x foyda':>10} {'qaror':<26}")
for nom, (X, y) in vazifalar.items():
model = HistGradientBoostingClassifier(learning_rate=0.1,
max_iter=200,
early_stopping=False,
random_state=0)
hajmlar, oquv, valid = learning_curve(
model, X, y, train_sizes=np.logspace(-2.4, 0, 7), cv=cv,
scoring="roc_auc", n_jobs=1, shuffle=True, random_state=0)
v = valid.mean(axis=1)
songgi = v[-1] - v[-2]
bir_ikki = songgi * np.log(2) / np.log(hajmlar[-1] / hajmlar[-2])
qaror = ("ma'lumot foydali" if bir_ikki > 0.005
else "ma'lumot foydasiz")
print(f" {nom:<26} {v[-1]:>9.4f} {bir_ikki:>+10.4f} {qaror:<26}")
print(" ⭐ Ma'lumot yig'ishdan oldin egri chiziqni chizing")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== shovqinli (flip_y=0.30) ===
hajm o_quv valid oldingidan o_sish
63 1.0000 0.6705 -
160 1.0000 0.7083 +0.0378
401 1.0000 0.7537 +0.0455
1009 1.0000 0.7746 +0.0209
2535 1.0000 0.7964 +0.0218
6369 0.9983 0.8097 +0.0133
16000 0.9588 0.8226 +0.0128
hajmni 2x oshirsak taxminan: +0.0096
hajmni 10x oshirsak taxminan: +0.0320
=== toza (flip_y=0.02) ===
hajm o_quv valid oldingidan o_sish
63 1.0000 0.7686 -
160 1.0000 0.8640 +0.0954
401 1.0000 0.9062 +0.0422
1009 1.0000 0.9373 +0.0311
2535 1.0000 0.9581 +0.0208
6369 1.0000 0.9668 +0.0087
16000 0.9984 0.9724 +0.0055
hajmni 2x oshirsak taxminan: +0.0042
hajmni 10x oshirsak taxminan: +0.0138
=== Qaror ===
vazifa yakuniy 2x foyda qaror
shovqinli (flip_y=0.30) 0.8226 +0.0096 ma'lumot foydali
toza (flip_y=0.02) 0.9724 +0.0042 ma'lumot foydasiz
⭐ Ma'lumot yig'ishdan oldin egri chiziqni chizingNima ko'rsatdi: 2.4-bo'lim.
Misol 3 — Validatsiya egri chizig'i
"""Bitta parametr bo'yicha underfitting va overfitting (real sklearn)."""
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, validation_curve
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
def main() -> None:
X, y = make_classification(n_samples=1400, n_features=40,
n_informative=8, n_redundant=10, flip_y=0.2,
class_sep=0.8, random_state=0)
cv = StratifiedKFold(4, shuffle=True, random_state=0)
print("=== 1. LogisticRegression: C ===")
quvur = Pipeline([("s", StandardScaler()),
("m", LogisticRegression(max_iter=3000))])
C_lar = np.logspace(-4, 3, 8)
oquv, valid = validation_curve(quvur, X, y, param_name="m__C",
param_range=C_lar, cv=cv,
scoring="roc_auc", n_jobs=1)
o, v = oquv.mean(axis=1), valid.mean(axis=1)
print(f" {'C':>10} {'o_quv':>8} {'valid':>8} {'bo_shliq':>10} "
f"{'hudud':<14}")
for C, oo, vv in zip(C_lar, o, v):
hudud = ("underfitting" if oo - vv < 0.01 and vv < v.max() - 0.005
else "overfitting" if oo - vv > 0.05 else "optimum")
print(f" {C:>10.4g} {oo:>8.4f} {vv:>8.4f} {oo - vv:>10.4f} "
f"{hudud:<14}")
print(f" eng yaxshi C = {C_lar[int(np.argmax(v))]:.4g}")
print("\n=== 2. RandomForest: min_samples_leaf ===")
barglar = [1, 2, 5, 10, 25, 60, 150]
oquv, valid = validation_curve(
RandomForestClassifier(n_estimators=80, random_state=0, n_jobs=1),
X, y, param_name="min_samples_leaf", param_range=barglar, cv=cv,
scoring="roc_auc", n_jobs=1)
o, v = oquv.mean(axis=1), valid.mean(axis=1)
print(f" {'min_leaf':>10} {'o_quv':>8} {'valid':>8} {'bo_shliq':>10}")
for b, oo, vv in zip(barglar, o, v):
print(f" {b:>10} {oo:>8.4f} {vv:>8.4f} {oo - vv:>10.4f}")
print(f" eng yaxshi min_samples_leaf = {barglar[int(np.argmax(v))]}")
print(f" min_leaf=1 da bo'shliq: {o[0] - v[0]:.4f} (yodlab olish)")
print("\n=== 3. 1D kesim cheklovi ===")
# max_features ni o'zgartirsak, optimal min_samples_leaf o'zgaradimi
print(f" {'max_features':>13} {'eng yaxshi min_leaf':>21} "
f"{'eng yaxshi ball':>17}")
for mf in [0.2, 0.5, 1.0]:
_, valid2 = validation_curve(
RandomForestClassifier(n_estimators=80, max_features=mf,
random_state=0, n_jobs=1),
X, y, param_name="min_samples_leaf", param_range=barglar,
cv=cv, scoring="roc_auc", n_jobs=1)
v2 = valid2.mean(axis=1)
print(f" {mf:>13} {barglar[int(np.argmax(v2))]:>21} "
f"{v2.max():>17.4f}")
print(" optimal qiymat boshqa parametrga bog'liq")
print("\n=== 4. Shaklni o'qish ===")
print(" chap tomon (sodda): ikkalasi past -> underfitting")
print(" o'rta: valid eng yuqori -> optimum")
print(" o'ng tomon (murakkab): o'quv o'sadi, valid tushadi")
print(" ⭐ validation_curve optimal qiymat emas, SHAKL beradi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. LogisticRegression: C ===
C o_quv valid bo_shliq hudud
0.0001 0.8648 0.8577 0.0070 underfitting
0.001 0.8751 0.8660 0.0091 underfitting
0.01 0.8849 0.8717 0.0132 optimum
0.1 0.8864 0.8682 0.0181 optimum
1 0.8863 0.8674 0.0190 optimum
10 0.8864 0.8674 0.0190 optimum
100 0.8864 0.8674 0.0190 optimum
1000 0.8864 0.8674 0.0190 optimum
eng yaxshi C = 0.01
=== 2. RandomForest: min_samples_leaf ===
min_leaf o_quv valid bo_shliq
1 1.0000 0.8851 0.1149
2 0.9998 0.8871 0.1127
5 0.9898 0.8902 0.0996
10 0.9695 0.8867 0.0828
25 0.9340 0.8814 0.0526
60 0.9035 0.8709 0.0326
150 0.8730 0.8541 0.0189
eng yaxshi min_samples_leaf = 5
min_leaf=1 da bo'shliq: 0.1149 (yodlab olish)
=== 3. 1D kesim cheklovi ===
max_features eng yaxshi min_leaf eng yaxshi ball
0.2 1 0.8876
0.5 5 0.8856
1.0 10 0.8821
optimal qiymat boshqa parametrga bog'liq
=== 4. Shaklni o'qish ===
chap tomon (sodda): ikkalasi past -> underfitting
o'rta: valid eng yuqori -> optimum
o'ng tomon (murakkab): o'quv o'sadi, valid tushadi
⭐ validation_curve optimal qiymat emas, SHAKL beradiNima ko'rsatdi: 2.3-bo'lim.
Misol 4 — Egri chiziqdan qarorga
"""To'rt holatni diagnostika qilish (real numpy/sklearn)."""
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, learning_curve
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
def tahlil(nom: str, model, X, y, cv) -> dict:
hajmlar, oquv, valid = learning_curve(
model, X, y, train_sizes=np.logspace(-1.7, 0, 6), cv=cv,
scoring="roc_auc", n_jobs=1, shuffle=True, random_state=0)
o, v = oquv.mean(axis=1), valid.mean(axis=1)
bosh = float(o[-1] - v[-1])
osish = float(v[-1] - v[-2])
if bosh > 0.06 and osish > 0.004:
qaror = "ko'proq ma'lumot"
elif bosh > 0.06:
qaror = "regularizatsiya"
elif v[-1] < 0.75:
qaror = "murakkabroq model"
else:
qaror = "belgilar / manba"
return {"nom": nom, "oquv": float(o[-1]), "valid": float(v[-1]),
"boshliq": bosh, "osish": osish, "qaror": qaror}
def main() -> None:
rng = np.random.default_rng(0)
cv = StratifiedKFold(3, shuffle=True, random_state=0)
# A: nochiziqli vazifa, chiziqli model
n = 3000
Xa = rng.normal(0, 1, (n, 8))
kuch = 1.8 * (Xa[:, 0] * Xa[:, 1] > 0) + 1.5 * (Xa[:, 2] ** 2 - 1) - 0.5
ya = (rng.random(n) < 1 / (1 + np.exp(-kuch))).astype(int)
# B: kichik ma'lumot, murakkab model
Xb, yb = make_classification(n_samples=600, n_features=40,
n_informative=10, n_redundant=10,
flip_y=0.12, class_sep=0.9, random_state=1)
# C: katta toza ma'lumot, mos model
Xc, yc = make_classification(n_samples=8000, n_features=20,
n_informative=8, n_redundant=4,
flip_y=0.05, class_sep=1.0, random_state=2)
# D: shovqin chegarasi
Xd, yd = make_classification(n_samples=8000, n_features=20,
n_informative=6, n_redundant=4,
flip_y=0.35, class_sep=0.9, random_state=3)
holatlar = [
tahlil("A: nochiziqli + chiziqli model",
make_pipeline(StandardScaler(),
LogisticRegression(max_iter=2000)), Xa, ya, cv),
tahlil("B: kichik ma'lumot + murakkab",
HistGradientBoostingClassifier(max_leaf_nodes=63,
min_samples_leaf=2,
max_iter=300,
early_stopping=False,
random_state=0), Xb, yb, cv),
tahlil("C: katta toza ma'lumot",
HistGradientBoostingClassifier(max_iter=200,
early_stopping=False,
random_state=0), Xc, yc, cv),
tahlil("D: shovqin chegarasi",
HistGradientBoostingClassifier(max_iter=200,
early_stopping=False,
random_state=0), Xd, yd, cv),
]
print("=== 1. Diagnostika jadvali ===")
print(f" {'holat':<34} {'o_quv':>8} {'valid':>8} {'bo_shliq':>10} "
f"{'o_sish':>9}")
for h in holatlar:
print(f" {h['nom']:<34} {h['oquv']:>8.4f} {h['valid']:>8.4f} "
f"{h['boshliq']:>10.4f} {h['osish']:>+9.4f}")
print("\n=== 2. Qarorlar ===")
print(f" {'holat':<34} {'qaror':<22}")
for h in holatlar:
print(f" {h['nom']:<34} {h['qaror']:<22}")
print("\n=== 3. A holatini tuzatish: murakkabroq model ===")
oldin = tahlil("chiziqli",
make_pipeline(StandardScaler(),
LogisticRegression(max_iter=2000)),
Xa, ya, cv)
keyin = tahlil("boosting",
HistGradientBoostingClassifier(max_iter=200,
early_stopping=False,
random_state=0),
Xa, ya, cv)
print(f" chiziqli: valid {oldin['valid']:.4f}, "
f"bo'shliq {oldin['boshliq']:.4f}")
print(f" boosting: valid {keyin['valid']:.4f}, "
f"bo'shliq {keyin['boshliq']:.4f}")
print(f" o'sish: {keyin['valid'] - oldin['valid']:+.4f}")
print("\n=== 4. B holatini tuzatish: regularizatsiya ===")
oldin = tahlil("cheklanmagan",
HistGradientBoostingClassifier(max_leaf_nodes=63,
min_samples_leaf=2,
max_iter=300,
early_stopping=False,
random_state=0),
Xb, yb, cv)
keyin = tahlil("cheklangan",
HistGradientBoostingClassifier(max_leaf_nodes=8,
min_samples_leaf=20,
l2_regularization=2.0,
max_iter=300,
early_stopping=False,
random_state=0),
Xb, yb, cv)
print(f" cheklanmagan: valid {oldin['valid']:.4f}, "
f"bo'shliq {oldin['boshliq']:.4f}")
print(f" cheklangan: valid {keyin['valid']:.4f}, "
f"bo'shliq {keyin['boshliq']:.4f}")
print(f" bo'shliq kamayishi: "
f"{oldin['boshliq'] - keyin['boshliq']:+.4f}")
print(" ⭐ Egri chiziq keyingi qadamni aniq ko'rsatadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Diagnostika jadvali ===
holat o_quv valid bo_shliq o_sish
A: nochiziqli + chiziqli model 0.5318 0.5008 0.0310 -0.0073
B: kichik ma'lumot + murakkab 1.0000 0.8634 0.1366 +0.1231
C: katta toza ma'lumot 1.0000 0.9694 0.0306 +0.0013
D: shovqin chegarasi 0.9995 0.7792 0.2204 +0.0134
=== 2. Qarorlar ===
holat qaror
A: nochiziqli + chiziqli model murakkabroq model
B: kichik ma'lumot + murakkab ko'proq ma'lumot
C: katta toza ma'lumot belgilar / manba
D: shovqin chegarasi ko'proq ma'lumot
=== 3. A holatini tuzatish: murakkabroq model ===
chiziqli: valid 0.5008, bo'shliq 0.0310
boosting: valid 0.7816, bo'shliq 0.2184
o'sish: +0.2807
=== 4. B holatini tuzatish: regularizatsiya ===
cheklanmagan: valid 0.8634, bo'shliq 0.1366
cheklangan: valid 0.8748, bo'shliq 0.1252
bo'shliq kamayishi: +0.0114
⭐ Egri chiziq keyingi qadamni aniq ko'rsatadiNima ko'rsatdi: 2.5, 2.6-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Ko'proq ma'lumot har doim yordam beradi" | Tekislangan bo'lsa — yo'q |
| "Past ball — model yomon" | Vazifa chegarasi bo'lishi mumkin |
| "O'quv balli muhim emas" | Bo'shliqni u ko'rsatadi |
"validation_curve optimal qiymatni beradi" |
1D kesim, shakl beradi |
| "Egri chiziq bitta bo'linishda yetarli" | CV kerak |
"train_sizes chiziqli bo'lsin" |
Logarifmik yaxshiroq |
| "O'quv balli 1.0 — yaxshi" | Yodlab olish |
| "Egri chiziq sozlash vositasi" | Diagnostika vositasi |
6. Keng tarqalgan xatolar va yechimlari
1. Chiziqli train_sizes
train_sizes=np.linspace(0.1, 1.0, 5) # ⚠️
train_sizes=np.logspace(-1.5, 0, 7) # ✅2. shuffle siz
learning_curve(m, X, y, cv=5) # tartib saqlanadi # ⚠️
learning_curve(m, X, y, cv=cv, shuffle=True, random_state=0) # ✅3. Faqat validatsiya egri chizig'iga qarash
print(valid.mean(axis=1)) # ⚠️
print(oquv.mean(axis=1), valid.mean(axis=1)) # ikkalasi # ✅4. Tayyorlashsiz
learning_curve(SVC(), X, y, ...) # masshtablanmagan # ⚠️
learning_curve(make_pipeline(StandardScaler(), SVC()), X, y, ...) # ✅5. Bitta bo'linish
learning_curve(m, X, y, cv=ShuffleSplit(1)) # ⚠️
learning_curve(m, X, y, cv=StratifiedKFold(5, shuffle=True,
random_state=0)) # ✅6. validation_curve ni ko'p o'lchovli qaror uchun
# validation_curve dan optimal min_samples_leaf olib,
# max_features ni alohida sozlash # ⚠️
RandomizedSearchCV(m, {"min_samples_leaf": ..., "max_features": ...}) # ✅7. Tekislanganini noto'g'ri talqin qilish
# "valid tekislandi -> model yomon, boshqasini olaman" # ⚠️
# "valid tekislandi -> ma'lumot yetarli, endi BELGILAR" # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 12.5-dars (o'tilgan): Bias-variance
- 18.3-dars (o'tilgan): CV dispersiyasi
- 18.5-dars (o'tilgan): Giperparametrlar
- 18.12-dars: Amaliyot
- 23-qism: Chuqur o'rganishda egri chiziqlar
8. Eng yaxshi amaliyotlar
Qarordan oldin egri chiziq.
Ikkala egri chiziqni ko'ring.
Logarifmik
train_sizes.shuffle=Trueva CV.Pipelineichida.Ekstrapolyatsiya qiling.
Narx bilan solishtiring.
Vazifa chegarasini baholang.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # o'rganish egri chizig'i nimani ko'rsatadi?
2. # bo'shliq nimani o'lchaydi?
3. # daraja nimani o'lchaydi?
4. # yuqori bias naqshi?
5. # yuqori dispersiya naqshi?
6. # tekislangan egri chiziq nima deydi?
7. # validation_curve nima beradi?
8. # 1D kesim cheklovi?
9. # train_sizes qanday?
10. # o'quv balli 1.0 nima?
11. # vazifa chegarasi nima?
12. # ekstrapolyatsiya qanday?Javoblar
- O'quv hajmi va ballar bog'liqligini
- Dispersiya (overfitting)
- Bias
- Ikkalasi past, bo'shliq kichik
- Bo'shliq katta
- Ma'lumot qo'shish foydasiz
- Bitta parametr bo'yicha shakl
- Boshqa parametrlar qat'iy
- Logarifmik
- Yodlab olish
- Erishish mumkin bo'lgan eng yaxshi natija
- Log-chiziqli: hajm 2x → bir xil o'sish
Vazifa 2: Xatolarni tuzating
1. train_sizes=np.linspace(0.1, 1.0, 5)
2. learning_curve(m, X, y, cv=5)
3. print(valid.mean(axis=1))
4. learning_curve(SVC(), X, y, ...)
5. learning_curve(m, X, y, cv=ShuffleSplit(1))Javoblar
1. train_sizes=np.logspace(-1.5, 0, 7)
2. learning_curve(m, X, y, cv=cv, shuffle=True, random_state=0)
3. print(oquv.mean(axis=1), valid.mean(axis=1))
4. learning_curve(make_pipeline(StandardScaler(), SVC()), X, y, ...)
5. learning_curve(m, X, y, cv=StratifiedKFold(5, shuffle=True,
random_state=0))Vazifa 3: Naqshlar
Modellang:
- Chiziqli model
- Cheklanmagan RF
- Sozlangan RF
- Talqin
Vazifa 4: Ma'lumot
Modellang:
- Shovqinli vazifa
- Toza vazifa
- Ekstrapolyatsiya
- Qaror
Vazifa 5: Validatsiya egri chizig'i
Modellang:
Cmin_samples_leaf- 1D cheklov
- Shakl
Vazifa 6: Diagnostika
Modellang:
- To'rt holat
- Qarorlar
- A ni tuzatish
- B ni tuzatish
Vazifa 7: O'ylash
O'rganish egri chizig'ida o'quv balli 0.999, validatsiya balli 0.998 va ikkalasi eng kichik o'quv hajmidayoq shunday yuqori. Bu nimani anglatadi?
Javob
Qisqa javob: deyarli aniq leakage. Bunday natija haqiqiy vazifada amalda uchramaydi.
1. Nima uchun shubhali
| Kuzatish | Odatdagi holat | Sizdagi holat |
|---|---|---|
| Kichik o'quv hajmida ball | Past | 0.998 |
| Ball o'sishi | Sekin ko'tariladi | O'smaydi, allaqachon maksimum |
| Bo'shliq | Kichik hajmda katta | Deyarli nol |
Model 50-100 qatordan "hamma narsani" o'rgangan — bu signal juda kuchli yoki javob belgilar ichida degani.
2. Eng ehtimoliy sabablar
- Maqsad belgisi kirishda:
ydan hosil qilingan ustun (natija_kodi,yopilish_sababi,qaytarish_summasi). - Tayyorlash leakage i: masshtablash, imputatsiya yoki belgi tanlash butun ma'lumotda qilingan.
- Duplikatlar: bir xil qatorlar o'quv va validatsiyada — model ularni yodlab oladi.
- Guruh leakage i: bir obyektning qatorlari ikki tomonda.
- Sun'iy ma'lumot: generator shovqinsiz (
flip_y=0).
3. Tekshirish tartibi
# 1. duplikatlar
print(df.duplicated().sum())
# 2. har belgining YAKKA CV balli
for ustun in belgilar:
b = cross_val_score(model, df[[ustun]], y, cv=cv, scoring="roc_auc")
if b.mean() > 0.9:
print("SHUBHALI:", ustun, b.mean())
# 3. barcha tayyorlash Pipeline ichidami
# 4. guruh ustuni bormi (user_id, bemor_id, buyurtma_id)4. Odatda nima topiladi
Amaliyotda bunday egri chiziqning ~80% ida sabab bitta belgi bo'ladi: uning yakka CV balli 0.95+ chiqadi va uni olib tashlash bilan natija realistik darajaga tushadi.
5. Agar leakage topilmasa
Vazifa haqiqatan oson bo'lishi mumkin (masalan, aniq qoidaga asoslangan tizim ma'lumoti). Unda:
- Modelni mustaqil to'plamda (boshqa davr, boshqa manba) sinang.
- Qoidani to'g'ridan-to'g'ri yozish modeldan arzonroq emasmi — o'ylab ko'ring.
6. Xulosa
- 0.998 ni nishonlamang, tekshiring
- Duplikatlar va yakka belgi ballari
- Barcha tayyorlash
Pipelineichida - Guruh tuzilmasi
- Mustaqil to'plamda tasdiqlash
Nimani mustahkamlaydi: 2.6-bo'lim.
Xulosa
Bu darsda o'rganish egri chiziqlarini o'rgandik.
Eng muhim uch fikr:
Egri chiziq ikki savolga javob beradi: bo'shliq va daraja. O'quv va validatsiya ballari orasidagi bo'shliq — dispersiya (overfitting) o'lchovi: katta bo'lsa ko'proq ma'lumot yoki regularizatsiya kerak. Validatsiya balli tekislangan daraja — bias o'lchovi: past bo'lsa murakkabroq model yoki yangi belgilar kerak.
"Ko'proq ma'lumot kerakmi?" degan savolga taxmin bilan javob bermang. Oxirgi ikki nuqta orasidagi o'sishni ekstrapolyatsiya qiling: "hajmni ikki barobar oshirsak +0.003" degan raqam ma'lumot yig'ish narxi bilan solishtirilishi mumkin. Validatsiya egri chizig'i tekislangan bo'lsa, yangi qatorlar deyarli hech narsa bermaydi.
validation_curveoptimal qiymat emas, shakl beradi. U bitta parametr bo'yicha 1D kesim va boshqa parametrlar qat'iy bo'lganda chiziladi; optimal qiymat boshqa parametrlarga bog'liq bo'lishi mumkin. Shuning uchun undan underfitting/overfitting yo'nalishini o'qing, yakuniy tanlovni esa ko'p o'lchovli qidiruvga qoldiring.
Keyingi darsda metrika tanlashni ko'rib chiqamiz: biznes maqsadidan metrikaga qanday o'tiladi, scoring qanday yoziladi va o'z metrikangizni qanday qurasiz.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!