Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Uch to'plam
- 2.2. Cross-validation
- 2.3. Stratifikatsiya
- 2.4. Guruh bo'yicha ajratish
- 2.5. Vaqt qatorlari uchun ajratish
- 2.6. Ichma-ich (nested) CV
- 2.7. Ajratish tuzoqlari
- 2.8. Validatsiya — halol bahoning asosi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Bitta bo'linish tasodifi va CV
- Misol 2 — Stratifikatsiya va guruh bo'yicha ajratish
- Misol 3 — Vaqt bo'yicha ajratish
- Misol 4 — Test to'plamini "ishlatib yuborish"
- 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
12.3-dars: Train, validation, test va cross-validation
12-QISM — MACHINE LEARNING ASOSLARI · 3-dars
1. Kirish va motivatsiya
ML ning markaziy savoli: "Model yangi ma'lumotda qanday ishlaydi?". Javobni faqat bitta yo'l bilan olish mumkin — modelni ko'rmagan ma'lumotda sinash. Shu sababli ma'lumot bo'linadi: train (o'qitish), validation (model va giperparametr tanlash), test (yakuniy, bir martalik baho).
Bu — 8.8-darsdagi mustaqil tekshiruv g'oyasining ML dagi shakli. Ammo amalda ko'p nozik joylar bor: kichik ma'lumotda bitta bo'linish tasodifiy bo'ladi (cross-validation kerak), sinflar nomutanosib bo'lsa stratifikatsiya kerak, bir foydalanuvchining ko'p qatori bo'lsa guruh bo'yicha ajratish kerak, vaqt qatorlarida esa kelajakdan o'tmishga bashorat qilib bo'lmaydi.
Real vaziyat. Jamoa model tanlash uchun 15 ta variantni sinadi va har birini test to'plamida baholaydi; eng yaxshisini tanlaydi (test aniqligi 0.91). Ishlab chiqarishda aniqlik 0.84 chiqadi. Sabab: test to'plami 15 marta ishlatilgani uchun u endi "mustaqil" emas — model shu to'plamga moslab tanlandi (11.9 dagi ko'p taqqoslash muammosining ML shakli). To'g'ri yo'l: model tanlashni validation (yoki cross-validation) da qilish, test to'plamini esa oxirida bir marta ochish.
Bu darsda ma'lumotni ajratish va validatsiyani o'rganamiz.
Bu darsda:
- Uch to'plam: train, validation, test
- Cross-validation (K-fold)
- Stratifikatsiya (nomutanosib sinflar)
- Guruh bo'yicha ajratish (klasterlangan ma'lumot)
- Vaqt qatorlari uchun ajratish
- Ichma-ich (nested) CV va halol baholash
- Ajratish tuzoqlari
- Amaliy: to'g'ri validatsiya sxemasi
ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Uch to'plam
TRAIN (60-80%) — model parametrlarini o'rganadi (fit)
VALIDATION (10-20%) — model va giperparametr tanlash (ko'p marta ishlatiladi)
TEST (10-20%) — YAKUNIY baho, BIR MARTA ochiladi
Nega uchta?
train'da baholash — yodlash (12.1, Misol 3)
validation'da ko'p tanlov qilinsa — unga ham "moslashish" boshlanadi
test — halol baho uchun daxlsiz qoladiUch to'plam qoidasi — halol baholashning asosi. Validation to'plami "sarflanadigan" resurs: unda qancha ko'p qaror qabul qilinsa, u shunchalik optimistik bo'ladi 11.9-bob. Test to'plami — bir martalik: natija e'lon qilingandan keyin unga qaytib model tanlash mumkin emas. Amalda test ko'pincha vaqt bo'yicha ajratiladi (eng yangi davr) — chunki ishlab chiqarishda model aynan kelajakda ishlaydi.
2.2. Cross-validation
K-FOLD (K = 5 odatiy):
ma'lumot 5 bo'lakka bo'linadi; har safar 4 bo'lakda o'qitiladi, 1 da baholanadi
→ 5 ta baho; o'rtacha va SD hisoblanadi
Afzalligi: butun ma'lumotdan foydalanadi, baho barqarorroq (bitta bo'linish tasodifi yo'q)
Narxi: K marta o'qitish (hisoblash vaqti)
from sklearn.model_selection import cross_val_score, KFold
cross_val_score(model, X, y, cv=5, scoring="r2")Cross-validation — kichik va o'rta ma'lumotda standart usul: bitta holdout bo'linishi tasodifiy bo'lishi mumkin, CV esa K ta bahoning o'rtachasini beradi va noaniqlikni (SD) ko'rsatadi. Odatiy K = 5 yoki 10. Juda kichik ma'lumotda — LOO (leave-one-out, K = n): kam siljish, lekin katta dispersiya va qimmat. CV — model tanlash va giperparametr sozlash uchun; test to'plami baribir alohida qoladi.
2.3. Stratifikatsiya
Nomutanosib sinflar (2% firibgar): tasodifiy bo'linishda bo'laklarda sinf ulushi farq qiladi
→ baholar beqaror, ba'zi bo'lakda musbat sinf umuman bo'lmasligi mumkin
YECHIM: stratifikatsiya — har bo'lakda sinf ulushi asl ulushga teng
train_test_split(..., stratify=y)
StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
cross_val_score(clf, X, y, cv=5) # klassifikatsiyada standart — Stratified Stratifikatsiya — klassifikatsiyada deyarli har doim kerak, ayniqsa sinflar nomutanosib bo'lsa 12.7-bob. sklearn cross_val_score klassifikator uchun standart holatda StratifiedKFold ishlatadi, lekin train_test_split da stratify=y ni qo'lda ko'rsatish kerak. Regressiyada kerak emas, lekin kuchli qiyshiq nishonda kvantillar bo'yicha stratifikatsiya foydali bo'lishi mumkin.
2.4. Guruh bo'yicha ajratish
Klasterlangan ma'lumot: bir foydalanuvchining 20 sessiyasi, bir bemorning 5 tashrifi
tasodifiy ajratishda BIR foydalanuvchi ham train'da, ham test'da bo'ladi
→ model uni "tanib qoladi" → optimistik baho (11.3 dagi soxta mustaqillik)
YECHIM: guruh bo'yicha ajratish
GroupShuffleSplit, GroupKFold, StratifiedGroupKFold
cross_val_score(model, X, y, cv=GroupKFold(5), groups=user_id)Guruh bo'yicha ajratish — ML dagi eng ko'p e'tibordan chetda qoladigan qoida. Guruh — bir-biriga bog'liq kuzatuvlar to'plami: foydalanuvchi, bemor, do'kon, hujjat. Agar guruh ikki to'plamga bo'linib ketsa, baho haqiqatdan yuqori chiqadi (model shaxsiy xususiyatlarni yodlab oladi). Qoida: bashorat qilinadigan birlik — ajratish birligi.
2.5. Vaqt qatorlari uchun ajratish
Vaqt bilan bog'liq ma'lumotda tasodifiy ajratish — leakage (kelajakdan o'tmishga)
TO'G'RI: vaqt bo'yicha ajratish
train: yanvar-sentabr test: oktabr-dekabr
TimeSeriesSplit: kengayuvchi oyna
fold 1: train [1..100] test [101..120]
fold 2: train [1..120] test [121..140]
...
Qo'shimcha: "gap" (bo'shliq) — nishon oynasi bilan ustma-ust tushmaslik uchun Vaqt tartibi muhim bo'lsa (talab, narx, churn, moliyaviy ma'lumot), ajratish vaqt bo'yicha bo'lishi shart: model faqat o'tmishni ko'rib, kelajakni bashorat qiladi. TimeSeriesSplit — bir necha "kengayuvchi oyna" bo'linishi. Bu 12.2 dagi vaqt kesimi g'oyasining validatsiya darajasidagi davomi.
2.6. Ichma-ich (nested) CV
Muammo: giperparametrni CV bilan tanlab, o'sha CV bahosini "yakuniy natija" deb olish —
optimistik (CV ma'lumotiga moslashish)
NESTED CV:
tashqi halqa (5-fold): halol baho
ichki halqa (5-fold): giperparametr tanlash
→ 25 marta o'qitish, lekin siljimagan baho
Amalda: kichik ma'lumotda nested CV; katta ma'lumotda alohida test to'plami yetarliNested CV — "model tanlash bahosi" va "model sifati bahosi" ni ajratadi. Oddiy (nested emas) CV da giperparametr tanlash uchun ishlatilgan bahoni yakuniy deb e'lon qilish — optimizm manbai 11.9-bob. Katta ma'lumotda soddaroq yechim: train/validation/test uch bo'linishi.
2.7. Ajratish tuzoqlari
Asosiy tuzoqlar: test bilan model tanlash (test — bir martalik); fit ni butun ma'lumotda (scaler, imputer — faqat train'da, 12.9); stratifikatsiyasiz nomutanosib sinf; guruhni bo'lib yuborish (user ikki to'plamda); vaqt qatorida tasodifiy ajratish; dublikatlar (bir xil qator train va testda — sun'iy yuqori baho); random_state yo'q (takrorlanmaydi); juda kichik test (baho beqaror — SD ni ko'ring); CV natijasini SD siz hisobot qilish.
2.8. Validatsiya — halol bahoning asosi
Ma'lumot train (o'qitish), validation (tanlov) va test (yakuniy, bir martalik) ga bo'linadi. Cross-validation — bitta bo'linish tasodifini yo'qotadi va noaniqlikni (SD) ko'rsatadi. Stratifikatsiya — nomutanosib sinflarda; guruh bo'yicha ajratish — klasterlangan ma'lumotda (bir foydalanuvchi bir to'plamda); vaqt bo'yicha — vaqt qatorlarida (TimeSeriesSplit). Nested CV — giperparametr tanlash va halol baholashni ajratadi. Keyingi dars — overfitting va underfitting: model murakkabligi va umumlashtirish.
3. Tez ma'lumotnoma
import numpy as np
from sklearn.model_selection import (GroupKFold, GroupShuffleSplit, KFold,
StratifiedKFold, TimeSeriesSplit,
cross_val_score, cross_validate, train_test_split)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=0, stratify=y)
cross_val_score(model, X_tr, y_tr, cv=5, scoring="roc_auc") # klassifikatsiya
cross_val_score(model, X_tr, y_tr, cv=KFold(5, shuffle=True, random_state=0)) # regressiya
# guruh bo'yicha
cross_val_score(model, X, y, cv=GroupKFold(5), groups=guruhlar)
# vaqt bo'yicha
for tr, te in TimeSeriesSplit(n_splits=5).split(X): ...
# ko'p metrika va vaqt
cross_validate(model, X, y, cv=5, scoring=["accuracy", "roc_auc"], return_train_score=True)
QOIDA: test — bir marta · stratify · guruh bo'yicha · vaqtda tartib bilan · SD ni ko'rsatValidatsiya xulosasi
Train — o'qitish; validation — tanlov; test — yakuniy (bir marta)
CV (K=5) — barqaror baho + SD; kichik ma'lumotda ayniqsa muhim
Stratifikatsiya — nomutanosib sinflar
Guruh bo'yicha — bir foydalanuvchi bir to'plamda
Vaqt bo'yicha — kelajakdan o'tmishga bashorat yo'q
Nested CV — tanlov va baholashni ajratadi4. Batafsil misollar
Misollar real numpy/pandas/sklearn bilan (Python 3.14).
Misol 1 — Bitta bo'linish tasodifi va CV
"""Holdout bahosi tasodifiy tebranadi; CV barqarorroq (real numpy/sklearn)."""
import numpy as np
from sklearn.linear_model import Ridge
from sklearn.model_selection import KFold, cross_val_score, train_test_split
def main() -> None:
rng = np.random.default_rng(0)
n = 200
X = rng.normal(size=(n, 5))
y = X @ np.array([2.0, -1.0, 0.5, 0.0, 0.0]) + rng.normal(0, 1.5, n)
print("=== 1. 10 xil tasodifiy holdout (20% test) ===")
ballar = []
for seed in range(10):
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, random_state=seed)
ballar.append(Ridge(alpha=1.0).fit(Xtr, ytr).score(Xte, yte))
ballar = np.array(ballar)
print(f" R^2: min {ballar.min():.3f}, max {ballar.max():.3f}, "
f"o'rtacha {ballar.mean():.3f} (SD {ballar.std():.3f})")
print("\n=== 2. 5-fold cross-validation ===")
cv = KFold(n_splits=5, shuffle=True, random_state=0)
cvb = cross_val_score(Ridge(alpha=1.0), X, y, cv=cv, scoring="r2")
print(f" bo'laklar: {np.round(cvb, 3).tolist()}")
print(f" o'rtacha {cvb.mean():.3f} (SD {cvb.std():.3f})")
print("\n=== 3. CV ning o'zi ham tasodifga bog'liq (turli seed) ===")
ort = [cross_val_score(Ridge(alpha=1.0), X, y,
cv=KFold(5, shuffle=True, random_state=s), scoring="r2").mean()
for s in range(10)]
print(f" CV o'rtachalari: min {min(ort):.3f}, max {max(ort):.3f} "
f"(tarqoqlik holdoutdan kichik)")
print("\n=== 4. Katta ma'lumotda farq kamayadi ===")
Xb = rng.normal(size=(5000, 5))
yb = Xb @ np.array([2.0, -1.0, 0.5, 0.0, 0.0]) + rng.normal(0, 1.5, 5000)
b2 = [Ridge(alpha=1.0).fit(*train_test_split(Xb, yb, test_size=0.2, random_state=s)[::2])
.score(*train_test_split(Xb, yb, test_size=0.2, random_state=s)[1::2])
for s in range(10)]
print(f" n=5000 holdout R^2 SD: {np.std(b2):.4f}")
print(" ⭐ Kichik ma'lumotda CV — majburiy")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. 10 xil tasodifiy holdout (20% test) ===
R^2: min 0.535, max 0.762, o'rtacha 0.643 (SD 0.074)
=== 2. 5-fold cross-validation ===
bo'laklar: [0.606, 0.719, 0.572, 0.686, 0.731]
o'rtacha 0.663 (SD 0.063)
=== 3. CV ning o'zi ham tasodifga bog'liq (turli seed) ===
CV o'rtachalari: min 0.624, max 0.663 (tarqoqlik holdoutdan kichik)
=== 4. Katta ma'lumotda farq kamayadi ===
n=5000 holdout R^2 SD: 0.0149
⭐ Kichik ma'lumotda CV — majburiyNima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Stratifikatsiya va guruh bo'yicha ajratish
"""Nomutanosib sinf va klasterlangan ma'lumot: to'g'ri ajratish (real numpy/sklearn)."""
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import (GroupKFold, StratifiedKFold, cross_val_score,
train_test_split)
def main() -> None:
rng = np.random.default_rng(1)
print("=== 1. Nomutanosib sinf: stratifikatsiyasiz va bilan ===")
n = 600
y = (rng.random(n) < 0.05).astype(int) # 5% musbat
X = rng.normal(y[:, None] * 1.2, 1.0, (n, 3))
ulush_siz, ulush_bilan = [], []
for s in range(20):
_, _, ytr, yte = train_test_split(X, y, test_size=0.25, random_state=s)
ulush_siz.append(yte.mean())
_, _, ytr2, yte2 = train_test_split(X, y, test_size=0.25, random_state=s, stratify=y)
ulush_bilan.append(yte2.mean())
print(f" stratifikatsiyasiz test ulushi: {min(ulush_siz):.3f}..{max(ulush_siz):.3f}")
print(f" stratifikatsiya bilan: {min(ulush_bilan):.3f}..{max(ulush_bilan):.3f}")
print("\n=== 2. Klasterlangan ma'lumot: 50 foydalanuvchi × 20 sessiya ===")
n_user, n_sess = 50, 20
shaxsiy = rng.normal(0, 2.0, n_user) # kuchli shaxsiy effekt
user_id = np.repeat(np.arange(n_user), n_sess)
signal = rng.normal(0, 1, n_user * n_sess)
z = shaxsiy[user_id] + 0.6 * signal
yg = (rng.random(n_user * n_sess) < 1 / (1 + np.exp(-z))).astype(int)
Xg = np.column_stack([signal, shaxsiy[user_id] + rng.normal(0, 0.3, n_user * n_sess)])
model = RandomForestClassifier(n_estimators=120, min_samples_leaf=2, random_state=0)
oddiy = cross_val_score(model, Xg, yg, cv=StratifiedKFold(5, shuffle=True, random_state=0),
scoring="roc_auc")
guruh = cross_val_score(model, Xg, yg, cv=GroupKFold(5), groups=user_id, scoring="roc_auc")
print(f" oddiy CV AUC: {oddiy.mean():.3f} (SD {oddiy.std():.3f}) ← optimistik")
print(f" guruh CV AUC: {guruh.mean():.3f} (SD {guruh.std():.3f}) ← halol")
print("\n=== 3. Nega farq bor ===")
print(" oddiy CV da bir foydalanuvchining sessiyalari ham train, ham testda —")
print(" moslashuvchan model (o'rmon) shaxsiy darajani yodlab oladi")
print(" ⭐ Ajratish birligi — bashorat birligi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Nomutanosib sinf: stratifikatsiyasiz va bilan ===
stratifikatsiyasiz test ulushi: 0.020..0.067
stratifikatsiya bilan: 0.040..0.047
=== 2. Klasterlangan ma'lumot: 50 foydalanuvchi × 20 sessiya ===
oddiy CV AUC: 0.801 (SD 0.010) ← optimistik
guruh CV AUC: 0.795 (SD 0.075) ← halol
=== 3. Nega farq bor ===
oddiy CV da bir foydalanuvchining sessiyalari ham train, ham testda —
moslashuvchan model (o'rmon) shaxsiy darajani yodlab oladi
⭐ Ajratish birligi — bashorat birligiNima ko'rsatdi: 2.3, 2.4-bo'limlar.
Misol 3 — Vaqt bo'yicha ajratish
"""Vaqt qatorida tasodifiy ajratish optimistik baho beradi (real numpy/sklearn)."""
import numpy as np
from sklearn.linear_model import Ridge
from sklearn.model_selection import KFold, TimeSeriesSplit, cross_val_score
def main() -> None:
rng = np.random.default_rng(2)
n = 500
t = np.arange(n)
trend = 0.05 * t
mavsum = 3 * np.sin(2 * np.pi * t / 30)
shovqin = np.cumsum(rng.normal(0, 0.5, n)) # tasodifiy yurish
y = 20 + trend + mavsum + shovqin
X = np.column_stack([t, np.sin(2 * np.pi * t / 30), np.cos(2 * np.pi * t / 30)])
print("=== 1. Tasodifiy K-fold (NOTO'G'RI) ===")
kf = cross_val_score(Ridge(), X, y, cv=KFold(5, shuffle=True, random_state=0), scoring="r2")
print(f" R^2: {np.round(kf, 3).tolist()}, o'rtacha {kf.mean():.3f}")
print("\n=== 2. TimeSeriesSplit (TO'G'RI) ===")
ts = cross_val_score(Ridge(), X, y, cv=TimeSeriesSplit(n_splits=5), scoring="r2")
print(f" R^2: {np.round(ts, 3).tolist()}, o'rtacha {ts.mean():.3f}")
print("\n=== 3. Bo'linishlar tuzilishi ===")
for i, (tr, te) in enumerate(TimeSeriesSplit(n_splits=3).split(X), start=1):
print(f" fold {i}: train [{tr[0]}..{tr[-1]}] ({len(tr)}), "
f"test [{te[0]}..{te[-1]}] ({len(te)})")
print("\n=== 4. Oxirgi davr — test ===")
kesim = int(0.8 * n)
m = Ridge().fit(X[:kesim], y[:kesim])
print(f" train [0..{kesim - 1}], test [{kesim}..{n - 1}]: R^2 = {m.score(X[kesim:], y[kesim:]):.3f}")
print(" izoh: R^2 manfiy — model o'rtachadan ham yomon; sabab — tasodifiy yurish")
print(" (nostatsionar qator). Tasodifiy K-fold buni YASHIRADI: 0.80 kabi soxta natija")
print(" ⭐ Vaqt tartibi — ajratishda ham saqlanadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Tasodifiy K-fold (NOTO'G'RI) ===
R^2: [0.779, 0.808, 0.807, 0.828, 0.797], o'rtacha 0.804
=== 2. TimeSeriesSplit (TO'G'RI) ===
R^2: [-0.522, 0.597, -3.956, 0.731, -0.359], o'rtacha -0.702
=== 3. Bo'linishlar tuzilishi ===
fold 1: train [0..124] (125), test [125..249] (125)
fold 2: train [0..249] (250), test [250..374] (125)
fold 3: train [0..374] (375), test [375..499] (125)
=== 4. Oxirgi davr — test ===
train [0..399], test [400..499]: R^2 = -0.017
izoh: R^2 manfiy — model o'rtachadan ham yomon; sabab — tasodifiy yurish
(nostatsionar qator). Tasodifiy K-fold buni YASHIRADI: 0.80 kabi soxta natija
⭐ Vaqt tartibi — ajratishda ham saqlanadiNima ko'rsatdi: 2.5, 2.7-bo'limlar.
Misol 4 — Test to'plamini "ishlatib yuborish"
"""Test to'plamida ko'p model sinash — optimistik natija (real numpy/sklearn)."""
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score, train_test_split
def main() -> None:
rng = np.random.default_rng(3)
n, p = 600, 40
X = rng.normal(size=(n, p))
y = rng.integers(0, 2, n) # NISHON — TASODIFIY (signal yo'q!)
X_qolgan, X_te, y_qolgan, y_te = train_test_split(X, y, test_size=0.3,
random_state=0, stratify=y)
X_tr, X_val, y_tr, y_val = train_test_split(X_qolgan, y_qolgan, test_size=0.3,
random_state=0, stratify=y_qolgan)
print("=== 1. 40 xil belgilar to'plamini sinaymiz ===")
eng_yaxshi_test, eng_yaxshi_val = -1.0, -1.0
i_test = i_val = -1
for i in range(40):
ustunlar = rng.choice(p, size=8, replace=False)
m = LogisticRegression(max_iter=1000).fit(X_tr[:, ustunlar], y_tr)
v = m.score(X_val[:, ustunlar], y_val)
t = m.score(X_te[:, ustunlar], y_te)
if t > eng_yaxshi_test:
eng_yaxshi_test, i_test = t, i
if v > eng_yaxshi_val:
eng_yaxshi_val, i_val, val_test = v, i, t
print(f" test bo'yicha tanlangan: test balli {eng_yaxshi_test:.3f} ← optimistik")
print(f" validation bo'yicha tanlangan: val {eng_yaxshi_val:.3f}, test {val_test:.3f}")
print(" (nishon tasodifiy — haqiqiy aniqlik 0.5 atrofida bo'lishi kerak)")
print("\n=== 2. Nega shunday ===")
print(" 40 ta variantdan eng yaxshisini tanlash — shovqinni 'topish' 11.9-bob")
print("\n=== 3. To'g'ri tartib ===")
print(" 1) CV yoki validation'da tanlash")
print(" 2) test'ni BIR MARTA ochish")
cv = cross_val_score(LogisticRegression(max_iter=1000), X_qolgan, y_qolgan, cv=5)
print(f" CV bahosi (tasodifiy nishon): {cv.mean():.3f} — to'g'ri, 0.5 atrofida")
print(" ⭐ Test to'plami — bir martalik resurs")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. 40 xil belgilar to'plamini sinaymiz ===
test bo'yicha tanlangan: test balli 0.589 ← optimistik
validation bo'yicha tanlangan: val 0.595, test 0.483
(nishon tasodifiy — haqiqiy aniqlik 0.5 atrofida bo'lishi kerak)
=== 2. Nega shunday ===
40 ta variantdan eng yaxshisini tanlash — shovqinni 'topish' 11.9-bob
=== 3. To'g'ri tartib ===
1) CV yoki validation'da tanlash
2) test'ni BIR MARTA ochish
CV bahosi (tasodifiy nishon): 0.474 — to'g'ri, 0.5 atrofida
⭐ Test to'plami — bir martalik resursNima ko'rsatdi: 2.1, 2.6, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Test bilan model tanlash mumkin" | Bir martalik resurs |
| "Bitta holdout yetarli" | Kichik ma'lumotda CV |
| "CV — test o'rnini bosadi" | Alohida test kerak |
| "Stratifikatsiya avtomatik" | train_test_split da qo'lda |
| "Tasodifiy ajratish har doim to'g'ri" | Guruh va vaqtni hisobga oling |
| "CV o'rtachasi yetarli" | SD ni ham bering |
| "Vaqt qatori — oddiy ma'lumot" | Vaqt bo'yicha ajratish |
| "Dublikatlar zarar qilmaydi" | Sun'iy yuqori baho |
6. Keng tarqalgan xatolar va yechimlari
1. Test bilan tanlash
for m in modellar: print(m.fit(X_tr, y_tr).score(X_te, y_te)) # ⚠️
for m in modellar: print(cross_val_score(m, X_tr, y_tr, cv=5).mean()) # ✅2. Stratifikatsiyasiz
train_test_split(X, y, test_size=0.2, random_state=0) # ⚠️
train_test_split(X, y, test_size=0.2, random_state=0, stratify=y) # ✅3. Guruhni bo'lish
cross_val_score(model, X, y, cv=5) # bir user ko'p qator # ⚠️
cross_val_score(model, X, y, cv=GroupKFold(5), groups=user_id) # ✅4. Vaqt qatorida shuffle
KFold(5, shuffle=True) # ⚠️
TimeSeriesSplit(n_splits=5) # ✅5. Butun ma'lumotda fit
X_scaled = StandardScaler().fit_transform(X); train_test_split(X_scaled, y) # ⚠️
make_pipeline(StandardScaler(), model) # CV ichida 12.9-bob # ✅6. SD siz hisobot
print("CV:", scores.mean()) # ⚠️
print(f"CV: {scores.mean():.3f} ± {scores.std():.3f}") # ✅7. Dublikatlar
train_test_split(df, ...) # takroriy qatorlar # ⚠️
df = df.drop_duplicates(); train_test_split(df, ...) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8.8-dars (o'tilgan): Mustaqil tekshiruv g'oyasi
- 11.9-dars (o'tilgan): Ko'p taqqoslash va optimizm
- 12.2-dars (o'tilgan): Vaqt kesimi, guruh birligi
- 12.4-12.5-darslar: Overfitting, bias-variance
- 12.9-dars: Pipeline (leakage oldini olish)
8. Eng yaxshi amaliyotlar
Test to'plamini birinchi kunda ajrating va yopib qo'ying.
Model tanlash — CV yoki validation'da.
Klassifikatsiyada stratifikatsiya.
Guruh bo'lsa — guruh bo'yicha ajratish.
Vaqt bo'lsa — vaqt bo'yicha.
CV natijasini SD bilan bering.
Barcha tayyorlashni pipeline ichida qiling.
Dublikatlarni oldindan tozalang.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # uch to'plam nomi?
2. # test qachon ishlatiladi?
3. # K-fold nima qiladi?
4. # odatiy K?
5. # stratifikatsiya nima uchun?
6. # guruh bo'yicha ajratish qachon?
7. # vaqt qatorida qaysi splitter?
8. # nested CV nima uchun?
9. # CV natijasida nima ko'rsatiladi?
10. # scaler qayerda fit qilinadi?
11. # dublikatlar ta'siri?
12. # test 15 marta ishlatilsa?Javoblar
- Train, validation, test
- Oxirida, bir marta
- K ta bo'lakda navbatma-navbat baholaydi
- 5 yoki 10
- Sinf ulushini saqlash
- Klasterlangan ma'lumotda
- TimeSeriesSplit
- Tanlov va baholashni ajratish
- O'rtacha va SD
- Faqat train'da (pipeline ichida)
- Sun'iy yuqori baho
- Baho optimistik bo'ladi
Vazifa 2: Xatolarni tuzating
1. best = max(modellar, key=lambda m: m.fit(X_tr, y_tr).score(X_te, y_te))
2. train_test_split(X, y, test_size=0.2) # 3% musbat sinf
3. cross_val_score(model, X, y, cv=5) # har user 15 sessiya
4. KFold(5, shuffle=True).split(kunlik_savdo)
5. print("CV:", scores.mean())Javoblar
1. best = max(modellar, key=lambda m: cross_val_score(m, X_tr, y_tr, cv=5).mean())
2. train_test_split(X, y, test_size=0.2, random_state=0, stratify=y)
3. cross_val_score(model, X, y, cv=GroupKFold(5), groups=user_id)
4. TimeSeriesSplit(n_splits=5).split(kunlik_savdo)
5. print(f"CV: {scores.mean():.3f} ± {scores.std():.3f}")Vazifa 3: Validatsiya sxemasi
Modellang:
- Ma'lumot turi (klaster, vaqt, nomutanosib)
- Mos splitter tanlash
- CV natijasi
- Sxemani hujjatlashtirish
Vazifa 4: Holdout tebranishi
Modellang:
- n = 100, 500, 2000
- 30 xil holdout
- SD ni solishtirish
- CV bilan solishtirish
Vazifa 5: Guruh effekti
Modellang:
- Klasterlangan ma'lumot
- Oddiy va guruh CV
- Farqni tushuntirish
- To'g'ri sxema
Vazifa 6: Integratsiya
Modellang:
- Vaqt kesimi (12.2)
- TimeSeriesSplit
- Stratifikatsiya
- Pipeline (12.9 ga tayyorgarlik)
Vazifa 7: O'ylash
Kaggle musobaqalarida ishtirokchilar ko'pincha "leaderboard'ga moslashib qolish" (leaderboard overfitting) muammosiga duch keladi: ochiq reyting jadvalida yuqori natija ko'rsatgan yechim yopiq baholashda pastga tushadi. Bu qanday mexanizm, va u kundalik ML ishida qanday ko'rinishda uchraydi?
Javob
Qisqa javob: ochiq leaderboard — takroriy ishlatiladigan validatsiya to'plami. Unga qarab yuzlab qaror qabul qilinsa, model shu to'plamning shovqiniga moslashadi 11.9-bob. Kundalik ishda xuddi shunday: test to'plamiga qarab model tanlash, CV natijasiga qarab cheksiz tajriba qilish.
1. Mexanizm
- Har yuborilgan yechim — yangi "test"
- Eng yaxshi natija tanlanadi (maksimum tanlash — 11.2 g'olib la'nati)
- Tanlangan natija haqiqiydan yuqori (shovqin + moslashish)
2. Kundalik ishdagi shakllari
| Holat | Xavf |
|---|---|
| Test bilan model tanlash | Optimistik baho |
| CV da yuzlab variant | CV ga moslashish |
| Belgilarni test natijasiga qarab tanlash | Leakage |
| Metrikani natijadan keyin almashtirish | p-hacking (8.8) |
3. Himoya
- Test to'plamini yopib qo'yish (bir martalik)
- Nested CV yoki alohida validation
- Tajribalar sonini hujjatlashtirish
- Yakuniy modelni yangi davr ma'lumotida sinash
- Oddiyroq modelni afzal ko'rish (barqarorroq)
4. Data Scientist qanday
- Har tajribani jurnalga yozadi (nechta variant sinaldi)
- Yakuniy natijani mustaqil ma'lumotda tasdiqlaydi
- CV va test farqini kuzatadi (katta farq — moslashish belgisi)
5. Xulosa
- Har takroriy baholash — moslashish xavfi
- Tanlov qancha ko'p bo'lsa, optimizm shuncha katta
- Test — bir martalik; CV — cheklangan resurs
- Mustaqil tasdiqlash — yagona ishonchli usul
Nimani mustahkamlaydi: 2.1, 2.6, 2.7-bo'limlar.
Xulosa
Bu darsda ma'lumotni ajratish va validatsiyani o'rgandik.
Eng muhim uch fikr:
Uch to'plam. Train — o'qitish, validation — model va giperparametr tanlash, test — yakuniy baho (bir marta ochiladi). Test bilan tanlov qilish — optimistik natija (11.9 ning ML shakli).
Cross-validation. K-fold (K = 5) bitta bo'linish tasodifini yo'qotadi va noaniqlikni ko'rsatadi (o'rtacha ± SD). Kichik ma'lumotda majburiy; katta ma'lumotda oddiy holdout ham yetarli bo'lishi mumkin.
Ma'lumot tuzilishiga mos ajratish. Stratifikatsiya (nomutanosib sinflar), guruh bo'yicha (bir foydalanuvchi bir to'plamda — aks holda optimistik baho), vaqt bo'yicha (TimeSeriesSplit — kelajakdan o'tmishga bashorat yo'q). Barcha tayyorlash qadamlari pipeline ichida 12.9-bob.
Keyingi darsda overfitting va underfittingni o'rganamiz: model murakkabligi, o'quv va validatsiya egri chiziqlari, hamda regularizatsiya bilan muvozanat.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!