机器学习 ex6
@ Shen Jianan · Friday, Oct 2, 2015 · 3 minute read · Update at Oct 2, 2015

第六次作业是关于支持向量机的一个小练习,借此小练习也巩固一下支持向量机的使用过程。

这次作业分为两个部分,第一部分的大致内容是利用支持向量机和多个二维数据集来体验运行SVM和使用高斯核函数的过程。第二部分则是使用支持向量机来构造一个简单的垃圾邮件分类器。

第一部分

第一部门的主要任务是利用SVM,得到一个线性边界并将在象限左下角和右上角的数据分隔开来。在这些数据中有一个异常数据(左方的"+”),稍后会看到这个异常数据的影响。

C值的影响

在这部分的练习中,需要使用不同的C值来试验SVM的表现(这一节的算法已经在作业中实现好)。通常来说C都是一个大于零的值,用来控制训练过程中错误分类的惩罚值。所以一个比较大的C值让SVM倾向于得到一个低偏差的结果(将所有的训练样本都正确分类,可能会导致过拟合,从而产生高方差)。

原数据的分布如下图所示:

数据分布

不同C值的影响如下图所示: 数据分布

使用高斯核函数的SVM

在这部分练习中,需要使用高斯核函数实现非线性分类。

实现高斯核函数

在gussianKernel.m中实现计算$(x^{(i)},x^{(j)})$之间的高斯核函数运算结果,高斯核函数的定义为: $$K_{gaussian}(x^{(i)},x^{(j)}) = exp(-\frac{||x^{(i)}-x^{(j)}||^2}{2\sigma^2}) = exp(-\frac{\sum\limits_{k=1}^n(x^{(i)}-x^{(j)})^2}{2\sigma^2})$$

所以在代码中的实现为:

function sim = gaussianKernel(x1, x2, sigma)
%RBFKERNEL returns a radial basis function kernel between x1 and x2
%   sim = gaussianKernel(x1, x2) returns a gaussian kernel between x1 and x2
%   and returns the value in sim

% Ensure that x1 and x2 are column vectors
x1 = x1(:); x2 = x2(:);

% You need to return the following variables correctly.
sim = 0;

% ====================== YOUR CODE HERE ======================

minus = x1-x2;
sim = exp(-sum(minus.*minus)/(2*(sigma^2)));

% =============================================================
    
end

使用高斯核函数来实现的这种非线性SVM可以训练一个决策边界来划分那些线性边界无能为力的数据集,如: 不能线性划分的数据分布 划分结果为: 非线性SVM划分结果

使用交叉验证调整$C$与$\sigma$

在课程指导里建议以$0.01,0.03,0.1,0.3,\ldots,30$这样的步骤来逐步尝试$C$和$\sigma$。

当实现交叉验证的时候,需要在交叉验证数据集上评估错误率。

function [C, sigma] = dataset3Params(X, y, Xval, yval)
%EX6PARAMS returns your choice of C and sigma for Part 3 of the exercise
%where you select the optimal (C, sigma) learning parameters to use for SVM
%with RBF kernel
%   [C, sigma] = EX6PARAMS(X, y, Xval, yval) returns your choice of C and 
%   sigma. You should complete this function to return the optimal C and 
%   sigma based on a cross-validation set.
%

% You need to return the following variables correctly.
C = 1;
sigma = 0.3;

% ====================== YOUR CODE HERE ======================
% 使用实现好的svmPredict来使用SVM得到预测的标签。mean(double(predictions ~= yval))用于计算交叉验证集的错误率。

candidate = [0.01,0.03,0.1,0.3,1,3,10,30];

num = 8;

for i = 1:num
    C_candidate = candidate(i);
    for j = 1:num
        sigma_candidate = candidate(j);
        model = svmTrain(X, y, C_candidate, @(x1, x2) gaussianKernel(x1, x2, sigma_candidate)); 
        predictions = svmPredict(model,Xval);
        validations(i,j) = mean(double(predictions ~= yval));
    end
end

M = min(validations(:));
[row col] = find(validations == M);

C = candidate(row);
sigma = candidate(col);

% =========================================================================

end

第二部分

第二部分是一个垃圾邮件分类器,但是显然做完感觉没什么长进,关键部分都已经被实现好,做的只是无关紧要的标记。就不写出来了吧= =

coursera上的作业还是太割裂了,照着tutorial做就没什么收获,也是一个弊端吧…

About Me

2018.02至今 杭州嘉云数据 算法引擎

2017.6-2017.12 菜⻦网络-⼈工智能部-算法引擎

2016.09-2018.06 南京大学研究生

2015.07-2015.09 阿里巴巴-ICBU-实习

2012.09-2016.06 南京大学本科