libsvm 代码分析

原创 2013年12月03日 13:34:30
void Solve(int l, QMatrix Q, double[] p_, byte[] y_,
  double[] alpha_, double Cp, double Cn, double eps, SolutionInfo si, int shrinking)
{

this.l = l;
this.Q = Q;
QD = Q.get_QD();
p = (double[])p_.clone();
y = (byte[])y_.clone();
alpha = (double[])alpha_.clone();
this.Cp = Cp;
this.Cn = Cn;
this.eps = eps;//停止迭代可以容忍的误差
this.unshrink = false;//对内存的处理


// initialize alpha_status
{
alpha_status = new byte[l];//新建一个长度为L的byte数组
for(int i=0;i<l;i++)
update_alpha_status(i);//调用改方法进行初始化,根据alpha的值,判定该样本属于是否属于支持向量support vector,分对的点,和分错的点
}


// initialize active set (for shrinking)
{
active_set = new int[l];
for(int i=0;i<l;i++)
active_set[i] = i;
active_size = l;
}


// initialize gradient
{
G = new double[l];
G_bar = new double[l];
int i;
for(i=0;i<l;i++)
{
G[i] = p[i];
G_bar[i] = 0;
}
for(i=0;i<l;i++)
if(!is_lower_bound(i))
{
float[] Q_i = Q.get_Q(i,l);
double alpha_i = alpha[i];
int j;
for(j=0;j<l;j++)
G[j] += alpha_i*Q_i[j];
if(is_upper_bound(i))
for(j=0;j<l;j++)
G_bar[j] += get_C(i) * Q_i[j];
}
}


// optimization step


int iter = 0;
int max_iter = Math.max(10000000, l>Integer.MAX_VALUE/100 ? Integer.MAX_VALUE : 100*l);
int counter = Math.min(l,1000)+1;
int[] working_set = new int[2];


while(iter < max_iter)
{
// show progress and do shrinking


if(--counter == 0)
{
counter = Math.min(l,1000);
if(shrinking!=0) do_shrinking();
svm.info(".");
}


if(select_working_set(working_set)!=0)
{
// reconstruct the whole gradient
reconstruct_gradient();
// reset active set size and check
active_size = l;
svm.info("*");
if(select_working_set(working_set)!=0)
break;
else
counter = 1; // do shrinking next iteration
}

int i = working_set[0];
int j = working_set[1];


++iter;


// update alpha[i] and alpha[j], handle bounds carefully


float[] Q_i = Q.get_Q(i,active_size);
float[] Q_j = Q.get_Q(j,active_size);


double C_i = get_C(i);
double C_j = get_C(j);


double old_alpha_i = alpha[i];
double old_alpha_j = alpha[j];


if(y[i]!=y[j])
{
double quad_coef = QD[i]+QD[j]+2*Q_i[j];
if (quad_coef <= 0)
quad_coef = 1e-12;
double delta = (-G[i]-G[j])/quad_coef;
double diff = alpha[i] - alpha[j];
alpha[i] += delta;
alpha[j] += delta;

if(diff > 0)
{
if(alpha[j] < 0)
{
alpha[j] = 0;
alpha[i] = diff;
}
}
else
{
if(alpha[i] < 0)
{
alpha[i] = 0;
alpha[j] = -diff;
}
}
if(diff > C_i - C_j)
{
if(alpha[i] > C_i)
{
alpha[i] = C_i;
alpha[j] = C_i - diff;
}
}
else
{
if(alpha[j] > C_j)
{
alpha[j] = C_j;
alpha[i] = C_j + diff;
}
}
}
else
{
double quad_coef = QD[i]+QD[j]-2*Q_i[j];
if (quad_coef <= 0)
quad_coef = 1e-12;
double delta = (G[i]-G[j])/quad_coef;
double sum = alpha[i] + alpha[j];
alpha[i] -= delta;
alpha[j] += delta;


if(sum > C_i)
{
if(alpha[i] > C_i)
{
alpha[i] = C_i;
alpha[j] = sum - C_i;
}
}
else
{
if(alpha[j] < 0)
{
alpha[j] = 0;
alpha[i] = sum;
}
}
if(sum > C_j)
{
if(alpha[j] > C_j)
{
alpha[j] = C_j;
alpha[i] = sum - C_j;
}
}
else
{
if(alpha[i] < 0)
{
alpha[i] = 0;
alpha[j] = sum;
}
}
}


// update G


double delta_alpha_i = alpha[i] - old_alpha_i;
double delta_alpha_j = alpha[j] - old_alpha_j;


for(int k=0;k<active_size;k++)
{
G[k] += Q_i[k]*delta_alpha_i + Q_j[k]*delta_alpha_j;
}


// update alpha_status and G_bar


{
boolean ui = is_upper_bound(i);
boolean uj = is_upper_bound(j);
update_alpha_status(i);
update_alpha_status(j);
int k;
if(ui != is_upper_bound(i))
{
Q_i = Q.get_Q(i,l);
if(ui)
for(k=0;k<l;k++)
G_bar[k] -= C_i * Q_i[k];
else
for(k=0;k<l;k++)
G_bar[k] += C_i * Q_i[k];
}


if(uj != is_upper_bound(j))
{
Q_j = Q.get_Q(j,l);
if(uj)
for(k=0;k<l;k++)
G_bar[k] -= C_j * Q_j[k];
else
for(k=0;k<l;k++)
G_bar[k] += C_j * Q_j[k];
}
}


}

if(iter >= max_iter)
{
if(active_size < l)
{
// reconstruct the whole gradient to calculate objective value
reconstruct_gradient();
active_size = l;
svm.info("*");
}
System.err.print("\nWARNING: reaching max number of iterations\n");
}


// calculate rho


si.rho = calculate_rho();


// calculate objective value
{
double v = 0;
int i;
for(i=0;i<l;i++)
v += alpha[i] * (G[i] + p[i]);


si.obj = v/2;
}


// put back the solution
{
for(int i=0;i<l;i++)
alpha_[active_set[i]] = alpha[i];
}


si.upper_bound_p = Cp;
si.upper_bound_n = Cn;


svm.info("\noptimization finished, #iter = "+iter+"\n");

}

