Ứng dụng thuật toán Naive Bayes trong giải quyết bài toán chuẩn đoán bệnh tiểu đường

Tram Ho

Chào tất cả mọi người, đã rất lâu rồi mình mới có một bài Viblo mới viết về Machine Learning và hôm nay chúng ta sẽ đến với một phương pháp không phải là mới trong học máy nhưng vẫn luôn là một phương pháp đem lại hiệu quả tốt trong lớp các bài toán phân lớp hay dự đoán. Giải thuật mà chúng ta sẽ thảo luận ngày hôm nay chính là Naive Bayes – một trong những thuật toán rất tiêu biểu cho hướng phân loại dựa trên lý thuyết xác suất. Có một điều đặc biết trong bài Viblo này đó là phàn code mình sẽ không sử dụng thư viện Naive Bayes trong gói thư viện Scikit-learn quen thuộc như những bài Viblo trước mà thay vào đó mình sẽ hướng dẫn các bạn triển khai thuật toán này trên Python một cách step-by-step thông qua một ví dụ thực tế rất hay đó là chuẩn đoán bệnh nhận bị tiểu đường dựa vào những biểu hiện của người đó. OK chúng ta bắt đầu thôi nào.

Phương pháp học dựa trên xác suất

Nếu các bạn đã dõi các bài viết của mình về Machine Learning hoặc các tutorial khác về học máy thì có thể thấy được một điều rằng giữa Machine Learning và lý thuyết xác suất có một sự liên hệ rất khăng khít. Các phương pháp phân loại dựa trên lý thuyết xác suất về cơ bản có thể hiểu là việc tính xem xác suất một sự việc của chúng ta sẽ xảy ra theo hướng như thế nào. Xác suất của hướng nào càng cao thì khả năng sự việc xảy ra theo hướng đó càng nhiều. Điều này đặc biết có ý nghĩa trong bài toán dự đoán và phân lớp của lĩnh vực Machine Learning. Một câu hỏi đặt ra là “Vậy rốt cuộc thì chiếc máy tính vô hồn của chúng ta sẽ xác định xác suất đó như thế nào?”. Theo thống kê học hiện đại thì tương ứng với mỗi bài toán giải quyết theo phương pháp xác suất thường đi kèm theo một phân phối xác suất phù hợp với bài toán đó. Tương ứng với mỗi phân phối xác suất chúng ta có một cách tính riêng các đại lượng cần thiết cho quá trình chạy các thuật toán như kỳ vọng, độ lệch chuẩn … mà chúng ta sẽ cùng nhau tìm hiểu và tiến hành tính toán trong suốt phạm vi bài viết này. Giờ thì chúng ta tiếp tục đến với phần tiếp theo thôi.

Thuật toán Naive Bayes

 Lý thuyết Bayes thì có lẽ không còn quá xa lạ với chúng ta nữa rồi. Nó chính là sự liên hệ giữa các xác suất có điều kiện. Điều đó gợi ý cho chúng ta rằng chúng ta có thể tính toán một xác suất chưa biết dựa vào các xác suất có điều kiện khác. Thuật toán Naive Bayes cũng dựa trên việc tính toán các xác suất có điều kiện đó. Nghe tên thuật toán là đã thấy gì đó ngây ngô rồi. Tại sao lại là Naive nhỉ. Không phải ngẫu nhiên mà người ta đặt tên thuật toán này như thế. Tên gọi này dựa trên một giả thuyết rằng các chiều của dữ liệu X=(x_1, x_2, …., x_n)X=(x1,x2,....,xn) là độc lập về mặt xác suất với nhau.  Chúng ta có thể thấy rằng giả thuyết này có vẻ khá ngây thơ vì trên thực tế điều này có thể nói là không thể xảy ra tức là chúng ta rất ít khi tìm được một tập dữ liệu mà các thành phần của nó không liên quan gì đến nhau. Tuy nhiên, giả thiết ngây ngô này lại mang lại những kết quả tốt bất ngờ. Giả thiết về sự độc lập của các chiều dữ liệu này được gọi là Naive Bayes (xin phép không dịch). Cách xác định class của dữ liệu dựa trên giả thiết này có tên là Naive Bayes Classifier (NBC). Tuy nhiên dựa vào giả thuyết này mà bước training và testing trở nên vô cùng nhanh chóng và đơn giản. Chúng ta có thể sử dụng nó cho các bài toán large-scale. Trên thực tế, NBC hoạt động khá hiệu quả trong nhiều bài toán thực tế, đặc biệt là trong các bài toán phân loại văn bản, ví dụ như lọc tin nhắn rác hay lọc email spam. Trong bài viết này mình sẽ cùng với các bạn áp dụng lý thuyết về NBC để giải quyết một bài toán mới đó chính là bài toán chuẩn đoán bệnh tiểu đường

