前面几节我们讨论了SVM原理、求解线性分类下SVM的SMO方法。本节将分析SVM处理非线性分类的相关问题。

一般的非线性分类例如以下左所看到的(后面我们将实战以下这种情况):



能够看到在原始空间中你想用一个直线分类面划分开来是不可能了,除非圆。而当你把数据点映射一下成右图所看到的的情况后,如今数据点明显看上去是线性可分的,那么在这个空间上的数据点我们再用前面的SVM算法去处理,就能够得到每一个数据点的分类情况了,而这个分类情况也是我们在低维空间的情况。也就是说,单纯的SVM是不能处理非线性问题的,说白了仅仅能处理线性问题,可是来了非线性样本怎么办呢?我们是在样本上做的文章,我把非线性样本变成线性样本,再去把变化后的线性样本拿去分类,经过这么一圈。就达到了把非线性样本分开的目的。所以仅仅看开头和结尾的话发现,SVM居然能够分非线性问题,事实上呢还是分的线性问题。

如今的问题是怎样找到这个映射关系对吧,就比方上面那个情况,我们能够人为计算出这种映射,比方一个样本点是用坐标表示的(x1,x2),它有个类标签,如果为1。那么把这个点映射到三维中变成(x21,2√x1x2,x22)。对每一个点我都这么去映射,如果一个原始点样本集是这种:



然后依照上面那个公式去把每一个点映射成3维坐标点后,画出来是这种:



能够看到是线性可分的吧。如果还看不清把视角换个角度(右视图):



如今能看清楚了吧。

那这是二维的点到三维。映射的关系就是上面的那个关系,那如果是三维到四维,四维到N维呢?这个关系你还想去找吗?理论上是找的到的。可是实际上人工去找你怎么去找?你怎么知道数据的映射关系是这种是那样的?不可能知道。然而我们真的须要找到这种关系吗?答案是不须要的。返回去看看前三节的关于SVM的理论部分能够看到,不管是计算α呀。还是b呀等等,仅仅要涉及到原始数据点的。都是以内积的形式出来的,也就是说是一个点的向量与还有一个点的向量相乘的。向量内积出来是一个值。

就拿α的更新来说,例如以下:

αnew2=αold2−y2(E1−E2)η其中Ei=ui−yiη=2K(x1,x2)−K(x1,x1)−K(x2,x2)

能够看到α的更新用到原始数据点的就在η的计算上。

而η的计算能够看到K表示的是内积,就是两个点的内积或者自己内积。

如果如今两个点的坐标非别是X1=(x1,y1),X2=(x2,y2)。那么

K(X1,X2)=XT1∗X2=x1x2+y1y2=C1

其它依次类推,K出来的是一个数比方C1。

那么如果这个样本点都映射到三维以后了,每一个样本点是一个1*3的向量。那么计算到这一块来了,就变成了以下这样:K(X1,X2)=XT1∗X2=(x1,y1,z1)T∗(x2,y2,z2)=x1y1+x2y2+x3y3=C2

最后也是得到一个值比方C2。既然SVM里面全部涉及到原始数据的地方都是以向量的形式出现的,那么我们还须要管它的映射关系吗?由于它也不须要你去计算说详细到比方说三维以后。三维里面的三个坐标值到底是多少,他须要的是内积以后的一个结果值。那么好办了,我就如果有一个黑匣子,输入原始数据维度下的两个坐标向量。然后经过黑匣子这么一圈,出来一个值,这个值我们就觉得是高维度下的值。

而黑匣子的潜在意义就相当于一个高维映射器一样。

更重要的是我们并不须要知道黑匣子到底是怎么映射的,仅仅须要知道它的低纬度下的形式就能够了。经常使用的黑匣子就是径向基函数。而这个黑匣子在数学上就叫做核函数,比如径向基函数的外在形式例如以下所看到的:

K(X1,X2)=exp(−||X1−X2||2σ)

σ是须要预先设定的參数。至于这个黑匣子把初始数据映射到多少维了。谁知道呢,既然是黑匣子。那就是看不到的,上帝给了人类这么一个黑匣子就已经很够意思了。能够看到的是原始数据结果黑匣子算了以后,出来就是一个值了。而这个值就觉得是高维度下的数据通过内积计算而来的值。当然上帝还留了一个窗户,就是σ,相传σ选取的越小,数据映射的维度越大,小到一定程度,维度空间大到无穷维。反之越大,映射的维度空间就越小,可是会不会小到低于原始空间维度呢?谁知道了,然而通过实验我发现,大到一定程度,样本点分的乱七八糟,而且σ正好在一定范围的时候效果很好,这个范围既不是极小的范围。也不是极大的范围。那这暗示了什么呢?也就是说非线性原始样本是有一个属于他自己的最佳高维空间的,大了小了似乎都不好。

好了既然黑匣子是藏着的。那也就仅仅能说这么多了。

