Danh sách bài viết

Bài 23: Confusion Matrix — ma trận nhầm lẫn

Confusion Matrix cho bài toán phân loại: 4 thành phần TP/TN/FP/FN, Type I và Type II error, cost của FP vs FN theo domain (medical, spam, fraud), confusion_matrix và ConfusionMatrixDisplay trong sklearn, multi-class K×K, normalized matrix, đọc nhầm lẫn trên imbalanced data.

24/05/2026
12 phút đọc
0 lượt xem
1

Vì sao accuracy không đủ

Sau khi train model phân loại (vd Logistic Regression ở Bài 22), câu hỏi tự nhiên: "Model có tốt không?". Cách đo nhanh nhất là accuracy — tỉ lệ sample được predict đúng trên tổng số sample.

Accuracy có 2 hạn chế lớn:

  • Không cho biết model sai ở đâu. Một model accuracy 90% có thể sai chủ yếu ở class hiếm (sai 50% class 1, đúng 100% class 0); một model khác cũng accuracy 90% nhưng sai đều ở cả 2 class. Cùng một con số, hai hành vi rất khác — accuracy không phân biệt.
  • Misleading trên imbalanced data. Nếu 95% sample là class 0, một model "luôn predict 0" đạt accuracy 95% mà không học gì cả. Trong các bài toán phát hiện gian lận, bệnh hiếm, spam — class quan tâm thường là class thiểu số — accuracy gần như vô dụng.

Confusion matrix giải hai vấn đề đó: nó tách lỗi của model theo từng loại — bao nhiêu sample class 0 bị nhầm thành 1, bao nhiêu sample class 1 bị nhầm thành 0, và ngược lại. Mọi metric phân loại quan trọng (Accuracy, Precision, Recall, F1, Specificity) đều được derive từ confusion matrix.

Sau bài này, bạn sẽ:

  • Đọc và vẽ được binary confusion matrix.
  • Phân biệt 4 ô TP, TN, FP, FN — và 2 loại error Type I / Type II.
  • Hiểu cost của FP và FN khác nhau theo domain.
  • Tính và visualize confusion matrix bằng sklearn (cả binary và multi-class).
  • Sử dụng normalized confusion matrix để đọc tỉ lệ thay vì count.
2

Binary Confusion Matrix — ma trận 2×2

Với binary classification, model output 1 trong 2 class — quy ước thường là 0 (negative) và 1 (positive). So sánh prediction với ground truth cho 4 trường hợp, tổng hợp thành ma trận 2×2:

                  Predicted
                  0       1
   Actual  0    [ TN     FP ]
           1    [ FN     TP ]

Cách đọc:

  • Hàng = ground truth (label thật của sample).
  • Cột = prediction của model.
  • Ô (i, j) = số sample có label thật i và bị model predict thành j.
  • Đường chéo chính (TN và TP) — predict đúng.
  • Ngoài đường chéo (FP và FN) — predict sai.

Tên các ô đặt theo prediction của model là gì + đúng/sai:

  • True / False — model predict đúng (True) hay sai (False)?
  • Positive / Negative — model predict ra class 1 (Positive) hay class 0 (Negative)?

Nắm quy ước này, đọc tên 4 ô không cần nhớ máy móc: "True Positive" = predict Positive và đúng → label thật cũng là 1.

3

4 thành phần TP / TN / FP / FN

Định nghĩa và ví dụ với bài toán "chẩn đoán bệnh ung thư" (label 1 = bị bệnh, label 0 = không bị):

  • TP (True Positive) — predict 1, actual 1. Model nói "bị bệnh" và đúng là bị bệnh. Bệnh nhân được phát hiện và điều trị kịp thời.
  • TN (True Negative) — predict 0, actual 0. Model nói "không bị" và đúng là không bị. Người khoẻ về nhà, không phải xét nghiệm thêm.
  • FP (False Positive) — predict 1, actual 0. Model nói "bị bệnh" nhưng thực ra khoẻ. Bệnh nhân bị làm thêm xét nghiệm không cần thiết, lo lắng oan — còn gọi là false alarm.
  • FN (False Negative) — predict 0, actual 1. Model nói "không bị" nhưng thực ra đang bị bệnh. Bỏ sót ca bệnh — bệnh nhân về nhà mà không được điều trị — còn gọi là missed detection.

