10-bo‘lim

Modelni baholash

Chalkashlik matritsasi, precision, recall, F1, ROC-AUC va nomutanosib sinflar bilan ishlash.

🕑 14 daqiqa o‘qish 📄 958 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Aniqlik qachon aldaydi?
  2. Chalkashlik matritsasi
  3. To'rt asosiy tushuncha
  4. Precision va Recall
  5. To'liq hisobot
  6. Chegarani o'zgartirish
  7. ROC egri chizig'i va AUC
  8. Regressiya metrikalari
  9. Metrika tanlash
  10. Nomutanosib sinflar bilan ishlash
  11. Asos model bilan solishtiring
  12. Xulosa

"Modelim 95% aniqlik ko'rsatdi" - bu gap ko'pincha hech nima anglatmaydi. Bu bo'limda modelni to'g'ri baholashni o'rganamiz.

Aniqlik qachon aldaydi? #

Python
import numpy as np
from sklearn.metrics import accuracy_score

# 1000 ta bemordan 20 tasi kasal
haqiqat = np.array([0] * 980 + [1] * 20)

# "Hech kim kasal emas" deydigan model
bashorat = np.zeros(1000)

print(f"Aniqlik: {accuracy_score(haqiqat, bashorat):.3f}")
Natija
Aniqlik: 0.980
98% aniqlik - ammo model foydasiz

Bu model bironta ham kasalni topa olmadi. Lekin aniqlik 98%.

Nomutanosib ma'lumotda aniqlik eng yomon metrika. Boshqa vositalar kerak.

Chalkashlik matritsasi #

Chalkashlik matritsasi - barcha metrikalarning asosi Bashorat Salbiy (0) Ijobiy (1) Haqiqat Salbiy (0) Ijobiy (1) TN To'g'ri salbiy 950 FP Noto'g'ri xavotir 30 FN O'tkazib yuborilgan 5 TP To'g'ri topilgan 15 Formulalar Aniqlik = (TP+TN) / hammasi Precision = TP / (TP+FP) Recall = TP / (TP+FN) F1 = 2·P·R / (P+R) Bu misolda: P=0.33 R=0.75 F1=0.46 Aniqlik 96.5% - lekin ijobiy bashoratlarning faqat 33 foizi to'g'ri
Har doim matritsani ko'ring, bitta raqamga ishonmang
Python
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

matritsa = confusion_matrix(y_sinov, bashorat)
print(matritsa)
Natija
[[950  30]
 [  5  15]]
Python
import matplotlib.pyplot as plt

ConfusionMatrixDisplay(matritsa, display_labels=["Sog'lom", "Kasal"]).plot(cmap="Blues")
plt.show()

To'rt asosiy tushuncha #

BelgiNomiMa'nosi
TPTo'g'ri ijobiyKasal edi, kasal dedi
TNTo'g'ri salbiySog'lom edi, sog'lom dedi
FPNoto'g'ri ijobiySog'lom edi, kasal dedi (yolg'on xavotir)
FNNoto'g'ri salbiyKasal edi, sog'lom dedi (o'tkazib yuborish)
Eslab qolish usuli

Ikkinchi so'z - modelning javobi. Birinchi so'z - javob to'g'rimi.

FN = "Noto'g'ri salbiy" = model "salbiy" dedi, lekin noto'g'ri.

Precision va Recall #

Python
from sklearn.metrics import precision_score, recall_score, f1_score

print(f"Precision: {precision_score(haqiqat, bashorat):.3f}")
print(f"Recall:    {recall_score(haqiqat, bashorat):.3f}")
print(f"F1:        {f1_score(haqiqat, bashorat):.3f}")
Precision va Recall nimani o'lchaydi Precision (aniqlik) "Kasal dedim - nechtasi rost?" TP / (TP + FP) Yolg'on xavotirni kamaytiradi Recall (qamrov) "Kasallarning nechtasini topdim?" TP / (TP + FN) O'tkazib yuborishni kamaytiradi Qaysi biri muhimroq? Saraton skrininigi → Recall: kasalni o'tkazib yuborish halokatli Spam filtri → Precision: muhim xatni yo'qotish qimmatroq Ikkalasi kerak bo'lsa → F1: ularning garmonik o'rtachasi
Bu ikki metrika bir-biriga qarshi - birini oshirsangiz, ikkinchisi tushadi
Nima uchun F1 garmonik o'rtacha?
Python
precision, recall = 1.0, 0.0

oddiy_ortacha = (precision + recall) / 2          # 0.5
f1 = 2 * precision * recall / (precision + recall) # 0.0

Oddiy o'rtacha 0.5 beradi - go'yo model yarim yaxshi. F1 esa 0.0 beradi - to'g'ri, chunki model hech qanday kasalni topmagan.

Garmonik o'rtacha eng zaif tomonni jazolaydi.

To'liq hisobot #

