支 持 向 量 机 { 线 性 S V M 分 类 { 硬 间 隔 分 类 软 间 隔 分 类 非 线 性 S V M 分 类 { 添 加 多 项 式 特 征 使 用 核 技 巧 添 加 相 似 特 征 ( 高 斯 径 向 基 函 数 R B F ) S V M 回 归 支持向量机 \begin{cases} 线性SVM分类\begin{cases}硬间隔分类\\软间隔分类\end{cases} \\ 非线性SVM分类\begin{cases}添加多项式特征\\使用核技巧\\添加相似特征(高斯径向基函数RBF)\end{cases} \\ SVM回归 \end{cases} 支持向量机⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧线性SVM分类{硬间隔分类软间隔分类非线性SVM分类⎩⎪⎨⎪⎧添加多项式特征使用核技巧添加相似特征(高斯径向基函数RBF)SVM回归
线性SVM分类
硬间隔分类:所有训练实例都要分类正确。
缺点:只在数据是线性可分离的时候才有效;对异常值很敏感。
软间隔分类:目标是尽可能在保持分类间隔宽阔和限制间隔违例(位于间隔之内或者在错误的一边)之间找到良好的平衡。
sklearn中的SVM类,可以通过超参数C控制这个平衡:C越小,街道越宽,间隔违例也越多。
如果SCM模型过拟合,可以降低C来进行正则化。
使用sklearn的LinearSVC分类鸢尾花:
import numpy as np
from sklearn import datasets
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
iris=datasets.load_iris()
x=iris['data'][:,(2,3)] #长度,宽度
y=(iris['target']==2).astype(np.float64)
svm_clf=Pipeline((
('scaler',StandardScaler()),
('linear_svc',LinearSVC(C=1,loss="hinge")),
))
svm_clf.fit(x,y)
svm_clf.predict([[5.5,1.7]])
输出:
array([1.])
也可以使用SVC类
把:
('linear_svc',LinearSVC(C=1,loss="hinge")),
换成:
('linear_svc',SVC(kernel='linear',C=1))
非线性SVM分类
添加多项式特征
有些数据集不是线性可分离的,处理方法之一是添加更多特征,例如多项式特征。
from sklearn.datasets import make_moons
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
polynomial_svm_clf=Pipeline((
('poly_features',PolynomialFeatures(degree=3)),
('scaler',StandardScaler()),
('svm_clf',LinearSVC(C=10,loss='hinge'))
))
polynomial_svm_clf.fit(x,y)
使用PolynomialFeatures转换器添加了3阶多项式特征,使得新的数据集线性可分。
核技巧
添加多项式特征通常简单有效,但是如果多项式太低阶,处理不了非常复杂的数据集,而高阶则会创造出大量的特征,导致模型变慢或者过拟合。
幸运的是,使用SVM时,可以使用核技巧。它产生的结果就和添加了许多多项式特征,甚至是非常高阶的多项式特征一样,但是实际上并没有真的添加,不存在数量爆炸的组合特征。
核技巧由SVC实现:
#多项式核
from sklearn.svm import SVC
poly_kernel_svm_clf=Pipeline((
('scaler',StandardScaler()),
('svm_clf',SVC(kernel='poly',degree=3,coef0=1,C=5)),
))
poly_kernel_svm_clf.fit(x,y)
以上代码使用三阶多项式内核训练SVM分类器。
添加相似特征
解决非线性问题的另一种技巧是添加相似特征。这些特征经过相似函数计算得出。相似函数可以测量每个实例与一个特定地标之间的相似度。
相似函数:高斯RBF
(1)
ϕ
γ
(
X
,
ι
)
=
e
−
γ
∣
∣
X
−
ι
∣
∣
2
\phi\gamma(X,\iota)=e^{-\gamma||X-\iota||^2}\tag{1}
ϕγ(X,ι)=e−γ∣∣X−ι∣∣2(1)
如何选择地标:在数据集里每一个实例的位置上创建一个地标。
高斯RBF核函数
#添加相似特征
rbf_kernel_svm_clf=Pipeline((
('scaler',StandardScaler()),
('svm_clf',SVC(kernel='rbf',gamma=5,C=0.001))
))
rbf_kernel_svm_clf.fit(x,y)
gamma相当于正则化参数:增加gamma值会使得相似函数宽度变窄(类似于正态分布概率密度曲线),使得每个实例的影响变小:决策边界变得不规则,开始围着单个实力绕弯。反过来,减小gamma会使相似函数变宽,每个实例影响范围增大,决策边界变得更平坦。
SVM回归:让尽可能多的实例位于分类间隔内,同时限制间隔违例(不在间隔上的实例)
from sklearn.svm import LinearSVR
svm_reg=LinearSVR(epsilon=1.5)
svm_reg.fit(x,y)
#使用二阶多项式核的SVM回归
from sklearn.svm import SVR
svm_poly_reg=SVR(kernel='poly',degree=2,C=100,epsilon=0.1)
svm_poly_reg.fit(x,y)