Một số đẳng thức cơ bản từ confusion matrix:

  • Tổng sample: \( N = \text{TP} + \text{TN} + \text{FP} + \text{FN} \).
  • Số sample positive thật: \( P = \text{TP} + \text{FN} \).
  • Số sample negative thật: \( N_{\text{neg}} = \text{TN} + \text{FP} \).
  • Số sample model predict positive: \( \text{TP} + \text{FP} \).
  • Accuracy: \( (\text{TP} + \text{TN}) / N \).

Các metric Precision, Recall, F1 (Bài 24, 25) đều là tỉ số giữa các ô này. Hiểu rõ 4 ô là điều kiện đủ để đọc mọi metric phân loại còn lại.

4

Type I và Type II error

Trong thống kê cổ điển (kiểm định giả thuyết), 2 loại sai có tên riêng — và trùng với FP, FN trong ML:

  • Type I error = FP. Bác bỏ \( H_0 \) khi \( H_0 \) đúng. Trong khuôn khổ ML phân loại với \( H_0 \): "sample là negative", Type I là khi model predict positive trong khi sample thực ra negative.
  • Type II error = FN. Chấp nhận \( H_0 \) khi \( H_0 \) sai. Tức model predict negative trong khi sample thực ra positive.

Mẹo nhớ: Type I là "false alarm" (báo động giả), Type II là "miss" (bỏ sót). Hai loại sai này không cùng cost — đó là lý do tại sao confusion matrix tách FP và FN ra riêng thay vì gộp thành "tổng số lỗi".

Một số khái niệm dùng chung với thống kê:

  • Significance level \( \alpha \) — xác suất Type I error chấp nhận được (thường 0.05). Trong ML, tương ứng với "FP rate" cho phép.
  • Power = 1 − P(Type II error). Trong ML, tương ứng với recall (Bài 24).
5

Cost của FP vs FN tuỳ domain

Đây là phần quan trọng nhất khi chọn metric cho bài toán thực: FP và FN không bao giờ có cost bằng nhau. Bằng cách định nghĩa rõ class 1 là gì, cost asymmetry sẽ định hướng metric ưu tiên.

Medical (chẩn đoán bệnh) — class 1 = bị bệnh:

  • FN nguy hiểm. Bỏ sót bệnh nhân thực sự bị bệnh → không được điều trị kịp thời → bệnh nặng lên hoặc tử vong.
  • FP bất tiện nhưng ít nguy hiểm. Bệnh nhân khoẻ bị nghi ngờ → làm thêm xét nghiệm xác nhận → lo lắng và tốn tiền nhưng không nguy hiểm tính mạng.
  • Hệ quả: trong sàng lọc bệnh hiểm nghèo, ưu tiên model có recall cao (giảm FN), chấp nhận precision thấp hơn.

Spam filter — class 1 = spam:

  • FP nguy hiểm. Email công việc quan trọng bị filter nhầm thành spam → người dùng không thấy → mất hợp đồng, lỡ deadline.
  • FN khó chịu nhưng dễ chấp nhận. Vài email spam lọt vào inbox → người dùng xoá tay.
  • Hệ quả: ưu tiên model có precision cao (giảm FP), chấp nhận một số spam lọt qua.

Fraud detection — class 1 = giao dịch gian lận:

  • FN nguy hiểm. Bỏ sót giao dịch gian lận → ngân hàng mất tiền trực tiếp.
  • FP có cost nhưng kiểm soát được. Giao dịch hợp lệ bị flag → khách hàng bị verify thêm → khó chịu nhưng không mất tiền.
  • Hệ quả: tương tự medical — ưu tiên recall, kèm pipeline "verify" để giảm FP ảnh hưởng UX.

Quy tắc đặt câu hỏi:

  • "Nếu model nói có (positive) nhưng thực ra không (negative) — hậu quả là gì?" → cost của FP.
  • "Nếu model nói không (negative) nhưng thực ra có (positive) — hậu quả là gì?" → cost của FN.
  • So sánh 2 cost → quyết định tối ưu hoá precision hay recall.
6

sklearn confusion_matrix

API cơ bản:

