1 二分类SVC的进阶
1.1 SVC用于二分类的原理复习
在上周的支持向量SVM(上)中,我们学习了二分类SVC的所有基本知识,包括SVM的原理,二分类SVC的损失函数,拉格朗日函数,拉格朗日对偶函数,预测函数以及这些函数在非线性,软间隔这些情况上的推广,并且引出了核函数这个关键概念。今天,基于我们已经学过的理论,我们继续探索支持向量机的其他性质,并在真实数据集上运用SVM。
开始今天的探索之前,我们先来简单回忆一下支持向量机是如何工作的。
平行于决策边界的两条虚线是距离决策边界相对距离为1的超平面,他们分别压过两类样本中距离决策边界最近的样本点,这些样本点就被成为支持向量。两条虚线超平面之间的距离叫做边际,简写为。支持向量机分类器,就是以找出最大化的边际d为目标来求解损失函数,以求解出参数和,以构建决策边界,然后用决策边界来分类的分类器。
1.2 参数C的理解进阶
有一些数据,可能是线性可分,但在线性可分状况下训练准确率不能达到100%,即无法让训练误差为0,这样的数据被我们称为“存在软间隔的数据”。此时此刻,我们需要让我们决策边界能够忍受一小部分训练误差,我们就不能单纯地寻求最大边际了。
因为对于软间隔地数据来说,边际越大被分错的样本也就会越多,因此我们需要找出一个”最大边际“与”被分错的样本数量“之间的平衡。因此,我们引入松弛系数和松弛系数的系数C作为一个惩罚项,来惩罚我们对最大边际的追求。
C就惩罚项
那我们的参数C如何影响我们的决策边界呢?在硬间隔的时候,我们的决策边界完全由两个支持向量和最小化损失函数(最大化边际)来决定,而我们的支持向量是两个标签类别不一致的点,即分别是正样本和负样本。然而在软间隔情况下我们的边际依然由支持向量决定,但此时此刻的支持向量可能就不再是来自两种标签类别的点了,而是分布在决策边界两边的,同类别的点。
此时此刻,所有可能影响我们的超平面的样本可能都会被定义为支持向量,所以支持向量就不再是所有压在虚线超平面上的点,而是所有可能影响我们的超平面的位置的那些混杂在彼此的类别中的点了。观察一下我们对不同数据集分类时,支持向量都有哪些?软间隔如何影响了超平面和支持向量,就一目了然了。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import svm
from sklearn.datasets import make_circles, make_moons, make_blobs,make_classification
n_samples = 100
datasets = [
make_moons(n_samples=n_samples, noise=0.2, random_state=0),
make_circles(n_samples=n_samples, noise=0.2, factor=0.5, random_state=1),
make_blobs(n_samples=n_samples, centers=2, random_state=5),
make_classification(n_samples=n_samples,n_features =
2,n_informative=2,n_redundant=0, random_state=5)
]
Kernel = ["linear"]
#四个数据集分别是什么样子呢?
for X,Y in datasets:
plt.figure(figsize=(5,4))
plt.scatter(X[:,0],X[:,1],c=Y,s=50,cmap="rainbow")
nrows=len(datasets)
ncols=len(Kernel) + 1
fig, axes = plt.subplots(nrows, ncols,figsize=(10,16))
#第一层循环:在不同的数据集中循环
for ds_cnt, (X,Y) in enumerate(datasets):
ax = axes[ds_cnt, 0]
if ds_cnt == 0:
ax.set_title("Input data")
ax.scatter(X[:, 0], X[:, 1], c=Y, zorder=10, cmap=plt.cm.Paired,edgecolors='k')
ax.set_xticks(())
ax.set_yticks(())
for est_idx, kernel in enumerate(Kernel):
ax = axes[ds_cnt, est_idx + 1]
clf = svm.SVC(kernel=kernel, gamma=2).fit(X, Y)
score = clf.score(X, Y)
ax.scatter(X[:, 0], X[:, 1], c=Y
,zorder=10
,cmap=plt.cm.Paired,edgecolors='k')
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
facecolors='none', zorder=10, edgecolors='white')
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j]
Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()]).reshape(XX.shape)
ax.pcolormesh(XX, YY, Z > 0, cmap=plt.cm.Paired)
ax.contour(XX, YY, Z, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'],
levels=[-1, 0, 1])
ax.set_xticks(())
ax.set_yticks(())
if ds_cnt == 0:
ax.set_title(kernel)
ax.text(0.95, 0.06, ('%.2f' % score).lstrip('0')
, size=15
, bbox=dict(boxstyle='round', alpha=0.8, facecolor='white')
#为分数添加一个白色的格子作为底色
, transform=ax.transAxes #确定文字所对应的坐标轴,就是ax子图的坐标轴本身
, horizontalalignment='right' #位于坐标轴的什么方向
)
plt.tight_layout()
plt.show()