Hỗ trợ Vector Machine là một thuật toán đơn giản khác hoạt động tương đối tốt với chi phí tính toán ít hơn. Trong hồi quy, SVM hoạt động bằng cách tìm một siêu phẳng trong không gian N chiều (N số đối tượng) phù hợp với dữ liệu đa chiều trong khi xem xét một lề. Trong phân loại, cùng một siêu phẳng được tính toán nhưng để phân loại rõ ràng các điểm dữ liệu một lần nữa trong khi xem xét một lề. Có thể có nhiều siêu máy bay có thể được lựa chọn. Tuy nhiên, mục tiêu là tìm siêu phẳng có lề tối đa, nghĩa là khoảng cách tối đa giữa các lớp mục tiêu.
SVM có thể được sử dụng cho cả các bài toán hồi quy và phân loại nhưng nó được sử dụng rộng rãi để phân loại.
Hãy giải thích một số thuật ngữ trước khi chúng ta đi sâu hơn.
Kernel là hàm được sử dụng để chuyển đổi dữ liệu thành thứ nguyên cao hơn.
Siêu phẳng là đường phân cách giữa các lớp (đối với các bài toán phân loại). Đối với hồi quy, đó là đường mà chúng tôi phù hợp với dữ liệu của mình để dự đoán các giá trị kết quả tiếp tục.
Các đường ranh giới là các đường tạo thành vùng có lỗi mà chúng ta đã đề cập trước đó. Chúng là hai đường bao quanh siêu phẳng đại diện cho lề.
Các vectơ hỗ trợ là các điểm dữ liệu gần nhất với các đường ranh giới này.
Chúng tôi đã đề cập rằng hạt nhân là chức năng để chuyển đổi dữ liệu của chúng tôi thành các kích thước cao hơn. Vậy điều đó hữu ích cho chúng ta như thế nào?
Đôi khi dữ liệu được phân phối theo cách mà không thể có được sự phù hợp chính xác bằng cách sử dụng một đường thẳng (dấu phân cách). SVR có thể xử lý dữ liệu phi tuyến tính cao bằng cách sử dụng hàm nhân. Hàm ánh xạ ngầm các đối tượng địa lý đến các kích thước cao hơn có nghĩa là không gian đối tượng địa lý cao hơn. Điều này cho phép chúng tôi mô tả nó cũng bằng cách sử dụng siêu phẳng tuyến tính.
Ba nhân được sử dụng nhiều nhất là:
Tương tự như các mô hình hồi quy tuyến tính, SVR cũng cố gắng tìm một đường cong phù hợp nhất với tập dữ liệu. Ghi nhớ phương trình của chúng tôi cho tập dữ liệu với một tính năng từ hồi quy tuyến tính:
y = w1x1 + c
Xem xét SVR cho một tập dữ liệu cũng có một tính năng, phương trình trông tương tự nhưng có xem xét lỗi.
−e≤y− (w1x1 + c) ≤e
Nhìn vào phương trình, rõ ràng là chỉ những điểm nằm ngoài vùng lỗi e mới được xem xét trong tính toán chi phí.
SVR tất nhiên cũng có thể được sử dụng cho các bộ dữ liệu phức tạp với nhiều tính năng hơn bằng cách sử dụng các thuật ngữ đặc trưng về chiều cao hơn tương tự như trong hồi quy đa thức.
Siêu phẳng là phù hợp nhất với dữ liệu khi nó trùng với số điểm tối đa có thể. Chúng ta xác định các đường biên (giá trị của e là khoảng cách từ siêu phẳng) để các điểm gần siêu phẳng nhất nằm trong các đường biên.
Hãy ghi nhớ vì lề (giữa các đường ranh giới) sẽ được dung sai, nó sẽ không được tính là sai số. Tôi đoán bạn đã có thể hình dung thuật ngữ này sẽ cho phép chúng tôi điều chỉnh mức độ phức tạp của mô hình của chúng tôi như thế nào (underfitting / overfitting).
import numpy as np from sklearn.svm import SVR import matplotlib.pyplot as plt np.random.seed(5) X = np.sort(5 * np.random.rand(40, 1), axis=0) T = np.linspace(0, 5, 5)[:, np.newaxis] y = np.sin(X).ravel() # Add noise to targets y[::5] += 1 * (0.5 - np.random.rand(8)) # Fit regression model SVR_rbf = SVR(kernel='rbf' ) SVR_lin = SVR(kernel='linear') SVR_poly = SVR(kernel='poly') y_rbf = SVR_rbf.fit(X, y).predict(X) y_lin = SVR_lin.fit(X, y).predict(X) y_poly = SVR_poly.fit(X, y).predict(X) # look at the results plt.scatter(X, y, c='k', label='data') plt.plot(X, y_rbf, c='b', label='RBF') plt.plot(X, y_lin, c='r',label='Linear') plt.plot(X, y_poly, c='g',label='Polynomial') plt.xlabel('data') plt.ylabel('outcome') plt.title('Support Vector Regression') plt.legend() plt.show()
Chúng ta đã biết cách hoạt động của thuật toán “Máy vectơ hỗ trợ (SVM)” để hồi quy. Đối với phân loại, ý tưởng thực sự gần giống nhau. Trong thực tế, SVM chủ yếu được sử dụng cho các bài toán phân loại. Tôi tin rằng bạn đã có thể hình dung tại sao…
Đối với hồi quy, chúng tôi đã đề cập rằng SVM cố gắng tìm một đường cong phù hợp nhất với tập dữ liệu và sau đó đưa ra dự đoán cho một điểm mới bằng cách sử dụng đường cong đó. Chà, có thể dễ dàng sử dụng cùng một đường cong để phân loại dữ liệu thành hai lớp khác nhau. Đối với không gian đa chiều có n chiều (nghĩa là dữ liệu có n số đặc trưng), mô hình phù hợp với một siêu mặt phẳng (còn gọi là ranh giới quyết định) phân biệt tốt nhất hai lớp. Ghi nhớ hình ảnh từ phần hồi quy nơi chúng tôi đã giải thích về hạt nhân…
Lề là khoảng cách giữa hai điểm gần nhất từ mỗi lớp, là khoảng cách từ siêu phẳng đến các điểm gần nhất (vectơ hỗ trợ). Siêu phẳng phù hợp nhất với dữ liệu, nghĩa là phân tách hai lớp tốt nhất, là siêu phẳng có biên độ lớn nhất có thể. Do đó, thuật toán SVM tìm kiếm siêu phẳng với lề lớn nhất (khoảng cách đến các điểm gần nhất).
Giống như chúng ta đã đề cập trong phần hồi quy, một số tập dữ liệu không phù hợp để được phân loại theo siêu phẳng tuyến tính… Trong trường hợp này, một lần nữa, “Kernel trick” lại giải cứu chúng ta ánh xạ ngầm dữ liệu đến các kích thước cao hơn, do đó có thể dữ liệu được phân loại bằng siêu phẳng tuyến tính. Vì chúng ta đã thảo luận về các loại Kernel và cách nó hoạt động, tôi sẽ tiếp tục với một ví dụ triển khai…
Hãy tiếp tục sử dụng bộ dữ liệu ung thư từ thư viện học scikit:
from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split X, y = load_breast_cancer(return_X_y = True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_sub = X[:, 0:2] # create a mesh to plot in x_min, x_max = X_sub[:, 0].min() - 1, X_sub[:, 0].max() + 1 y_min, y_max = X_sub[:, 1].min() - 1, X_sub[:, 1].max() + 1 h = (x_max / x_min)/100 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) #import the SVM model from sklearn import svm C = 1.0 # SVM regularization parameter svc = svm.SVC(kernel='linear').fit(X_sub, y) #play with this, change kernel to rbf plt.subplot(1, 1, 1) Z = svc.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8) plt.scatter(X_sub[:, 0], X_sub[:, 1], c=y, cmap=plt.cm.Paired) plt.scatter(X_sub[svc.support_, 0], X_sub[svc.support_, 1],c='k', cmap=plt.cm.Paired) plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.xlim(xx.min(), xx.max()) plt.title('SVC with linear kernel') plt.show()
#Create and instance of the classifier model with a linear kernel lsvm = svm.SVC(kernel="linear") #fit the model to our train split from previous example lsvm.fit(X_train,y_train) #Make predictions using the test split so we can evaluate its performance y_pred = lsvm.predict(X_test)
Hãy so sánh hiệu suất của mô hình bằng cách so sánh các dự đoán với giá trị thực từ bộ thử nghiệm…
from sklearn import metrics print("Accuracy:",metrics.accuracy_score(y_test, y_pred)) print("Precision:",metrics.precision_score(y_test, y_pred)) print("Recall:",metrics.recall_score(y_test, y_pred))
Chúng tôi đã có thể đạt được độ chính xác 95,6%, điều này rất tốt. Hãy so sánh điểm đào tạo và bài kiểm tra để kiểm tra xem có quá trang bị…
print("training set score: %f" % lsvm.score(X_train, y_train)) print("test set score: %f" % lsvm.score(X_test, y_test))
Điểm rèn luyện có vẻ nhỉnh hơn điểm thi. Có thể nói mô hình này đang được trang bị quá mức mặc dù không nhiều.
Nếu bạn thích điều này, hãy theo dõi tôi để biết thêm các hướng dẫn và khóa học máy học miễn phí!