吴恩达机器学习 EX6 作业 第一部分 了解支持向量机 高斯核函数

1、支持向量机

支持向量机比较复杂,看了好多遍讲义对深入原理还不是很理解。想深入研究的可以看支持向量机通俗导论(理解SVM的三层境界)

1.1 作业介绍

在本练习的前半部分,您将使用支持向量机。各种示例2D数据集。使用这些数据集进行实验将帮助您直观地了解支持向量机如何工作,以及如何使用支持向量机的高斯内核。

1.2 导入模块和数据

导入模块

import matplotlib.pyplot as plt
import numpy as np
import scipy.io as scio
from sklearn import svm # 调用sklearn的svm模块
import plotData as pd
import visualizeBoundary as vb # 可视化边界
# import gaussianKernel as gk # 高斯核函数

from sklearn.model_selection import GridSearchCV # 使用sklearn已有网格选择模块
plt.ion()
np.set_printoptions(formatter={'float': '{: 0.6f}'.format})

导入数据

# Load from ex6data1:
data = scio.loadmat('ex6data1.mat')
X = data['X']
y = data['y'].flatten()
m = y.size

打印X y维度

print('X.shape: ', X.shape, '\ny.shape: ', y.shape)
X.shape:  (51, 2) 
y.shape:  (51,)

1.3 plotData 绘图函数

def plot_data(X, y):
    plt.figure()

    pos_X = X[np.where(y==1)] # 正类
    neg_X = X[np.where(y==0)] # 负类
    plt.scatter(pos_X[:, 0], pos_X[:, 1], c='b', marker='+') #散点图绘制正类
    plt.scatter(neg_X[:, 0], neg_X[:, 1], c='y', marker='o') #散点图绘制负类

调用函数绘图

# Plot training data
plot_data(X, y)

在这里插入图片描述

1.4 svm模块之线性核函数

c=100,可以很好的拟合正类和负类,但由于一个异常点造成过拟合,不能最大边界

# ===================== Part 2: Training Linear SVM =====================

c = 100
clf = svm.SVC(c, kernel='linear', tol=1e-3)
clf.fit(X, y)

plot_data(X, y)
vb.visualize_boundary(clf, X, 0, 4.5, 1.5, 5)
plt.title('decision boundary with c = {}'.format(c))
Text(0.5,1,'decision boundary with c = 100')

在这里插入图片描述

c=1,此时不因为一个异常点影响“大边界”,拟合效果较好

c = 1
clf = svm.SVC(c, kernel='linear', tol=1e-3)
clf.fit(X, y)

plot_data(X, y)
vb.visualize_boundary(clf, X, 0, 4.5, 1.5, 5)
plt.title('decision boundary with c = {}'.format(c))
Text(0.5,1,'decision boundary with c = 1')

在这里插入图片描述

1.5 svm模块之高斯核函数

x1 = np.array([1, 2, 1])
x2 = np.array([0, 4, -1])
sigma = 2

高斯核函数公式:
在这里插入图片描述
高斯核函数gaussian_kernel

def gaussian_kernel(x1, x2, sigma=0.1):
    x1 = x1.flatten()
    x2 = x2.flatten()

    sim = 0

    sim = np.exp(-np.sum(np.power((x1 - x2), 2)) / (2 * np.power(sigma,2)))

    return sim

调用高斯核函数测试,结果正确

sim = gaussian_kernel(x1, x2, sigma)

print('Gaussian kernel between x1 = [1, 2, 1], x2 = [0, 4, -1], sigma = {} : {:0.6f}\n'
      '(for sigma = 2, this value should be about 0.324652'.format(sigma, sim))
Gaussian kernel between x1 = [1, 2, 1], x2 = [0, 4, -1], sigma = 2 : 0.324652
(for sigma = 2, this value should be about 0.324652

1.6 加载一组更复杂数据,不能线性核函数拟合

加载数据

data = scio.loadmat('ex6data2.mat')
X = data['X']
y = data['y'].flatten()
m = y.size

打印X y维度

print('X.shape: ', X.shape, '\ny.shape: ', y.shape)
X.shape:  (863, 2) 
y.shape:  (863,)

调用绘图函数绘制图形,可以看出很不规则,无法用线性核函数拟合

# Plot training data
plot_data(X, y)

在这里插入图片描述

1.6.1 visualizeBoundary函数,绘制等高线图

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


def visualize_boundary(clf, X, x_min, x_max, y_min, y_max):
    h = .02

    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    plt.contour(xx, yy, Z, colors='r')

1.6.2 使用sklearn.svm.SVCmo模块rbf核函数拟合数据,并绘图

c = 1
sigma = 0.1

clf = svm.SVC(c, kernel='rbf', gamma=np.power(sigma, -2))
clf.fit(X, y)

plot_data(X, y)
vb.visualize_boundary(clf, X, 0, 1, .4, 1.0)

可以看出用高斯核函数拟合效果较好
在这里插入图片描述

1.7 高斯核函数 合适参数拟合效果

导入数据

data = scio.loadmat('ex6data3.mat')
X = data['X']
y = data['y'].flatten()
Xval = data['Xval']
yval = data['yval']
m = y.size
print('X.shape: ', X.shape, '\ny.shape: ', y.shape)
X.shape:  (211, 2) 
y.shape:  (211,)
print('X.shape: ', Xval.shape, '\ny.shape: ', yval.shape)
X.shape:  (200, 2) 
y.shape:  (200, 1)

绘制图形

plot_data(X, y)

在这里插入图片描述
绘制C=1时拟合效果图

c = 1

clf = svm.SVC(c, kernel='rbf')
clf.fit(X, y)

plot_data(X, y)
vb.visualize_boundary(clf, X, -0.7, 0.4, -0.7, 0.6)

在这里插入图片描述

1.8 使用sklearn的GridSearchCV自动搜索最佳参数(c gamma)

不同C和gamma配合产生不同拟合效果,详情参考博客:SVM基本使用
GridSearchCV能自动选择最优的参数,达到最佳效果

def svm_c(X, y, Xval, yval):
    # rbf核函数
    svc = svm.SVC(kernel='rbf', class_weight='balanced',)
    c_list = gamma_list = np.array([0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30])
    # 网格搜索交叉验证的参数范围,cv=3,3折交叉
    param_grid = [{'kernel': ['rbf'], 'C': c_list, 'gamma': gamma_list}]
    grid = GridSearchCV(svc, param_grid, cv=3, n_jobs=-1)
    # 训练模型
    clf = grid.fit(X, y)
    # 计算测试集精度
    score = grid.score(Xval, yval)
    print('精度为: {}'.format( score))
svm_c(X, y, Xval, yval)
精度为: 0.95

前一篇 吴恩达机器学习 EX5 作业 正则化线性回归 偏差 VS 方差 学习曲线
后一篇 吴恩达机器学习 EX6 第二部分 支持向量机 垃圾邮件分类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值