6、支持向量机SVM(support Vector Machine)

介绍:

解决的问题:怎样的决策边界最好
决策边界:Large Margin :使两种分开距离最远的地方

在这里插入图片描述
红色的就是决策边界,两个红点是距决策边界最近的点

原理

注意要标准化,使横竖轴观察更加直观

1、目标函数:

在这里插入图片描述

1、求点到决策边界的距离

求两个类之间最远的分类,那么就要找两个距分类最近的点,找他们之间的最远分类距离
设x是最近的一点,任取决策边界上的一点x‘
x到决策边界的距离,就是|x-x’|在决策边界上方向向量w投影:
在这里插入图片描述

2、数据集(X,Y):

Y为样本类别:X为正,Y=1;X为负,Y=-1
总体来说:XY>0,可以用来表示距离恒大于0
决策方程:Y(X)=W.T*Φ(X)+b
Φ(X)是对x进行了转换,可以先看做X

3、优化目标:

找到一条线,使得距该线最近的点之间的距离能够最远
距离简化为在这里插入图片描述

4、进行化简:

1、进行放缩,原为XY>0,现在XY>1
在这里插入图片描述
2、所求符号化表示:
在这里插入图片描述
3、最终优化目标为:
由于在这里插入图片描述,所以子需要考虑在这里插入图片描述

2、第一次拉格朗日

1、当求最大时,常规思路是将最大值转换成最小值:在这里插入图片描述
2、带着条件,用拉格朗日求极值:
在这里插入图片描述
分别对w,b求偏导:在这里插入图片描述

再代入原始:
在这里插入图片描述
在这里插入图片描述

3、第二次拉格朗日

1、继续对α求极大值:在这里插入图片描述
条件:在这里插入图片描述2、常规思路转换成最小值:
在这里插入图片描述
3、代入实例计算:
取的三个点,正例x1(3,3),x2(4,3),负例x3(1,1)
在这里插入图片描述
求解:
在这里插入图片描述
条件:在这里插入图片描述
代入得:
在这里插入图片描述
化简为:
在这里插入图片描述
对α1,α2再求偏导为0,满足条件α>0,得α1=0.25,α2=0,α3=0.25
代入:在这里插入图片描述W=(0.25,0.25)
在这里插入图片描述
平面方程:0.5x1+0.5x2-2=0
4、总结:
真正发挥作用的是,α不为0的点(最近的点)

4、代码解释:

使用iris数据集,选择其中的两个特征

from sklearn.svm import SVC
from sklearn import datasets

iris = datasets.load_iris()
X = iris['data'][:,(2,3)]
y = iris['target']

setosa_or_versicolor = (y==0)|(y==1)
X = X[setosa_or_versicolor]
y = y[setosa_or_versicolor]

svm_clf = SVC(kernel='linear')
svm_clf.fit(X,y)

画图显示:

def plot_svc_decision_boundary(svm_clf, xmin, xmax,sv=True):
    w = svm_clf.coef_[0]
    b = svm_clf.intercept_[0]
    print ("svm_clf.coef_:",svm_clf.coef_)
    print("svm_clf.intercept_:",svm_clf.intercept_)
    x0 = np.linspace(xmin, xmax, 200)#已知x0
    decision_boundary = - w[0]/w[1] * x0 - b/w[1]#求解x1
    margin = 1/w[1]#优化目标的距离
    gutter_up = decision_boundary + margin
    gutter_down = decision_boundary - margin
    if sv:
        svs = svm_clf.support_vectors_#支持向量
        print("svs:",svs)
        plt.scatter(svs[:,0],svs[:,1],s=180,facecolors='#FFAAAA')
    plt.plot(x0,decision_boundary,'r-',linewidth=2)
    plt.plot(x0,gutter_up,'k--',linewidth=2)
    plt.plot(x0,gutter_down,'k--',linewidth=2)
plot_svc_decision_boundary(svm_clf, 0, 5.5)
plt.plot(X[:,0][y==1],X[:,1][y==1],'bs')
plt.plot(X[:,0][y==0],X[:,1][y==0],'ys')
plt.axis([0,5.5,0,2])

升级:

1、软间隔:

1、介绍:

考虑到数据中有一些噪声点,要放宽一下约束条件,引入了松弛因子:ξ
在这里插入图片描述
以及超参数C
在这里插入图片描述

2、C的使用:

当C大时,在这里插入图片描述就小,1-就大,那么分类就更加严格;
当C小时,在这里插入图片描述就大,1-就小,那么分类就更加宽松

画图对比C
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)] # petal length, petal width
y = (iris["target"] == 2).astype(np.float64) # Iris-Viginica

