机器学习 -- SVM

SVM 支撑向量机

support Vector Machine

逻辑回归:
在这里插入图片描述
但是当决策边界不唯一时,
定义一个概率函数,求损失函数。然后求出决策边界
在这里插入图片描述
在这里插入图片描述
我们希望的决策边界是距离红色,蓝色最近的点都尽可能的远,而且还能很好的分别红色和蓝色两种类别的数据点
在这里插入图片描述
在这里插入图片描述

hard svm

假设我们的数据是线性可分的,用 hard svm

svm求得的是 margin 最大化
margin=2d
svm也就要d 最大化

点到直线的距离:
点(x,y) 到Ax+By +C =0 的距离 ∣ A x + B y + C ∣ A 2 + B 2 \frac{|Ax+By+C|}{\sqrt{A^2+B^2}} A2+B2 Ax+By+C
拓展到n 维:
原来我们都是 θ T x b = 0 \theta^Tx_b = 0 θTxb=0
但是我们从上面可以二维平面看到 分母和截距C没有关系
所以式子变成 W T x + b = 0 W^Tx+b =0 WTx+b=0
所以 就是 ∣ w T x + b ∣ ∣ ∣ w ∣ ∣ \frac{|w^Tx+b|}{||w||} wwTx+b
∣ ∣ w ∣ ∣ = w 1 2 + w 2 2 + w 3 2 + . . . + w n 2 ||w|| = \sqrt{w^2_1+w^2_2+w^2_3+...+w^2_n} w=w12+w22+w32+...+wn2

在这里插入图片描述
上面的 d是一个正数, ∣ ∣ w ∣ ∣ ||w|| w也是一个正数,所以
在这里插入图片描述
对上面的变量进行改名,
在这里插入图片描述
可以上图右边的两个式子合二为一,就变成了
y i ( w T x i + b ) ≥ 1 y^i(w^Tx^i+b) \geq1 yi(wTxi+b)1

在这里插入图片描述
所以算法就变成了 m i n 1 2 ∣ ∣ w 2 ∣ ∣ min\frac{1}{2}||w^2|| min21w2的最优化问题
但是要满足 y i ( w T x i + b ) ≥ 1 y^i(w^Tx^i+b) \geq1 yi(wTxi+b)1
有条件的最优化问题

soft svm

很多时候数据不是线性可分的,就要使用 soft svm
在这里插入图片描述
在这里插入图片描述
但是当数据变成上图 ,就无法进行处理了,·我们需要有一定容错的svm,增加一个宽松量

在这里插入图片描述
我们可以给 其加上一个系数,来平衡这两个的比例
如果C在0,1之间。我们主要优化前面的
如果C特别大的化,我们要主要优化后面的式子
在这里插入图片描述

scikit-learn 中的svm

使用 svm算法和使用knn算法一样,都要先做数据标准化处理’
因为svm 是计算margin,涉及距离,如果特征数据的量纲不同则会有问题

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()

在这里插入图片描述
绘制·svm支撑点

def plot_svc_decision_boundary(model,axis):
    x0,x1 = np.meshgrid(
        np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)),
        np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100))
    )
    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,cmap=custom_cmap)
    
    w = model.coef_[0]
    b = model.intercept_[0]
    
    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='black')
    plt.plot(plot_x[down_index], down_y[down_index],color='black')

当C=1e9时

from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()
standardScaler.fit(X)
X_standard = standardScaler.transform(X)

from sklearn.svm import LinearSVC
svc = LinearSVC(C=1e9)
svc.fit(X_standard, y)

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()

在这里插入图片描述

当C=0.01时
在这里插入图片描述

svm中使用多项式特征

创建数据

from sklearn import datasets
X,y = datasets.make_moons()

plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述
对数据增加噪音

X,y = datasets.make_moons(noise=0.15, random_state=666)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述
使用多项式svm

from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline

def PolynomialSVC(degree,C=1.0):
    return Pipeline(
    [
        ('poly', PolynomialFeatures(degree=degree)),
        ('std_scaler', StandardScaler()),
        ('linearSVC',LinearSVC(C=C))
    ])