有趣的是上帝给的这个黑匣子不止一个,有好几个,仅仅是上面的那个普遍效果更好而已。

基于此,那么对于上节的SMO算法,如果拿来求解非线性数据的话,我们仅仅须要将当中相应的内积部分改成核函数的形式就可以。一个数据核函数程序例如以下:

function result = Kernel(data1,data2,sigma)
% data里面每一行数据是一个样本(的行向量)
[m1,~] = size(data1);
[m2,~] = size(data2);
result = zeros(m1,m2);
for i = 1:m1
for j = 1:m2
result(i,j) = exp(-norm(data1(i,:)-data2(j,:))/(2*sigma^2));
end
end

有了此核函数。我们用上节的随机遍历α的方式(这个函数代码少一点)来实验一下非线性样本,非线性样本例如以下:



然后把主程序相应的部分用上述核函数取代:

%%
% * svm 简单算法设计
%
%% 载入数据
% * 终于data格式:m*n,m样本数。n维度
% * label:m*1 标签必须为-1与1这两类
clc
clear
% close all
data = load('data_test1.mat');
data = data.data;
train_data = data(1:end-1,:)';
label = data(end,:)';
[num_data,d] = size(train_data);
data = train_data;
%% 定义向量机參数
alphas = zeros(num_data,1);
% 系数
b = 0;
% 松弛变量影响因子
C = 0.6;
iter = 0;
max_iter = 80;
% 核函数的參数
sigma = 4;
%%
while iter < max_iter
alpha_change = 0;
for i = 1:num_data
%输出目标值
pre_Li = (alphas.*label)'*Kernel(data,data(i,:),sigma) + b;
%样本i误差
Ei = pre_Li - label(i);
% 满足KKT条件
if (label(i)*Ei<-0.001 && alphas(i)<C)||(label(i)*Ei>0.001 && alphas(i)>0)
% 选择一个和 i 不同样的待改变的alpha(2)--alpha(j)
j = randi(num_data,1);
if j == i
temp = 1;
while temp
j = randi(num_data,1);
if j ~= i
temp = 0;
end
end
end
% 样本j的输出值
pre_Lj = (alphas.*label)'*Kernel(data,data(j,:),sigma) + b;
%样本j误差
Ej = pre_Lj - label(j);
%更新上下限
if label(i) ~= label(j) %类标签同样
L = max(0,alphas(j) - alphas(i));
H = min(C,C + alphas(j) - alphas(i));
else
L = max(0,alphas(j) + alphas(i) -C);
H = min(C,alphas(j) + alphas(i));
end
if L==H %上下限一样结束本次循环
continue;end
%计算eta
eta = 2*Kernel(data(i,:),data(j,:),sigma)- ...
Kernel(data(i,:),data(i,:),sigma)...
- Kernel(data(j,:),data(j,:),sigma);
%保存旧值
alphasI_old = alphas(i);
alphasJ_old = alphas(j);
%更新alpha(2),也就是alpha(j)
alphas(j) = alphas(j) - label(j)*(Ei-Ej)/eta;
%限制范围
if alphas(j) > H
alphas(j) = H;
elseif alphas(j) < L
alphas(j) = L;
end
%如果alpha(j)没怎么改变,结束本次循环
if abs(alphas(j) - alphasJ_old)<1e-4
continue;end
%更新alpha(1)。也就是alpha(i)
alphas(i) = alphas(i) + label(i)*label(j)*(alphasJ_old-alphas(j));
%更新系数b
b1 = b - Ei - label(i)*(alphas(i)-alphasI_old)*...
Kernel(data(i,:),data(i,:),sigma) - label(j)*...
(alphas(j)-alphasJ_old)*Kernel(data(i,:),data(j,:),sigma);
b2 = b - Ej - label(i)*(alphas(i)-alphasI_old)*...
Kernel(data(i,:),data(j,:),sigma)- label(j)*...
(alphas(j)-alphasJ_old)*Kernel(data(j,:),data(j,:),sigma);
%b的几种选择机制
if alphas(i)>0 && alphas(i)<C
b = b1;
elseif alphas(j)>0 && alphas(j)<C
b = b2;
else
b = (b1+b2)/2;
end
%确定更新了,记录一次
alpha_change = alpha_change + 1;
end
end
% 没有实行alpha交换,迭代加1
if alpha_change == 0
iter = iter + 1;
%实行了交换,迭代清0
else
iter = 0;
end
disp(['iter ================== ',num2str(iter)]);
end
%% 计算权值W
% W = (alphas.*label)'*data;
%记录支持向量位置
index_sup = find(alphas ~= 0);
%计算预測结果
predict = (alphas.*label)'*Kernel(data,data,sigma) + b;
predict = sign(predict);
%% 显示结果
figure;
index1 = find(predict==-1);
data1 = (data(index1,:))';
plot(data1(1,:),data1(2,:),'+r');
hold on
index2 = find(predict==1);
data2 = (data(index2,:))';
plot(data2(1,:),data2(2,:),'*');
hold on
dataw = (data(index_sup,:))';
plot(dataw(1,:),dataw(2,:),'og','LineWidth',2);
title(['核函数參数sigma = ',num2str(sigma)]);

