Học máy, học sâu và trí tuệ nhân tạo là một tập hợp các thuật toán được sử dụng để nhận diện các quy luật trong dữ liệu. Các thuật toán này thường có những cái tên khá độc đáo như rừng ngẫu nhiên, mạng nơ-ron hay phân cụm phổ. Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách sử dụng một trong những thuật toán phổ biến nhất có tên là support vector machine. Mục tiêu của chúng ta là giới thiệu ngắn gọn và hướng dẫn cách triển khai mô hình này bằng Python ngay bên trong môi trường Stata.
Bài toán thực tế được đặt ra là sử dụng support vector machine để phân biệt giữa những người có khả năng mắc bệnh tiểu đường và những người không mắc bệnh. Chúng ta sẽ dựa vào hai biến số là tuổi tác và chỉ số HbA1c. Tuổi được tính bằng năm, còn HbA1c là một xét nghiệm máu giúp đo lường mức độ kiểm soát đường huyết. Mô hình sẽ dự đoán rằng những người lớn tuổi với mức HbA1c cao có nhiều nguy cơ mắc tiểu đường hơn, trong khi những người trẻ tuổi với mức HbA1c thấp thường ít có nguy cơ hơn.
Tải, gộp và làm sạch dữ liệu
Chúng ta sẽ sử dụng bộ dữ liệu từ Cuộc khảo sát Kiểm tra Sức khỏe và Dinh dưỡng Quốc gia Hoa Kỳ. Cụ thể, các biến số được quan tâm bao gồm biến tuổi từ bộ dữ liệu nhân khẩu học, biến HbA1c từ bộ dữ liệu hemoglobin glycosyl hóa và biến tiểu đường từ bộ dữ liệu bệnh lý.
Đoạn mã dưới đây sẽ tải ba tệp tin từ trang web của cơ sở dữ liệu, lưu chúng thành các tập dữ liệu Stata, gộp chúng lại với nhau, đổi tên và mã hóa lại các biến số. Sau đó, chúng ta chỉ giữ lại ba biến mục tiêu, loại bỏ các quan sát có giá trị khuyết và lưu thành một tập dữ liệu hoàn chỉnh.
1import sasxport5 "https://wwwn.cdc.gov/Nchs/Nhanes/2015-2016/DEMO_I.XPT", clear
2save age.dta, replace
3import sasxport5 "https://wwwn.cdc.gov/Nchs/Nhanes/2015-2016/GHB_I.XPT", clear
4save glucose.dta, replace
5import sasxport5 "https://wwwn.cdc.gov/Nchs/Nhanes/2015-2016/DIQ_I.XPT", clear
6save diabetes, replace
7merge 1:1 seqn using "glucose.dta"
8drop _merge
9merge 1:1 seqn using "age.dta"
10rename ridageyr age
11rename lbxgh HbA1c
12rename diq010 diabetes
13recode diabetes (1 = 1) (2/3 = 0) (9=.)
14keep diabetes age HbA1c
15drop if missing(diabetes, age, HbA1c)
16save diabetes, replace
17erase age.dta
18erase glucose.dtaMở và vẽ biểu đồ dữ liệu thô bằng Python
Tiếp theo, chúng ta sẽ đọc tập dữ liệu Stata vừa tạo vào một data frame của pandas và tiến hành vẽ biểu đồ dữ liệu thô. Trong thuật ngữ thống kê, chúng ta gọi các biến về tuổi và HbA1c là biến độc lập, còn tình trạng tiểu đường là biến phụ thuộc. Trong thuật ngữ học máy, chúng lần lượt được gọi là biến đặc trưng và biến mục tiêu. Mục đích ở đây là dùng thông tin từ các biến đặc trưng để phân loại biến mục tiêu.