Python
from sklearn.metrics import classification_report

print(classification_report(
    y_sinov, bashorat,
    target_names=["Sog'lom", "Kasal"],
))
Natija
              precision    recall  f1-score   support

     Sog'lom       0.99      0.97      0.98       980
       Kasal       0.33      0.75      0.46        20

    accuracy                           0.96      1000
   macro avg       0.66      0.86      0.72      1000
weighted avg       0.98      0.96      0.97      1000
macro avg va weighted avg farqi
  • macro avg - sinflarning oddiy o'rtachasi, kichik sinf ham teng hisobga olinadi
  • weighted avg - sinf hajmiga qarab vazn beriladi

Nomutanosib ma'lumotda macro avg ga qarang - u haqiqiy holatni ko'rsatadi. Bu misolda 0.72 va 0.97 orasidagi farq juda katta.

Chegarani o'zgartirish #

Python
ehtimollik = model.predict_proba(X_sinov)[:, 1]

print(f"{'Chegara':>8} {'Precision':>10} {'Recall':>8} {'F1':>7}")

for chegara in [0.1, 0.3, 0.5, 0.7, 0.9]:
    b = (ehtimollik >= chegara).astype(int)
    print(f"{chegara:>8.1f} "
          f"{precision_score(y_sinov, b, zero_division=0):>10.3f} "
          f"{recall_score(y_sinov, b):>8.3f} "
          f"{f1_score(y_sinov, b):>7.3f}")
Natija
 Chegara  Precision   Recall      F1
     0.1      0.198    0.950   0.328
     0.3      0.312    0.850   0.457
     0.5      0.484    0.750   0.588
     0.7      0.688    0.550   0.611
     0.9      0.889    0.400   0.552
Muvozanatni ko'ryapsizmi?

Chegara oshgani sari precision o'sadi, recall tushadi.

Bu misolda eng yaxshi F1 - 0.7 chegarada. Lekin agar kasallikni o'tkazib yubormaslik muhimroq bo'lsa, 0.3 ni tanlaysiz.

ROC egri chizig'i va AUC #

Python
from sklearn.metrics import roc_curve, roc_auc_score, RocCurveDisplay

fpr, tpr, chegaralar = roc_curve(y_sinov, ehtimollik)
auc = roc_auc_score(y_sinov, ehtimollik)

print(f"AUC: {auc:.3f}")
ROC egri chizig'i FPR (yolg'on xavotir darajasi) TPR (Recall) tasodifiy (AUC=0.5) yaxshi model (AUC=0.92) o'rtacha (AUC=0.72) 0 1 0 1 AUC talqini 1.00 - mukammal 0.90+ - a'lo 0.80+ - yaxshi 0.70+ - qoniqarli 0.50 - tasodifiy Chap yuqori burchakka qanchalik yaqin - shuncha yaxshi
ROC barcha chegaralardagi natijani bir grafikda ko'rsatadi
AUC nimani anglatadi?

AUC = tasodifan tanlangan ijobiy namuna tasodifan tanlangan salbiy namunadan yuqoriroq ball olish ehtimoli.

AUC = 0.92 degani: 100 ta juftlikdan 92 tasida model kasalni sog'lomdan yuqoriroq baholaydi.

Katta afzalligi: AUC chegaraga bog'liq emas - u modelning umumiy ajratish qobiliyatini o'lchaydi.

Nomutanosib ma'lumotda AUC ham aldashi mumkin

1000 dan 20 tasi ijobiy bo'lgan holatda ROC juda chiroyli ko'rinishi mumkin, chunki FPR maxrajida katta son (950) turibdi.

Bunday holatda Precision-Recall egri chizig'i ishonchliroq:

Python
from sklearn.metrics import average_precision_score, PrecisionRecallDisplay

print(f"Average Precision: {average_precision_score(y_sinov, ehtimollik):.3f}")
PrecisionRecallDisplay.from_predictions(y_sinov, ehtimollik)

Regressiya metrikalari #

Python
from sklearn.metrics import (
    mean_squared_error, mean_absolute_error,
    r2_score, mean_absolute_percentage_error,
)

print(f"MSE:   {mean_squared_error(y_s, b):.1f}")
print(f"RMSE:  {np.sqrt(mean_squared_error(y_s, b)):.1f}")
print(f"MAE:   {mean_absolute_error(y_s, b):.1f}")
print(f"MAPE:  {mean_absolute_percentage_error(y_s, b) * 100:.1f}%")
print(f"R2:    {r2_score(y_s, b):.3f}")
MetrikaBirlikChetdagi qiymatlargaTalqin
MSEKvadratJuda sezgirQiyin
RMSENishon birligiSezgirOson
MAENishon birligiChidamliEng oson
MAPEFoizSezgirJuda oson
NisbatSezgirOson
MAPE va nol qiymatlar

