|
|
@ -1,38 +0,0 @@
|
|
|
|
SVM原理:
|
|
|
|
|
|
|
|
支持向量机(SVM)是Vapnik及其研究小组提出的针对二类别的分类问题而提出的一种分类技术,是一种新的非常有发展前景的分类技术。支持向量机的基本思想是在样本空间或特征空间,构造出最优超平面使超平面与不同类样本集之间的距离最大,从而达到最大的泛化能力,其算法的详细叙述可参考文献。 支持向量机方法根据Vapnik的结构风险最小化原则,尽量提高学习机的泛化能力,使有限少量训练样本得到的决策规则对独立的测试集仍能得到小的误差。这样只需有限的少量样本参与训练,就可以保证训练产生的分类器具有很小的误差。而车牌字符识别时,相对于预测的样本,只能有有限的少量样本参与训练,支持向量机的方法可以使训练产生的分类器在识别车牌字符时只有小的误差,并且大幅减少训练的时间。
|
|
|
|
|
|
|
|
对于数据分类问题,通用的神经网络方法的机理可以简单地描述为:系统随机产生一个超平面并移动它,直到训练集中属于不同类别的点正好位于平面的不同侧面。这种处理机制决定了神经网络方法最终获得的分割平面并不是一个最优超平面,只是一个局部的次优超平面。而SVM将最优超平面的求解问题转换为一个不等式约束下的二次函数寻优问题,这是一个凸二次优化问题,存在唯一解,能保证找到的极值解就是全局最优解。 SVM通过一个非线性函数将输入数据映射到具有高维甚至为无穷维的特征空间,并在这个高维特征空间进行线性分类,构造最优分类超平面,但在求解最优化问题和计算判别函数时并不需要显式计算该非线性函数,而只需计算核函数,从而避免特征空间维数灾难问题。 车牌字符识别问题中每个样本为一个字符图像,每个字符图像由许多像素组成,具有高维的特点。SVM通过核函数的计算,避免了神经网络解决样本空间的高维问题带来的网络结构设计问题,使训练模型与输入数据的维数无关;并且每个字符的整幅图像作为一个样本输入,不需要进行特征提取,节省了识别时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SVM算法:
|
|
|
|
|
|
|
|
支持向量机(SVM)是通过已知训练点的类别,求训练点和类别之间的对应关系,以便将训练集按照类别分开,或者是预测新的训练点所对应的类别。其数据主要分为线性可分数据和非线性可分数据,通过建立数据之间的最优超平面来区分数据类别。最优超平面:假设线性可分样本(x1,d1),(x2,d2),....,(xn,dn),对于任意输入的样本,其期望输出都为1或-1(d=1或-1),用来代表两类类别的标识。当空间为二维空间时,直线可划分区域块,其方程为x1+x2 = 1,用向量表示即为[1,1]^{T}[x1,x2]-1 = 0当空间为三维空间时,平面可划分区域块,其方程为x1+x2+x3 = 1,用向量表示即为[1,1,1]^{T} [x1,x2,x3]-1 = 0由此推广到高维空间可得超平面方程为W^{T} X+b = 0(X为输入向量,W为向量权值,b为偏置),则W^{T} X+b > 0,d = 1;W^{T} X+b < 0,d = -1超平面与最近的样本之间的间隔称为分离边缘,用ρ表示,SVM的目标就是找到使ρ最大时的W和b由于无法直接求得W和b,可通过预测函数y = f(x) = sgn(W^{T} X+b)对给定样本的分类错误最小由几何数学可知空间内一点到最优超平面的距离为
|
|
|
|
|
|
|
|
r = (W^{T} X+b)/ ||W0||令g(x) = r ||W0|| = W^{T} X+b → r = g(x)/ ||W0|| = 1/ ||W0|| ,
|
|
|
|
|
|
|
|
d = 1;r = g(x)/ ||W0|| = -1/ ||W0|| ,d = -1所以分离边缘ρ = 2r = 2/ ||W0||线性可分数据最优超平面:最优超平面的权向量是训练样本向量的线性组合,且只有支持向量影响最终划分结果W = α01d1X1 + α02d2X2 + ... + α0ndnXnb = 1-W^{T} X非线性可分数据:SVM对于非线性可分的数据是将输入向量映射到一个高维度特征向量空间,如果选用的映射函数适当且特征空间的维数足够高,则大多数非线性可分模式在特征空间中可转化为线性可分模式,该构造与内积核相关以下为四种常用的核函数:线性核函数:
|
|
|
|
|
|
|
|
K(X,Xp) = X' Xp多项式核函数:K(X,Xp) = [(X Xp)+1]^qGauss核函数:K(X,Xp) = exp(- |X - X^p|^2/2ρ^2)Sigmoid核函数:K(X,Xp) = tanh(k(X·X^p))+c tanh(x)=(e^x - e^(-x))/(e^x + e^(-x))支持向量机的学习算法:(1)准备一组训练样本(x1,d1),(x2,d2),....,(xn,dn)(2)在约束条件α1d1+α2d2+ ... +αndn = 0,0<=α<=C下使目标函数Q(α)最大化的αop(3)计算最优权值W(4)对于待分类模式X,计算判别函数决定X的归属
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SVM性质:
|
|
|
|
|
|
|
|
稳健性与稀疏性:SVM的优化问题同时考虑了经验风险和结构风险最小化,因此具有稳定性。从几何观点,SVM的稳定性体现在其构建超平面决策边界时要求边距最大,因此间隔边界之间有充裕的空间包容测试样本 。SVM使用铰链损失函数作为代理损失,铰链损失函数的取值特点使SVM具有稀疏性,即其决策边界仅由支持向量决定,其余的样本点不参与经验风险最小化。在使用核方法的非线性学习中,SVM的稳健性和稀疏性在确保了可靠求解结果的同时降低了核矩阵的计算量和内存开销。
|
|
|
|
|
|
|
|
与其它线性分类器的关系:SVM是一个广义线性分类器,通过在SVM的算法框架下修改损失函数和优化问题可以得到其它类型的线性分类器,例如将SVM的损失函数替换为logistic损失函数就得到了接近于logistic回归的优化问题。SVM和logistic回归是功能相近的分类器,二者的区别在于logistic回归的输出具有概率意义,也容易扩展至多分类问题,而SVM的稀疏性和稳定性使其具有良好的泛化能力并在使用核方法时计算量更小。
|
|
|
|
|
|
|
|
作为核方法的性质:SVM不是唯一可以使用核技巧的机器学习算法,logistic回归、岭回归和线性判别分析(Linear DiscriminantAnalysis, LDA)也可通过核方法得到核logistic回归(kernel logistic regression)、核岭回归(kernel ridge regression)和核线性判别分析(Kernelized LDA, KLDA)方法。因此SVM是广义上核学习的实现之一。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SVM应用:
|
|
|
|
|
|
|
|
SVM在各领域的模式识别问题中有应用,包括人像识别、文本分类、手写字符识别、生物信息学等。包含SVM的编程模块。按引用次数,由台湾大学资讯工程研究所开发的LIBSVM是使用最广的SVM工具。LIBSVM包含标准SVM算法、概率输出、支持向量回归、多分类SVM等功能,其源代码由C编写,并有JAVA、Python、R、MATLAB等语言的调用接口、基于CUDA的GPU加速和其它功能性组件,例如多核并行计算、模型交叉验证等。
|
|
|
|
|
|
|
|
基于Python开发的机器学习模块scikit-learn提供预封装的SVM工具,其设计参考了LIBSVM。其它包含SVM的Python模块有MDP、MLPy、PyMVPA等。TensorFlow的高阶API组件Estimators有提供SVM的封装模型。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SVM实例:
|
|
|
|
|
|
|
|
# Example:
|
|
|
|
|
|
|
|
from sklearn import datasets
|
|
|
|
|
|
|
|
import numpy
|
|
|
|
|
|
|
|
from numpy import *
|
|
|
|
|
|
|
|
from sklearn import svm
|
|
|
|
|
|
|
|
print ('''加载数据集''')
|
|
|
|
|
|
|
|
digits = datasets.load_digits()
|
|
|
|
|
|
|
|
# 例如在digits数据集中,digits.data是可以用来分类数字样本的特征
|
|
|
|
|
|
|
|
print(digits.data,"type(digits.data)=%s"%type(digits.data))
|
|
|
|
|
|
|
|
print("shape(digits.data)=%s,%s"%shape(digits.data))
|
|
|
|
|
|
|
|
print (digits.target)
|
|
|
|
|
|
|
|
print ('''训练和预测''')
|
|
|
|
|
|
|
|
#选择参数
|
|
|
|
|
|
|
|
clf = svm.SVC(gamma=0.0001,C=100)
|
|
|
|
|
|
|
|
# 进行训练
|
|
|
|
|
|
|
|
clf.fit(digits.data[:-1],digits.target[:-1])
|
|
|
|
|
|
|
|
# 进行预测
|
|
|
|
|
|
|
|
print (clf.predict(digits.data[:-1]))
|
|
|
|
|