svm_clf = Pipeline((
    ('std',StandardScaler()),
    ('linear_svc',LinearSVC(C=1))
))   
svm_clf.fit(X,y)
scaler = StandardScaler()
svm_clf1 = LinearSVC(C=1,random_state = 42)
svm_clf2 = LinearSVC(C=100,random_state = 42)

scaled_svm_clf1 = Pipeline((
    ('std',scaler),
    ('linear_svc',svm_clf1)
))  

scaled_svm_clf2 = Pipeline((
    ('std',scaler),
    ('linear_svc',svm_clf2)
)) 
scaled_svm_clf1.fit(X,y)
scaled_svm_clf2.fit(X,y)
#画图时要将标准化的数据再转回来(具体为什么,我还需要再想想)
b1 = svm_clf1.decision_function([-scaler.mean_ / scaler.scale_])
b2 = svm_clf2.decision_function([-scaler.mean_ / scaler.scale_])
w1 = svm_clf1.coef_[0] / scaler.scale_
w2 = svm_clf2.coef_[0] / scaler.scale_
svm_clf1.intercept_ = np.array([b1])
svm_clf2.intercept_ = np.array([b2])
svm_clf1.coef_ = np.array([w1])
svm_clf2.coef_ = np.array([w2])


plt.figure(figsize=(14,4.2))
plt.subplot(121)

plt.plot(X[:, 0][y==1], X[:, 1][y==1], "g^", label="Iris-Virginica")
plt.plot(X[:, 0][y==0], X[:, 1][y==0], "bs", label="Iris-Versicolor")

plot_svc_decision_boundary(svm_clf1, 4, 6,sv=False)

plt.xlabel("Petal length", fontsize=14)
plt.ylabel("Petal width", fontsize=14)
plt.legend(loc="upper left", fontsize=14)
plt.title("$C = {}$".format(svm_clf1.C), fontsize=16)
plt.axis([4, 6, 0.8, 2.8])

plt.subplot(122)
plt.plot(X[:, 0][y==1], X[:, 1][y==1], "g^")
plt.plot(X[:, 0][y==0], X[:, 1][y==0], "bs")
plot_svc_decision_boundary(svm_clf2, 4, 6,sv=False)
plt.xlabel("Petal length", fontsize=14)
plt.title("$C = {}$".format(svm_clf2.C), fontsize=16)
plt.axis([4, 6, 0.8, 2.8])

结果展示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/31d6661da4544d069778f675789241c1.png

2、核变换:

解决:低微不可分的问题
低维不可分的情况下,就映射到高维上
在这里插入图片描述

x==>Φ(X),就是由低微转换到了高维

预处理(转换至高维)

设置degree不同值,对比分类效果
degree越大,分类越清楚,越易过拟合
分类:画决策边界
1、数据

from sklearn.datasets import make_moons
X, y = make_moons(n_samples=100, noise=0.15, random_state=42)

def plot_dataset(X, y, axes):
    plt.plot(X[:, 0][y==0], X[:, 1][y==0], "bs")
    plt.plot(X[:, 0][y==1], X[:, 1][y==1], "g^")
    plt.axis(axes)
    plt.grid(True, which='both')
    plt.xlabel(r"$x_1$", fontsize=20)
    plt.ylabel(r"$x_2$", fontsize=20, rotation=0)

plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
plt.show()

2、决策边界的划分

def plot_predictions(clf,axes):
    x0s = np.linspace(axes[0],axes[1],100)
    x1s = np.linspace(axes[2],axes[3],100)
    x0,x1 = np.meshgrid(x0s,x1s)#构建棋盘
    X = np.c_[x0.ravel(),x1.ravel()]#进行拼接
    y_pred = clf.predict(X).reshape(x0.shape)#必须与原始形状相同
    plt.contourf(x0,x1,y_pred,cmap=plt.cm.brg,alpha=0.2)

3、训练模型,设置不同的degree

from sklearn.datasets import make_moons
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures

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)
poly100_kernel_svm_clf = Pipeline([
        ("scaler", StandardScaler()),
        ("svm_clf", SVC(kernel="poly", degree=10, coef0=1, C=5))
    ])
#coef0偏置值,影响不大

poly100_kernel_svm_clf.fit(X, y)

4、画图展示:

plt.figure(figsize=(11, 4))

plt.subplot(121)
plot_predictions(poly_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])
plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
plt.title(r"$d=3, r=1, C=5$", fontsize=18)

plt.subplot(122)
plot_predictions(poly100_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])
plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
plt.title(r"$d=10, r=100, C=5$", fontsize=18)

plt.show()

在这里插入图片描述

常用方法:高斯核函数

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值