Tập dữ liệu bệnh tiểu đường

Tập dữ liệu này bao gồm dữ liệu của 768 tình nguyện viên bao gồm những người bị tiểu đường và những người không bị tiểu đường. Tập dữ liệu này bao gồm các thuộc tính như sau:

  1. Number of times pregnant
  2. Plasma glucose concentration a 2 hours in an oral glucose tolerance test
  3. Diastolic blood pressure (mm Hg)
  4. Triceps skin fold thickness (mm)
  5. 2-Hour serum insulin (mu U/ml)
  6. Body mass index (weight in kg/(height in m)^2)
  7. Diabetes pedigree function
  8. Age (years)

với mỗi tình nguyện viện, dữ liệu bao gồm tập hợp các chỉ số kể trên và tình trạng bị bênh tức class 1 hay không bị bệnh tức class 0. Về bản chất đây là một bài toán phân loại 2 lớp và chúng ta có thể sử dụng các phương pháp phân loại khác như SVM, Random Forest, kNN… để phân loại cũng cho kết quả khá tốt. Nếu có dịp mình sẽ trình bày phương pháp này trong một dịp khác. Chúng ta có thể hình dung tập dữ liệu này thông qua biểu diễn dưới dạng file CSV như sau, trong đó cột cuối cùng chính là tình trạng bị bệnh của tình nguyện viên, các cột từ 1 đến 8 tương ứng với các chỉ số nếu trên

Có một điều nhận thấy rằng giá trị của các chỉ số là một biến liên tục chứ không phải một giá trị rời rạc chính vì thế nên khi áp dụng thuật toán Naive Bayes chúng ta cần phải áp dụng một phân phối xác suất cho nó. Một trong những phân phối xác suất phổ biến được sử dụng trong phần này đó chính là phân phối Gaussian. Chúng ta cùng tìm hiểu qua một chút về nó nhé. Phải hiểu được bản chất thì mới có thể thực hành được.

Phân phối Gaussian

Với một một dữ liệu x_ixi thuộc một class c_ici chúng ta thấy x_ixi tuân theo một phân phối chuẩn với kì vọng muμ và độ lệch chuẩn sigmaσ. Khi đó hàm xác suất của x_ixi được xác định như sau:

Đây chính là cách tính của thư viện sklearn tuy nhiên trong bài viết này mình sẽ hướng dẫn các bạn cài đặt thủ công. Chính việc cài đặt thủ công này giúp cho chúng ta hiểu hơn về bài toán

