Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Segmentlar bo'yicha xato
- 2.2. Ishonch va xato
- 2.3. Yorliq sifati
- 2.4. Xato turlari taksonomiyasi
- 2.5. Belgi muhimligi
- 2.6. Bitta bashoratni tushuntirish
- 2.7. Tuzoqlar
- 2.8. Xatolar — yaxshilash yo'l xaritasi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Segmentlar bo'yicha xato
- Misol 2 — Ishonch va yuqori ishonchli xatolar
- Misol 3 — Xato turlari va belgi muhimligi
- Misol 4 — Bitta bashoratni tushuntirish va yaxshilash rejasi
- 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
14.13-dars: Xatolar tahlili
14-QISM — KLASSIFIKATSIYA · 13-dars
1. Kirish va motivatsiya
Model tanlandi, metrikalar o'lchandi. Endi eng ko'p foyda keltiradigan qadam: model qayerda va nega yanglishadi? Amaliyotda aniqlikni oshirishning eng samarali yo'li ko'pincha yangi algoritm emas — bu xatolarni guruhlash va ular ortidagi sababni topish.
Bu darsda: xatolarni segmentlar bo'yicha tahlil qilish, ishonch darajasi bo'yicha ajratish, yorliq sifati muammolarini topish, xato turlarini klassifikatsiya qilish, belgi muhimligi (permutation) va bitta bashoratni tushuntirish, hamda topilmalarni yaxshilash rejasiga aylantirish.
Real vaziyat. Kredit modelining F1 si 0.72 da qotib qoldi; jamoa 3 ta yangi algoritm sinab ko'rdi — foyda yo'q. Keyin xatolar tahlili qilindi: xatolarning 58% i "yangi mijoz" segmentiga tushdi (tarixi yo'q) va 19% i noto'g'ri yorliqlangan yozuvlar edi. Yangi segment uchun alohida qoida va yorliqlarni tozalash F1 ni 0.81 ga ko'tardi — model o'zgarmadi.
Bu darsda xatolar tahlilini o'rganamiz.
Bu darsda:
- Segmentlar bo'yicha xato
- Ishonch va xato bog'liqligi
- Yorliq sifati
- Xato turlari taksonomiyasi
- Belgi muhimligi
- Bitta bashoratni tushuntirish
- Tuzoqlar
- Amaliy: yaxshilash rejasi
ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Segmentlar bo'yicha xato
Umumiy metrika bitta son beradi; segmentlar qayerda muammo borligini ko'rsatadi
Segmentlar: kategoriyalar (hudud, tarif), diapazonlar (yosh, summa),
vaqt (oy, hafta kuni), ma'lumot manbai, til, qurilma
Har segment uchun: n, sinf ulushi, precision/recall/F1, xato ulushi
Diqqat: kichik segmentlarda metrika juda shovqinli (n >= 50-100 bo'lsin)
Qidirish kerak:
· metrikasi umumiy o'rtachadan sezilarli past segment
· xatolarning katta ulushini beradigan segment (n katta bo'lgani uchun)Segment tahlili — xatolar tahlilining asosi: u "model yomon" degan umumiy gapni "model shu yerda yomon" degan aniq topilmaga aylantiradi. Ikki savolni ajrating: qaysi segment eng yomon ishlaydi (sifat) va qaysi segment eng ko'p xato beradi (hajm) — ular har xil segmentlar bo'lishi mumkin.
2.2. Ishonch va xato
Bashoratlarni ishonch bo'yicha guruhlang: max(predict_proba)
Kutilgan naqsh:
yuqori ishonch -> kam xato; past ishonch -> ko'p xato
Anomaliyalar:
· YUQORI ishonchli XATOLAR — eng qimmatli topilma
(yorliq xatosi, leakage, model tuzilmasi noto'g'ri)
· past ishonchda ham aniqlik yuqori — model ehtiyotkor (kalibrlash - 14.10)
Amaliy: past ishonchli holatlarni INSON ko'rigiga yo'naltirish
("abstain" yoki "selective prediction")Yuqori ishonchli xatolar — xatolar tahlilidagi eng ma'lumotli guruh: model ishonch bilan yanglishsa, bu odatda ma'lumotdagi muammoni (noto'g'ri yorliq, ziddiyatli yozuv) yoki vazifa ta'rifidagi muammoni ko'rsatadi, algoritmnikini emas.
2.3. Yorliq sifati
Belgilar: bir xil (yoki juda o'xshash) namunalarda TURLI yorliq
model ishonch bilan yanglishgan holatlar
yorliqlovchilar orasidagi kelishmovchilik
Tekshirish usullari:
1. Dublikat/yaqin namunalarni topib, yorliqlarini solishtirish
2. Yuqori ishonchli xatolarni QO'LDA ko'rib chiqish (20-50 ta)
3. Cross-validation bashorati bilan yorliq mos kelmagan holatlar (confident learning)
Yorliq shovqini 5-10% bo'lsa — u Bayes xatosiga o'xshab ishlaydi (14.1)Ko'p loyihalarda yorliq sifati modelni almashtirishdan ko'ra ko'proq foyda beradi. Oltin qoida: 20-50 ta xatoni qo'lda ko'rib chiqing — bu bir soatlik ish odatda haftalik modellashtirish tajribasidan ko'proq ma'lumot beradi.
2.4. Xato turlari taksonomiyasi
Xatolarni SABABI bo'yicha guruhlang:
1. YORLIQ xatosi — haqiqiy yorliq noto'g'ri
2. BELGI yetishmasligi — kerakli ma'lumot belgilar ichida yo'q
3. AJRALMAS holat — sinflar haqiqatan ustma-ust (Bayes xatosi - 14.1)
4. KAM NAMUNA — shu turdagi holatlar o'quvda kam
5. TAQSIMOT siljishi — test holati o'quvdan farq qiladi (drift)
6. MODEL cheklovi — chegara shakli mos emas 14.7-bob
Har tur BOSHQA yechim talab qiladi:
yorliq -> tozalash; belgi -> yangi belgi; kam namuna -> ma'lumot yig'ish
ajralmas -> qabul qilish; drift -> qayta o'qitish; model -> boshqa algoritmTaksonomiya — xatolar tahlilining mahsuloti: har xato turiga boshqa qaror mos keladi. "Aniqlikni oshirish" degan noaniq vazifa shu tarzda "yorliqlarni tozalash + 2 ta yangi belgi + shu segment uchun ma'lumot yig'ish" degan aniq rejaga aylanadi.
2.5. Belgi muhimligi
from sklearn.inspection import permutation_importance
nat = permutation_importance(model, X_te, y_te, n_repeats=10,
random_state=0, scoring="f1")
nat.importances_mean, nat.importances_stdPermutation importance — belgini aralashtirib, metrika qancha tushishini o'lchaydi: u har qanday model uchun ishlaydi va test ma'lumotida hisoblanadi. Diqqat: korrelyatsiyalangan belgilarda muhimlik "bo'linib ketadi" (ikkalasi ham past ko'rinadi) — bu 13.3 dagi multikollinearlik muammosining aksi.
2.6. Bitta bashoratni tushuntirish
Chiziqli modelda: hissa_j = koeffitsiyent_j * belgi_qiymati_j (13.3, 14.11)
-> to'g'ridan-to'g'ri o'qiladi
Daraxt/ansamblda: qaror yo'li yoki SHAP qiymatlari
Amaliy foyda:
· xatoni tekshirish ("nega bu holatda yanglishdi?")
· foydalanuvchiga sabab ko'rsatish (kredit rad etish sababi)
· leakage topish (kutilmagan belgi hukmron - 12.9)Bitta bashoratni tushuntirish xatolar tahlilini aniq qiladi: umumiy muhimlik "daromad muhim" desa, bitta holat "aynan shu arizada kechikishlar soni hal qildi" deydi. Chiziqli modellarda bu bepul keladi — bu ularning amaliy afzalligi 13.10-bob.
2.7. Tuzoqlar
Asosiy tuzoqlar: kichik segmentlarda metrikaga ishonish (shovqin); xatolar tahlilini test to'plamida qilib, keyin o'sha testda baholash (12.3 — validatsiyada qiling); qo'lda ko'rib chiqmaslik; yorliq shovqinini model kamchiligi deb hisoblash; korrelyatsiyalangan belgilarda permutation importance ni noto'g'ri o'qish; topilmalarni rejaga aylantirmaslik; faqat umumiy metrikaga qarash.
2.8. Xatolar — yaxshilash yo'l xaritasi
Xatolar tahlili umumiy metrikadan aniq harakat rejasiga o'tish vositasi: xatolarni segmentlar (qayerda yomon va qayerda ko'p), ishonch darajasi (yuqori ishonchli xatolar eng qimmatli) va sabab turlari (yorliq, belgi, ajralmas, kam namuna, drift, model) bo'yicha guruhlang. Permutation importance va bitta bashoratni tushuntirish sababni aniqlashtiradi. Har xato turi boshqa yechim talab qiladi — shuning uchun tahlil natijasi aniq reja bo'lishi kerak. Keyingi dars — amaliyot: to'liq klassifikatsiya loyihasi.
3. Tez ma'lumotnoma
import numpy as np
import pandas as pd
from sklearn.inspection import permutation_importance
from sklearn.metrics import classification_report, confusion_matrix
df = pd.DataFrame({"y": y_val, "p": proba, "pred": pred, **segmentlar})
df["xato"] = df["y"] != df["pred"]
df["ishonch"] = np.maximum(df["p"], 1 - df["p"])
# segmentlar bo'yicha
df.groupby("hudud").agg(n=("y", "size"), xato_ulushi=("xato", "mean"),
xatolar=("xato", "sum"))
# ishonch bo'yicha
df["guruh"] = pd.qcut(df["ishonch"], 5)
df.groupby("guruh", observed=True)["xato"].mean()
# yuqori ishonchli xatolar — qo'lda ko'rib chiqish
df[df.xato].nlargest(20, "ishonch")
permutation_importance(model, X_val, y_val, n_repeats=10, random_state=0)
QOIDA: validatsiyada tahlil qil · segment + ishonch · 20-50 xatoni qo'lda ko'rXatolar tahlili xulosasi
Segmentlar: qaysi yomon (sifat) va qaysi ko'p xato beradi (hajm)
Ishonch: yuqori ishonchli xatolar -> yorliq/leakage/vazifa muammosi
Turlari: yorliq, belgi, ajralmas, kam namuna, drift, model
Har turga boshqa yechim; natija — aniq reja4. Batafsil misollar
Misollar real numpy/pandas/sklearn bilan (Python 3.14). Misollar bitta kredit ma'lumotidan foydalanadi.
Misol 1 — Segmentlar bo'yicha xato
"""Model qayerda yomon va qayerda ko'p xato qiladi (real pandas/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
def yarat(seed: int = 7, n: int = 9000) -> pd.DataFrame:
"""Kredit: 'yangi mijoz' segmentida belgilar kam ma'lumot beradi."""
rng = np.random.default_rng(seed)
yangi = rng.random(n) < 0.22
hudud = rng.choice(["markaz", "shimol", "janub", "chekka"], n,
p=[0.4, 0.25, 0.2, 0.15])
daromad = rng.lognormal(14.6, 0.5, n)
kechikish = rng.poisson(np.where(yangi, 0.15, 0.6), n).astype(float)
muddat = rng.integers(3, 48, n).astype(float)
ball = (-1.0 - 0.55 * (np.log(daromad) - 14.6) + 0.85 * kechikish
- 0.012 * muddat)
# yangi mijozlarda tarix yo'q -> ko'proq tasodifiylik
ball = ball + np.where(yangi, rng.normal(0, 1.6, n), rng.normal(0, 0.5, n))
y = (rng.random(n) < 1 / (1 + np.exp(-ball))).astype(int)
return pd.DataFrame({"yangi": yangi, "hudud": hudud, "daromad": daromad,
"kechikish": kechikish, "muddat": muddat,
"qaytarmadi": y})
def main() -> None:
df = yarat()
SON = ["daromad", "kechikish", "muddat"]
KAT = ["hudud"]
X = df[SON + KAT]
y = df["qaytarmadi"]
Xtr, Xval, ytr, yval, dtr, dval = train_test_split(
X, y, df, test_size=0.35, random_state=0, stratify=y)
model = Pipeline([
("t", ColumnTransformer([("son", StandardScaler(), SON),
("kat", OneHotEncoder(handle_unknown="ignore",
drop="first"), KAT)])),
("m", LogisticRegression(max_iter=3000)),
]).fit(Xtr, ytr)
nat = dval.copy()
nat["p"] = model.predict_proba(Xval)[:, 1]
nat["pred"] = (nat["p"] >= 0.5).astype(int)
nat["xato"] = nat["pred"] != nat["qaytarmadi"]
print("=== 1. Umumiy natija ===")
print(f" validatsiya {len(nat)} qator, musbat sinf {yval.mean():.1%}")
print(f" aniqlik {1 - nat['xato'].mean():.4f}, "
f"F1 {f1_score(nat['qaytarmadi'], nat['pred']):.4f}")
print("\n=== 2. Segment: yangi va eski mijozlar ===")
for qiymat, qism in nat.groupby("yangi"):
nom = "yangi" if qiymat else "eski"
print(f" {nom:<6}: n={len(qism):>4}, xato ulushi "
f"{qism['xato'].mean():.4f}, "
f"F1 {f1_score(qism['qaytarmadi'], qism['pred']):.4f}, "
f"barcha xatolarning {qism['xato'].sum() / nat['xato'].sum():.1%} i")
print("\n=== 3. Segment: hudud ===")
for qiymat, qism in nat.groupby("hudud"):
print(f" {qiymat:<8}: n={len(qism):>4}, xato ulushi "
f"{qism['xato'].mean():.4f}, "
f"barcha xatolarning {qism['xato'].sum() / nat['xato'].sum():.1%} i")
print("\n=== 4. Segment: daromad diapazoni ===")
nat["daromad_guruh"] = pd.qcut(nat["daromad"], 4,
labels=["past", "o_rta", "yuqori", "eng yuqori"])
for qiymat, qism in nat.groupby("daromad_guruh", observed=True):
print(f" {str(qiymat):<10}: n={len(qism):>4}, xato ulushi "
f"{qism['xato'].mean():.4f}, "
f"musbat sinf {qism['qaytarmadi'].mean():.3f}")
print(" ⭐ 'Eng yomon segment' va 'eng ko'p xato beruvchi segment' har xil")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Umumiy natija ===
validatsiya 3150 qator, musbat sinf 32.8%
aniqlik 0.6860, F1 0.2636
=== 2. Segment: yangi va eski mijozlar ===
eski : n=2477, xato ulushi 0.3121, F1 0.3141, barcha xatolarning 78.2% i
yangi : n= 673, xato ulushi 0.3210, F1 0.0000, barcha xatolarning 21.8% i
=== 3. Segment: hudud ===
chekka : n= 465, xato ulushi 0.2796, barcha xatolarning 13.1% i
janub : n= 655, xato ulushi 0.3130, barcha xatolarning 20.7% i
markaz : n=1266, xato ulushi 0.3065, barcha xatolarning 39.2% i
shimol : n= 764, xato ulushi 0.3482, barcha xatolarning 26.9% i
=== 4. Segment: daromad diapazoni ===
past : n= 788, xato ulushi 0.3579, musbat sinf 0.385
o_rta : n= 787, xato ulushi 0.3380, musbat sinf 0.341
yuqori : n= 787, xato ulushi 0.2757, musbat sinf 0.307
eng yuqori: n= 788, xato ulushi 0.2843, musbat sinf 0.280
⭐ 'Eng yomon segment' va 'eng ko'p xato beruvchi segment' har xilNima ko'rsatdi: 2.1-bo'lim.
Misol 2 — Ishonch va yuqori ishonchli xatolar
"""Ishonch darajasi bo'yicha xatolar (real pandas/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
def yarat(seed: int = 11, n: int = 9000, yorliq_shovqini: float = 0.05):
"""Ba'zi yorliqlar ataylab NOTO'G'RI (yorliq shovqini)."""
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, 6))
ball = 1.2 * X[:, 0] - 1.0 * X[:, 1] + 0.7 * X[:, 2]
y = (rng.random(n) < 1 / (1 + np.exp(-ball))).astype(int)
buzuq = rng.random(n) < yorliq_shovqini
y[buzuq] = 1 - y[buzuq]
return X, y, buzuq
def main() -> None:
X, y, buzuq = yarat()
idx = np.arange(len(X))
Xtr, Xval, ytr, yval, itr, ival = train_test_split(
X, y, idx, test_size=0.35, random_state=0, stratify=y)
model = Pipeline([("sc", StandardScaler()),
("m", LogisticRegression(max_iter=3000))]).fit(Xtr, ytr)
p = model.predict_proba(Xval)[:, 1]
nat = pd.DataFrame({"y": yval, "p": p, "buzuq": buzuq[ival]})
nat["pred"] = (nat["p"] >= 0.5).astype(int)
nat["xato"] = nat["pred"] != nat["y"]
nat["ishonch"] = np.maximum(nat["p"], 1 - nat["p"])
print("=== 1. Umumiy ===")
print(f" {len(nat)} qator, xato ulushi {nat['xato'].mean():.4f}")
print(f" ataylab buzilgan yorliqlar: {nat['buzuq'].mean():.1%}")
print("\n=== 2. Ishonch guruhlari bo'yicha xato ===")
nat["guruh"] = pd.qcut(nat["ishonch"], 5,
labels=["eng past", "past", "o_rta", "yuqori",
"eng yuqori"])
for qiymat, qism in nat.groupby("guruh", observed=True):
print(f" {str(qiymat):<11}: ishonch {qism['ishonch'].mean():.3f}, "
f"xato ulushi {qism['xato'].mean():.4f}, "
f"n={len(qism):>4}")
print("\n=== 3. Yuqori ishonchli xatolar ===")
yuqori_xato = nat[nat["xato"] & (nat["ishonch"] > 0.9)]
print(f" ishonch > 0.9 bo'lgan xatolar: {len(yuqori_xato)} ta")
print(f" ulardan buzilgan yorliqli: {yuqori_xato['buzuq'].mean():.1%}")
oddiy_xato = nat[nat["xato"] & (nat["ishonch"] <= 0.9)]
print(f" qolgan xatolarda buzilgan yorliq: {oddiy_xato['buzuq'].mean():.1%}")
print(" (yuqori ishonchli xatolar — yorliq muammosining indikatori)")
print("\n=== 4. Past ishonchda insonga yo'naltirish ===")
for ulush in [0.05, 0.10, 0.20]:
chegara = nat["ishonch"].quantile(ulush)
qolgan = nat[nat["ishonch"] > chegara]
print(f" eng past {ulush:.0%} ni insonga bersak: "
f"qolganda aniqlik {1 - qolgan['xato'].mean():.4f} "
f"(umumiy {1 - nat['xato'].mean():.4f})")
print(" ⭐ Selektiv bashorat: ishonchsiz holatlarni insonga bering")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Umumiy ===
3150 qator, xato ulushi 0.2822
ataylab buzilgan yorliqlar: 4.4%
=== 2. Ishonch guruhlari bo'yicha xato ===
eng past : ishonch 0.542, xato ulushi 0.4444, n= 630
past : ishonch 0.623, xato ulushi 0.4111, n= 630
o_rta : ishonch 0.709, xato ulushi 0.2508, n= 630
yuqori : ishonch 0.794, xato ulushi 0.2016, n= 630
eng yuqori : ishonch 0.901, xato ulushi 0.1032, n= 630
=== 3. Yuqori ishonchli xatolar ===
ishonch > 0.9 bo'lgan xatolar: 19 ta
ulardan buzilgan yorliqli: 47.4%
qolgan xatolarda buzilgan yorliq: 11.3%
(yuqori ishonchli xatolar — yorliq muammosining indikatori)
=== 4. Past ishonchda insonga yo'naltirish ===
eng past 5% ni insonga bersak: qolganda aniqlik 0.7269 (umumiy 0.7178)
eng past 10% ni insonga bersak: qolganda aniqlik 0.7383 (umumiy 0.7178)
eng past 20% ni insonga bersak: qolganda aniqlik 0.7583 (umumiy 0.7178)
⭐ Selektiv bashorat: ishonchsiz holatlarni insonga beringNima ko'rsatdi: 2.2, 2.3-bo'limlar.
Misol 3 — Xato turlari va belgi muhimligi
"""Xatolarni sababi bo'yicha guruhlash (real numpy/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.inspection import permutation_importance
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
def yarat(seed: int = 15, n: int = 8000):
"""Uch xil xato manbai: yorliq shovqini, yashirin belgi, ajralmas zona."""
rng = np.random.default_rng(seed)
X = rng.normal(0, 1, (n, 5))
yashirin = rng.normal(0, 1, n) # modelga BERILMAYDI
ball = 1.1 * X[:, 0] - 0.9 * X[:, 1] + 1.3 * yashirin
y = (rng.random(n) < 1 / (1 + np.exp(-ball))).astype(int)
buzuq = rng.random(n) < 0.04
y[buzuq] = 1 - y[buzuq]
return X, y, yashirin, buzuq
def main() -> None:
X, y, yashirin, buzuq = yarat()
idx = np.arange(len(X))
Xtr, Xval, ytr, yval, itr, ival = train_test_split(
X, y, idx, test_size=0.35, random_state=0, stratify=y)
model = Pipeline([("sc", StandardScaler()),
("m", LogisticRegression(max_iter=3000))]).fit(Xtr, ytr)
p = model.predict_proba(Xval)[:, 1]
pred = (p >= 0.5).astype(int)
xato = pred != yval
print("=== 1. Umumiy xato ===")
print(f" {len(yval)} qator, xato ulushi {xato.mean():.4f}")
print("\n=== 2. Xato turlari ===")
buzuq_val = buzuq[ival]
yashirin_val = np.abs(yashirin[ival])
ishonch = np.maximum(p, 1 - p)
turlar = {
"yorliq xatosi": xato & buzuq_val,
"yashirin belgi kuchli": xato & ~buzuq_val & (yashirin_val > 1.2),
"ajralmas zona (past ishonch)": xato & ~buzuq_val & (yashirin_val <= 1.2)
& (ishonch < 0.65),
"boshqa": xato & ~buzuq_val & (yashirin_val <= 1.2) & (ishonch >= 0.65),
}
for nom, mos in turlar.items():
print(f" {nom:<30}: {mos.sum():>4} ta "
f"({mos.sum() / xato.sum():.1%} barcha xatolardan)")
print("\n=== 3. Yashirin belgi qo'shilsa ===")
X2tr = np.column_stack([Xtr, yashirin[itr]])
X2val = np.column_stack([Xval, yashirin[ival]])
model2 = Pipeline([("sc", StandardScaler()),
("m", LogisticRegression(max_iter=3000))]).fit(X2tr, ytr)
xato2 = (model2.predict(X2val) != yval)
print(f" belgi qo'shilmagan: xato {xato.mean():.4f}")
print(f" belgi qo'shilgan: xato {xato2.mean():.4f}")
print(f" yaxshilanish: {(xato.mean() - xato2.mean()) / xato.mean():.1%}")
print("\n=== 4. Permutation importance ===")
nat = permutation_importance(model, Xval, yval, n_repeats=10,
random_state=0, scoring="accuracy")
tartib = np.argsort(nat.importances_mean)[::-1]
for i in tartib:
print(f" belgi {i}: {nat.importances_mean[i]:+.4f} "
f"+- {nat.importances_std[i]:.4f}")
print(" ⭐ Har xato turiga boshqa yechim mos keladi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Umumiy xato ===
2800 qator, xato ulushi 0.3193
=== 2. Xato turlari ===
yorliq xatosi : 78 ta (8.7% barcha xatolardan)
yashirin belgi kuchli : 234 ta (26.2% barcha xatolardan)
ajralmas zona (past ishonch) : 384 ta (43.0% barcha xatolardan)
boshqa : 198 ta (22.1% barcha xatolardan)
=== 3. Yashirin belgi qo'shilsa ===
belgi qo'shilmagan: xato 0.3193
belgi qo'shilgan: xato 0.2482
yaxshilanish: 22.3%
=== 4. Permutation importance ===
belgi 0: +0.1248 +- 0.0061
belgi 1: +0.0676 +- 0.0060
belgi 3: +0.0005 +- 0.0004
belgi 2: +0.0002 +- 0.0015
belgi 4: -0.0006 +- 0.0003
⭐ Har xato turiga boshqa yechim mos keladiNima ko'rsatdi: 2.4, 2.5-bo'limlar.
Misol 4 — Bitta bashoratni tushuntirish va yaxshilash rejasi
"""Xatolar tahlilidan aniq rejaga (real pandas/sklearn)."""
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
def yarat(seed: int = 7, n: int = 9000) -> pd.DataFrame:
rng = np.random.default_rng(seed)
yangi = rng.random(n) < 0.22
hudud = rng.choice(["markaz", "shimol", "janub", "chekka"], n,
p=[0.4, 0.25, 0.2, 0.15])
daromad = rng.lognormal(14.6, 0.5, n)
kechikish = rng.poisson(np.where(yangi, 0.15, 0.6), n).astype(float)
muddat = rng.integers(3, 48, n).astype(float)
ball = (-1.0 - 0.55 * (np.log(daromad) - 14.6) + 0.85 * kechikish
- 0.012 * muddat)
ball = ball + np.where(yangi, rng.normal(0, 1.6, n), rng.normal(0, 0.5, n))
y = (rng.random(n) < 1 / (1 + np.exp(-ball))).astype(int)
return pd.DataFrame({"yangi": yangi, "hudud": hudud, "daromad": daromad,
"kechikish": kechikish, "muddat": muddat,
"qaytarmadi": y})
def main() -> None:
df = yarat()
SON = ["daromad", "kechikish", "muddat"]
KAT = ["hudud"]
X, y = df[SON + KAT], df["qaytarmadi"]
Xtr, Xval, ytr, yval, dtr, dval = train_test_split(
X, y, df, test_size=0.35, random_state=0, stratify=y)
model = Pipeline([
("t", ColumnTransformer([("son", StandardScaler(), SON),
("kat", OneHotEncoder(handle_unknown="ignore",
drop="first"), KAT)])),
("m", LogisticRegression(max_iter=3000)),
]).fit(Xtr, ytr)
nomlar = model.named_steps["t"].get_feature_names_out()
w = model.named_steps["m"].coef_[0]
kesma = model.named_steps["m"].intercept_[0]
Z = model.named_steps["t"].transform(Xval)
p = model.predict_proba(Xval)[:, 1]
pred = (p >= 0.5).astype(int)
xato = pred != yval.to_numpy()
ishonch = np.maximum(p, 1 - p)
print("=== 1. Eng ishonchli xatolar ===")
tartib = np.argsort(np.where(xato, ishonch, -1))[::-1][:3]
for i in tartib:
qator = dval.iloc[i]
print(f" #{i}: haqiqiy {int(yval.iloc[i])}, bashorat {pred[i]} "
f"(p={p[i]:.3f}), yangi={bool(qator['yangi'])}, "
f"kechikish={qator['kechikish']:.0f}")
print("\n=== 2. Bitta bashoratni tushuntirish ===")
i = int(tartib[0])
hissa = Z[i] * w
tartib_h = np.argsort(np.abs(hissa))[::-1][:4]
print(f" kesma: {kesma:+.3f}")
for j in tartib_h:
print(f" {nomlar[j]:<16}: {hissa[j]:+.3f}")
z = float(hissa.sum() + kesma)
print(f" jami log-odds {z:+.3f} -> ehtimol {1 / (1 + np.exp(-z)):.3f}")
print("\n=== 3. Topilmalar jadvali ===")
yangi_val = dval["yangi"].to_numpy()
topilmalar = [
("yangi mijozlar segmenti",
f"xato ulushi {xato[yangi_val].mean():.3f} vs "
f"{xato[~yangi_val].mean():.3f}",
"tarix belgilari yo'q",
"alohida model yoki qo'shimcha belgilar"),
("barcha xatolarning ulushi",
f"{xato[yangi_val].sum() / xato.sum():.1%} yangi mijozlardan",
f"segment hajmi {yangi_val.mean():.0%}",
"shu segmentga ustuvorlik berish"),
("yuqori ishonchli xatolar",
f"{(xato & (ishonch > 0.85)).sum()} ta",
"yorliq yoki ziddiyatli yozuv",
"20-50 tasini qo'lda ko'rib chiqish"),
]
for nom, olchov, sabab, harakat in topilmalar:
print(f" [{nom}]")
print(f" o'lchov: {olchov}")
print(f" taxminiy sabab: {sabab}")
print(f" harakat: {harakat}")
print("\n=== 4. Rejani sinash: segment belgisi qo'shish ===")
X2tr = Xtr.assign(yangi=dtr["yangi"].astype(float))
X2val = Xval.assign(yangi=dval["yangi"].astype(float))
model2 = Pipeline([
("t", ColumnTransformer([("son", StandardScaler(), SON + ["yangi"]),
("kat", OneHotEncoder(handle_unknown="ignore",
drop="first"), KAT)])),
("m", LogisticRegression(max_iter=3000)),
]).fit(X2tr, ytr)
pred2 = model2.predict(X2val)
print(f" F1: {f1_score(yval, pred):.4f} -> {f1_score(yval, pred2):.4f}")
print(f" yangi mijozlarda xato: {xato[yangi_val].mean():.4f} -> "
f"{(pred2 != yval.to_numpy())[yangi_val].mean():.4f}")
print(" ⭐ Tahlil natijasi — aniq reja, keyin uni sinash")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Eng ishonchli xatolar ===
#788: haqiqiy 0, bashorat 1 (p=0.891), yangi=False, kechikish=4
#1795: haqiqiy 0, bashorat 1 (p=0.878), yangi=False, kechikish=4
#2623: haqiqiy 1, bashorat 0 (p=0.131), yangi=False, kechikish=0
=== 2. Bitta bashoratni tushuntirish ===
kesma: -0.819
son__kechikish : +2.671
son__daromad : +0.190
son__muddat : +0.058
kat__hudud_markaz: +0.007
jami log-odds +2.106 -> ehtimol 0.891
=== 3. Topilmalar jadvali ===
[yangi mijozlar segmenti]
o'lchov: xato ulushi 0.321 vs 0.312
taxminiy sabab: tarix belgilari yo'q
harakat: alohida model yoki qo'shimcha belgilar
[barcha xatolarning ulushi]
o'lchov: 21.8% yangi mijozlardan
taxminiy sabab: segment hajmi 21%
harakat: shu segmentga ustuvorlik berish
[yuqori ishonchli xatolar]
o'lchov: 7 ta
taxminiy sabab: yorliq yoki ziddiyatli yozuv
harakat: 20-50 tasini qo'lda ko'rib chiqish
=== 4. Rejani sinash: segment belgisi qo'shish ===
F1: 0.2636 -> 0.2674
yangi mijozlarda xato: 0.3210 -> 0.3254
⭐ Tahlil natijasi — aniq reja, keyin uni sinashNima ko'rsatdi: 2.6-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Aniqlikni oshirish — yangi algoritm" | Ko'pincha ma'lumot muammosi |
| "Xatolar tasodifiy" | Segmentlarga to'planadi |
| "Yuqori ishonchli xato — model aybi" | Ko'pincha yorliq muammosi |
| "Qo'lda ko'rib chiqish — vaqt isrofi" | Eng ma'lumotli qadam |
| "Barcha xatolar bir xil" | Turlari va yechimlari har xil |
| "Permutation importance — sababiy" | Bashorat hissasi |
| "Tahlil test'da qilinadi" | Validatsiyada |
| "Kichik segment ham ishonchli" | Shovqin katta |
6. Keng tarqalgan xatolar va yechimlari
1. Faqat umumiy metrikaga qarash
print(f"F1 = {f1:.3f}") # ⚠️
df.groupby("segment")["xato"].agg(["mean", "sum", "size"]) # ✅2. Test to'plamida tahlil
# test xatolarini tahlil qilib, shu testda qayta baholash # ⚠️
# tahlil validatsiyada, test faqat yakuniy baho uchun 12.3-bob # ✅3. Kichik segmentlarga ishonish
# n = 12 bo'lgan segmentda F1 = 0.42 -> "muammo" # ⚠️
# n >= 50-100 bo'lgan segmentlarni ko'ring # ✅4. Qo'lda ko'rmaslik
# faqat sonlarga qarash # ⚠️
df[df.xato].nlargest(30, "ishonch") # va o'qib chiqing # ✅5. Yorliq shovqinini e'tiborsiz qoldirish
# "model 8% xato qiladi" (yorliqlarning 5% i noto'g'ri) # ⚠️
# yorliq sifatini alohida o'lchang # ✅6. Korrelyatsiyalangan belgilarda muhimlikni noto'g'ri o'qish
# "ikkala belgi ham muhim emas" (ular bir-birini almashtiradi) # ⚠️
# guruh bo'lib aralashtiring yoki korrelyatsiyani tekshiring # ✅7. Topilmalarni rejaga aylantirmaslik
# "yangi mijozlarda yomon" — va shu yerda to'xtash # ⚠️
# har topilma uchun: sabab + harakat + kutilgan ta'sir # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 12.6-dars (o'tilgan): Xatolar tahlili oqimda
- 12.9-dars (o'tilgan): Leakage indikatorlari
- 14.8-dars (o'tilgan): Chalkashlik matritsasi
- 14.14-dars: Amaliy loyiha
- MLOps qismi: Monitoring va drift
8. Eng yaxshi amaliyotlar
Tahlilni validatsiyada qiling.
Segmentlarni ikki savol bilan ko'ring: sifat va hajm.
Ishonch bo'yicha guruhlang.
20-50 xatoni qo'lda o'qing.
Xatolarni turlarga ajrating.
Permutation importance ni qo'shing.
Bitta bashoratni tushuntirib ko'ring.
Har topilmaga harakat yozing.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # segment tahlilining ikki savoli?
2. # kichik segment chegarasi?
3. # ishonch qanday hisoblanadi?
4. # yuqori ishonchli xato nimani anglatadi?
5. # selektiv bashorat nima?
6. # yorliq shovqinini qanday topish?
7. # xato turlari?
8. # yorliq xatosiga yechim?
9. # belgi yetishmasligiga?
10. # permutation importance nima o'lchaydi?
11. # korrelyatsiyada u qanday buziladi?
12. # tahlil qaysi to'plamda?Javoblar
- Qayerda yomon va qayerda ko'p xato
- n >= 50-100
- max(p, 1-p)
- Yorliq yoki vazifa muammosi
- Ishonchsizlarni insonga yo'naltirish
- Yuqori ishonchli xatolarni qo'lda ko'rish
- Yorliq, belgi, ajralmas, kam namuna, drift, model
- Tozalash
- Yangi belgi
- Belgi aralashtirilsa metrika tushishi
- Muhimlik bo'linib ketadi
- Validatsiyada
Vazifa 2: Xatolarni tuzating
1. print(f"F1 = {f1:.3f}") # boshqa tahlil yo'q
2. # test xatolarini tahlil qilib, o'sha testda baholash
3. # n = 15 bo'lgan segmentda xulosa chiqarish
4. # "model 8% xato" (yorliqlarning 5% i noto'g'ri)
5. # "yangi mijozlarda yomon" — xulosa shu yerda tugadiJavoblar
1. df.groupby("segment")["xato"].agg(["mean", "sum", "size"])
2. # tahlil validatsiyada
3. # n >= 50-100 bo'lgan segmentlar
4. # yorliq sifatini alohida o'lchang
5. # sabab + harakat + kutilgan ta'sir yozingVazifa 3: Segmentlar
Modellang:
- Bir nechta segment
- Sifat va hajm
- Eng muammoli
- Xulosa
Vazifa 4: Ishonch
Modellang:
- Ishonch guruhlari
- Yuqori ishonchli xatolar
- Yorliq bog'liqligi
- Selektiv bashorat
Vazifa 5: Turlar
Modellang:
- Uch xato manbai
- Taksonomiya
- Yangi belgi ta'siri
- Muhimlik
Vazifa 6: Reja
Modellang:
- Tushuntirish
- Topilmalar jadvali
- Harakatlar
- Sinash
Vazifa 7: O'ylash
Andrew Ng "data-centric AI" g'oyasini targ'ib qiladi: modelni qotirib, ma'lumot sifatini yaxshilash. Bu yondashuv qachon to'g'ri va uning chegarasi qayerda?
Javob
Qisqa javob: ma'lumot sifatiga e'tibor ko'p amaliy loyihada eng yuqori qaytim beradi — ayniqsa ma'lumot kichik, yorliqlar shovqinli yoki vazifa ta'rifi noaniq bo'lsa. Chegarasi: ma'lumot toza va katta bo'lsa, model va belgi muhandisligi yana yetakchi bo'ladi.
1. Nega ma'lumotga e'tibor samarali
- Yorliq shovqini Bayes xatosiga o'xshab ishlaydi 14.1-bob — uni model yenga olmaydi
- Kam segmentlar uchun ma'lumot yig'ish to'g'ridan-to'g'ri yordam beradi
- Vazifa ta'rifini aniqlashtirish (sinflar chegarasi) ko'pincha eng katta yutuq (14.8)
- Model o'zgarmagani uchun natija izohlanadigan bo'ladi
2. Amaliy qadamlar
| Qadam | Foyda |
|---|---|
| Yorliqlash qo'llanmasini aniqlashtirish | Ziddiyatli yorliqlar kamayadi |
| Ikkilamchi yorliqlash (kelishuvni o'lchash) | Shovqin darajasi ma'lum bo'ladi |
| Yuqori ishonchli xatolarni tozalash | Tez va arzon |
| Kam segmentga ma'lumot yig'ish | Aniq segmentda yaxshilanish |
3. Chegaralari
- Ma'lumot toza va ko'p bo'lsa, qaytim kamayadi
- Ba'zi vazifalarda yorliqlash juda qimmat (tibbiyot)
- Model cheklovi haqiqatan asosiy bo'lishi mumkin (14.7)
- "Ma'lumotni tozalash" leakage yoki siljish kiritishi mumkin
4. Muvozanatli yondashuv
- Xatolar tahlili bilan sababni aniqlang
- Sabab ma'lumotda bo'lsa — ma'lumot bilan ishlang
- Sabab modelda bo'lsa — model bilan
- Har ikkalasini o'lchab taqqoslang
5. Xulosa
- "Data-centric" — usul emas, ustuvorlik
- Xatolar tahlili qaysi yo'lni tanlashni aytadi
- Yorliq sifati ko'pincha eng arzon yutuq
- Chegara: ma'lumot yetarli va toza bo'lganda
Nimani mustahkamlaydi: 2.3, 2.4-bo'limlar.
Xulosa
Bu darsda xatolar tahlilini o'rgandik.
Eng muhim uch fikr:
Xatolar tasodifiy emas — ular segmentlarga to'planadi. Har segment uchun ikki savol bering: qaysi segment eng yomon ishlaydi (sifat) va qaysi segment eng ko'p xato beradi (hajm) — bular ko'pincha har xil segmentlar. Kichik segmentlarda metrika juda shovqinli (
n >= 50-100bo'lsin).Yuqori ishonchli xatolar — eng qimmatli topilma. Model ishonch bilan yanglishsa, sabab odatda yorliq xatosi, ziddiyatli yozuv yoki vazifa ta'rifidagi muammo bo'ladi. Shuning uchun 20-50 ta xatoni qo'lda ko'rib chiqish bir soatlik ish sifatida haftalik modellashtirish tajribasidan ko'proq ma'lumot beradi.
Har xato turiga boshqa yechim. Xatolarni sababi bo'yicha guruhlang: yorliq xatosi (tozalash), belgi yetishmasligi (yangi belgi), ajralmas holat (qabul qilish — Bayes xatosi), kam namuna (ma'lumot yig'ish), drift (qayta o'qitish), model cheklovi (boshqa algoritm). Tahlil natijasi — aniq reja: har topilma uchun sabab, harakat va kutilgan ta'sir.
Keyingi darsda amaliyot — 14-qismning to'liq klassifikatsiya loyihasi: ma'lumotdan qarorgacha.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!