机器学习算法(8)-支持向量机

什么是支持向量机

支持向量机是分类算法,目标是确立一个超平面来切分数据,(超平面在二维中是一条线,在三维中是一个面,以此类推),并且这个分类的边界要足够好,即离分割边界最近的数据点到分割边界的距离要越远越好(前提是所有的分类都是正确的,加入软间隔后可忽略部分离群点)。如图
这里写图片描述

点到面的距离

点到面的距离公式看这个链接:https://www.cnblogs.com/graphics/archive/2010/07/10/1774809.html
总之我们得到点到面的公式是 d = P Q n n PQ 表示点P到平面上的点Q的向量,n表示平面的法向量

目标函数

  • 设超平面的的一般公式为 y ( x ) = W T x + b = n x + b , W T 等于法线量n
  • P Q 可表示为 x x 1 , 由于 x 1 是平面上的点,所以 n x 1 + b = 0 , x 1 = b n ,
  • 那么 d = P Q n n = ( x + b n ) n n = 1 n ( n x + b ) = 1 n y ( x )
  • 要求 m i n i 1 n y ( x ) (距离超平面最近的点,求出的距离有可能是负的,加上绝对值)
  • 假设 y ( x i ) > 0 y i = 1 , y ( x i ) < 0 y i = 1 , y i y ( x i ) > 0
  • 那么 m i n i 1 n y ( x ) = 1 n m i n i y i y ( x )
  • 通过放缩使得 y i y ( x i ) >= 1 ,那么距离最近的点的距离可表示为 1 n
  • 最近的点的距离表示出来了,那么现在要求w和b使得这个距离最大,求 m a x w , b 1 n ,这就是我们的目标函数

目标函数求解(拉格朗日乘子法)

  • 求解目标: m a x w , b 1 n
  • 约束条件: y i y ( x ) >= 1 y i ( w T x i + b ) >= 1
  • 转换为求极小值: m a x w , b 1 w => m i n w , b 1 2 w 2
  • 拉格朗日求子法(有约束条件下的极值求法)
    • 套公式转换为 L ( w , b , a ) = 1 2 w 2 i = 1 n a i ( y i ( w T x i + b ) 1 )
    • Θ ( w ) = m a x a i > 0 L ( w , b , a ) ,那么 Θ ( w ) 的最优解就是 1 2 w 2
    • 因此问题转换成 m i n w , b 1 2 w 2 = m i n w , b m a x a i > 0 L ( w , b , a )
    • 根据拉格朗日乘子法对偶性质: m i n w , b m a x a i > 0 L ( w , b , a ) > m a x a i > 0 m i n w , b L ( w , b , a )
    • 求解 m i n w , b L ( w , b , a )
      • 在L(w,b,a)对w求偏导 L w = 0 w = i = 1 n a i y i x n
      • 在L(w,b,a)对b求偏导 L b = 0 0 = i = 1 n y i x n
      • 代入L(w,b,a) 得 m i n L ( w , b , a ) = i = 1 n a i i = 1 , j = 1 n 1 2 a i a j y i y j ( x i x j )
    • 求解 m a x a i > 0 [ i = 1 n a i i = 1 , j = 1 n 1 2 a i a j y i y j ( x i x j ) ]
      • 转化为求极小值 m i n a i > 0 [ i = 1 , j = 1 n 1 2 a i a j y i y j ( x i x j ) i = 1 n a i ]
      • 注意条件 i = 0 n a i y i = 0 , a i > 0
      • 将实际中的数据,代入到 [ i = 1 , j = 1 n 1 2 a i a j y i y j ( x i x j ) i = 1 n a i ]
      • 对每个 a i 求偏导=0的值,可求出每个 a i 的值,其中满足 i = 0 n a i y i = 0 , a i > 0 的点为支持向量的点
      • 利用支持向量的点的 a i 的值,求出w,b,即最终的结果

软间隔soft-margin

引入松弛因子,C,C越大,越严格,分类错误越小,但是可能过拟合,C越大,容忍错误越大