poly_svc = PolynomialSVC(degree=3)
poly_svc.fit(X,y)


plot_decision_boundary(poly_svc, axis=[-1.5,2.5,-1,1.5])
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()

在这里插入图片描述

使用多项式核函数的svm
from sklearn.svm import SVC

def PolynomialKernelSVC(degree,C=1):
    return Pipeline(
        [
            ('std_scaler',StandardScaler()),
        ('KernelSVC',SVC(kernel='poly',degree=degree,C=C))
        ]
    )
  
poly_kernel_svc = PolynomialKernelSVC(degree=3)
poly_kernel_svc.fit(X,y)
plot_decision_boundary(poly_kernel_svc, axis=[-1.5,2.5,-1,1.5])
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()

在这里插入图片描述

什么是核函数

svm 的本质
在这里插入图片描述
在这里插入图片描述
其中的K叫核函数
对于二次多项式的核函数:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

高斯核函数 RBF核

在这里插入图片描述
将每一样本点映射到一个无穷维的特征空间

多项式特征: 依靠升维使得原本新型不可分的数据线性可分
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-4,5,1)
y = np.array((X>=-2) & (X<=2), dtype='int')

plt.scatter(x[y==0],[0]*len(x[y==0]))
plt.scatter(x[y==1],[0]*len(x[y==1]))
plt.show()

在这里插入图片描述

def gaussian(x,l):
    gamma = 1
    return np.exp(-gamma * (x-l)**2)

l1,l2 = -1,1
X_new =np.empty((len(x),2))
for i,data in enumerate(x):
    X_new[i,0] = gaussian(data,l1)
    X_new[i,1] = gaussian(data, l2)
    
plt.scatter(X_new[y==0,0],X_new[y==0,1])
plt.scatter(X_new[y==1,0],X_new[y==1,1])
plt.show()

在这里插入图片描述

高斯核函数中的gamma

在这里插入图片描述
gamma越大,高斯分布越窄
gamma越小,高斯分布越宽

测试数据

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

X,y = datasets.make_moons(noise=0.15, random_state=666)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述

创建RBF svm对象

from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

def RBFKernelSVC(gamma=1):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

# 画图
def plot_decision_boundary(model,axis):
    x0,x1 = np.meshgrid(
        np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)),
        np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100))
    )
    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,cmap=custom_cmap)
def get_RBF_SVM_plot(gamma=1)
	svc = RBFKernelSVC(gamma=gamma)
	svc.fit(X,y)
	plot_decision_boundary(svc, axis=[-1.5,2.5,-1,1.5])
	plt.scatter(X[y==0,0],X[y==0,1])
	plt.scatter(X[y==1,0],X[y==1,1])
	plt.show()

当 gamma=1时:

在这里插入图片描述
当 gamma=100时
在这里插入图片描述
当gamma=10时
在这里插入图片描述
当 gamma=0.5时
在这里插入图片描述
当gamma=0.1时
在这里插入图片描述
gamma越大。就会出现过拟合,
gamma越小,就会出现欠拟合

svm 思路解决回归问题

分类问题是在margin中值越小越好,
回归问题是在margin 中,包含的点越多越好,然后取中间的直线

在scikit-learn 中使用 svm 解决回归问题

import numpy as np
import matplotlib.pyplot as plt

from sklearn import datasets

boston =  datasets.load_boston()
X = boston.data
y = boston.target

from sklearn.model_selection import train_test_split
X_train,X_test, y_train,y_test = train_test_split(X,y, random_state=666)


from sklearn.svm import LinearSVR
# from sklearn.svm import SVR  # 可以使用 SVR ,也可以使用LinearSVR ,和上面一样
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

def StandardLinearSVR(epsilon=0.1):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('linearSVR',LinearSVR(epsilon=epsilon))
    ])


svr = StandardLinearSVR()
svr.fit(X_train,y_train)

svr.score(X_test, y_test)  # 0.6357705223702143
# 这里的值比较低。因为有很多的 超参数可以调整,
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值