Precision, recall va F1
Confusion matrix ko'p ma'lumot beradi, lekin modellarni solishtirish uchun bitta raqam qulayroq. Bu raqamlarning hammasi matritsaning ma'lum bir qismidan hisoblanadi. Qaysi qismdan ekanini bilsangiz, formulani yodlash shart emas.
Accuracy — diagonal / hammasi
accuracy = (TP + TN) / (TP + TN + FP + FN)
Butun matritsaga qaraydi, shuning uchun natija asosan eng katta katakka (TN) bog'liq bo'ladi.
Precision — "bashorat: 5" ustuniga qaraydi
precision = TP / (TP + FP)
Savol: model "5" deganda, unga qanchalik ishonsa bo'ladi? Model "5" degan hamma rasmlar ustunda turibdi: TP (to'g'ri) va FP (xato). Precision — shu ustundagi to'g'ri javoblar ulushi.
Nega "precision"? Inglizcha "aniqlik" degani: model aytgan narsasi qanchalik aniq.
Recall — "haqiqat: 5" qatoriga qaraydi
recall = TP / (TP + FN)
Savol: haqiqiy 5 larning qanchasini model topdi? Hamma haqiqiy 5 lar qatorda turibdi: TP (topilgan) va FN (o'tkazib yuborilgan). Recall — shu qatordagi topilganlar ulushi.
Nega "recall"? Inglizcha recall — "esga olish" degani. Bu atama qidiruv tizimlaridan kelgan. Google ga so'rov berdingiz. Precision: "chiqqan sahifalarning qanchasi haqiqatan kerakli?" Recall: "internetdagi kerakli sahifalarning qanchasini Google esga olib, ko'rsata oldi?" Bizda esa: "haqiqiy 5 larning qanchasini model topa oldi?" Recall boshqa nomlar bilan ham uchraydi: sensitivity (tibbiyotda) va true positive rate (TPR).
Nega bittasi yetmaydi?
Ikkalasini ham sun'iy ravishda 100% qilish oson: - Precision ni 100% qilish: model faqat bitta, eng aniq rasmga "5" desin. U to'g'ri bo'lsa, precision = 1/1 = 100%. Lekin qolgan 5420 ta 5 o'tkazib yuborildi. - Recall ni 100% qilish: model hamma rasmga "5" desin. Hamma 5 lar topildi, recall = 100%. Lekin 54 579 ta noto'g'ri signal bor.
Shuning uchun ularga doim birga qaraladi.
To'rtta metrikani avval matritsadan qo'lda hisoblaymiz, keyin sklearn bilan tekshiramiz:
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score pd.DataFrame({ "qo'lda": [(tp + tn) / cm.sum(), tp / (tp + fp), tp / (tp + fn), 2 * tp / (2 * tp + fp + fn)], "sklearn": [accuracy_score(y_train_5, y_train_pred), precision_score(y_train_5, y_train_pred), recall_score(y_train_5, y_train_pred), f1_score(y_train_5, y_train_pred)], }, index=["accuracy", "precision", "recall", "F1"])
qo'lda sklearn accuracy 0.957033 0.957033 precision 0.837088 0.837088 recall 0.651171 0.651171 F1 0.732517 0.732517
Qo'lda va sklearn bir xil chiqdi. Demak bu metrikalarning hammasi shunchaki matritsadagi to'rtta raqamdan hisoblanadi.
Endi raqamlarni o'qiymiz: - Accuracy 0.957 — yaxshi ko'rinadi. - Precision 0.837 — model "5" desa, 84% hollarda to'g'ri. Taxminan har 6 ta "5" javobidan bittasi noto'g'ri. - Recall 0.651 — haqiqiy 5 larning atigi 65% i topildi. Har 3 ta 5 dan bittasi o'tkazib yuborildi.
Accuracy bu muammoni yashirgan edi. Confusion matrix va recall uni ochib berdi.
F1 — nega oddiy o'rtacha emas?
Precision va recall ni bitta raqamga birlashtirish kerak. Oddiy o'rtacha olsak bo'lmaydimi? F1 harmonic mean ishlatadi:
F1 = 2 × precision × recall / (precision + recall) = TP / (TP + (FN + FP) / 2)
O'ngdagi ko'rinishga qarang: F1 — TP ni "TP + xatolarning yarmi" ga bo'lish. FN ham, FP ham bir xil og'irlikda hisobga olinadi.
Nega harmonic mean? Chunki uning natijasi doim kichik qiymatga yaqin chiqadi. Uchta holatni solishtiramiz:
pr = pd.DataFrame({"precision": [0.9, 0.5, 0.99], "recall": [0.1, 0.5, 0.01]}) pr.assign(oddiy_orta=(pr.precision + pr.recall) / 2, F1=2 * pr.precision * pr.recall / (pr.precision + pr.recall))
precision recall oddiy_orta F1 0 0.90 0.10 0.5 0.1800 1 0.50 0.50 0.5 0.5000 2 0.99 0.01 0.5 0.0198
Uchala qatorda ham oddiy o'rtacha 0.5. Lekin: - 0-qator: recall 0.1 — model 5 larning 90% ini o'tkazib yuboradi. F1 = 0.18. - 2-qator: recall 0.01 — deyarli hech narsa topmaydi. F1 = 0.02. - 1-qator: ikkalasi ham 0.5. F1 = 0.5.
Oddiy o'rtacha bitta yaxshi va bitta yomon sondan "o'rtacha yaxshi" baho chiqaradi va yomon sonni yashiradi. F1 esa yashirmaydi: F1 yuqori bo'lishi uchun ikkalasi ham yuqori bo'lishi kerak.
Qachon precision, qachon recall muhimroq?
F1 ikkalasiga teng qaraydi. Lekin real masalada xatolarning narxi har xil:
- Bolalar uchun xavfsiz video filtri → precision. Yaxshi videolarning bir qismini rad etsa ham mayli (recall past). Lekin bitta yomon video bolaga ko'rinib qolmasligi kerak (FP xavfli).
- Do'kondagi o'g'rini kamera orqali topish → recall. Qo'riqchi bir necha marta bekorga borsa ham mayli (precision 30%). Lekin o'g'rilarning deyarli hammasi ushlanishi kerak (FN qimmat).
- Kasallikni aniqlash → recall. Kasalni "sog'lom" deb uyiga jo'natish (FN) — eng qimmat xato.
- Spam filtri → precision. Muhim xatni spam papkasiga tashlab yuborish (FP) — yomon. Bir nechta spam o'tib ketsa, mayli.
classification_report
sklearn hamma metrikani bitta jadvalda beradi. Bu matn bo'lgani uchun print bilan chiqaramiz:
from sklearn.metrics import classification_report print(classification_report(y_train_5, y_train_pred, target_names=["5 emas", "5"], digits=3))
precision recall f1-score support
5 emas 0.966 0.987 0.977 54579
5 0.837 0.651 0.733 5421
accuracy 0.957 60000
macro avg 0.902 0.819 0.855 60000
weighted avg 0.954 0.957 0.955 60000Jadvalni o'qish:
- Har bir klass uchun alohida qator. "5" qatori — biz yuqorida hisoblagan raqamlar. "5 emas" qatori — xuddi shu formulalar, lekin "5 emas" positive deb olinganda.
- support — haqiqatda nechta bor, ya'ni matritsaning qator yig'indisi: 54 579 va 5421.
- macro avg — ikki klassning oddiy o'rtachasi. Har bir klassga teng vazn beradi. 5 lar uchun recall 0.651 bo'lgani uchun macro recall 0.819 ga tushdi.
- weighted avg — support bo'yicha o'rtacha. "5 emas" 10 baravar ko'p, shuning uchun o'rtachaga asosan u ta'sir qiladi va hammasi 0.95 atrofida chiqadi.
Nomutanosib ma'lumotda weighted avg ga aldanmang. U accuracy kabi katta klassni ko'rsatadi. Har doim kam klassning qatoriga qarang.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.