以图像分割为例浅谈支持向量机(SVM)

以图像分割为例浅谈⽀持向量机(SVM)
1. 什么是⽀持向量机?
  在机器学习中,分类问题是⼀种⾮常常见也⾮常重要的问题。常见的分类⽅法有决策树、聚类⽅法、贝叶斯分类等等。举⼀个常见的分类的例⼦。如下图1所⽰,在平⾯直⾓坐标系中,有⼀些点,已知这些点可以分为两类,现在让你将它们分类。
(图1)
显然我们可以发现所有的点⼀类位于左下⾓,⼀类位于右上⾓。所以我们可以很⾃然将它们分为两类,如图2所⽰:红⾊的点代表⼀类,蓝⾊的点代表⼀类。
加勒比海盗3电影(图2)
现在如果让你⽤⼀条直线将这两类点分开,这应该是⼀件⾮常容易的事情,⽐如如图3所⽰的三条直线都可以办到这点。
(图3)
事实上,可以很容易发现,我们可以作⽆数条直线将这两类点分开。这⾥,我们不禁要问,是不是所有的直线分类的效果都⼀样好呢?如果不是,那么哪⼀条直线分类效果最好呢?评判的标准⼜是什么?⽐如对于如图4所⽰的两条直线,\(line1\)和\(line2\),这两条直线哪条分类效果更好呢?
(图4)
直观上可以发现,\(line1\)的分类效果要⽐\(line2\)更好的,这是因为\(line1\)⼏乎位于这两类点的中间,不偏向于任何⼀类点;⽽\ (line2\)则偏向右上部分的点更多⼀些。如果这时⼜增加了⼀些点让你将它们归为这两类,显然\(line1\)要更“公正”⼀些,⽽\(line2\)则有可能将本来属于右上类的点错误地归为左下类。说到这⾥,你可能会问,如何才能确定那个最佳分类的直线呢?其实这正是⽀持向量机(\ (SVM,Support Vector Machine\))要解决的问题。
  更⼀般地情况下,如图5所⽰,有时两类点(图5中红⾊的点和蓝⾊的点)是交错分布的,“你中有我,我中有你”,根本不可能⽤⼀条直线分开,这个时候该怎么办呢?这也是⽀持向量机要解决的问题,⽽且是⽀持向量机的优势所在。这类问题叫做⾮线性分类问题。
(图5)
  说到这⾥,你可能⼤概有些明⽩⽀持向量机是⽤来⼲什么的了。⽀持向量机的基本模型是定义在特征空间上的间隔最⼤的线性分类器。它是⼀种⼆分类模型。当采⽤了核技巧之后,⽀持向量机即可以⽤于⾮线性分类。不同类型的⽀持向量机解决不同的问题。
1.线性可分⽀持向量机:当训练数据线性可分时,通过硬间隔最⼤化,学习⼀个线性可分⽀持向量机。
2. 线性⽀持向量机:当训练数据近似可分时,通过软间隔最⼤化,学习⼀个线性⽀持向量机。
3. ⾮线性⽀持向量机:当训练数据线性不可分时,通过使⽤核技巧以及软间隔最⼤化,学习⼀个⾮线性⽀持向量机。
  以上只是对于⽀持向量机的最粗浅的说明,其实⽀持向量机内在的数学原理还是⾮常复杂的,其内容也⼗分丰富。我在学习的过程中参考了不少教材,⽐如《数据挖掘导论》、《神经⽹络与机器学习》、《Python⼤战机器学习》等。⾥⾯对于⽀持向量机有⾮常详细的说明,⽽且还从数学的⾓度推导了⼀遍。个⼈觉得好好研究⼀下原理以及数学推导对于深刻理解⽀持向量机还是⾮常有帮助的。鉴于我这⾥只是介绍,⽽⾮严格地教程,所以公式就不罗列了,感兴趣的请⾃⾏阅读相关⽂献与书籍。
