支持向量机并不关心数据的概率,而是基于判别式找到最优的超平面作为二分类问题的决策边界。简单来说就是能走直线就别兜弯子。
不要引入更复杂的问题为解决当前问题的中间步骤。——弗拉基米尔·瓦普尼克(SVM发明者)
在SVM中,估算数据的概率分布就是那个作为中间步骤的复杂问题。SVM是基于几何意义的非线性二分类器。
最小间距超平面:所有样本到平面的距离最小
。那么问题来了,这中间的超平面有无数个,如何确定这个超平面呢?于是我们可以约束这个超平面到两个最近的点的距离是一样的。
上图中两个红色菱形点与一个蓝色实心圆点就是支持向量。
通过这个求解目标,以及约束条件来求解这个超平面。
通过一个例子来看看:
这里例子中有 w 1 , w 2 w_1,w_2 w1,w2,这是因为坐标点是二维的,相当于样本特征是两个,分类的结果是这两个特征的结果标签,所以这里的 w w w就是一个二维的,说明在具体的应用里需要根据特征来确定 w w w的维度。
原始问题是这样的:
max w , b γ s . t . y i ( w ∣ ∣ w ∣ ∣ x i + b ∣ ∣ w ∣ ∣ ) > γ \max \limits_{w,b} \quad \gamma \\ s.t. \quad y_i(\frac{w}{||w||}x_i+\frac{b}{||w||}) > \gamma w,bmaxγs.t.yi(∣∣w∣∣wxi+∣∣w∣∣b)>γ
利用几何距离与函数距离的关系 γ = γ ^ ∣ ∣ w ∣ ∣ \gamma = \frac{\hat{ \gamma}}{||w||} γ=∣∣w∣∣γ^将公式改为:
max w , b γ ^ ∣ ∣ w ∣ ∣ s . t . y i ( w x i + b ) > γ ^ \max \limits_{w,b} \quad \frac{\hat{ \gamma}}{||w||} \\ s.t. \quad y_i(wx_i+b) > \hat{\gamma} w,bmax∣∣w∣∣γ^s.t.yi(wxi+b)>γ^
函数间隔会随着 w 与 b w与b w与b的变化而变化,同时将 w 与 b w与b w与b变成 λ w 与 λ b \lambda w与\lambda b λw与λb,则函数间隔也会变成 λ γ \lambda \gamma λγ,所以书中直接将 γ = 1 \gamma=1 γ=1来转换问题。同样的问题又改为:
max w , b 1 ∣ ∣ w ∣ ∣ s . t . y i ( w x i + b ) > 1 \max \limits_{w,b} \quad \frac{1}{||w||} \\ s.t. \quad y_i(wx_i+b) >1 w,bmax∣∣w∣∣1s.t.yi(wxi+b)>1
求解最大值改为另一个问题,求解最小值:
min 1 2 ∣ ∣ w ∣ ∣ 2 s . t . y i ( w x i + b ) > 1 \min \quad \frac{1}{2} ||w||^2 \\ s.t. \quad y_i(wx_i+b) >1 min21∣∣w∣∣2s.t.yi(wxi+b)>1
这就是一个对偶问题的例子,也是书中支持向量机模型的一个目标函数转换的过程。
对偶问题将原问题转化为凸优化问题,便于求解。
硬间隔是方便用来分隔线性可分的数据,如果样本中的数据是线性不可分的呢?也就是如图所示:
有一部分红色点在绿色点那边,绿色点也有一部分在红色点那边,无法找到一条直线能把两种颜色的点完全区分开,所以就不满足上述的约束条件: s . t . y i ( x i + b ) > 1 s.t. \quad y_i(x_i+b) >1 s.t.yi(xi+b)>1,
软间隔的最基本含义同硬间隔比较区别在于允许某些样本点不满足原约束
,从直观上来说,也就是“包容”了那些不满足原约束的点
。软间隔对约束条件进行改造,迫使某些不满足约束条件的点作为损失函数,如图所示:
这里要区别非线性情况,非线性的意思就是一个圆圈,圆圈里是一个分类结果,圆圈外是一个分类结果。这就是非线性的情况
。
其中当样本点不满足约束条件时,损失是有的,但是满足条件的样本都会被置为0,这是因为加入了转换函数,使得求解 m i n min min的条件会专注在不符合条件的样本节点上。
引入松弛变量,使得一部分异常数据也可以满足约束条件: y i ( x i + b ) > = 1 − ε i y_i(x_i+b) >=1 - \varepsilon_i yi(xi+b)>=1−εi,既然约束条件引入了松弛变量,那么点到超平面的距离也要改变,于是调整为:
min 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i N ε i s . t . y i ( x i + b ) ≥ 1 − ε i i=1,2...,n ε i ≥ 0 \min \quad \frac{1}{2} ||w||^2+C\sum_{i}^{N}\varepsilon_i \\ s.t. \quad y_i(x_i+b) \ge 1 - \varepsilon_i \qquad \text{i=1,2...,n}\\ \varepsilon_i \ge 0 min21∣∣w∣∣2+Ci∑Nεis.t.yi(xi+b)≥1−εii=1,2...,nεi≥0
这也是一个凸二次规划问题,可以求解得到 w w w,但 b b b的求解是一个区间范围,求解过程如下:
直接得到拉格朗日对偶问题:
max a i > 0 , μ > 0 min w i , b , ε L ( w , b , ε , a , μ ) = 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i N ε i + ∑ i = 1 N a i [ 1 − y i ( w x i + b ) + ε i ] + ∑ i N μ i ε i \max_{a_i>0,\mu>0} \min_{w_i,b,\varepsilon} \quad L(w,b,\varepsilon,a,\mu)= \frac{1}{2} ||w||^2+C\sum_{i}^{N}\varepsilon_i+\sum_{i=1}^{N}a_{i}[1-y_i(wx_i+b)+\varepsilon_i]+\sum_{i}^{N} \mu_i \varepsilon_i ai>0,μ>0maxwi,b,εminL(w,b,ε,a,μ)=21∣∣w∣∣2+Ci∑Nεi+i=1∑Nai[1−yi(wxi+b)+εi]+i∑Nμiεi
继续按照流程走:
max a i > 0 , μ > 0 L ( w , b , ε , a , μ ) = − 1 2 ∑ i ∑ j a i a j y i y j ( x i ∗ x j ) + ∑ i a i s . t . ∑ i N a i y i = 0 0 ≤ a i ≤ C \max_{a_i>0,\mu>0} \quad L(w,b,\varepsilon,a,\mu) = -\frac{1}{2}\sum_{i} \sum_{j}a_{i}a_{j}y_{i}y_{j}(x_i * x_j) + \sum_{i}a_i \\ s.t. \quad \sum_{i}^{N}a_iy_i=0 \\ \quad 0\le a_i\le C ai>0,μ>0maxL(w,b,ε,a,μ)=−21i∑j∑aiajyiyj(xi∗xj)+i∑ais.t.i∑Naiyi=00≤ai≤C
去掉符号,将 m a x max max转换为 m i n min min:
min a i > 0 , μ > 0 L ( w , b , ε , a , μ ) = 1 2 ∑ i ∑ j a i a j y i y j ( x i ∗ x j ) − ∑ i a i s . t . ∑ i N a i y i = 0 0 ≤ a i ≤ C \min_{a_i>0,\mu>0} \quad L(w,b,\varepsilon,a,\mu) = \frac{1}{2}\sum_{i} \sum_{j}a_{i}a_{j}y_{i}y_{j}(x_i * x_j) - \sum_{i}a_i \\ s.t. \quad \sum_{i}^{N}a_iy_i=0 \\ \quad 0\le a_i\le C ai>0,μ>0minL(w,b,ε,a,μ)=21i∑j∑aiajyiyj(xi∗xj)−i∑ais.t.i∑Naiyi=00≤ai≤C
这里代入之后就只有一个因子 a i a_i ai,对此方程求解 a i a_i ai
w 、 b w、b w、b:
w = ∑ i a i y i x i w = \sum_{i}a_iy_ix_i \\ w=i∑aiyixi
b b b的计算就需要思考了,选取满足 0 ≤ a i ≤ C \quad 0\le a_i\le C 0≤ai≤C 的 a i a_i ai,利用这些点来求解 b b b:
b = y j − ∑ i a i y i ( x i ∗ x j ) b = y_j-\sum_{i}a_iy_i(x_i*x_j) b=yj−i∑aiyi(xi∗xj)
当然符合这个条件的也不只有一个,存在多个条件。求解平均值作为一个唯一值。
超平面
y = w x + b y = wx+b y=wx+b
和硬间隔最大化的线性可分SVM相比,多了一个约束条件: 0 ≤ a i ≤ C 0\le a_i \le C 0≤ai≤C。
这里思考一个问题:既然是线性不可分,难道最后求出来的支持向量就不是直线?某种意义上的直线?
其实还是直线,不满足条件的节点也被错误的分配了,只是尽可能的求解最大间隔。
引入核函数可以解决非线性的情况:将样本从原始空间映射到一个更高为的特征空间,使得样本在这个特征空间内线性可分。
最理想的情况下,我们希望知道数据的具体形状和分布,从而得到一个刚好可以将数据映射成线性可分的 ϕ ( ⋅ ) ϕ(⋅) ϕ(⋅),然后通过这个 ϕ ( ⋅ ) ϕ(⋅) ϕ(⋅)得出对应的 κ ( ⋅ , ⋅ ) κ(⋅,⋅) κ(⋅,⋅)进行内积计算。然而,第二步通常是非常困难甚至完全没法做的。不过,由于第一步也是几乎无法做到,因为对于任意的数据分析其形状找到合适的映射本身就不是什么容易的事情,所以,人们通常都是“胡乱”选择映射的,所以,根本没有必要精确地找出对应于映射的那个核函数,而只需要“胡乱”选择一个核函数即可——我们知道它对应了某个映射,虽然我们不知道这个映射具体是什么。由于我们的计算只需要核函数即可,所以我们也并不关心也没有必要求出所对应的映射的具体形式。
其实还有很多核函数,在参考博客里大家都可以看到这些核函数,对于核函数如何选择的问题,吴恩达教授是这么说的:
思想:通过观察SVM的优化目标我们可以发现其最终的目的是要计算出一组最优的 α \alpha α和常数项 b b b的值。SMO算法的中心思想就是每次选出两个 α \alpha α进行优化(之所以是两个是因为 α \alpha α的约束条件决定了其与标签乘积的累加等于0,因此必须一次同时优化两个,否则就会破坏约束条件),然后固定其他的 α \alpha α值。重复此过程,直到达到某个终止条件程序退出并得到我们需要的优化结果。
具体求解可以参考https://www.jianshu.com/p/eef51f939ace
from sklearn import svm
from sklearn.svm import SVC
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
def plot_point2(dataArr, labelArr, Support_vector_index):
for i in range(np.shape(dataArr)[0]):
if labelArr[i] == 0:
plt.scatter(dataArr[i][0], dataArr[i][1], c='b', s=20)
elif labelArr[i] == 1:
plt.scatter(dataArr[i][0], dataArr[i][1], c='y', s=20)
else:
plt.scatter(dataArr[i][0], dataArr[i][1], c='g', s=20)
for j in Support_vector_index:
plt.scatter(dataArr[j][0], dataArr[j][1], s=100, c='',alpha=0.5, linewidth=1.5, edgecolor='red')
plt.show()
if __name__ == "__main__":
iris = load_iris()
x, y = iris.data, iris.target
x = x[:, :2]
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=0)
clf = SVC(C=1, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma=0.1, kernel='linear', max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False)
clf.fit(X_train, y_train)
predict_list = clf.predict(X_test)
precition = clf.score(X_test, y_test)
print("preciton is : ", precition * 100, "%")
n_Support_vector = clf.n_support_
print("vector num is : ", n_Support_vector)
Support_vector_index = clf.support_
x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1
y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1
h = 0.02
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.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plot_point2(x, y, Support_vector_index)
统计学习基础
支持向量机SVM:原理讲解+手写公式推导+疑惑分析
支持向量机 - 软间隔最大化
使用SVM对鸢尾花数据集进行分类