前言
正文
01-使用带有RBF核的非线性SVC执行二分类任务
这段代码演示了如何使用支持向量机(SVM)进行二分类,并使用 NuSVC
模型拟合一个 XOR 数据集,并可视化决策边界。
代码解释
-
数据生成:
xx, yy = np.meshgrid(np.linspace(-3, 3, 500), np.linspace(-3, 3, 500)) np.random.seed(0) X = np.random.randn(300, 2) Y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)
meshgrid
创建了一个二维网格xx
和yy
,用于绘制决策边界。np.random.randn(300, 2)
生成一个包含300个样本的二维随机数据集X
。logical_xor
创建了标签Y
,其为True
当且仅当X[:, 0] > 0
与X[:, 1] > 0
中有一个成立时。
-
模型拟合:
clf = svm.NuSVC(gamma='auto') clf.fit(X, Y)
- 使用
NuSVC
模型初始化一个支持向量机分类器,gamma='auto'
表示自动选择核函数的参数。 - 使用
fit
方法拟合模型到数据集(X, Y)
上。
- 使用
-
决策函数计算:
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape)
decision_function
计算网格上每个点的决策函数值,这些值用于绘制决策边界。np.c_[xx.ravel(), yy.ravel()]
将网格点展平并连接成二维数组,以便作为输入进行预测。Z
被重塑为与网格xx
相同的形状,以便用于绘制。
-
可视化:
plt.imshow(Z, interpolation='nearest', extent=(xx.min(), xx.max(), yy.min(), yy.max()), aspect='auto', origin='lower', cmap=plt.cm.PuOr_r) contours = plt.contour(xx, yy, Z, levels=[0], linewidths=2, linestyles='dashed') plt.scatter(X[:, 0], X[:, 1], s=30, c=Y, cmap=plt.cm.Paired, edgecolors='k') plt.xticks(()) plt.yticks(()) plt.axis([-3, 3, -3, 3]) plt.show()
imshow
显示决策函数Z
的值作为背景色彩图,extent
确定显示范围,cmap
为颜色映射。contour
绘制决策边界,使用levels=[0]
表示绘制决策函数为0的等高线。scatter
绘制样本数据点X
,根据标签Y
的不同类别使用不同的颜色。- 其他绘图设置用于美化图像和删除坐标轴标签。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
xx, yy = np.meshgrid(np.linspace(-3, 3, 500),
np.linspace(-3, 3, 500))
np.random.seed(0)
X = np.random.randn(300, 2)
Y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)
#(译者注:可以在这里通过显示Y来查看什么是XOR数据)
# 拟合模型
clf = svm.NuSVC(gamma='auto')
clf.fit(X, Y)
# 在网格上为每个数据点绘制决策函数
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.imshow(Z, interpolation='nearest',
extent=(xx.min(), xx.max(), yy.min(), yy.max()), aspect='auto',
origin='lower', cmap=plt.cm.PuOr_r)
contours = plt.contour(xx, yy, Z, levels=[0], linewidths=2,
linestyles='dashed')
plt.scatter(X[:, 0], X[:, 1], s=30, c=Y, cmap=plt.cm.Paired,
edgecolors='k')
plt.xticks(())
plt.yticks(())
plt.axis([-3, 3, -3, 3])
plt.savefig("../5.png", dpi=500)
plt.show()
结果如下图所示:
图像显示了使用非线性 SVM(使用 RBF 核)在 XOR 数据集上学习的决策边界。这个数据集在原始空间中是线性不可分的,但在高维特征空间中可能是线性可分的。关键点包括:
- 背景色彩图:显示了决策函数的值,越接近0的区域表示决策边界附近。
- 虚线等高线:标记了决策函数为0的等高线,即决策边界。
- 散点图:显示了原始数据点,根据其标签用不同颜色表示不同类别。
这种图像演示了 SVM 如何利用 RBF 核处理非线性问题,并展示了如何在二维空间中绘制决策边界和样本点。
02-支持向量机:最大边际分割超平面
这段代码演示了如何使用支持向量机(SVM)进行二分类,并在二维空间中绘制决策边界、支持向量以及间隔。让我们逐步解释和分析代码:
代码解释
-
生成数据集:
X, y = make_blobs(n_samples=40, centers=2, random_state=6)
- 使用
make_blobs
生成一个包含40个样本的二维数据集X
,每个样本属于两个中心之一,由centers=2
指定,random_state
用于复现结果。
- 使用
-
模型拟合:
clf = svm.SVC(kernel='linear', C=1000) clf.fit(X, y)
- 使用
SVC
初始化一个线性核的支持向量机分类器,C=1000
表示正则化参数的倒数,控制间隔的硬度。 - 使用
fit
方法将模型拟合到数据集(X, y)
上。
- 使用
-
绘制数据点:
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
- 使用
scatter
绘制数据点X
,不同的类别用不同的颜色标识,颜色映射为Paired
。
- 使用
-
绘制决策函数结果:
ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim() xx = np.linspace(xlim[0], xlim[1], 30) yy = np.linspace(ylim[0], ylim[1], 30) YY, XX = np.meshgrid(yy, xx) xy = np.vstack([XX.ravel(), YY.ravel()]).T Z = clf.decision_function(xy).reshape(XX.shape) ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
- 获取当前图形对象
ax
并获取当前的 x 和 y 轴限制。 - 创建一个网格
xx
和yy
,并用meshgrid
将它们组合成XX
,YY
。 decision_function
计算网格上每个点的决策函数值,并将结果绘制为等高线contour
。levels=[-1, 0, 1]
表示绘制决策函数为-1
,0
,1
的等高线,分别对应于间隔的边界和决策边界。
- 获取当前图形对象
-
绘制支持向量:
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100, linewidth=1, facecolors='none', edgecolors='k')
- 使用
scatter
绘制支持向量,这些向量是决策边界上最靠近数据点的样本。 clf.support_vectors_
包含支持向量的坐标,s=100
控制支持向量的大小,facecolors='none'
表示使用空心圆点,edgecolors='k'
表示边框颜色为黑色。
- 使用
-
保存和显示图像:
plt.savefig("../5.png", dpi=500) plt.show()
- 使用
savefig
保存图像为5.png
,分辨率为500
dpi。 plt.show()
显示生成的图像。
- 使用
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs
# 我们创建40个用来分割的数据点
X, y = make_blobs(n_samples=40, centers=2, random_state=6)
# 拟合模型,并且为了展示作用,并不进行标准化
clf = svm.SVC(kernel='linear', C=1000)
clf.fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
# 绘制decision function的结果
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# 创造网格来评估模型
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# 绘制决策边界和边际
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
# 绘制支持向量
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k')
plt.savefig("../5.png", dpi=500)
plt.show()
这幅图展示了线性核支持向量机在二维空间中的工作效果:
- 散点图:显示了生成的二维数据集,每个类别用不同颜色表示。
- 等高线:展示了决策函数的值,黑色虚线表示决策边界,而实线则表示间隔的边界。
- 支持向量:用大圆圈表示的支持向量,它们是决策边界上距离最近的数据点。
03-带有自定义核函数的支持向量机
这段代码演示了如何使用带有自定义核函数的支持向量机(SVM)对鸢尾花数据集进行分类,并绘制分类结果的决策边界。
代码解释
-
导入库和数据集
import numpy as np import matplotlib.pyplot as plt from sklearn import svm, datasets
这里导入了需要使用的库,包括NumPy用于数据处理,Matplotlib用于绘图,以及sklearn中的svm和datasets模块。
-
加载数据
iris = datasets.load_iris() X = iris.data[:, :2] # 仅使用前两个特征,这里使用了切片操作 Y = iris.target
从鸢尾花数据集中加载数据,仅使用前两个特征(萼片长度和宽度),目标变量为类别标签。
-
定义自定义核函数
def my_kernel(X, Y): """ 我们创建一个自定义的核函数: (2 0) k(X, Y) = X ( ) Y.T (0 1) """ M = np.array([[2, 0], [0, 1.0]]) return np.dot(np.dot(X, M), Y.T)
这里定义了一个简单的自定义核函数,它是一个线性核函数的变体,通过矩阵M对输入数据进行线性变换。
-
创建SVM实例并拟合数据
clf = svm.SVC(kernel=my_kernel) clf.fit(X, Y)
使用
svm.SVC
创建了一个支持向量机实例,指定了自定义核函数my_kernel
,并对数据进行拟合。 -
生成网格并预测
h = .02 # 设置网格中的步长 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, h), np.arange(y_min, y_max, h)) Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
创建了一个网格来覆盖输入空间的范围,并使用训练好的SVM模型对每个网格点进行分类预测。
-
绘制决策边界和数据点
Z = Z.reshape(xx.shape) plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Paired) # 绘制训练点 plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired, edgecolors='k')
使用
pcolormesh
绘制网格中每个点的预测结果,使用scatter
绘制原始数据点,其中不同颜色表示不同的类别。 -
图像设置和显示
plt.title('3-Class classification using Support Vector Machine with custom kernel') plt.axis('tight') plt.show()
设置标题和坐标轴,然后显示绘制的图像。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
# 导入数据以便处理
iris = datasets.load_iris()
X = iris.data[:, :2]
# 我们仅仅使用前两个特征,我们可以通过使用二维数据集来避免复杂的切片
Y = iris.target
def my_kernel(X, Y):
"""
我们创建一个自定义的核函数:
(2 0)
k(X, Y) = X ( ) Y.T
(0 1)
"""
M = np.array([[2, 0], [0, 1.0]])
return np.dot(np.dot(X, M), Y.T)
h = .02 # 设置网格中的步长
# 我们创建一个SVM实例并拟合数据。
clf = svm.SVC(kernel=my_kernel)
clf.fit(X, Y)
# 绘制决策边界。为此,我们将为网格[x_min,x_max] x [y_min,y_max]中的每个点分配颜色。
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, h), np.arange(y_min, y_max, h))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
# 将结果放入颜色图
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Paired)
# 绘制训练点
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired, edgecolors='k')
plt.title('3-Class classification using Support Vector Machine with custom'
' kernel')
plt.axis('tight')
plt.savefig("../5.png", dpi=500)
plt.show()
-
背景色块和决策边界:
- 背景色块通过颜色区分了不同类别的预测区域,每个颜色块表示SVM预测该区域内的所有点属于同一类别。
- 决策边界是分类器在特征空间中的决策界限,分隔不同类别的区域。
-
数据点:
- 数据点在图中以散点的形式显示,每种类别使用不同的颜色表示,有助于可视化各个类别在特征空间中的分布。
这样,通过自定义核函数,支持向量机能够有效地处理非线性问题,并提供清晰的分类决策边界。
04-绘制线性支持向量机(基于liblinear)的支持向量
这段代码演示了如何使用Scikit-Learn的LinearSVC绘制线性支持向量机(Linear SVM)的决策边界和支持向量。
代码解释
-
数据生成与初始化模型
X, y = make_blobs(n_samples=40, centers=2, random_state=0)
- 使用
make_blobs
生成一个二分类的数据集,共40个样本,用于模拟实际数据。
- 使用
-
模型训练与决策边界绘制
for i, C in enumerate([1, 100]): clf = LinearSVC(C=C, loss="hinge", random_state=42).fit(X, y) decision_function = clf.decision_function(X) support_vector_indices = np.where((2 * y - 1) * decision_function <= 1)[0] support_vectors = X[support_vector_indices]
- 对每个参数C(正则化参数)分别训练一个LinearSVC模型。
loss="hinge"
指定了线性SVM所使用的损失函数。 decision_function
计算决策函数的值,支持向量的索引通过条件(2 * y - 1) * decision_function <= 1
确定。- 支持向量通过这些索引从数据集X中获取。
- 对每个参数C(正则化参数)分别训练一个LinearSVC模型。
-
绘制图像
plt.subplot(1, 2, i + 1) plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired) ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim() xx, yy = np.meshgrid(np.linspace(xlim[0], xlim[1], 50), np.linspace(ylim[0], ylim[1], 50)) Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contour(xx, yy, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--']) plt.scatter(support_vectors[:, 0], support_vectors[:, 1], s=100, linewidth=1, facecolors='none', edgecolors='k') plt.title("C=" + str(C))
- 使用
subplot
在一行两列中创建子图,分别展示不同参数C的结果。 - 通过
scatter
方法绘制所有数据点,根据类别用不同颜色标示。 - 使用
contour
函数绘制决策边界,其中levels=[-1, 0, 1]
绘制了决策函数为-1、0、1的等高线,代表不同的决策边界。 - 通过
scatter
绘制支持向量,使用大圆圈表示,以突出显示它们。
- 使用
-
图像属性设置与展示
plt.tight_layout() plt.savefig("../5.png", dpi=500) plt.show()
- 使用
tight_layout
确保图像布局合适。 savefig
保存图像为高分辨率PNG格式。show
展示生成的图像。
- 使用
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.svm import LinearSVC
X, y = make_blobs(n_samples=40, centers=2, random_state=0)
plt.figure(figsize=(10, 5))
for i, C in enumerate([1, 100]):
# "hinge"是支持向量机惯例使用的损失函数
clf = LinearSVC(C=C, loss="hinge", random_state=42).fit(X, y)
# 通过决策函数获得支持向量
decision_function = clf.decision_function(X)
# 我们也可以手动计算决策函数
# decision_function = np.dot(X, clf.coef_[0]) + clf.intercept_[0]
support_vector_indices = np.where((2 * y - 1) * decision_function <= 1)[0]
support_vectors = X[support_vector_indices]
plt.subplot(1, 2, i + 1)
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx, yy = np.meshgrid(np.linspace(xlim[0], xlim[1], 50),
np.linspace(ylim[0], ylim[1], 50))
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
plt.scatter(support_vectors[:, 0], support_vectors[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k')
plt.title("C=" + str(C))
plt.tight_layout()
plt.savefig("../5.png", dpi=500)
plt.show()
- 左图(C=1):较小的正则化参数C,决策边界可以更接近一些数据点,支持向量的数量较多。
- 右图(C=100):较大的正则化参数C,决策边界更严格,支持向量的数量较少。
在每幅图中,数据点用不同颜色表示不同的类别,决策边界用黑色实线(0值)、虚线(-1和1值)表示,支持向量用大圆圈标出。这种可视化方式清晰地展示了线性支持向量机在不同正则化参数下的决策边界和支持向量位置。