支持向量机 SVM Support Vector Machine (11.1)(线性(hard/soft))

SVM既可以解决分类问题也可以解决回归问题

1线性SVM公式推导

     

将W_d计为W; b_d计为b,得到下面的方程。其中新的W和b和一开始的W和b不一样了,差一个系数||W||d

不要忘记我们的目标是最大化d,而d代表我们的支撑向量x到决策边界的距离。

对于任意支持向量x有: =1

任意支持向量到决策边界的距离d=    

所以max d = = =

所以最终优化条件为

有条件的最优化问题

这个最优化条件和之前所讲解的无论是线性回归问题还是逻辑回归问题对应的最优化问题是不一样的,之前的最优化问题都是全局最优化问题(即没有限定条件)。而对于SVM是有条件的最后问题。有没有条件在最优化领域求解这个问题方法是大不相同的

求最优解:求出W和b就求出了决策边界

2.soft margin  和SVM中的正则化问题

     

hard margin 要求所有的点都要在margin外面,现在我们对限制条件加以宽松,允许有一些数据点在实线和虚线中间

大于等于0是限制虚线在上面一条实线的下方,下面那条实线的上方,而且它不是一个固定值,而是对于每一个样本 i 都有一个相应的,也即对每一个数据点都计算一个他相应的容错空间

但是只限制 大于等于0,如果为正无穷时也满足条件,但此时显然容错范围太大了,那该如何解决那?

在最小化项后面加上一个限制

这样一来我们最小化的式子,就同时顾及了前半部分时hard margin SVM 对应的最优化内容,后半部分可以使得SVM容忍一定的错误,但是这个容忍的程度要尽量的小,这二者之间应该取得一定平衡

这种方式为L1正则

用C来平衡两个部分的比例,C是一个超参数  。

C越大,越接近0,使得soft margin 越接近 hard margin,容错能力,容错空间越小

这里的正则化项和以前的正则化项是一致的,只不过这里的和之前的θ(代表多项式前系数)代表的意义不同了,还有就是线性回归逻辑回归的C放在MSE部分使得算法必须使用正则化,这里的C放在了正则化项。但是C代表的意义是不变的。

在SVM 中 C越大,越接近0,使得soft margin 越接近 hard margin,容错能力,容错空间越小

在线性/逻辑回归中,C越大,MSE部分占的比重越大,正则化部分变得弱,容错空间变小

3实际使用SVM算法

和knn算法一样,在使用SVM算法前要做数据标准化处理。

这是因为svm寻找的是使得margin最大的中间的那条线,而我们衡量margin的方式是数据点之间的距离,它是涉及距离的。如果不同的数据点在不同的维度上量纲不同,就会使得我们对距离的估计是有问题的。如下图例子:

  

图一中横轴范围0-1,纵轴范围0-10000,此时使用SVM算法得到的线条是图二样子的,此时相当于画标注的两个点是支撑向量这两个点离决策边界时是最近的。在纵向范围里一个很短的距离都代表一个很大的数。

如果我们的数据特征在不同的尺度不同的话就会非常严重的SVM算法得到的最终决策边界的样子,所以为了避免这种情况在使用SVM前先进行标准化处理

4sklearn中的SVM算法

4.1.准备数据,选取鸢尾花前两个类别,以及前两个特征(为了可视化方便)

import numpy as np
import matplotlib.pyplot as plt

from sklearn import datasets

iris = datasets.load_iris()

X = iris.data
y = iris.target

X = X[y<2,:2]  #选取鸢尾花前两个类别,以及前两个特征
y = y[y<2]

可视化选取的数据

plt.scatter(X[y==0,0], X[y==0,1], color='red')
plt.scatter(X[y==1,0], X[y==1,1], color='blue')
plt.show()

4.2数据标准化

from sklearn.preprocessing import StandardScaler

standardScaler = StandardScaler()
standardScaler.fit(X)
X_standard = standardScaler.transform(X)

4.3调用SVM算法

from sklearn.svm import LinearSVC
'''如果使用线性SVM算法,可以import 一个LinearSVC类,
为什么叫SVC,Sorport Vector Classifier,就是说这个类使用支持向量机思想进行分类工作
'''

svc = LinearSVC(C=1e9)  #C为正则项前面系数,c这么大相当于hard margin 了
svc.fit(X_standard, y)  #使用标准化后的数据fit

 参数C=1e9 这么大相当于 hard margin了

4.4.绘制决策边界

def plot_decision_boundary(model, axis):
    
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1, 1),
        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1, 1),
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]

    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)

    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
plot_decision_boundary(svc, axis=[-3, 3, -3, 3])
plt.scatter(X_standard[y==0,0], X_standard[y==0,1])
plt.scatter(X_standard[y==1,0], X_standard[y==1,1])
plt.show()

4.4.2 C=0.001时 C越小相应的每个样本的\xi可以大些,代表我们的容错空间越大 。决策边界如下图:

 容错能力变大后,有一个蓝点分错了

svc.coef_     array([[ 4.03243305, -2.49295041]])   结果为决策边界方程前的系数,sklearn中的SVM可以处理多分类问题,所有结果是二维数组

svc.intercept_     array([ 0.9536471])  截距

AX1+BX2+C=0 的直线形式

5.绘制margin 区域上线对应的两个线

def plot_svc_decision_boundary(model, axis):
    
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1, 1),
        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1, 1),
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]

    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)

    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
    
    w = model.coef_[0]
    b = model.intercept_[0]
    
    # w0*x0 + w1*x1 + b = 0
    # => x1 = -w0/w1 * x0 - b/w1
    #up_y:w0*x0 + w1*x1 + b = 1
    #down_y:w0*x0 + w1*x1 + b = -1
    plot_x = np.linspace(axis[0], axis[1], 200)
    up_y = -w[0]/w[1] * plot_x - b/w[1] + 1/w[1]
    down_y = -w[0]/w[1] * plot_x - b/w[1] - 1/w[1]
    
    up_index = (up_y >= axis[2]) & (up_y <= axis[3])
    down_index = (down_y >= axis[2]) & (down_y <= axis[3])
    plt.plot(plot_x[up_index], up_y[up_index], color='red')
    plt.plot(plot_x[down_index], down_y[down_index], color='black')
plot_svc_decision_boundary(svc, axis=[-3, 3, -3, 3])
plt.scatter(X_standard[y==0,0], X_standard[y==0,1])
plt.scatter(X_standard[y==1,0], X_standard[y==1,1])
plt.show()

上面有3个点落在直线上,下面有两个点落在直线上,训练的svc模型c=1e9相当于hard margin,所以margin中没有其他点。

5.2 绘制svc2,c=5,容错空间比svc大  (margin中存在点)

5.3绘制svc3 , c =0.01 容错空间更大

6使用LinearSVC类进行fit时输出的参数

LinearSVC(C=0.01, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=1000,
     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
     verbose=0)

注意两个参数:

1.  multi_class='ovr' 参数:当遇到多分类时算法默认使用OVR方式将二分类转换为多分类问题

2. penalty='l2'          参数: 默认使用L2正则的方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值