/***********************************************************************
This file is part of KEEL-software, the Data Mining tool for regression,
classification, clustering, pattern mining and so on.
Copyright (C) 2004-2010
F. Herrera (herrera@decsai.ugr.es)
L. S�nchez (luciano@uniovi.es)
J. Alcal�-Fdez (jalcala@decsai.ugr.es)
S. Garc�a (sglopez@ujaen.es)
A. Fern�ndez (alberto.fernandez@ujaen.es)
J. Luengo (julianlm@decsai.ugr.es)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/
**********************************************************************/
//
// SVMSEL.java
//
// Diego J. Romero López, basado en el código de Salvador García López
//
// Created by Salvador Garc�a L�pez 16-7-2004.
// Copyright (c) 2004 __MyCompanyName__. All rights reserved.
//
package keel.Algorithms.Instance_Generation.HYB;
import keel.Algorithms.Instance_Generation.Basic.PrototypeSet;
import keel.Algorithms.Instance_Generation.Basic.PrototypeGenerator;
import keel.Algorithms.Instance_Generation.*;
import keel.Algorithms.Instance_Generation.utilities.*;
import keel.Algorithms.Instance_Generation.utilities.KNN.*;
import org.libsvm.*;
import keel.Dataset.*;
import org.core.*;
import java.util.*;
/**
* SVM process of selection of prototype set.
* @author Salvador García López, adapted by Diego J. Romero López
*/
public class SVMSEL extends PrototypeGenerator
{
// Own parameters of the algorithm
/** Kernel type used in the SVM */
private String kernelType;
/** Number of inputs of the prototypes */
private int k;
/*Set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1).*/
private double C = 1.0;
/*Epsilon in loss function of epsilon-SVR (default 0.1)*/
private double eps = 0.1;
/**Degree in kernel function (default 3)*/
private int degree = 3;
/** Gamma in kernel function (default 1/k) */
private double gamma;
/** Parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5). */
private double nu = 0.5;
/** I don't remember */
private double p;
/** Whether to use the shrinking heuristics, 0 or 1 (default 1) */
private int shrinking;
/*
-s svm_type : set type of SVM (default 0)
0 -- C-SVC
1 -- nu-SVC
2 -- one-class SVM
3 -- epsilon-SVR
4 -- nu-SVR
-t kernel_type : set type of kernel function (default 2)
0 -- linear: u'*v
1 -- polynomial: (gamma*u'*v + coef0)^degree
2 -- radial basis function: exp(-gamma*|u-v|^2)
3 -- sigmoid: tanh(gamma*u'*v + coef0)
-d degree : set degree in kernel function (default 3)
-g gamma : set gamma in kernel function (default 1/k)
-r coef0 : set coef0 in kernel function (default 0)
-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)
-n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)
-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
-m cachesize : set cache memory size in MB (default 100)
-e epsilon : set tolerance of termination criterion (default 0.001)
-h shrinking: whether to use the shrinking heuristics, 0 or 1 (default 1)
-b probability_estimates: whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)
-w weight: set the parameter C of class i to weight*C, for C-SVC (default 1)
*/
/**
* Performs an selection of the training data set using SVM.
* @param kernelType {LINEAR, POLY, RBF, SIGMOID} linear: u'*v; polynomial: (gamma*u'*v + coef0)^degree; radial basis function: exp(-gamma*|u-v|^2); sigmoid: tanh(gamma*u'*v + coef0)
* @param C Parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1).
* @param eps Epsilon in loss function of epsilon-SVR (default 0.1)
* @param degree Degree in kernel function (default 3)
* @param gamma Gamma in kernel function (default 1/k)
* @param nu Parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)
* @param p P-parameter of the SVM.
* @param shrinking Whether to use the shrinking heuristics, 0 or 1 (default 1)
*/
public SVMSEL(PrototypeSet _trainingDataSet, String kernelType, double C, double eps, int degree, double gamma, double nu, double p, int shrinking)
{
super(_trainingDataSet);
this.k = trainingDataSet.get(0).numberOfInputs();
this.kernelType = kernelType;
this.C = C;
this.eps = eps;
this.degree = degree;
this.gamma = gamma;
this.nu = nu;
this.p = p;
this.shrinking = shrinking;
}
/**
* Performs an selection of the training data set using SVM.
* @param kernelType {LINEAR, POLY, RBF, SIGMOID} linear: u'*v; polynomial: (gamma*u'*v + coef0)^degree; radial basis function: exp(-gamma*|u-v|^2); sigmoid: tanh(gamma*u'*v + coef0)
* */
public SVMSEL(PrototypeSet _trainingDataSet, String kernelType)
{
super(_trainingDataSet);
this.k = trainingDataSet.get(0).numberOfInputs();
this.kernelType = kernelType;
this.C = 1.0;
this.eps = 0.1;
this.degree = 3;
this.gamma = 1.0/(double)k;
this.nu = 0.5;
this.p = 0.1;
this.shrinking = 1;
}
/**
* Executes the SVM prototype selection.
* @return Selected prototypes by SVM method.
*/
public PrototypeSet doSVMSelection()
{
//SVM WTF!
PrototypeSet T = trainingDataSet.copy();
int Tsize = T.size();
int protSize = this.k;
svm_parameter SVMparam = new svm_parameter();
svm_problem SVMp = null;
svm_model svr = null;
double exTmp[];
//SVM PARAMETERS
SVMparam.C = C;
SVMparam.cache_size = 20; //20MB of cache
SVMparam.degree = degree;
SVMparam.eps = eps;
SVMparam.gamma = gamma;
SVMparam.nr_weight = 0;
SVMparam.nu = nu;
SVMparam.p = p;
SVMparam.shrinking = shrinking;
SVMparam.probability = 0;
if (kernelType.compareTo("LINEAR") == 0)
SVMparam.kernel_type = svm_parameter.LINEAR;
else if (kernelType.compareTo("POLY") == 0)
SVMparam.kernel_type = svm_parameter.POLY;
else if (kernelType.compareTo("RBF") == 0)
SVMparam.kernel_type = svm_parameter.RBF;
else if (kernelType.compareTo("SIGMOID") == 0)
SVMparam.kernel_type = svm_parameter.SIGMOID;
SVMparam.svm_type = svm_parameter.C_SVC;
SVMp = new svm_problem();
SVMp.l = Tsize;
SVMp.y = new double[SVMp.l];
SVMp.x = new svm_node[SVMp.l][protSize + 1];
for (int i = 0; i < SVMp.l; i++)
for (int j = 0; j < protSize + 1; j++)
SVMp.x[i][j] = new svm_node();
for (int i = 0; i < Tsize; i++)
{
SVMp.y[i] = T.get(i).label();
for (int j = 0; j < protSize; j++)
{
SVMp.x[i][j].index = j;
SVMp.x[i][j].value = T.get(i).getInput(j);
}
//end of instance
SVMp.x[i][protSize].index = -1;
}
if (svm.svm_check_parameter(SVMp, SVMparam) != null)
{
Debug.errorln("SVM parameter error in training: ");
Debug.errorln(svm.svm_check_parameter(SVMp, SVMparam));
Debug.goout("Error in SVM parameters");
}
//Train the SVM
svr = svm.svm_train(SVMp, SVMparam);
exTmp = new double[protSize];
boolean[] marcas = new boolean[Tsize];
Arrays.fill(marcas, false);
int nSel = 0;
for (int i = 0; i < svr.getSV().length; i++)
{
for (int j = 0; j < svr.getSV()[i].length - 1; j++)
exTmp[j] = svr.getSV()[i][j].value;
boolean coincide = false;
for (int j = 0; j < Tsize && !coincide; j++)
{
boolean igual = true;
for (int l = 0; l < protSize && igual; l++)
igual = (exTmp[l] == T.get(j).getInput(l));
if (igual)
{
marcas[j] = true;
nSel++;
coincide = true;
}
}
}
PrototypeSet S = new PrototypeSet(nSel);
for(int i=0; i<Tsize; ++i)
if(marcas[i])
S.add(T.get(i));
return S;
}
/**
* Reduction of the original prototype set by the SVM.
* @return Prototypes selected by SVM.
*/
@Override
public PrototypeSet reduceSet()
{
return doSVMSelection();
}
}