我在项目中应用的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应用的更多相关文章

  1. EasyPR--开发详解(6)SVM开发详解

    在前面的几篇文章中,我们介绍了EasyPR中车牌定位模块的相关内容.本文开始分析车牌定位模块后续步骤的车牌判断模块.车牌判断模块是EasyPR中的基于机器学习模型的一个模块,这个模型就是作者前文中从机 ...

  2. 8.SVM用于多分类

    从前面SVM学习中可以看出来,SVM是一种典型的两类分类器.而现实中要解决的问题,往往是多类的问题.如何由两类分类器得到多类分类器,就是一个值得研究的问题. 以文本分类为例,现成的方法有很多,其中一劳 ...

  3. 5.SVM核函数

    核函数(Kernels) 定义 1.1 (核或正定核) 设是中的一个子集,称定义在上的函数是核函数,如果存在一个从到Hilbert空间的映射 使得对任意的,都成立.其中表示Hilbert空间中的内积. ...

  4. 4. SVM分类器求解(2)

    最优间隔分类器(optimal margin classifier) 重新回到SVM的优化问题: 我们将约束条件改写为: 从KKT条件得知只有函数间隔是1(离超平面最近的点)的线性约束式前面的系数,也 ...

  5. 2. SVM线性分类器

    在一个线性分类器中,可以看到SVM形成的思路,并接触很多SVM的核心概念.用一个二维空间里仅有两类样本的分类问题来举个小例子.如图所示 和是要区分的两个类别,在二维平面中它们的样本如上图所示.中间的直 ...

  6. 1. SVM简介

    从这一部分开始,将陆续介绍SVM的相关知识,主要是整理以前学习的一些笔记内容,梳理思路,形成一套SVM的学习体系. 支持向量机(Support Vector Machine)是Cortes和Vapni ...

  7. SVM分类与回归

    SVM(支撑向量机模型)是二(多)分类问题中经常使用的方法,思想比较简单,但是具体实现与求解细节对工程人员来说比较复杂,如需了解SVM的入门知识和中级进阶可点此下载.本文从应用的角度出发,使用Libs ...

  8. 【十大经典数据挖掘算法】SVM

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART SVM(Support Vector ...

  9. 卷积神经网络提取特征并用于SVM

    模式识别课程的一次作业.其目标是对UCI的手写数字数据集进行识别,样本数量大约是1600个.图片大小为16x16.要求必须使用SVM作为二分类的分类器. 本文重点是如何使用卷积神经网络(CNN)来提取 ...

  10. 机器学习实战笔记(Python实现)-05-支持向量机(SVM)

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

随机推荐

  1. Python中的SET集合操作

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和 ...

  2. iOS动画篇:UIView动画

    iOS的动画效果一直都很棒很,给人的感觉就是很炫酷很流畅,起到增强用户体验的作用.在APP开发中实现动画效果有很多种方式,对于简单的应用场景,我们可以使用UIKit提供的动画来实现. UIView动画 ...

  3. Spring + JMS + ActiveMQ实现简单的消息队列(监听器异步实现)

    首先声明:以下内容均是在网上找别人的博客综合学习而成的,可能会发现某些代码与其他博主的相同,由于参考的文章比较多,这里对你们表示感谢,就不一一列举,如果有侵权的地方,请通知我,我可以把该文章删除. 1 ...

  4. 汇编debug 截图3

  5. 239. Sliding Window Maximum

    题目: Given an array nums, there is a sliding window of size k which is moving from the very left of t ...

  6. sql server 读取表结构

    SELECT 表名 then d.name else '' end, 字段序号=a.colorder, 主键 FROM sysobjects where xtype='PK' and name in ...

  7. mac 下 apache设置

    windows下面的apache配置 apache是mac下是默认就有的,我们只需使用命令开启.暂停和重启就好了 sudo apachectl start sudo apachectl stop su ...

  8. [反汇编练习] 160个CrackMe之004

    [反汇编练习] 160个CrackMe之004. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  9. UVA 11426 GCD-Extreme(II) ★ (欧拉函数)

    题意 求Σ{1<=i<N} Σ{i<j<=N} GCD(i, j)     (N<=4000000) 分析 原始思路 暴力求明显是不行的,我们把式子简化形式一下发现它可以 ...

  10. busybox filesystem udhcpc 原理

    /******************************************************************** * busybox filesystem udhcpc 原理 ...