用我自己话说,就是一种二分类器,分类方式是画一个平面,这个平面到两边最近点点距离最大。看看下图来了解一下(图来自网络):
这两条线都能划分清楚,但是要选一个最优的,评判标准是什么?间距越大越优秀,容错率越小嘛,就像就开车走马路中间最安全。
所以选择下面一条:
w ⋅ x + b = 0 , w ∈ R m , b ∈ R w·x+b=0 , w\in R^m,b\in R w⋅x+b=0,w∈Rm,b∈R
这个公式怎么来的,有一个退到过程,这里引用一个别人的《推导过程》,通过让w取最小值来获得最优超平面
约束条件是什么?这个需要进一步探讨……
用拉格朗日方法求解。其中, α i ⩾ 0 \alpha_i \geqslant0 αi⩾0为每一个样本的拉氏乘子 ,由L分别对b和w导数为0.可以导出: ∑ i = 1 m α i y i = 0 w = ∑ i = 1 m α i y i x i \sum\limits_{i=1}^{m}\alpha_iy_i=0 \quad w=\sum\limits_{i=1}^{m}\alpha_iy_ix_i i=1∑mαiyi=0w=i=1∑mαiyixi
我们知道对于线性不可分的样本点需要映射到高维空间,用 x 表示原来的样本点,用 φ(x)表示 x 映射到特征新的特征空间后到新向量。那么分割超平面可以表示为:
f ( x ) = w ϕ ( x ) + b f(x)=w\phi(x)+b f(x)=wϕ(x)+b
就是把低维度的 ( x i ⋅ y j ) (x_i·y_j) (xi⋅yj)变成了高维度的 ( ϕ ( x i ) ⋅ ϕ ( y j ) ) (\phi(x_i)·\phi(y_j)) (ϕ(xi)⋅ϕ(yj))问题。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
%matplotlib inline
# 画图
X, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=60, cmap=plt.cm.Paired)
# 画散点图
X, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap=plt.cm.Paired)
x_fit = np.linspace(0, 3)
# 画函数
y_1 = 1 * x_fit + 0.8
plt.plot(x_fit, y_1, '-c')
y_2 = -0.3 * x_fit + 3
plt.plot(x_fit, y_2, '-k')
# 画散点图
X, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap=plt.cm.Paired)
plt.scatter([3], [2.8], c='#cccc00', marker='<', s=100, cmap=plt.cm.Paired)
x_fit = np.linspace(0, 3)
# 画函数
y_1 = 1 * x_fit + 0.8
plt.plot(x_fit, y_1, '-c')
y_2 = -0.3 * x_fit + 3
plt.plot(x_fit, y_2, '-k')
# 画散点图
X, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap=plt.cm.Paired)
x_fit = np.linspace(0, 3)
# 画函数
y_1 = 1 * x_fit + 0.8
plt.plot(x_fit, y_1, '-c')
# 画边距
plt.fill_between(x_fit, y_1 - 0.6, y_1 + 0.6, edgecolor='none', color='#AAAAAA', alpha=0.4)
y_2 = -0.3 * x_fit + 3
plt.plot(x_fit, y_2, '-k')
plt.fill_between(x_fit, y_2 - 0.4, y_2 + 0.4, edgecolor='none', color='#AAAAAA', alpha=0.4)
from sklearn.svm import SVC
# SVM 函数
clf = SVC(kernel='linear')
clf.fit(X, y)
# 最佳函数
w = clf.coef_[0]
a = -w[0] / w[1]
y_3 = a*x_fit - (clf.intercept_[0]) / w[1]
# 最大边距 下届
b_down = clf.support_vectors_[0]
y_down = a* x_fit + b_down[1] - a * b_down[0]
# 最大边距 上届
b_up = clf.support_vectors_[-1]
y_up = a* x_fit + b_up[1] - a * b_up[0]
# 画散点图
X, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap=plt.cm.Paired)
# 画函数
plt.plot(x_fit, y_3, '-c')
# 画边距
plt.fill_between(x_fit, y_down, y_up, edgecolor='none', color='#AAAAAA', alpha=0.4)
# 画支持向量
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], edgecolor='b',
s=80, facecolors='none')
带黑边的点是距离当前分类器最近的点,我们称之为支持向量。
支持向量机为我们提供了在众多可能的分类器之间进行选择的原则,从而确保对未知数据集具有更高的泛化性。