KNN in Symptom Checkers
k-NN trong kiểm tra triệu chứng
Công ty nào đang ứng dụng k láng giềng gần nhất?
Nửa đêm, bạn đau đầu kèm sốt nhẹ. Thay vì gõ Google rồi tự doạ mình với kết quả u não, bạn mở app kiểm tra triệu chứng như Buoy Health. Chatbot hỏi vài câu: “Bạn có sốt không?”, “Bạn có ho không?”. Sau 30 giây, app gợi ý: nhiều khả năng là cảm cúm thường, nghỉ ngơi và uống nước; đến bác sĩ nếu triệu chứng kéo dài quá 3 ngày.
Đằng sau phần “gợi ý” đó chính là k-NN. App biến bộ triệu chứng của bạn thành một vector số, so với hàng ngàn ca bệnh đã được bác sĩ chẩn đoán, chọn các ca gần nhất và gợi ý bệnh phổ biến trong các ca đó. Phần tiếp theo sẽ cho bạn thử chính quy trình ấy — chỉ việc bật/tắt các nút triệu chứng.
Vấn đề công ty cần giải quyết
Hàng trăm triệu lượt tìm kiếm triệu chứng bệnh trên internet mỗi tháng — riêng WebMD có hơn 95 triệu lượt truy cập/tháng. Nhưng tìm kiếm thông thường trả về kết quả gây hoang mang: một cơn đau đầu có thể là cảm, cũng có thể là u não. Người dùng cần một công cụ đưa ra gợi ý có trọng tâm, không phải danh sách mọi bệnh có thể.
Vấn đề cốt lõi: từ một bộ triệu chứng (tất cả đều rời rạc có/không), chọn ra một vài bệnh khả năng cao nhất và phân loại mức độ khẩn cấp (triage). Phải đủ nhanh để trả lời trong 1–2 giây, đủ chính xác để không bỏ sót cấp cứu, và đủ đơn giản để cập nhật liên tục khi có ca mới.
Cách k láng giềng gần nhất giải quyết vấn đề
Biến triệu chứng thành vector số.Mỗi triệu chứng (sốt, ho, mệt mỏi, đau đầu...) là một chiều. Bệnh nhân trả lời có/không, hệ thống ghi lại 1 hoặc 0. Nếu theo dõi 200 triệu chứng, mỗi người là một vector 200 chiều. Với mức độ nghiêm trọng có thể dùng số liên tục (ví dụ “sốt 38.5°C” thay vì chỉ 0/1).
Tính khoảng cách với các ca đã có. Hệ thống so vector mới với mọi ca trong cơ sở dữ liệu bằng khoảng cách phù hợp: Hamming (đếm số chiều khác nhau — phù hợp với dữ liệu 0/1 như triệu chứng có/không), Euclid (khi chiều liên tục), hoặc Cosine(khi quan trọng tỉ lệ chứ không phải giá trị tuyệt đối). Ca nào có vector “gần” bạn nhất = có triệu chứng giống bạn nhất.
Chọn k ca gần nhất. Lấy k ca (thường 5, 7 hoặc 11 — số lẻ để tránh hoà phiếu). k quá nhỏ → nhạy với ca cá biệt; k quá lớn → bỏ qua bệnh hiếm. Trong y tế, k được tinh chỉnh qua cross-validation trên dữ liệu ca đã biết.
Bỏ phiếu đa số. Trong k ca gần nhất, bệnh nào xuất hiện nhiều nhất được chọn. Có thể dùng weighted voting — ca gần hơn thì phiếu nặng hơn. Ví dụ: 5/7 ca là cúm, 2/7 là viêm họng → app gợi ý cúm với độ tin cậy ~71%.
Phân loại mức độ khẩn cấp (triage).Kết hợp kết quả k-NN với luật y khoa đơn giản: nếu có một số tổ hợp triệu chứng “đèn đỏ” (đau ngực, khó thở, sốt rất cao), luôn ưu tiên đi cấp cứu — bất kể k-NN gợi ý gì. Đây là lớp an toàn để tránh bỏ sót ca nặng.
Hình minh họa
Bật/tắt các nút triệu chứng bên trái. Bên phải bạn sẽ thấy ca của mình xuất hiện trong “không gian bệnh nhân” — càng gần một cụm màu, bệnh càng có khả năng cao. Các đường nối là k ca gần nhất đang được bỏ phiếu.
k lẻ để tránh hoà phiếu. Quá nhỏ → nhạy với nhiễu, quá lớn → bỏ qua bệnh hiếm.
Mỗi chấm = một ca cũ đã được bác sĩ chẩn đoán. Ca càng gần ca của bạn trong không gian này = triệu chứng càng trùng. Đường nối = k ca gần nhất.
Minh, 24 tuổi, đang sốt và ho. Theo dõi từng bước app xử lý dữ liệu.
Minh, 24 tuổi, mở app Buoy Health lúc 10 giờ đêm. Các triệu chứng: sốt, ho, mệt mỏi, đau cơ. App biến bộ triệu chứng này thành một vector 8 chiều — mỗi chiều là một triệu chứng, giá trị 1 (có) hoặc 0 (không).
Tại sao app kiểm tra triệu chứng không nhanh khi database có hàng triệu ca?
Con số thật
- k-NN đạt 91.29% độ chính xác trong phát hiện bệnh từ dữ liệu lâm sàng [1]
- k-NN tối ưu đạt 97.18% độ chính xác trong dự đoán đột quỵ [2]
- Hơn 95 triệu lượt truy cập WebMD mỗi tháng — nhu cầu kiểm tra triệu chứng rất lớn [5]
- Công cụ kiểm tra triệu chứng đưa đúng chẩn đoán vào top-3 gợi ý trong 51% trường hợp [5]
Nếu không có k láng giềng gần nhất, app sẽ ra sao?
Không có k-NN, app kiểm tra triệu chứng sẽ phải quay về hai cách cũ: (1) expert system— bác sĩ viết hàng ngàn luật “nếu có A và B thì có thể là C”, rất tốn công và khó cập nhật; hoặc (2) mô hình phức tạp (neural net) — chính xác hơn nhưng không giải thích được vì sao chọn chẩn đoán cụ thể, gây khó cho việc điều chỉnh và kiểm toán y khoa.
k-NN đơn giản đến mức dễ giải thích: “gợi ý cúm vì 4/5 ca có triệu chứng giống bạn nhất đều được chẩn đoán cúm”. Điều đó giúp bác sĩ kiểm tra nhanh, và giúp người dùng tin vào app. Khi có ca mới → chỉ cần thêm vào database, không cần huấn luyện lại. Sự đơn giản đó chính là lý do k-NN xuất hiện ở nền của nhiều công cụ triage — trước khi hệ thống được nâng cấp với embedding deep learning và approximate nearest neighbor để chạy được trên triệu ca.
- App biến triệu chứng thành vector, rồi so khoảng cách Hamming/Euclid với mọi ca cũ — đó là k-NN.
- k lẻ, thường 5–11, chọn bằng cross-validation. Quyết định triage có thêm lớp luật y khoa 'đèn đỏ'.
- k-NN đơn giản, dễ giải thích — nhưng chậm khi N lớn. Giải pháp: KD-tree hoặc approximate NN (HNSW, FAISS).
- App gợi ý ≠ chẩn đoán của bác sĩ. Chính xác top-3 ~51% — đủ để định hướng, không đủ để thay bác sĩ.
Muốn hiểu kỹ phần thuật toán đứng sau — k là gì, chọn k thế nào, các thước đo khoảng cách — xem bài lý thuyết: k láng giềng gần nhất (k-NN).