以下是几个不同參数下的结果:









能够看到σ到4以后就分不出来了。绿色的为支持向量,能够看到在σ在0.6到1之间是最少的,结果应该也是最好的。

至此SMO实验非线性样本完成。

当今学者已经有很多的人研究SVM算法。同一时候开发了很多开源的程序,这些程序都是经过不断优化的。性能比起我们这里自己编的来说要好得多,所以在实际应用中通常都是用他们无私贡献的软件包。

一个典型的软件包就是台湾一个教授团队的LIBSVM软件包。那么你是否想一窥其使用方法。看看它的性能怎样呢?请看下节matlab下LIBSVM的简单使用。

解密SVM系列(四):SVM非线性分类原理实验的更多相关文章

  1. kafka系列四、kafka架构原理、高可靠性存储分析及配置优化

    一.概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如Cl ...

  2. 10.Java 加解密技术系列之 DH

    Java 加解密技术系列之 DH 序 概念 原理 代码实现 结果 结束语 序 上一篇文章中简单的介绍了一种非对称加密算法 — — RSA,今天这篇文章,继续介绍另一种非对称加密算法 — — DH.当然 ...

  3. 8.Java 加解密技术系列之 PBE

    Java 加解密技术系列之 PBE 序 概念 原理 代码实现 结束语 序 前 边的几篇文章,已经讲了几个对称加密的算法了,今天这篇文章再介绍最后一种对称加密算法 — — PBE,这种加密算法,对我的认 ...

  4. 7.java 加解密技术系列之 AES

    java 加解密技术系列之 AES 序 概念 原理 应用 代码实现 结束语 序 这篇文章继续介绍对称加密算法,至于今天的主角,不用说,也是个厉害的角色 — — AES.AES 的出现,就是为了来替代原 ...

  5. 解密SVM系列(二):SVM的理论基础(转载)

    解密SVM系列(二):SVM的理论基础     原文博主讲解地太好了  收藏下 解密SVM系列(三):SMO算法原理与实战求解 支持向量机通俗导论(理解SVM的三层境界) 上节我们探讨了关于拉格朗日乘 ...

  6. 吴裕雄 python 机器学习——支持向量机SVM非线性分类SVC模型

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

  7. 【机器学习算法基础+实战系列】SVM

    概述 支持向量机是一种二分类模型,间隔最大使它有别于感知机.支持向量机学习方法由简至繁的模型:线性可分支持向量机(linear support vector machine in linearly s ...

  8. 机器学习四 SVM

    目录 引言 SVM 线性可分SVM 线性不可分SVM Hinge Loss 非线性SVM 核函数 总结 参考文献 引言 在深度神经网终(Deep Neural Network, DNN) 大热之前, ...

  9. java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现

    java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...

随机推荐

  1. React Native踩坑之Unable to load script from assets

    报错: Unable to load script from assets 'index.android.bundle'. Make sure your bundle is packaged corr ...

  2. cdoj1092-韩爷的梦 (字符串hash)【hash】

    http://acm.uestc.edu.cn/#/problem/show/1092 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limi ...

  3. 深入理解正则表达式-----应用于检测csrf的正则表达式

    如何写检测和防御csrf的规则?我们可以利用正则表达式进行匹配.对POST包进行正则匹配,这里只是提供了一个思路. pcre:"/POST \/(?P<uri>.*?) HTTP ...

  4. 使用ApplicationContext

    ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特,容器创建时就创建了singleton Bean 相对BeanFactory而言,ApplicationCo ...

  5. Hibernate 基于外键的双向一对一关联映射

    之前简单介绍了基于外键的单项一对一的关联映射关系,本文简单介绍基于外键的双向一对一的关联映射. 1.设计表结构 表结构对于双向一对一来说没有多少改变,只是双向都可以获取到对方. 2.创建Person对 ...

  6. [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)

    3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 449  Solved: 254[Submit][Sta ...

  7. UI/GUI/UE/UX/ID/UED/UCD的区别

    简述: UI (User Interface):用户界面 UE (User Experience):用户体验 ID (Interaction design):交互设计 UID (User Interf ...

  8. ArrayList源码阅读----JDK1.8

    //定义一个默认的长度10 private static final int DEFAULT_CAPACITY = 10; //定义空的数组 private static final Object[] ...

  9. Codeforces Round #302 (Div. 2) C. Writing Code 简单dp

    C. Writing Code Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544/prob ...

  10. Shell基础学习(七) 输入输出重定向

    命令 说明 command>file 将输出重定向到file command<file 将输入重定向到file command >> file 将输出追加到file n > ...