线性SVM模型
线性支持向量机(SVM)是一种用于分类任务的监督学习模型。线性 SVM 通过寻找一个超平面来最大化数据点间的间隔,从而实现数据的分类。线性 SVM 特别适合处理高维数据和二分类问题。以下是对线性 SVM 模型的介绍及其在 Python 中的实现。
线性 SVM 的基本概念
1.超平面(Hyperplane): 在 n 维空间中,超平面是一个 n-1 维的平面,用于分割不同类别的数据点。在二维空间中,超平面是一条线;在三维空间中,超平面是一个平面。
2.间隔(Margin): 超平面到最近数据点的距离。线性 SVM 通过最大化这个间隔来实现数据的分类。
3.支持向量(Support Vectors): 离超平面最近的那些数据点。这些点决定了超平面的位置和方向。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
# from sklearn.svm import LinearSVR
import warnings
with warnings.catch_warnings():
warnings.simplefilter("ignore")
导入数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y<2,:2]
y = y[y<2]
plt.scatter(X[y==0,0], X[y==0,1], color='red')
plt.scatter(X[y==1,0], X[y==1,1], color='blue')
plt.show()
归一化
standardScaler = StandardScaler()
standardScaler.fit(X)
X_standard = standardScaler.transform(X)
导入模型训练评估并可视化边界
硬间隔的效果
svc=LinearSVC(C=1e9) #软间隔,C正则化参数,C越大,要求越严格,越接近于hard margin
svc.fit(X_standard, y)
def plot_decisionboundary(model, X):
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
predict = model.predict(np.c_[xx.ravel(), yy.ravel()])
predict = predict.reshape(xx.shape)
from matplotlib.colors import ListedColormap
plt.contourf(xx, yy, predict, cmap=ListedColormap(['#CCCCFF', '#EF9A9A', '#90CAF9']))
plot_decisionboundary(svc, X_standard)
plt.scatter(X_standard[y==0, 0], X_standard[y==0, 1], color='r')
plt.scatter(X_standard[y==1, 0], X_standard[y==1, 1], color='b')
plt.show()
def plot_decisionboundary_margin(model, X):
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
predict = model.predict(np.c_[xx.ravel(), yy.ravel()])
predict = predict.reshape(xx.shape)
from matplotlib.colors import ListedColormap
plt.contourf(xx, yy, predict, cmap=ListedColormap(['#CCCCFF', '#EF9A9A', '#90CAF9']))
w = model.coef_[0]
b = model.intercept_[0]
# w0*x0 + w1*x1 + b = 0
# => x1 = -w0/w1 * x0 - b/w1
plot_x = np.linspace(x_min, x_max, 200)
up_y = -w[0]/w[1] * plot_x - b/w[1] + 1/w[1]
down_y = -w[0]/w[1] * plot_x - b/w[1] - 1/w[1]
up_index = (up_y >= y_min) & (up_y <= y_max)
down_index = (down_y >= y_min) * (down_y <= y_max)
plt.plot(plot_x[up_index], up_y[up_index], color='black')
plt.plot(plot_x[down_index], down_y[down_index], color='black')
plot_decisionboundary_margin(svc, X_standard)
plt.scatter(X_standard[y==0, 0], X_standard[y==0, 1], color='r')
plt.scatter(X_standard[y==1, 0], X_standard[y==1, 1], color='b')
plt.show()
软间隔的效果
svc2 = LinearSVC(C=1) #C越小,容错能力越大,soft margin
svc2.fit(X_standard, y)
plot_decisionboundary_margin(svc2, X_standard)
plt.scatter(X_standard[y==0, 0], X_standard[y==0, 1], color='r')
plt.scatter(X_standard[y==1, 0], X_standard[y==1, 1], color='b')
plt.show()