2. 如何理解⽀持向量机?
  如果不从数学公式的⾓度出发,在不涉及公式细节的情况下,如何直观理解⽀持向量机呢?虽然这并⾮易事(因为⽀持向量机的复杂性),但是还是可以办到的。我在查阅资料的过程中,看到了知乎上的⼀个问题,⾥⾯有⼏个答案我觉得⾮常棒,可以让你在不理解数学公式的情况下,对于⽀持向量机有⼀个直观的了解。地址如下:。这⾥我仍然以两类点的分类问题为例来谈谈我⾃⼰的理解。以图1中的两类点为例,前⾯我们已经说过了,存在⽆穷多条直线可以将这两类点分开。现在我们的⽬标是在⼀定的准则下,出划分最好的那⼀条。从直观的理解来看,这条最佳直线应该满⾜“公正性”:即不偏向任何⼀类点,或者说处于中间位置。现在假设我们已经到了⼀条分割直线\ (l\),每⼀个样本点都到这条直线存在⼀个距离。设直线\(l\)的⽅程为:\(wx + b = 0\),共有\(n\)个点,\(n\)个点的坐标为\((x_1,y_1), (x_2,y_2),\cdots,(x_n,y_n)\),\(n\)个点到直线\(l\)的距离分别为\(d_1,d_2,\cdots,d_n\),现在我们需要\(d_1,d_2,\cdots,d_n\)中的最⼩值:\(d_{min} = min\{d_1,d_2,\cdots,d_n\}\),显然我们希望\(d_{min}\)越⼤越好,\(d_{min}\)越⼤,说明它距离两类的距离都较远。于是问题转化为在所有可⾏的直线划分中,到 使得\(d_{min}\)最⼤的那条即是最佳划分直线。对于线性可分的情况⽽⾔,我们可以证明,这样的最佳直线总是存在的。我们称到的最佳划分两类的直线为:最⼤⼏何间隔分离超平⾯(对于⼆维点⽽⾔是直线,三维空间中则是平⾯,更⾼维则是超平⾯了,这⾥统称为超平⾯)。
什么是⽀持向量?
  ⽀持向量机(\(SVM\))之所以称之为⽀持向量机,是因为有⼀个叫作⽀持向量(\(Support Vector\))的东西。那么什么叫作⽀持向量呢?假设我们现在已经到了最⼤⼏何间隔分离超平⾯,容易理解,我们可以到许多条与这条直线平⾏的直线,在所有平⾏的直线中,存在两条直线,它们恰好可以划分两类点,所谓恰好是指,如果再平移哪怕⼀点点,就会不能正确划分两类点,这两条临界直线(超平⾯)被称之为间隔边界。对于线性可分的情况⽽⾔,我们可以证明,在样本点中总会有⼀些样本点落在间隔边界上(但是对于线性不可分的情况,则未必如此),落在间隔边界上的这些样本点就被我们称为⽀持向量。之所以被称之为⽀持向量呢,是因为我们确定的最⼤⼏何间隔分离超平⾯只与这些⽀持向量有关,与其他的样本点⽆关,也就是说哪怕你去掉再多⾮⽀持向量的点,最⼤⼏何间隔分离超平⾯也⼀样不变。这也就是⽀持向量机名字的来源。
⽀持向量机如何处理线性不可分的情况?
  这个问题其实涉及到\(SVM\)的核⼼了。在之前我们多次提到了⼀个词:核技巧。那么什么是核技巧呢?⾸先,我们需要明确输⼊空间与特征空间这两个概念。所谓输⼊空间就是我们定义样本点的空间,由于问题线性不可分,所以我们⽆法⽤⼀个超平⾯将两类点分开,但是我们总可以到⼀个合适的超曲⾯将两类点正确划分。问题的关键就是到这个超曲⾯。直接寻显然是很困难的,所以我们聪明的数学家就定义了⼀个映射,简单来说就是从低维到⾼维的映射,研究发现,如果映射定义地恰当,则原来在低维线性不可分的问题,到了⾼维居然就线性可分了!这真的是⼀个让⼈惊喜的发现。
所以我们只要在⾼维按照之前线性可分的情况去最⼤⼏何间隔分离超平⾯,到之后,再还原到低维就可以了。理论上已经证明,在低维线性不可分的情况下,我们总可以到合适的从低维到⾼维的映射,使得在⾼维线性可分。于是问题的关键就是这个从低维到⾼维的映射了,这个其实就是核函数(核技巧)要⼲的事情了。具体的定义较为复杂,这⾥不展开了。在给定核函数的情况下,我们可以利⽤求解线性分类问题的⽅法来求解⾮线性分类问题的⽀持向量机,学习是隐式地在特征空间(也就是映射之后的⾼维空间)进⾏的,这被称之为核技巧。在实际应⽤中,往往直接依赖经验选择核函数,然后再验证其是有效的即可。常⽤的核函数有:多项式核函数、⾼斯核函数、sigmoid核函数等。
3. ⽀持向量机的实际应⽤举例(附matlab代码与Python代码)
1. 将两类点分类(⼆维平⾯)
  作为第⼀个例⼦,我们⾸先解决开头提到的那个平⾯上两类点的分类问题。我们出最⼤⼏何间隔分离超平⾯与⽀持向量,然后验证该最佳超平⾯能否对新加⼊的点进⾏准确分类。这⾥我们分别使⽤Matlab与Pyhton来实现这个例⼦。Matlab中的\(svmtrain\)、\ (svmclassify\)函数以及Python sklearn(⼀个机器学习的库)均对SVM有很好的⽀持。如果想要详细了解⼆者的⽤法,对于Matlab可以直接查看其帮助⼿册,对于Pyhton则可以参考相关机器学习的书籍或者直接去看sklearn的⽹站学习。