.ua5053c41ed5d326bbde2c897e5b5bfdc { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .ua5053c41ed5d326bbde2c897e5b5bfdc:active, .ua5053c41ed5d326bbde2c897e5b5bfdc:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .ua5053c41ed5d326bbde2c897e5b5bfdc { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .ua5053c41ed5d326bbde2c897e5b5bfdc .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .ua5053c41ed5d326bbde2c897e5b5bfdc .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .ua5053c41ed5d326bbde2c897e5b5bfdc:hover .postTitle { text-decoration: underline!important; }

  Bàn về các nguyên lý lập trình

.ubda7d2517ed10d3723b2920da839e242 { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .ubda7d2517ed10d3723b2920da839e242:active, .ubda7d2517ed10d3723b2920da839e242:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .ubda7d2517ed10d3723b2920da839e242 { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .ubda7d2517ed10d3723b2920da839e242 .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .ubda7d2517ed10d3723b2920da839e242 .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .ubda7d2517ed10d3723b2920da839e242:hover .postTitle { text-decoration: underline!important; }

  Chỉ bằng thuật toán và đám mây, các nhà nghiên cứu có thể tăng thời lượng pin smartphone tới 60%

Cài đặt thủ công

Load dữ liệu

Dữ liệu của chúng ta được lưu dưới dạng file CSV nên chúng ta sẽ sử dụng thư viện csv của Python để đọc dữ liệu

Tính độ lệch chuẩn

Như đã trình bày phần trên chúng ta cần một đoạn code để tính độ lệch chuẩn của biến ngẫu nhiên liên tục. Chúng ta có thể tham khảo công thức tính của nó như biểu thức sau:

Trong đó overline{x}x là gía trị trung bình của biến ngẫu nhiên trên toàn tập dữ liệu. Chúng ta sử dụng Python để thực hiện hàm tính giá trị trung bình và độ lệch chuẩn như sau

Tiền xử lý dữ liệu

Trước khi bắt đầu mỗi bài toán về Machine Learning bước tiền xử lý dữ liệu là rất quan trọng. Nếu như tập dữ của chúng ta chưa chuẩn chúng ta sẽ cần phải làm thêm một số bước khác như lấy mẫu dữ liệu, loại bỏ dữ liệu thiếu và biến đổi dữ liệu về dạng thích hợp để xử lý.. Đối với tập dữ liệu bênh tiểu đường thì dữ liệu đã được chuẩn hóa rồi nên tùy vào từng thuật toán mà chúng ta chọn cách biểu diễn dữ liệu cho phù hợp. Như phần trên đã nói chúng ta sẽ sử dụng Độ lệch chuẩn và giá trị trung bình để tính toán các xác suất cần thiết nên cần có một hàm để chuyển đổi dữ liệu ban đầu về dạng tập hợp của độ lệch chuẩn và trung bình nhằm phục vụ cho các phép tính xác suất sau này.

Tính xác suất của từng biến liên tục theo phân phối Gausian

Dựa vào cơ sở lý thuyết ở bên trên. Chúng ta tiến hành tính các xác suất phụ thuộc của biến ngẫu nhiên bao gồm p(x)p(x) của mỗi chỉ số sức khỏe và p(x|c)p(xc) của mỗi class tương ứng với chỉ số đó.

Dự đoán dựa vào xác suất

Đây là bước áp dụng định lý Bayes đã đước giới thiệu bên trên vào dự đoán các class thông qua các chỉ số trong tập dữ liệu

Learning

Sau bước xử lý dữ liệu ban đầu chúng ta tiến hành learning như sau:

Kết quả cài đặt

Sau khi cài đặt ta nhận thấy thuật toán tính toán rất nhanh và cho độ chính xác khoảng 75% tùy thuộc vào cách phân chia dữ liệu.

 Tiếp theo để kiểm tra cài đặt của thuật toán đã đúng chưa. Mình sẽ thử nghiệm so sánh với thư viện sklearn trong phần tiếp theo

Sử dụng thư viện Sklearn

Phân chia dữ liệu

Đầu tiên ta cần phân chia tập dữ liệu ban đầu thành hai ma trận, 1 ma trận chứa chỉ số của tình nguyện viên chính là 8 chỉ số đã chỉ ra ở phần đầu tiên và một ma trận chứa các class tương ứng.

Training

Chúng ta thêm vào phần hàm main()main() bên trên đoạn code sau để thực hiện training sử dụng thư viện

Predict

Sau khi training xong chúng ta sẽ sử dụng model để đánh giá trên tập dữ liệu testing.

So sánh hai cách cài đặt

Sau khi chạy thử nghiệm cho kết quả giống nhau chứng tỏ cách cài đặt thủ công của chúng ta đã chính xác

Source code

Các bạn có thể tham khảo source code trong bài viết tại đây

Kết luận

Chúng ta đã cùng nhau đi qua một chặng đường dài tự lý thuyết xác suất đến thuật toán Naive Bayes rồi ứng dụng nó trong bài toán phần loại bệnh nhân mắc bệnh tiểu đường. Vấn đề của chúng ta rõ ràng vẫn là thống kê được những mối liện hệ và tìm được những xác suất của nó với vấn đề mà chúng ta quan tâm (ở đây chính là việc có bị tiểu đường hay không). Tuy độ chính xác còn chưa cao do bản chất cuả phương pháp cũng như tập dữ liệu chưa đủ lớn tuy nhiên nó cũng giúp bạn đọc hình dung được cách cài đặt thuật toán Naive Bayes.

.ueaab7225fd55ec82813b115d25763b05 { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .ueaab7225fd55ec82813b115d25763b05:active, .ueaab7225fd55ec82813b115d25763b05:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .ueaab7225fd55ec82813b115d25763b05 { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .ueaab7225fd55ec82813b115d25763b05 .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .ueaab7225fd55ec82813b115d25763b05 .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .ueaab7225fd55ec82813b115d25763b05:hover .postTitle { text-decoration: underline!important; }

  Katie Bouman – Cô gái đã dùng thuật toán “chụp” lại ảnh hố đen đầu tiên trong lịch sử

.ub04db53010d1a29066f0baadaf917aee { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .ub04db53010d1a29066f0baadaf917aee:active, .ub04db53010d1a29066f0baadaf917aee:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .ub04db53010d1a29066f0baadaf917aee { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .ub04db53010d1a29066f0baadaf917aee .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .ub04db53010d1a29066f0baadaf917aee .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .ub04db53010d1a29066f0baadaf917aee:hover .postTitle { text-decoration: underline!important; }

  Algorithms by Jeff Erickson, cuốn sách mang thuật toán đến gần bạn hơn

Chia sẻ bài viết ngay

Nguồn bài viết : viblo