from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_true, y_pred)
# Mac dinh: row = actual, col = predicted
# Label order: theo numpy.unique(y_true, y_pred), tang dan
# Voi binary 0/1: cm[0,0]=TN, cm[0,1]=FP, cm[1,0]=FN, cm[1,1]=TP

Lưu ý quan trọng:

  • Convention sklearn: hàng = actual, cột = predicted. Khớp với layout đã giới thiệu ở Bước 2.
  • Một số sách / slide bài giảng đảo trục. Có tài liệu vẽ hàng = predicted, cột = actual. Khi đọc confusion matrix ở nguồn khác, luôn kiểm tra label trục trước khi diễn giải.
  • Order các class. Theo mặc định sklearn sắp xếp tăng dần. Truyền labels=[1, 0] để đảo thứ tự, hoặc labels=['cat', 'dog', 'bird'] để cố định thứ tự cho nhiều class.

Ví dụ binary:

y_true = [0, 1, 1, 0, 1, 1, 0, 0, 1, 0]
y_pred = [0, 1, 0, 0, 1, 1, 1, 0, 1, 0]

cm = confusion_matrix(y_true, y_pred)
print(cm)
# [[4 1]    -> TN=4, FP=1
#  [1 4]]   -> FN=1, TP=4

tn, fp, fn, tp = cm.ravel()   # tien khi unpack binary
print(f"TN={tn}, FP={fp}, FN={fn}, TP={tp}")

Method .ravel() chỉ hợp lý cho ma trận 2×2 — multi-class phải truy cập theo index.

Nếu muốn lấy báo cáo có cả Precision, Recall, F1 — dùng classification_report:

from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred, target_names=["khoe", "benh"]))
7

ConfusionMatrixDisplay — visualize

Đọc ma trận raw bằng print khó hơn nhìn heatmap. sklearn có class wrap sẵn:

import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay

# Cach 1: tu model + data (chua predict)
ConfusionMatrixDisplay.from_estimator(
    model, X_test, y_test,
    display_labels=["khoe", "benh"],
    cmap="Blues",
)
plt.show()

# Cach 2: tu y_true va y_pred co san
ConfusionMatrixDisplay.from_predictions(
    y_test, y_pred,
    display_labels=["khoe", "benh"],
    cmap="Blues",
)
plt.show()

# Cach 3: tu ma tran cm tinh san
disp = ConfusionMatrixDisplay(
    confusion_matrix=cm,
    display_labels=["khoe", "benh"],
)
disp.plot(cmap="Blues")
plt.show()

Tham số đáng nhớ:

  • normalizeNone (count), "true" (normalize theo hàng), "pred" (theo cột), "all" (theo tổng).
  • cmap — colormap matplotlib. "Blues" dễ đọc cho người colorblind hơn các palette nhiều màu.
  • values_format — định dạng số trong ô. Vd ".2%" cho phần trăm, "d" cho integer count.
  • xticks_rotation — xoay label nhãn cột (hữu ích khi có nhiều class, tên dài).

Output là một matplotlib.figure — có thể save bằng plt.savefig("cm.png", dpi=150).

8

Multi-class Confusion Matrix

Với \( K \) class, confusion matrix là ma trận \( K \times K \). Cách đọc giữ nguyên:

  • Đường chéo chính — predict đúng. Sample class \( i \) được predict đúng là \( i \).
  • Off-diagonal — predict sai. Ô \( (i, j) \) với \( i \neq j \) = số sample class \( i \) bị nhầm thành class \( j \).

Khái niệm TP/TN/FP/FN không còn cố định một ô — phải chọn 1 class làm "positive", các class còn lại gộp thành "negative" (one-vs-rest):

  • TP của class \( c \) = ô đường chéo \( (c, c) \).
  • FN của class \( c \) = tổng hàng \( c \) trừ TP — sample class \( c \) bị nhầm thành class khác.
  • FP của class \( c \) = tổng cột \( c \) trừ TP — sample class khác bị nhầm thành \( c \).
  • TN của class \( c \) = tổng còn lại — sample không thuộc class \( c \) và cũng không được predict thành \( c \).