libsvm代码阅读:关于Solver类分析(二)

如果你看完了上篇博文的伪代码,那么我们就可以开始谈谈它的源代码了。 // An SMO algorithm in Fan et al., JMLR 6(2005), p. 1889--1918 // ...
  • Linoi
  • Linoi
  • 2014年02月22日 22:15
  • 3368

使用libsvm实现文本分类

原贴:http://blog.csdn.net/qq_26562641/article/details/50416971/ 文本分类,首先它是分类问题,应该对应着分类过程的两个重...
  • soipray
  • soipray
  • 2016年12月08日 15:56
  • 1932

LibSVM-2.6 程序代码

第一节: SVM.h 文件 structsvm_node { int index; double value; }; structsvm_node 用来存储单一向量中的单个特征,例...
  • kobesdu
  • kobesdu
  • 2013年05月23日 17:45
  • 1748

libsvm3.2.1 - SVM多分类简单实现

首先,感谢湾湾的林教授提供的libsvm。 1.安装配置到matlab -------据说直接将libsvm-3.21\windows目录添加到工作路径下即可(点击 set p...
  • u011391905
  • u011391905
  • 2016年09月08日 22:35
  • 2918

LibSVM笔记系列(2)——如何提升LibSVM分类效果

提升LibSVM分类效果的一些技巧
  • xiahouzuoxin
  • xiahouzuoxin
  • 2013年07月18日 20:30
  • 22407

LIBSVM的FQA

这里是libsvm的FQA : 我研究了好久才发现有这么个好东西的:转别人的 问: 我在那里能够找到libsvm的文件 ?  软件包中有一个 README 文件,里面详细说明了所有参数选项、...
  • wangpengfei163
  • wangpengfei163
  • 2016年09月06日 15:17
  • 566

libsvm 2.6 的代码注释

第一节: SVM.h 文件 struct svm_node {  int index;  double value; } ; struct svm_node 用来存储单一...
  • le_zhou
  • le_zhou
  • 2014年10月16日 15:13
  • 514

Linux下使用Libsvm

最近在自己的笔记本上安装Ubuntu,感叹现在的Linux技术发展太快了,许多操作已经跟Windows没有差别,许多Windows下的应用软件都有对应的Linux版本。应该说使用Ubuntu相当的方便...
  • jkxsanger
  • jkxsanger
  • 2010年04月07日 20:12
  • 9112

libsvm-javaAPI

获得 tw.edu.ntu.csie libsvm 3.17 libsvm-3.17.jar的结构见下图, default package:这里是工具制作者自己封装出来的一些类,它们都有m...
  • chuchus
  • chuchus
  • 2015年05月11日 16:44
  • 1156

在matlab中使用libsvm

http://www.csie.ntu.edu.tw/~cjlin/libsvm/ 这个链接可以下载到libsvm。一个台湾人写得,很好很强大。 不需要安装,直接解压缩就行了。...
  • ahuang1900
  • ahuang1900
  • 2013年05月24日 22:02
  • 1078
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:libsvm 代码分析
举报原因:
原因补充:

(最多只允许输入30个字)