⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smo.c

📁 支持向量机工具箱
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -------------------------------------------------------------------- [Alpha,bias,nsv,kercnt,trnerr,margin]=       smo(data,labels,ker,arg,C,eps,tol,Alpha,bias ) Sequential Minimal Optimizer for Support Vector Machines. Make executable file by command 'mex smo.c kernel.c'.  mandatory inputs:   data [D x N ] matrix of N training D-dimensional patterns.   labels [1 x N] pattern labels (1 for 1st class, 2 for 2nd class ).   ker [string] kernel identifier: 'linear', 'poly', 'rbf'.   arg [real] kernel argument.   C [real] or [2 x real] one trade-off constant for both the classes     or two constants for the first and the second class.  optional inputs:   eps [real] tolerance of KKT-conditions fulfilment (default 0.001).   tol [real] minimal change of optimized Lagrangeians (default 0.001).   Alpha [1xL] initial values of optimized Lagrangeians. If not given     then SMO starts up from Alpha = zeros(1,L).   bias [real] initial value of the threshold. If not given then SMO     starts from bias = 0.  mandatory outputs:   Alpha [1 x N] found Lagrangeian multipliers.   bias [real] found bias.  optional outputs:   nsv [real] number of Support Vectors (number of Alpha > ZERO_LIM).   kercnt [int] number of kernel evaluations.   trnerr [real] classification error on training data.   margin [real] margin between classes and the found hyperplane. Statistical Pattern Recognition Toolbox, Vojtech Franc, Vaclav Hlavac (c) Czech Technical University Prague, http://cmp.felk.cvut.cz Modifications: 23-october-2001, V.Franc 16-October-2001, V.Franc 27-september-2001, V.Franc, roundig of a2 in takeStep removed. 23-September-2001, V.Franc, different trade-off C1 and C2. 22-September-2001, V.Franc, kernel.c used. 19-September-2001, V.Franc, computation of nsv and nerr added. 17-September-2001, V.Franc, created. -------------------------------------------------------------------- */#include "mex.h"#include "matrix.h"#include <math.h>#include <stdlib.h>#include <string.h>#include "kernel.h"/* case insensitive string comparision */#ifdef __BORLANDC__   #define STR_COMPARE(A,B,C)      strncmpi(A,B,C)  /* Borland */#else  #define STR_COMPARE(A,B,C)      strncmp(A,B,C) /* Linux gcc */#endif/* if RANDOM is defined then a random element is used within optimization procedure as originally suggested. */#define RANDOM#define ZERO_LIM   1e-9     /* patterns with alpha > ZERO_LIM are SV */#define MAX(A,B)   (((A) > (B)) ? (A) : (B) )#define MIN(A,B)   (((A) < (B)) ? (A) : (B) )#define C(arg)   (target[arg] > 0 ? C1 : C2)/* --- Global variables ---------------------------------------------- */long N = 0;                /* number of training patterns */double C1=1;               /* trade-off constant for the 1st class */double C2=1;               /* trade-off constant for the 2nd class */double tolerance=0.001;    /* tolerance in KKT fulfilment  */double eps=0.001;          /* minimal Lagrangeian change */double *data;              /* pointer at patterns */double *target;            /* pointer at labels */double *error_cache;       /* error cache */double *alpha;             /* Lagrange multipliers */double *b;                 /* Bias (threshold) *//* ============================================================== Implementation of Sequential Minimal Optimizer (SMO)============================================================== *//* -------------------------------------------------------------- Computes value of the learned function for k-th pattern.-------------------------------------------------------------- */double learned_func( long k ){   double s = 0.;   long i;   for( i = 0; i < N; i++ ) {      if( alpha[i] > 0 )         s += alpha[i]*target[i]*kernel(i,k);   }  s -= *b;  return( s );}/* -------------------------------------------------------------- Optimizes objective function for i1-th and i2-th pattern.-------------------------------------------------------------- */long takeStep( long i1, long i2 ) {   double y1, y2, s;   long i;   double alpha1, alpha2;    double a1, a2;   double E1, E2, L, H, k11, k22, k12, eta, Lobj, Hobj;   double gamma;   double c1, c2;   double t;   double b1, b2, bnew;   double delta_b;   double t1, t2;   if( i1 == i2 ) return( 0 );   alpha1 = alpha[i1];   y1 = target[i1];   if( alpha1 > 0 && alpha1 < C(i1) )      E1 = error_cache[i1];   else      E1 = learned_func(i1) - y1;   alpha2 = alpha[i2];   y2 = target[i2];   if( alpha2 > 0 && alpha2 < C(i2) )      E2 = error_cache[i2];   else      E2 = learned_func(i2) - y2;   s = y1 * y2;   if(s < 0)   {
      L = MAX(0, alpha2 - alpha1);
      H = MIN(C(i2), C(i1) + alpha2 - alpha1);
   }
   else
   {
     L = MAX(0, alpha2 + alpha1 - C(i1) );
     H = MIN(C(i2), alpha2 + alpha1);
   }
   if( L == H ) return( 0 );   k11 = kernel(i1,i1);   k12 = kernel(i1,i2);   k22 = kernel(i2,i2);   eta = 2 * k12 - k11 - k22;   if( eta < 0 ) {      a2 = alpha2 + y2 * (E2 - E1) / eta;      if( a2 < L )         a2 = L;      else if( a2 > H )         a2 = H;   }   else {      c1 = eta/2;      c2 = y2 * (E1-E2)- eta * alpha2;      Lobj = c1 * L * L + c2 * L;      Hobj = c1 * H * H + c2 * H;      if( Lobj > Hobj+eps )         a2 = L;      else if( Lobj < Hobj-eps )         a2 = H;      else         a2 = alpha2;   }   if( fabs(a2-alpha2) < eps*(a2+alpha2+eps )) return( 0 );   a1 = alpha1 - s * (a2 - alpha2 );   if( a1 < 0 ) {      a2 += s * a1;      a1 = 0;   }   else if( a1 > C(i1) ) {      t = a1-C(i1);      a2 += s * t;      a1 = C(i1);   }   if( a1 > 0 && a1 < C(i1) )      bnew = *b + E1 + y1 * (a1 - alpha1) * k11 + y2 * (a2 - alpha2) * k12;   else {      if( a2 > 0 && a2 < C(i2) )         bnew = *b + E2 + y1 *(a1 - alpha1)*k12 + y2*(a2 - alpha2) * k22;      else {         b1 = *b + E1 + y1 * (a1 - alpha1) * k11 + y2 * (a2 - alpha2) * k12;         b2 = *b + E2 + y1 * (a1 - alpha1) * k12 + y2 * (a2 - alpha2) * k22;         bnew = (b1 + b2) / 2;      }   }   delta_b = bnew - *b;   *b = bnew;   t1 = y1 * (a1-alpha1);   t2 = y2 * (a2-alpha2);   for( i = 0; i < N; i++ ) {     if (0 < alpha[i] && alpha[i] < C(i)) {        error_cache[i] +=  t1 * kernel(i1,i) + t2 * kernel(i2,i) - delta_b;     }   }   error_cache[i1] = 0;   error_cache[i2] = 0;   alpha[i1] = a1;  /* Store a1 in the alpha array.*/   alpha[i2] = a2;  /* Store a2 in the alpha array.*/   return( 1 );}/* -------------------------------------------------------------- Finds the second Lagrange multiplayer to be optimize.-------------------------------------------------------------- */long examineExample( long i1 ){   double y1, alpha1, E1, r1;   double tmax;   double E2, temp;   long k, i2;   long k0;   y1 = target[i1];   alpha1 = alpha[i1];   if( alpha1 > 0 && alpha1 < C(i1) )      E1 = error_cache[i1];   else      E1 = learned_func(i1) - y1;   r1 = y1 * E1;   if(( r1 < -tolerance && alpha1 < C(i1) )      || (r1 > tolerance && alpha1 > 0)) {    /* Try i2 by three ways; if successful, then immediately return 1; */      for( i2 = (-1), tmax = 0, k = 0; k < N; k++ ) {         if( alpha[k] > 0 && alpha[k] < C(k) ) {            E2 = error_cache[k];            temp = fabs(E1 - E2);            if( temp > tmax ) {               tmax = temp;               i2 = k;            }         }      }      if( i2 >= 0 ) {         if( takeStep(i1,i2) )            return( 1 );      }#ifdef RANDOM      for( k0 = rand(), k = k0; k < N + k0; k++ ) {         i2 = k % N;#else      for( k = 0; k < N; k++) {         i2 = k;#endif         if( alpha[i2] > 0 && alpha[i2] < C(i2) ) {            if( takeStep(i1,i2) )               return( 1 );         }      }#ifdef RANDOM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -