相关视频讲解地址:https://www.bilibili.com/video/av50785769/
数据及源码地址:https://download.csdn.net/download/yiyongzhifu/11150357
支持向量机有两种:SVC,支持向量分类,用于分类问题;SVR,支持向量回归,用于回归问题。
%pylab inline
import numpy as np
import pylab as pl
from sklearn import svm
我们采用一个非常有名的用于分类问题的数据集:鸢尾花数据集。它是基于鸢尾花的花萼的长度和宽度进行分类的。我们只用其中两维特征,这能够方便可视化。
svc = svm.SVC(kernel='linear')
# 鸢尾花数据集是sklearn自带的。
from sklearn import datasets
iris = datasets.load_iris()
# 只提取前面两列数据作为特征
X = iris.data[:, :2]
y = iris.target
# 基于这些数据训练出一个支持向量分离器SVC
svc.fit(X, y)
输出
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
kernel='linear', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
可视化结果
from matplotlib.colors import ListedColormap
# 因为鸢尾花是3分类问题,我们要对样本和预测结果均用三种颜色区分开。
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])
def plot_estimator(estimator, X, y):
'''
这个函数的作用是基于分类器,对预测结果与原始标签进行可视化。
'''
estimator.fit(X, y)
# 确定网格最大最小值作为边界
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.linspace(x_min, x_max, 100),
np.linspace(y_min, y_max, 100))
# 基于分离器,对网格节点做预测
Z = estimator.predict(np.c_[xx.ravel(), yy.ravel()])
# 对预测结果上色
Z = Z.reshape(xx.shape)
pl.figure()
pl.pcolormesh(xx, yy, Z, cmap=cmap_light)
# 同时对原始训练样本上色
pl.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold)
pl.axis('tight')
pl.axis('off')
pl.tight_layout()
plot_estimator(svc, X, y)
kernel="linear"
(线性核函数)给了我们线性的决策边界:两类之间的分离边界是直线。LinearSVC
,它使用了不同的算法。在某些数据集上运行地更快(比如稀疏数据集,文本挖掘就是典型的例子)。它对于多分类采用的是"one versus all"策略。
plot_estimator(svm.LinearSVC(), X, y)
support_vectors_
来找到。我们在图中将对它们着重标记
X, y = X[np.in1d(y, [1, 2])], y[np.in1d(y, [1, 2])]
plot_estimator(svc, X, y)
pl.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=80, facecolors='none', zorder=10)
svc = svm.SVC(kernel='linear', C=1e3)
plot_estimator(svc, X, y)
pl.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=80, facecolors='none', zorder=10)
pl.title('High C values: small number of support vectors')
svc = svm.SVC(kernel='linear', C=1e-3)
plot_estimator(svc, X, y)
pl.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=80, facecolors='none', zorder=10)
pl.title('Low C values: high number of support vectors')
采用核方法,能够很方便地产生非线性分类边界。
svc = svm.SVC(kernel='linear')
plot_estimator(svc, X, y)
pl.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=80, facecolors='none', zorder=10)
pl.title('Linear kernel')
svc = svm.SVC(kernel='poly', degree=4)
plot_estimator(svc, X, y)
pl.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=80, facecolors='none', zorder=10)
pl.title('Polynomial kernel')
svc = svm.SVC(kernel='rbf', gamma=1e2)
plot_estimator(svc, X, y)
pl.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=80, facecolors='none', zorder=10)
pl.title('RBF kernel')
我们可以看到,高斯核更灵活,而且对于训练数据效果是最好的。但是要担心过拟合。