MAPE maxrajida haqiqiy qiymat turadi. Agar u nol bo'lsa - cheksizlik chiqadi.

Nishonda nollar bo'lsa MAPE ni ishlatmang.

Metrika tanlash #

Qaysi metrikani tanlash kerak?
VazifaMetrika
Muvozanatli klassifikatsiyaAniqlik, F1
Nomutanosib klassifikatsiyaF1, AUC-PR, macro avg
Kasallikni aniqlashRecall (o'tkazib yubormaslik)
Spam filtriPrecision (yolg'on xavotir kam bo'lsin)
Reyting, tartiblashAUC
Regressiya, odatiyRMSE
Regressiya, chetdagi qiymatlar borMAE
Biznes hisobotiMAPE (foiz tushunarli)

Eng muhimi: metrikani loyiha boshida tanlang, natijani ko'rgandan keyin emas. Aks holda o'zingizni aldashingiz mumkin.

Nomutanosib sinflar bilan ishlash #

Python
from sklearn.linear_model import LogisticRegression

# 1. Sinf vaznlari
model = LogisticRegression(class_weight="balanced")

# 2. Qo'lda vazn berish
model = LogisticRegression(class_weight={0: 1, 1: 50})

# 3. Chegarani o'zgartirish
bashorat = (model.predict_proba(X_s)[:, 1] >= 0.3).astype(int)
Python
# 4. Namunalar sonini o'zgartirish (imbalanced-learn kutubxonasi)
# pip install imbalanced-learn
from imblearn.over_sampling import SMOTE

smote = SMOTE(random_state=42)
X_muvozanat, y_muvozanat = smote.fit_resample(X_oqitish, y_oqitish)

print(Counter(y_oqitish))
print(Counter(y_muvozanat))
Natija
Counter({0: 784, 1: 16})
Counter({0: 784, 1: 784})
SMOTE ni faqat o'qitish to'plamida qo'llang
Python
# XATO - sinov to'plamiga ham sun'iy namunalar tushadi
X_yangi, y_yangi = smote.fit_resample(X, y)
X_o, X_s = train_test_split(X_yangi, ...)

# TO'G'RI
X_o, X_s, y_o, y_s = train_test_split(X, y, ...)
X_o, y_o = smote.fit_resample(X_o, y_o)

Sinov to'plami haqiqiy taqsimotni aks ettirishi kerak - aks holda natija haqiqatdan yaxshiroq ko'rinadi.

Asos model bilan solishtiring #

Python
from sklearn.dummy import DummyClassifier, DummyRegressor

# Har doim eng ko'p uchraydigan sinfni aytadi
asos = DummyClassifier(strategy="most_frequent")
asos.fit(X_o, y_o)

print(f"Asos model:  {asos.score(X_s, y_s):.3f}")
print(f"Sizning model: {model.score(X_s, y_s):.3f}")
Har doim asos model bilan boshlang

Agar modelingiz DummyClassifier dan yaxshiroq bo'lmasa - u hech nima o'rganmagan.

Bu oddiy tekshiruv ko'p vaqtni tejaydi.

Amaliy topshiriq
  1. 95% / 5% nomutanosib ma'lumot yarating.
  2. Har doim ko'p sinfni aytadigan model uchun aniqlikni hisoblang.
  3. Logistik regressiya o'qiting va chalkashlik matritsasini chizing.
  4. TP, TN, FP, FN qiymatlarini aniqlang.
  5. Precision, recall va F1 ni qo'lda formula bilan hisoblang.
  6. classification_report bilan tekshiring.
  7. Chegarani 0.1 dan 0.9 gacha o'zgartirib jadval tuzing.
  8. ROC egri chizig'ini chizing va AUC ni hisoblang.
  9. Precision-Recall egri chizig'ini ham chizing va solishtiring.
  10. class_weight="balanced" qo'shing - qaysi metrika o'zgardi?

Xulosa #

  • Aniqlik nomutanosib ma'lumotda aldaydi - unga yolg'iz ishonmang.
  • Chalkashlik matritsasi barcha metrikalarning asosi.
  • Precision: "ijobiy dedim - nechtasi rost?"
  • Recall: "haqiqiy ijobiylarning nechtasini topdim?"
  • F1 - ikkalasining garmonik o'rtachasi, eng zaif tomonni jazolaydi.
  • Precision va recall bir-biriga qarshi - chegara ularni boshqaradi.
  • AUC chegaraga bog'liq emas, modelning umumiy sifatini o'lchaydi.
  • Kuchli nomutanosiblikda Precision-Recall egri chizig'i ishonchliroq.
  • Regressiyada: RMSE odatiy, MAE chetdagi qiymatlarga chidamli.
  • Metrikani loyiha boshida tanlang, natija ko'rgandan keyin emas.
  • Har doim DummyClassifier bilan solishtiring.

Keyingi bo'limda yangi algoritm - KNN bilan tanishamiz.

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.