Matlab 对两类点分类的代码:
% 使⽤SVM(⽀持向量机)分割两类点并画出图形
XY1 = 2 + rand(100,2); % 随机产⽣100⾏2列在2-3之间的点
XY2 = 3+ rand(100,2);% 随机产⽣100⾏2列在3-4之间的点
XY = [XY1;XY2]; % 合并两点
Classify =[zeros(100,1);ones(100,1)]; % 第⼀类点⽤0表⽰,第⼆类点⽤1表⽰
Sample = 2+ 2*rand(100,2); % 测试点
%figure(1);
%plot(XY1(:,1),XY1(:,2),'r*'); % 第⼀类点⽤红⾊表⽰
%hold on;
%plot(XY2(:,1),XY2(:,2),'b*'); % 第⼆类点⽤蓝⾊表⽰
% 训练SVM
SVM = svmtrain(XY,Classify,'showplot',true);
% 给测试点分类,并作出最⼤间隔超平⾯(⼀条直线)
svmclassify(SVM,Sample,'showplot',true);
得到结果如图6所⽰:
(图6)
图6中的直线即是所求的最⼤⼏何间隔分离超平⾯,画⿊圈的点为⽀持向量,⽽且可以看出其对新增加的点划分得很好,这说明了SVM最⼤⼏何间隔分离超平⾯分类的有效性。
再来看Python的代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time  : 2017/7/22 10:45
# @Author : Lyrichu
# @Email  : 919987476@qq
热女
# @File  : svm_split_points.py
'''
@Description:使⽤svm对两类点进⾏分类(线性可分)
'''
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC # 导⼊SVM 线性分类器
XY1 = 2 + np.random.rand(100,2) # 100⾏2列在2到3之间的数据点
XY2 = 4 + np.random.rand(100,2) # 100⾏2列在4到5之间的数据点
XY = np.concatenate((XY1,XY2),axis=0)
test_data = 2 + 3*np.random.rand(100,2) # 测试数据,2-5之间
label = np.s(100),np.ones(100)) # XY1 ⽤0标志,XY2⽤1标志svm = LinearSVC()
svm.fit(XY,label)
predict_test =svm.predict(test_data) # 对测试数据进⾏预测
coef = f_ # 系数(w向量)
intercept = svm.intercept_ # 截距(b)
jnk>缘毛鸟足兰
# print("coef:",coef)
# print("intercept:",intercept)
# print("predict_test:",predict_test)
sort1_index = predict_test == 0. # 测试数据属于第⼀类的序号(bool 数组)
sort2_index = predict_test == 1. # 测试数据属于第⼆类的序号(bool 数组)
test_sort1 = test_data[sort1_index,:] # 测试数据属于第⼀类的点
test_sort2 = test_data[sort2_index,:] # 测试数据属于第⼆类的点
躲羊羊
# 最⼤间隔超平⾯的⽅程为:Wx + b = 0
# 画图
plt.plot(XY1[:,0],XY1[:,1],'r*',label='train data 1')
plt.plot(XY2[:,0],XY2[:,1],'b*',label='train data 2')
line_x = np.arange(2,5,0.01) # 直线x坐标
line_y = (coef[0,0]*line_x + intercept[0])/(-coef[0,1]) # 直线y坐标
# 画出直线
朱毛会师发生在哪一年plt.plot(line_x,line_y,'-')
# 画出预测点
plt.plot(test_sort1[:,0],test_sort1[:,1],'r+',label='test data 1')
plt.plot(test_sort2[:,0],test_sort2[:,1],'b+',label='test data 2')
plt.legend(loc = 'best')
plt.show()

本文发布于:2024-09-24 17:19:12,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/570003.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线性   向量   直线   分类
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议