LibSVMMultiClass.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 1999-2009 Soeren Sonnenburg
00008  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #include "classifier/svm/LibSVMMultiClass.h"
00012 #include "lib/io.h"
00013 
00014 CLibSVMMultiClass::CLibSVMMultiClass()
00015 : CMultiClassSVM(ONE_VS_ONE), model(NULL)
00016 {
00017 }
00018 
00019 CLibSVMMultiClass::CLibSVMMultiClass(float64_t C, CKernel* k, CLabels* lab)
00020 : CMultiClassSVM(ONE_VS_ONE, C, k, lab), model(NULL)
00021 {
00022 }
00023 
00024 CLibSVMMultiClass::~CLibSVMMultiClass()
00025 {
00026     //SG_PRINT("deleting LibSVM\n");
00027 }
00028 
00029 bool CLibSVMMultiClass::train()
00030 {
00031     struct svm_node* x_space;
00032 
00033     ASSERT(labels && labels->get_num_labels());
00034     int32_t num_classes = labels->get_num_classes();
00035     problem.l=labels->get_num_labels();
00036     SG_INFO( "%d trainlabels, %d classes\n", problem.l, num_classes);
00037 
00038     problem.y=new float64_t[problem.l];
00039     problem.x=new struct svm_node*[problem.l];
00040     x_space=new struct svm_node[2*problem.l];
00041 
00042     for (int32_t i=0; i<problem.l; i++)
00043     {
00044         problem.y[i]=labels->get_label(i);
00045         problem.x[i]=&x_space[2*i];
00046         x_space[2*i].index=i;
00047         x_space[2*i+1].index=-1;
00048     }
00049 
00050     ASSERT(kernel);
00051 
00052     param.svm_type=C_SVC; // C SVM
00053     param.kernel_type = LINEAR;
00054     param.degree = 3;
00055     param.gamma = 0;    // 1/k
00056     param.coef0 = 0;
00057     param.nu = 0.5;
00058     param.kernel=kernel;
00059     param.cache_size = kernel->get_cache_size();
00060     param.C = get_C1();
00061     param.eps = epsilon;
00062     param.p = 0.1;
00063     param.shrinking = 1;
00064     param.nr_weight = 0;
00065     param.weight_label = NULL;
00066     param.weight = NULL;
00067 
00068     const char* error_msg = svm_check_parameter(&problem,&param);
00069 
00070     if(error_msg)
00071         SG_ERROR("Error: %s\n",error_msg);
00072 
00073     model = svm_train(&problem, &param);
00074 
00075     if (model)
00076     {
00077         ASSERT(model->nr_class==num_classes);
00078         ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef));
00079         create_multiclass_svm(num_classes);
00080 
00081         int32_t* offsets=new int32_t[num_classes];
00082         offsets[0]=0;
00083 
00084         for (int32_t i=1; i<num_classes; i++)
00085             offsets[i] = offsets[i-1]+model->nSV[i-1];
00086 
00087         int32_t s=0;
00088         for (int32_t i=0; i<num_classes; i++)
00089         {
00090             for (int32_t j=i+1; j<num_classes; j++)
00091             {
00092                 int32_t k, l;
00093 
00094                 float64_t sgn=1;
00095                 if (model->label[i]>model->label[j])
00096                     sgn=-1;
00097 
00098                 int32_t num_sv=model->nSV[i]+model->nSV[j];
00099                 float64_t bias=-model->rho[s];
00100 
00101                 ASSERT(num_sv>0);
00102                 ASSERT(model->sv_coef[i] && model->sv_coef[j-1]);
00103 
00104                 CSVM* svm=new CSVM(num_sv);
00105 
00106                 svm->set_bias(sgn*bias);
00107 
00108                 int32_t sv_idx=0;
00109                 for (k=0; k<model->nSV[i]; k++)
00110                 {
00111                     svm->set_support_vector(sv_idx, model->SV[offsets[i]+k]->index);
00112                     svm->set_alpha(sv_idx, sgn*model->sv_coef[j-1][offsets[i]+k]);
00113                     sv_idx++;
00114                 }
00115 
00116                 for (k=0; k<model->nSV[j]; k++)
00117                 {
00118                     svm->set_support_vector(sv_idx, model->SV[offsets[j]+k]->index);
00119                     svm->set_alpha(sv_idx, sgn*model->sv_coef[i][offsets[j]+k]);
00120                     sv_idx++;
00121                 }
00122 
00123                 int32_t idx=0;
00124 
00125                 if (sgn>0)
00126                 {
00127                     for (k=0; k<model->label[i]; k++)
00128                         idx+=num_classes-k-1;
00129 
00130                     for (l=model->label[i]+1; l<model->label[j]; l++)
00131                         idx++;
00132                 }
00133                 else
00134                 {
00135                     for (k=0; k<model->label[j]; k++)
00136                         idx+=num_classes-k-1;
00137 
00138                     for (l=model->label[j]+1; l<model->label[i]; l++)
00139                         idx++;
00140                 }
00141 
00142 
00143 //              if (sgn>0)
00144 //                  idx=((num_classes-1)*model->label[i]+model->label[j])/2;
00145 //              else
00146 //                  idx=((num_classes-1)*model->label[j]+model->label[i])/2;
00147 //
00148                 SG_DEBUG("svm[%d] has %d sv (total: %d), b=%f label:(%d,%d) -> svm[%d]\n", s, num_sv, model->l, bias, model->label[i], model->label[j], idx);
00149 
00150                 set_svm(idx, svm);
00151                 s++;
00152             }
00153         }
00154 
00155         CSVM::set_objective(model->objective);
00156 
00157         delete[] offsets;
00158         delete[] problem.x;
00159         delete[] problem.y;
00160         delete[] x_space;
00161 
00162         svm_destroy_model(model);
00163         model=NULL;
00164 
00165         return true;
00166     }
00167     else
00168         return false;
00169 }
00170 

SHOGUN Machine Learning Toolbox - Documentation