Đoạn mã Python dưới đây sẽ thiết lập môi trường bằng cách nhập các thư viện cần thiết như pandas và matplotlib, đọc dữ liệu, phân tách các biến và vẽ một biểu đồ phân tán.
1import pandas as pd
2import matplotlib.pyplot as plt
3import matplotlib.colors as mcolors
4data = pd.read_stata('diabetes.dta',
5convert_categoricals=False,
6preserve_dtypes=True,
7convert_missing=False)
8X = data[['age','HbA1c']]
9y = data['diabetes']
10plt.scatter(X['age'], X['HbA1c'],
11c=y,
12cmap = mcolors.ListedColormap(["navy", "darkred"]))
13plt.xlabel('Age (years)')
14plt.ylabel('HbA1c')
15plt.xticks((12,20,30,40,50,60,70,80))
16plt.yticks((4,6,8,10,12,14,16))
17plt.title('Diabetes status by Age and HbA1c')
18plt.savefig("scatterplot.png")Biểu đồ thu được sẽ cho thấy những người mắc bệnh tiểu đường thường có xu hướng lớn tuổi hơn và có nồng độ HbA1c trong máu cao hơn.
Chia dữ liệu thành tập huấn luyện và tập kiểm tra
Trong học máy, một quy trình chuẩn mực là phải chia dữ liệu thành tập huấn luyện và tập kiểm tra. Tập huấn luyện được dùng để xây dựng mô hình, còn tập kiểm tra giúp đánh giá tính nhất quán. Điều này giúp chúng ta tránh được tình trạng mô hình quá khớp với một bộ dữ liệu cụ thể và mất đi khả năng tổng quát hóa trên các bộ dữ liệu mới.
Chúng ta sẽ dành ra bốn mươi phần trăm dữ liệu cho việc kiểm tra và sáu mươi phần trăm cho việc huấn luyện. Việc phân chia này là một quá trình ngẫu nhiên, do đó chúng ta cần thiết lập hạt giống ngẫu nhiên để kết quả có thể được tái tạo trong những lần chạy sau.
1from sklearn.model_selection import train_test_split
2X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=0)Chọn tham số cho mô hình bằng tìm kiếm dạng lưới và xác thực chéo
Có nhiều biến thể khác nhau của support vector machine, và trong bài này chúng ta sẽ tinh chỉnh một bộ phân loại c-support vector classifier (SVC). Chúng ta sẽ thiết lập ba đối số chính: hàm hạt nhân, bậc của hàm hạt nhân và tham số điều chuẩn. Thay vì đoán mò, chúng ta sẽ chỉ định một hàm hạt nhân đa thức và sử dụng tập huấn luyện để chọn ra bậc cũng như tham số điều chuẩn tối ưu nhất thông qua kỹ thuật tìm kiếm dạng lưới.
Để tăng độ tin cậy, chúng ta áp dụng phương pháp xác thực chéo k-fold. Phương pháp này bắt đầu bằng cách chia tập huấn luyện thành k nhóm phụ. Mô hình sẽ được huấn luyện trên k trừ một nhóm và kiểm tra trên nhóm còn lại. Quá trình này lặp lại k lần để mỗi nhóm đều đóng vai trò là dữ liệu kiểm tra, sau đó tính trung bình các kết quả.
1from sklearn import svm
2from sklearn.model_selection import GridSearchCV
3model = svm.SVC(kernel='poly')
4parameters = {'degree':[1,2,3], 'C':[1,2,3]}
5poly_svc = GridSearchCV(model,
6parameters,
7cv=10,
8scoring='accuracy').fit(X_train, y_train)
9poly_svc.fit(X_train,y_train)
10print(poly_svc.best_params_)Kết quả của thuật toán tìm kiếm dạng lưới sẽ chỉ ra rằng mô hình đạt độ khớp tốt nhất khi tham số điều chuẩn bằng ba và bậc của đa thức cũng bằng ba.
Kiểm tra mô hình trên tập dữ liệu kiểm tra
Bây giờ chúng ta đã sẵn sàng để đánh giá mức độ chính xác của mô hình dựa trên tập dữ liệu kiểm tra. Chúng ta sẽ khởi tạo mô hình với các tham số tối ưu vừa tìm được và tính toán điểm số xác thực chéo.
1from sklearn.model_selection import cross_val_score
2poly_svc = svm.SVC(kernel='poly', degree=3, C=3).fit(X_train, y_train)
3scores = cross_val_score(poly_svc, X_test, y_test, cv=10, scoring='accuracy')
4print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))Kết quả in ra màn hình sẽ cho thấy mô hình của chúng ta dự đoán tình trạng bệnh tiểu đường với độ chính xác lên tới chín mươi ba phần trăm, cộng trừ sai số không phẩy không ba.
Vẽ biểu đồ kết quả của mô hình
Cuối cùng, để trực quan hóa cách mô hình đưa ra quyết định phân loại, chúng ta sẽ sử dụng biểu đồ đường đồng mức. Lưới hai chiều sẽ trải dài từ giá trị nhỏ nhất đến giá trị lớn nhất của độ tuổi và chỉ số HbA1c. Thuật toán sẽ phân loại từng điểm trên không gian này thành nhóm mắc bệnh hoặc không mắc bệnh, sau đó đổ màu tương ứng để tạo ra ranh giới quyết định.

Đoạn mã dưới đây sử dụng NumPy để tạo lưới tọa độ, dự đoán nhãn cho từng điểm ảnh và phủ biểu đồ phân tán của dữ liệu thô lên trên ranh giới quyết định vừa tạo.
1import numpy as np
2h = 0.1
3x_min, x_max = X['age'].min() - 1, X['age'].max() + 1
4y_min, y_max = X['HbA1c'].min() - 1, X['HbA1c'].max() + 1
5xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
6np.arange(y_min, y_max, h))
7Z = poly_svc.predict(np.c_[xx.ravel(), yy.ravel()])
8Z = Z.reshape(xx.shape)
9plt.contourf(xx, yy, Z,
10cmap = mcolors.ListedColormap(["dodgerblue", "red"]),
11alpha=0.8)
12plt.scatter(X['age'], X['HbA1c'],
13c=y,
14cmap = mcolors.ListedColormap(["navy", "darkred"]))
15plt.xlabel('Age (years)')
16plt.ylabel('HbA1c')
17plt.xlim(xx.min(), xx.max())
18plt.ylim(yy.min(), yy.max())
19plt.xticks((12,20,30,40,50,60,70,80))
20plt.yticks((4,6,8,10,12,14,16))
21plt.title('Diabetes status by Age and HbA1c')
22plt.savefig("contourplot.png")✨ Việc kết hợp khả năng xử lý dữ liệu mạnh mẽ, gọn gàng của Stata với hệ sinh thái học máy đa dạng từ thư viện scikit-learn của Python mang lại cho các nhà phân tích một quy trình làm việc hoàn hảo. Bạn hoàn toàn có thể làm sạch dữ liệu bằng các câu lệnh quen thuộc, sau đó lập tức chuyển sang thiết lập các thuật toán dự đoán phức tạp mà không cần phải thoát khỏi nền tảng phân tích cốt lõi của mình.
Dựa trên đoạn mã tìm kiếm tham số tối ưu bên trên, nếu bạn muốn đổi từ hàm hạt nhân đa thức sang hàm hạt nhân cơ sở xuyên tâm, bạn sẽ cần điều chỉnh cú pháp của hàm thuật toán như thế nào và bộ tham số lưới nào sẽ là phù hợp nhất để đưa vào thử nghiệm?


