机器学习笔记-线性可分支持向量机的实现

关于线性可分支持向量机的实现

  在支持向量机那篇文章中,我们推导出线性可分支持向量机的最终形式,即二次规划问题:
min ⁡ α       1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j ( x i ⋅ x j ) − ∑ i = 1 N α i s . t .      ∑ i = 1 N α i y i = 0 α i ≥ 0      i = 1 , 2 , ⋯   , N \min\limits_{\alpha}\,\,\,\,\,\frac{1}{2}\sum\limits_{i=1}^N\sum\limits_{j=1}^N{\alpha_i\alpha_jy_iy_j(x_i\cdot x_j)}-\sum\limits_{i=1}^N{\alpha_i}\\ s.t.\,\,\,\,\sum\limits_{i=1}^N{\alpha_iy_i=0}\\ \alpha_i\ge0\,\,\,\,i=1,2,\cdots,N αmin21i=1Nj=1Nαiαjyiyj(xixj)i=1Nαis.t.i=1Nαiyi=0αi0i=1,2,,N
  我们要做的就是如何求解上述的优化问题,在支持向量机中是有一个专门的求解方法,叫做SMO最小序列算法,但是该算法的内容较多,本文不详细介绍。在这里我们不使用SMO算法求解,我们可以借助MATLAB中求解二次规划问题的函数来求解。

在matlab中有一个专门求解二次规划问题的函数:quadprog
  该函数是求解二次规划问题的专用函数,此函数的调用有专门的格式:

min ⁡ x 1 2 x T H x A ⋅ x ≤ b A e q ⋅ x = b e q l b ≤ x ≤ u b \min\limits_{x}\frac{1}{2}x^{T}Hx\\ A\cdot x\le b\\ Aeq\cdot x=beq\\ lb\le x\le ub xmin21xTHxAxbAeqx=beqlbxub

我们需要把对偶问题转化成上述的标准形式,在这里变量 x x x就是 α \alpha α于是我们可以认为 H H H就是
∑ i = 1 N ∑ j = 1 N α i α j y i y j \sum\limits_{i=1}^N\sum\limits_{j=1}^N{\alpha_i\alpha_jy_iy_j} i=1Nj=1Nαiαjyiyj,而且没有不等式约束,只有一个等式约束,以及自变量的下界。
代码如下:

%% 线性可分数据用支持向量机分类,其求解采【用二次规划函数
clc;clear;
% 初始化数据集
random_1 = unifrnd(8,12,100,2);
random = [random_1(1:50,:);random_1(51:100,:)+4];
y = [zeros(50,1)-1;ones(50,1)]; % 标签数据
X = random; % 特征数据
% 可视化
scatter(random(1:50,1),random(1:50,2),'red')
hold on
grid on
scatter(random(51:100,1),random(51:100,2),'blue')


%% 采用Matlab自带的二次规划函数求解问题
% 构建二次系数矩阵H
H = [];
for i =1:length(X)
    for j = 1:length(X)
        H(i,j) = X(i,:)*(X(j,:))'*y(i)*y(j);
    end
end
% 构造一次项系数f
f = zeros(length(X),1)-1;
A = [];b = []; % 不等式约束
Aeq = y';beq = 0; % 等式约束
ub = [];lb = zeros(length(X),1); % 自变量范围
[x,fval] = quadprog(H,f,A,b,Aeq,beq,lb,ub);
% x表示自变量的解,以及在x处的函数值
% 将很小的x直接赋值为0
x(x < 1e-5) = 0;

% 利用求解得到x求解系数w
w = [0,0];
[a,~] = find(x~=0); % 找到可以求解b的值
temp = 0;
for i = 1:length(X)
    w = w + x(i)*y(i)*X(i,:);
    temp = temp + x(i)*y(i)*X(i,:)*X(a(1),:)';
end
% 计算偏置系数
b = y(a(1)) - temp;

% 数据可视化
k = - w(1)/w(2); % 构造截距式
b_ = -b/w(2); % 构造系数b
m = 8:2:16; % 生成一些点
n = k*m+b_;
plot(m,n,'--')
n_2 = k*m+b_+1/w(2);
hold on
plot(m,n_2,'--')
n_3 = k*m+b_-1/w(2);
plot(m,n_3,'--');
grid on
title('线性可分支持向量机分类结果')
legend('类别1','类别二','分界线')

% 添加文本说明可视化
% 获取支持向量下标
Vctor_index = find(x~=0);
% 对下标进行分类
Vctor_length = length(Vctor_index); % 获取支持向量的个数
category_1 = []; % 定义第一类
category_2 = []; % 定义第二类
% 对支持向量的下标进行遍历然后一一分类
for i =1:Vctor_length
    if y(Vctor_index(i))==-1
        category_1 = [category_1;Vctor_index(i)];
    else
        category_2 = [category_2;Vctor_index(i)];
    end
end
% 分类进行可视化
%绘制第一类category_1,用红色填充
scatter(X(category_1,1),X(category_1,2),'filled','r','HandleVisibility','off')
t1 = text(X(category_1,1)+0.1,X(category_1,2)-0.1,'支持向量','Color','red');
t1.Color = 'red';

% 绘制第二类category_2,用蓝色填充
scatter(X(category_2,1),X(category_2,2),'filled','blue','HandleVisibility','off')
t2 = text(X(category_2,1)+0.1,X(category_2,2)-0.1,'支持向量','Color','blue');


% 计算支持向量到超平面的距离
D_1 = abs(w*X(category_1(1),:)'+ b)/norm(w,2);
D_2 = abs(w*X(category_2(1),:)'+ b)/norm(w,2);
disp(['正类支持向量到超平面的距离为',num2str(D_1)])
disp(['负类支持向量到超平面的距离为',num2str(D_2)]

运行结果如下:
在这里插入图片描述
在这里插入图片描述
  代码在实现中分为创建数据、求解二次规划和结果可视化这三个模块。最后通过对结果图的分析,我们发现一般来说支持向量是有两个的,而且这两个支持向量到超平面的距离还是相等的。不过有的时候支持向量可以有两个或者更多,此时同一类的支持向量都在一条线上,且它们到超平面的距离全部都是相等的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值