Use case kinh điển: MNIST (nhận dạng chữ số 0-9). Confusion matrix 10×10 thường cho thấy các cặp nhầm lẫn cố hữu:

  • 4 ↔ 9 — nét cong dễ nhầm.
  • 3 ↔ 5, 3 ↔ 8 — nét cong tương tự.
  • 1 ↔ 7 — đặc biệt với chữ số viết kiểu châu Âu (có gạch ngang ở 7).

Pattern này không thấy được từ accuracy. Confusion matrix chỉ thẳng vào cặp class hay nhầm — gợi ý cho feature engineering (vd thêm feature về độ cong) hoặc data augmentation (thêm sample chữ số dễ nhầm) để cải thiện.

9

Normalized confusion matrix

Khi các class có số sample khác nhau, count trong từng ô có thể đánh lừa thị giác — class nhiều sample sẽ "đậm màu" hơn dù tỉ lệ lỗi không cao hơn. Normalize giải vấn đề này.

Ba kiểu normalize trong confusion_matrixConfusionMatrixDisplay:

  • normalize="true" — chia theo hàng (theo actual class). Mỗi hàng tổng bằng 1.
    Ô \( (i, j) \) = "trong các sample thực sự là class \( i \), bao nhiêu phần trăm được model predict thành class \( j \)?".
    Đường chéo của ma trận này = recall của từng class.
  • normalize="pred" — chia theo cột (theo predicted class). Mỗi cột tổng bằng 1.
    Ô \( (i, j) \) = "trong các sample model predict là class \( j \), bao nhiêu phần trăm thực sự thuộc class \( i \)?".
    Đường chéo của ma trận này = precision của từng class.
  • normalize="all" — chia tổng số sample. Toàn ma trận tổng bằng 1.
    Ô \( (i, j) \) = joint probability \( P(\text{actual}=i, \text{predicted}=j) \).

Khi nào dùng cái nào:

  • "true": muốn biết "model bắt được bao nhiêu phần trăm của từng class" → debug class nào model bỏ sót nhiều.
  • "pred": muốn biết "khi model nói class \( j \), độ tin cậy thế nào" → debug class nào model hay báo nhầm.
  • "all": phân tích phân phối lỗi tổng thể.

Trong report cho stakeholder không kỹ thuật, normalized với values_format=".2%" dễ đọc hơn count. Trong debug pipeline, count vẫn cần để biết absolute number sample.

10

Đọc confusion matrix nhanh

Quy trình 4 bước khi nhận confusion matrix mới:

  1. Kiểm tra trục. Hàng nào là actual, cột nào là predicted? Class order? Đừng giả định — luôn đọc label trục.
  2. Nhìn đường chéo. Tỉ lệ giá trị đường chéo so với tổng hàng tương ứng → recall per class. Class nào recall thấp = class bị bỏ sót nhiều.
  3. Nhìn off-diagonal. Ô nào off-diagonal có giá trị cao? Ô \( (i, j) \) cao = class \( i \) hay bị nhầm thành class \( j \). Tìm pattern: có cặp class nào nhầm hai chiều không (\( i \to j \) và \( j \to i \) đều cao)?
  4. Đánh giá theo cost. Liên hệ ô FN, FP với cost trong domain (Bước 5). Số nào cần ưu tiên giảm trong iteration tiếp theo?

Câu hỏi cần đặt thêm:

  • Có class nào hoàn toàn bị model bỏ sót (cột toàn 0)? → model chưa học class đó, có thể do quá ít sample.
  • Có class nào model gán bừa cho mọi thứ (cột rất "dày")? → model bias về class đó, có thể do class đó chiếm đa số trong train data.
  • Confusion matrix có gần đối xứng (\( i \to j \approx j \to i \)) không? Nếu có, hai class đó về bản chất khó tách bằng feature hiện tại.
11

Imbalanced dataset — vấn đề lộ ra

Ví dụ minh hoạ vì sao accuracy không đủ — và vì sao confusion matrix bắt buộc với imbalanced data.

Tình huống: dataset 1000 sample, 950 class 0, 50 class 1 (5% positive). Model "ngu" luôn predict 0:

                  Predicted
                  0       1
   Actual  0    [ 950     0 ]
           1    [  50     0 ]
  • Accuracy = (950 + 0) / 1000 = 95% — nhìn riêng rất "tốt".
  • TP = 0 — model không bắt được sample positive nào.
  • FN = 50 — bỏ sót tất cả ca cần phát hiện.
  • Recall của class 1 = 0 / 50 = 0% — model hoàn toàn vô dụng cho mục tiêu chính.

