Một model gợi ý ba nhóm xử lý ticket và được báo cáo đạt top-3 accuracy cao. Nhưng sản phẩm lại tự chuyển ticket vào đúng một nhóm đầu tiên. Hai cách sử dụng cần hai câu hỏi đánh giá khác nhau: nhãn đứng đầu đúng bao nhiêu lần, hay nhãn đúng có xuất hiện trong danh sách cho người dùng chọn?
Bài đọc tài liệu scikit-learn 1.9.1 ngày 06/11/2026. Ví dụ chạy bằng Python 3.9.6 thuần với score tự tạo; chưa gọi scikit-learn, chạy model hoặc đánh giá dữ liệu thật. Helper chỉ minh họa phân loại nhiều lớp, mỗi mẫu có đúng một nhãn và trọng số bằng nhau.
Chốt hợp đồng của danh sách dự đoán
Top-k accuracy chấm một mẫu là đúng nếu nhãn thật nằm trong k lớp có score cao nhất. Khi k tăng, điều kiện được nới rộng. Một kết quả top-2 vì vậy không thể tự thay cho kết quả top-1 của cùng model.
Trước khi tính, cần biết mỗi cột score ứng với nhãn nào. Sai thứ tự cột có thể cho ra một điểm số hợp lệ về mặt số học nhưng không còn chấm đúng dự đoán. Ví dụ dưới đây dùng cố định ba nhãn theo thứ tự billing, bug, question.
1. Tính hai mức k trên cùng dữ liệu
Chạy đoạn sau như một file Python độc lập. Helper kiểm tra hình dạng đầu vào và quy tắc nhãn trước khi xếp hạng:
import math
def top_k_accuracy(actual, scores, labels, k):
if len(labels) < 3 or len(set(labels)) != len(labels):
raise ValueError("Can it nhat ba nhan khac nhau")
if type(k) is not int or not 1 <= k <= len(labels):
raise ValueError("k khong hop le")
if not actual or len(actual) != len(scores):
raise ValueError("Can du lieu khong rong va cung so mau")
hits = 0
for target, row in zip(actual, scores):
if target not in labels or len(row) != len(labels):
raise ValueError("Sai nhan hoac so cot")
if not all(math.isfinite(value) for value in row):
raise ValueError("Score phai huu han")
ranked = sorted(range(len(labels)),
key=lambda index: (row[index], index),
reverse=True)
hits += target in [labels[index] for index in ranked[:k]]
return hits / len(actual)
labels = ["billing", "bug", "question"]
actual = ["billing", "question", "bug", "question"]
scores = [
[0.8, 0.1, 0.1],
[0.6, 0.1, 0.3],
[0.1, 0.7, 0.2],
[0.6, 0.3, 0.1],
]
assert top_k_accuracy(actual, scores, labels, 1) == 0.5
assert top_k_accuracy(actual, scores, labels, 2) == 0.75
assert top_k_accuracy(actual, scores, labels, 3) == 1.0
print("top-1:", top_k_accuracy(actual, scores, labels, 1))
print("top-2:", top_k_accuracy(actual, scores, labels, 2))
Mẫu thứ hai có question đứng sau billing nên trượt top-1 nhưng đạt top-2. Mẫu thứ tư có nhãn thật đứng cuối nên trượt cả hai mức. Đó là toàn bộ lý do chênh lệch trong fixture; không có dữ liệu đo từ một dịch vụ thực tế.
Với ba lớp, lấy cả ba nhãn luôn chứa nhãn thật hợp lệ. Điểm top-3 bằng 1 ở đây vì danh sách đã bao phủ toàn bộ lựa chọn, không chứng minh model có khả năng phân biệt tốt.
2. Kiểm tra score bằng nhau ở biên
Helper đặt chỉ số cột lớn hơn lên trước nếu score bằng nhau, theo quy tắc tie được tài liệu scikit-learn mô tả. Nối tiếp file trên:
tied = [[0.5, 0.5, 0.0]]
assert top_k_accuracy(["billing"], tied, labels, 1) == 0.0
assert top_k_accuracy(["bug"], tied, labels, 1) == 1.0
assert top_k_accuracy(["billing"], tied, labels, 2) == 1.0
Nếu hệ thống production có quy tắc tie khác, cần chốt lại metric cho tương thích. Không đảo thứ tự nhãn mà giữ nguyên các cột score rồi kỳ vọng kết quả vẫn có cùng ý nghĩa.
Đưa metric về đúng cách sản phẩm hoạt động
Nếu model tự chọn một nhóm, báo top-1 cùng lỗi theo từng nhóm. Nếu người vận hành xem hai gợi ý, báo thêm top-2 và kiểm tra thực tế họ có chọn được nhóm đúng hay không. Danh sách chứa nhãn đúng vẫn có thể tốn công đọc hoặc đưa gợi ý gây hiểu nhầm.
Giữ cùng tập mẫu và cùng thứ tự nhãn khi so hai model. Ghi rõ k, số lớp, số mẫu, cách xử lý tie và trọng số nếu có. Với tập test thiếu một lớp, kiểm tra cấu hình labels khi dùng thư viện; đừng suy ra danh sách cột chỉ từ các nhãn tình cờ có trong test.
Giới hạn của ví dụ
Helper không hỗ trợ binary theo giao diện score một chiều của scikit-learn, multilabel, sample_weight hoặc giá trị thiếu. Score trong demo cộng thành 1, nhưng phép xếp hạng không tự chứng minh xác suất đã được hiệu chỉnh.
Đây cũng không phải phép đo truy hồi tài liệu RAG hay pass@k của code sinh tự động. Đối tượng được xếp hạng ở đây là các lớp của một mẫu phân loại. Chọn đúng metric theo quyết định sản phẩm, rồi giữ top-1 cạnh top-k để tránh đọc nhầm mức độ thành công.

