SVM应用
我在项目中应用的SVM库是国立台湾大学林智仁教授开发的一套开源软件,主要有LIBSVM与LIBLINEAR两个,LIBSVM是对非线性数据进行分类,大家也比较熟悉,LIBLINEAR是对线性数据进行分类,时间复杂度较之LIBSVM要低得多,而且运用于嵌入式领域的话产生的训练集占用芯片内存也要少得多,所以如果需要分类的数据有比较好的区分度的话,推荐使用LIBLINEAR。
LIBLINEAR主要解决大规模数据分类,先来看一下前几章提到的最优间隔分类器模型:

基于上面的模型,LIBLINEAR提供了8种分类方法和3中回归方法,而且能够任意的设置,优化参数。下面是源码中对LIBLINEAR的功能介绍:
void exit_with_help()
{
printf(
"Usage: train [options] training_set_file [model_file]\n"
"options:\n"
"-s type : set type of solver (default 1)\n"
" for multi-class classification\n"
" 0 -- L2-regularized logistic regression (primal)\n"
" 1 -- L2-regularized L2-loss support vector classification (dual)\n"
" 2 -- L2-regularized L2-loss support vector classification (primal)\n"
" 3 -- L2-regularized L1-loss support vector classification (dual)\n"
" 4 -- support vector classification by Crammer and Singer\n"
" 5 -- L1-regularized L2-loss support vector classification\n"
" 6 -- L1-regularized logistic regression\n"
" 7 -- L2-regularized logistic regression (dual)\n"
" for regression\n"
" 11 -- L2-regularized L2-loss support vector regression (primal)\n"
" 12 -- L2-regularized L2-loss support vector regression (dual)\n"
" 13 -- L2-regularized L1-loss support vector regression (dual)\n"
"-c cost : set the parameter C (default 1)\n"
"-p epsilon : set the epsilon in loss function of SVR (default 0.1)\n"
"-e epsilon : set tolerance of termination criterion\n"
" -s 0 and 2\n"
" |f'(w)|_2 <= eps*min(pos,neg)/l*|f'(w0)|_2,\n"
" where f is the primal function and pos/neg are # of\n"
" positive/negative data (default 0.01)\n"
" -s 11\n"
" |f'(w)|_2 <= eps*|f'(w0)|_2 (default 0.001)\n"
" -s 1, 3, 4, and 7\n"
" Dual maximal violation <= eps; similar to libsvm (default 0.1)\n"
" -s 5 and 6\n"
" |f'(w)|_1 <= eps*min(pos,neg)/l*|f'(w0)|_1,\n"
" where f is the primal function (default 0.01)\n"
" -s 12 and 13\n"
" |f'(alpha)|_1 <= eps |f'(alpha0)|,\n"
" where f is the dual function (default 0.1)\n"
"-B bias : if bias >= 0, instance x becomes [x; bias]; if < 0, no bias term added (default -1)\n"
"-wi weight: weights adjust the parameter C of different classes (see README for details)\n"
"-v n: n-fold cross validation mode\n"
"-q : quiet mode (no outputs)\n"
);
exit();
}
库的实现主要在linear.cpp这个文件中,其中train()函数负责训练数据得出相应的model,predict()函数负责预判未知的输入数据。具体的使用帮助请参考软件包中的README文件。我在项目中使用的训练方法主要是坐标下降法,下面就是坐标下降法 的主要原理和应用。
L2-regularized L1- and L2-loss Support Vector Classification(dual)
L2-regularized L1-loss support vector classification (dual)的最优化模型:

L2-regularized L2-loss support vector classification (dual)的最后化模型:

他们的对偶形式都是

下面讨论的求解过程以L1 SVC为准,L1与L2的泛化能力差不多,而训练时间一般L2要快些。
在求解这个方程之前我们先来了解一下坐标下降法(上述对偶形式的求解方法)。

J(θ)以线性回归的例子来定义:

这里的α是叫做学习速度(learning rate), 它决定了坐标下降的幅度大小,假设在只有一个训练样本的情况下对J(θ)求偏导并代入上式:


Θ的大小与误差偏移(y-h(x))成比例,也就是说如果遇上一个与实际值相近的预测值,则我们几乎不需要对θ做改变,相反,如遇到差距比较大的值,则要对θ做一定的调整。
现在再回到先前提到的对偶问题

为方便起见,我们把式子改写成:

对
关于
求导得


当d=0,即
时收敛,也就是说
达到最优值,在先前SVM原理简介中提到
,带入到
中得到:
。在更新α的同时我们也需要更新w:
,其中
是更新后的值,
是更新前的值,
,两个值的差值d可以对上面的
关于d求导得到 :
,可能写的比较乱,下面列出整个流程的伪代码来理清思路。