Trong bài toán phát hiện gian lận, ung thư hiếm, hay churn — class 1 là class bạn quan tâm. Một model "accuracy 95% nhưng recall class 1 = 0%" không có giá trị thực tế. Confusion matrix làm rõ ngay điều này; accuracy đơn lẻ không.

Khi gặp imbalanced data, các metric đáng tin cậy hơn accuracy:

  • Precision, Recall, F1 của class thiểu số (Bài 24, 25).
  • ROC-AUC, PR-AUC (Bài 26).
  • Confusion matrix normalized để nhìn tỉ lệ thay vì count.
12

Cost-sensitive learning — preview

Khi FP và FN có cost khác nhau rõ rệt, tối ưu accuracy (coi mọi lỗi như nhau) không đúng mục tiêu kinh doanh. Cost-sensitive learning đưa cost vào training và evaluation.

Cost matrix — bảng cost cho từng loại lỗi, vd:

                  Predicted
                  0           1
   Actual  0    [ 0           1     ]   <- FP cost = 1
           1    [ 100         0     ]   <- FN cost = 100

Mục tiêu: tối thiểu hoá total cost = \( \text{FP} \times 1 + \text{FN} \times 100 \), thay vì tối thiểu hoá tổng lỗi = \( \text{FP} + \text{FN} \). Khi FN đắt gấp 100 lần FP, model sẽ "thà có nhiều false alarm còn hơn bỏ sót".

Trong sklearn, tiếp cận phổ biến nhất là class_weight cho model:

from sklearn.linear_model import LogisticRegression

# Vd dataset 95% class 0 / 5% class 1
model = LogisticRegression(class_weight="balanced")
# Hoac chi dinh tay:
model = LogisticRegression(class_weight={0: 1, 1: 19})

Tham số class_weight="balanced" tự động đặt trọng số tỉ lệ nghịch với tần suất class — class hiếm được weight cao hơn trong loss function, kéo model về phía bắt được class hiếm.

Use case: fraud detection (FN = mất tiền, FP = phiền khách), medical screening (FN = chết người, FP = thêm xét nghiệm), churn prediction (FN = mất khách, FP = ưu đãi không cần thiết). Chi tiết cost-sensitive learning sẽ quay lại ở module Tối ưu và Đánh giá.

13

Code Python — breast cancer và imbalanced demo

Hai kịch bản: (1) confusion matrix trên dataset cân bằng (breast cancer), (2) confusion matrix lộ vấn đề trên dataset imbalanced 95/5.

Kịch bản 1 — breast cancer:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import (
    confusion_matrix,
    ConfusionMatrixDisplay,
    classification_report,
)