核变换

低纬度不可分,转换为高维进行切分
这里写图片描述

  • 常用核函数 参考:https://blog.csdn.net/wsj998689aa/article/details/47027365
    • 1.线性核 Linear Kernel k ( x , y ) = x t y (以一条直线切分)
    • 2.多项式核 Polynomial Kernel k ( x , y ) = ( a x t y + c ) d (适合于正交归一化后的数据)
    • 3.高斯核Gaussian Kernel k ( x , y ) = e x p ( x y 2 2 σ 2 )
    • 4.Exponential Kernel 指数核函数就是高斯核函数的变种,它仅仅是将向量之间的L2距离调整为L1距离

使用sklearn.SVM

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns; sns.set()

# 构造数据
from sklearn.datasets.samples_generator import make_blobs
X, y =make_blobs(n_samples=50, centers=2, random_state=0,cluster_std=0.60)
plt.scatter(X[:,0],X[:,1], c=y, s=50, cmap='autumn')

# 训练一个线性核SVM
from sklearn.svm import SVC
model = SVC(kernel='linear')
model.fit(X, y)

#绘图函数,用于绘制svm训练结果曲线
def plot_svc_decision_function(model, ax=None, plot_support=True):
    if ax is None:
        ax = plt.gca()#Get Current Axes获取当前轴线
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    # create grid to evaluate model
    x = np.linspace(xlim[0], xlim[1], 30)
    y = np.linspace(ylim[0], ylim[1], 30)
    Y, X = np.meshgrid(y, x)
    xy = np.vstack([X.ravel(), Y.ravel()]).T
    P = model.decision_function(xy).reshape(X.shape)

    # plot decision boundary and margins
    ax.contour(X, Y, P, colors='k',
               levels=[-1, 0, 1], alpha=0.5,
               linestyles=['--', '-', '--'])

    # plot support vectors
    if plot_support:
        ax.scatter(model.support_vectors_[:, 0],
                   model.support_vectors_[:, 1],
                   s=300, linewidth=1, facecolors='none');
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)

#绘制散点图
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')
# 绘制model的结果
plot_svc_decision_function(model)

#支持向量的点
print(model.support_vectors_)

# 生成圆形的散点数据,举例rbf和函数
from sklearn.datasets.samples_generator import make_circles
X, y = make_circles(100, factor=.1,noise=.1)
clf =SVC(kernel='rbf',C=10,gamma=1).fit(X,y)
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')
plot_svc_decision_function(clf, plot_support=False)
  • 参数说明
    sklearn.svm.SVC(C=1.0, kernel=’rbf’, degree=3, gamma=’auto’, coef0=0.0, shrinking=True, probability=False,

tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=None,random_state=None)

参数:

l C:C-SVC的惩罚参数C?默认值是1.0

C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。

l kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’

  0 – 线性:u’v

   1 – 多项式:(gamma*u’*v + coef0)^degree

  2 – RBF函数:exp(-gamma|u-v|^2)

  3 –sigmoid:tanh(gamma*u’*v + coef0)

l degree :多项式poly函数的维度,默认是3,选择其他核函数时会被忽略。

l gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features

l coef0 :核函数的常数项。对于‘poly’和 ‘sigmoid’有用。

l probability :是否采用概率估计?.默认为False

l shrinking :是否采用shrinking heuristic方法,默认为true

l tol :停止训练的误差值大小,默认为1e-3

l cache_size :核函数cache缓存大小,默认为200

l class_weight :类别的权重,字典形式传递。设置第几类的参数C为weight*C(C-SVC中的C)

l verbose :允许冗余输出?

l max_iter :最大迭代次数。-1为无限制。

l decision_function_shape :‘ovo’, ‘ovr’ or None, default=None3

l random_state :数据洗牌时的种子值,int值

主要调节的参数有:C、kernel、degree、gamma、coef0。

问题

  • 什么是支持向量
  • 为什么要使用对偶

猜你喜欢

转载自blog.csdn.net/weixin_35885196/article/details/80027971