贴出LIBLINEAR源码中使用坐标下降法的核心代码
if(fabs(PG) > 1.0e-12)
{
double alpha_old = alpha[i];
alpha[i] = min(max(alpha[i] - G/QD[i], 0.0), C);
d = (alpha[i] - alpha_old)*yi;
xi = prob->x[i];
while (xi->index != -)
{
w[xi->index-] += d*xi->value;
xi++;
}
}
至于LIBLINEAR用到的其他方法(比如牛顿法)由于空余时间有限,也因为我在项目中用到的SVM对于训练时间没有太多要求,等有时间再来好好研究一下。一般来讲牛顿法比坐标下降法收敛的迭代次数要少得多,牛顿法要用到Hesse矩阵,所以每次迭代的运算量将会更大,但总的来说使用牛顿法所消耗的训练时间还是要比坐标下降法快得多,特别在特征量比较少的时候。
下面再来看predict,LIBLINEAR在训练时求出来的实际上就是个超平面,在预测时只要判断未知点在超平面的里面还是外面就可以完成判断,是常数级别的时间复杂度。因为我使用的SVM应用于嵌入式领域,使用核函数的SVM对于我来说太慢了,而LIBLINEAR刚好符合我的要求,在实际使用时我选取的是6个特征量,在cortex-m3中平均0.25ms就可以完成一次预测。下面是predict的源码。
double predict_values(const struct model *model_, const struct feature_node *x, double *dec_values)
{
int idx;
int n;
if(model_->bias>=)
n=model_->nr_feature+;
else
n=model_->nr_feature;
double *w=model_->w;
int nr_class=model_->nr_class;
int i;
int nr_w;
if(nr_class== && model_->param.solver_type != MCSVM_CS)
nr_w = ;
else
nr_w = nr_class; const feature_node *lx=x;
for(i=;i<nr_w;i++)
dec_values[i] = ;
for(; (idx=lx->index)!=-; lx++)
{
// the dimension of testing data may exceed that of training
if(idx<=n)
for(i=;i<nr_w;i++)
dec_values[i] += w[(idx-)*nr_w+i]*lx->value;
} if(nr_class==)
{
if(model_->param.solver_type == L2R_L2LOSS_SVR ||
model_->param.solver_type == L2R_L1LOSS_SVR_DUAL ||
model_->param.solver_type == L2R_L2LOSS_SVR_DUAL)
return dec_values[];
else
return (dec_values[]>)?model_->label[]:model_->label[];
}
else
{
int dec_max_idx = ;
for(i=;i<nr_class;i++)
{
if(dec_values[i] > dec_values[dec_max_idx])
dec_max_idx = i;
}
return model_->label[dec_max_idx];
}
}
对于惩罚因子C的优化问题,可以借助LIBSVM中grid.py这个工具,它使用交叉验证来选出预测精度最高的那个参数,如果同时优化两个参数(RBF kernel中的c和g),它可以借助gnuplot画出等高线来帮助我们直观的了解整个优化的过程,当然可以根据你自己的需要来修改grid.py来优化你想要的参数,非常有用的小工具。
Usage: grid.py [grid_options] [svm_options] dataset grid_options :
-log2c {begin,end,step | "null"} : set the range of c (default -,,)
begin,end,step -- c_range = ^{begin,...,begin+k*step,...,end}
"null" -- do not grid with c
-log2g {begin,end,step | "null"} : set the range of g (default ,-,-)
begin,end,step -- g_range = ^{begin,...,begin+k*step,...,end}
"null" -- do not grid with g
-v n : n-fold cross validation (default )
-svmtrain pathname : set svm executable path and name
-gnuplot {pathname | "null"} :
pathname -- set gnuplot executable path and name
"null" -- do not plot
-out {pathname | "null"} : (default dataset.out)
pathname -- set output file path and name
"null" -- do not output file
-png pathname : set graphic output file path and name (default dataset.png)
-resume [pathname] : resume the grid task using an existing output file (default pathname is dataset.out)
This is experimental. Try this option only if some parameters have been checked for the SAME data.
SVM应用的更多相关文章
- EasyPR--开发详解(6)SVM开发详解
在前面的几篇文章中,我们介绍了EasyPR中车牌定位模块的相关内容.本文开始分析车牌定位模块后续步骤的车牌判断模块.车牌判断模块是EasyPR中的基于机器学习模型的一个模块,这个模型就是作者前文中从机 ...
- 8.SVM用于多分类
从前面SVM学习中可以看出来,SVM是一种典型的两类分类器.而现实中要解决的问题,往往是多类的问题.如何由两类分类器得到多类分类器,就是一个值得研究的问题. 以文本分类为例,现成的方法有很多,其中一劳 ...
- 5.SVM核函数
核函数(Kernels) 定义 1.1 (核或正定核) 设是中的一个子集,称定义在上的函数是核函数,如果存在一个从到Hilbert空间的映射 使得对任意的,都成立.其中表示Hilbert空间中的内积. ...
- 4. SVM分类器求解(2)
最优间隔分类器(optimal margin classifier) 重新回到SVM的优化问题: 我们将约束条件改写为: 从KKT条件得知只有函数间隔是1(离超平面最近的点)的线性约束式前面的系数,也 ...
- 2. SVM线性分类器
在一个线性分类器中,可以看到SVM形成的思路,并接触很多SVM的核心概念.用一个二维空间里仅有两类样本的分类问题来举个小例子.如图所示 和是要区分的两个类别,在二维平面中它们的样本如上图所示.中间的直 ...
- 1. SVM简介
从这一部分开始,将陆续介绍SVM的相关知识,主要是整理以前学习的一些笔记内容,梳理思路,形成一套SVM的学习体系. 支持向量机(Support Vector Machine)是Cortes和Vapni ...
- SVM分类与回归
SVM(支撑向量机模型)是二(多)分类问题中经常使用的方法,思想比较简单,但是具体实现与求解细节对工程人员来说比较复杂,如需了解SVM的入门知识和中级进阶可点此下载.本文从应用的角度出发,使用Libs ...
- 【十大经典数据挖掘算法】SVM
[十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART SVM(Support Vector ...
- 卷积神经网络提取特征并用于SVM
模式识别课程的一次作业.其目标是对UCI的手写数字数据集进行识别,样本数量大约是1600个.图片大小为16x16.要求必须使用SVM作为二分类的分类器. 本文重点是如何使用卷积神经网络(CNN)来提取 ...
- 机器学习实战笔记(Python实现)-05-支持向量机(SVM)
--------------------------------------------------------------------------------------- 本系列文章为<机器 ...
随机推荐
- iOS UICollectionView简单使用
UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableVie ...
- iOS视频录制、压缩导出、取帧
概述 花了点时间研究了一下常用的视频获取.录制.压缩.取帧图功能,分享给大家了!相信阅读完本篇文章,会对你有很大的帮助的! 本篇文章研究几下以个功能: 视频录制 从相册选择视频 保持视频到相册 获取视 ...
- Go推出的主要目的之一就是G内部大东西太多了,系统级开发巨型项目非常痛苦,Go定位取代C++,Go以简单取胜(KISS)
以前为了做compiler,研读+实现了几乎所有种类的语言.现在看语法手册几乎很快就可以理解整个语言的内容.后来我对比了一下go和rust,发现go的类型系统简直就是拼凑的.这会导致跟C语言一样,需要 ...
- Photoshop技巧:图层蒙版同步隐藏图层样式
原效果: 添加图层蒙版后,遮住一半,图层样式仍在,如: 进入图层样式,勾选“图层蒙版隐藏效果” 最终效果:
- PCL—低层次视觉—关键点检测(NARF)
关键点检测本质上来说,并不是一个独立的部分,它往往和特征描述联系在一起,再将特征描述和识别.寻物联系在一起.关键点检测可以说是通往高层次视觉的重要基础.但本章节仅在低层次视觉上讨论点云处理问题,故所有 ...
- mysql shell
mysql 查询10分钟以内的数据:select *from t_agent where int_last_login>=CURRENT_TIMESTAMP - INTERVAL 10 MINU ...
- (step4.3.4)hdu 1258(Sum It Up——DFS)
题目大意:输入t,n,接下来有n个数组成的一个序列.输出总和为t的子序列 解题思路:DFS 代码如下(有详细的注释): #include <iostream> #include <a ...
- BZOJ 2820 YY的GCD(莫比乌斯函数)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2820 题意:给定n,m.求1<=x<=n, 1<=y<=m且Gc ...
- poj 3273 Monthly Expense(贪心+二分)
题目:http://poj.org/problem?id=3273 题意:把n个数分成m份,使每份的和尽量小,输出最大的那一个的和. 思路:二分枚举最大的和,时间复杂度为O(nlog(sum-max) ...
- 无法连接到SQL Server 2008 R2
服务器环境: 操作系统 名称: Microsoft Windows Server 2008 R2 Enterprise 版本: 6.1.7601 服务包: Ser ...