# 1. Load data
data = load_breast_cancer()
X, y = data.data, data.target
# Quy uoc sklearn: 0 = malignant (ac tinh), 1 = benign (lanh tinh)
# Doi quy uoc cho ngu canh "phat hien ung thu" -> class 1 = malignant
y = 1 - y
class_names = ["benign", "malignant"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 2. Train pipeline (scale + logistic)
model = make_pipeline(
    StandardScaler(),
    LogisticRegression(max_iter=1000),
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# 3. Confusion matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)
tn, fp, fn, tp = cm.ravel()
print(f"TN={tn}, FP={fp}, FN={fn}, TP={tp}")

# 4. Visualize
ConfusionMatrixDisplay.from_predictions(
    y_test, y_pred,
    display_labels=class_names,
    cmap="Blues",
)
plt.title("Breast cancer - confusion matrix")
plt.show()

# 5. Bao cao day du
print(classification_report(y_test, y_pred, target_names=class_names))

Quan sát: dataset breast cancer khá cân bằng (~63% benign / 37% malignant) và feature tách rõ — model thường đạt accuracy > 95%. Hãy chú ý FN trong output: dù chỉ 1-2 ca FN, trong context y khoa đó là 1-2 bệnh nhân ung thư bị bỏ sót.

Kịch bản 2 — imbalanced 95/5:

from sklearn.datasets import make_classification

# Tao dataset imbalanced 95/5
X, y = make_classification(
    n_samples=2000,
    n_features=20,
    n_informative=5,
    weights=[0.95, 0.05],
    random_state=42,
)
print("Class distribution:", np.bincount(y))   # [1900, 100]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

# Model thuong (khong xu ly imbalance)
model_plain = LogisticRegression(max_iter=1000).fit(X_train, y_train)
y_pred_plain = model_plain.predict(X_test)
print("Accuracy plain:", (y_pred_plain == y_test).mean())
print(confusion_matrix(y_test, y_pred_plain))

# Model voi class_weight="balanced"
model_bal = LogisticRegression(max_iter=1000, class_weight="balanced")
model_bal.fit(X_train, y_train)
y_pred_bal = model_bal.predict(X_test)
print("Accuracy balanced:", (y_pred_bal == y_test).mean())
print(confusion_matrix(y_test, y_pred_bal))

Pattern điển hình của output:

  • Model "plain" có accuracy cao (~95-96%) nhưng confusion matrix cho thấy hầu hết sample class 1 bị nhầm thành class 0 — TP rất thấp, FN cao.
  • Model "balanced" có accuracy thấp hơn (~85-90%) nhưng TP cao hơn nhiều — bắt được phần lớn sample class 1, đổi lại tăng FP.

Lựa chọn giữa hai model không phải dựa vào accuracy, mà dựa vào: FP và FN bên nào nguy hiểm hơn trong bài toán của bạn?.

14

Bài tập thực hành

Bài 1 — Đọc ma trận bằng tay. Cho confusion matrix (convention sklearn: hàng = actual, cột = predicted, class order [0, 1]):

[[80, 5],
 [10, 5]]

Yêu cầu:

  • Xác định TP, TN, FP, FN.
  • Tính accuracy của model.
  • Trong tổng số 15 sample positive, model bắt được bao nhiêu?
  • Nếu đây là bài toán phát hiện bệnh, FP và FN cái nào đáng lo hơn? Đề xuất hướng cải thiện.

Bài 2 — Confusion matrix trên breast cancer. Train Logistic Regression trên load_breast_cancer() (giữ nguyên quy ước sklearn 0=malignant, 1=benign — không đảo). In ra:

  • Confusion matrix dạng count.
  • Confusion matrix normalize theo hàng (normalize="true").
  • Confusion matrix normalize theo cột (normalize="pred").

Giải thích sự khác biệt giữa 3 dạng và khi nào dùng dạng nào.

Bài 3 — Imbalanced 95/5. Dùng make_classification tạo dataset 2000 sample, tỉ lệ class 95/5. Train 2 phiên bản Logistic Regression:

  • Phiên bản 1: mặc định.
  • Phiên bản 2: class_weight="balanced".

So sánh confusion matrix và accuracy của 2 phiên bản. Trong tình huống FN có cost cao gấp 20 lần FP, phiên bản nào nên chọn? Tính total cost = \( \text{FP} \times 1 + \text{FN} \times 20 \) cho cả hai để verify.

Bài 4 — Multi-class với MNIST-like. Dùng load_digits() của sklearn (8×8 ảnh chữ số 0-9). Train Logistic Regression và in confusion matrix 10×10. Quan sát:

  • Đường chéo có "đậm" không?
  • Cặp chữ số nào hay bị nhầm nhất (off-diagonal cao nhất)?
  • Có cặp nào nhầm 2 chiều (\( i \to j \) và \( j \to i \) đều cao)?

Gợi ý đáp án Bài 1: TN=80, FP=5, FN=10, TP=5. Accuracy = (80+5)/100 = 85%. Recall class 1 = 5/15 ≈ 33% — model bỏ sót 10/15 ca positive. Trong y khoa, FN nguy hiểm hơn FP → nên giảm FN bằng cách thay đổi threshold (về sau ở ROC) hoặc dùng class_weight="balanced".

15

Bài tiếp theo

Bài 24: Accuracy, Precision, Recall — chọn metric nào? — từ 4 ô của confusion matrix derive 3 metric kinh điển: accuracy (đường chéo / tổng), precision (TP / predicted positive), recall (TP / actual positive). Khi nào ưu tiên precision, khi nào ưu tiên recall, và vì sao 2 metric này thường đối nghịch nhau trong thực tế.