/*********************************************************************** 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/ **********************************************************************/ /** * * File: CenterNN.java * * The CenterNN Algorithm. * A enhanced 1-NN classifier,which uses the distance between train instances * and centers of their class,as a reference of how far is the train instance * from the query object * * @author Written by Joaqu�n Derrac (University of Granada) 13/11/2008 * @version 1.0 * @since JDK1.5 * */ package keel.Algorithms.Lazy_Learning.CenterNN; import keel.Algorithms.Lazy_Learning.LazyAlgorithm; public class CenterNN extends LazyAlgorithm{ //Adictional structures double centers[][]; double diferences[][]; double quads[]; double classDistance[]; double projection[]; double separation[]; /** * The main method of the class * * @param script Name of the configuration script * */ public CenterNN (String script) { readDataFiles(script); //Naming the algorithm name="Center NN"; //Inicialization of auxiliar structures classDistance=new double [nClasses]; diferences=new double[trainData.length][inputAtt]; quads=new double[trainData.length]; projection=new double[inputAtt]; separation=new double[inputAtt]; centers=new double[nClasses][inputAtt]; for(int i=0;i<nClasses;i++){ for(int j=0;j<inputAtt;j++){ centers[i][j]=0.0; } } //Initialization stuff ends here. So, we can start time-counting setInitialTime(); } //end-method /** * Reads configuration script, to extract the parameter's values. * * @param script Name of the configuration script * */ protected void readParameters (String script) { //No parameters to read in this algorithm } //end-method /** * Calculates centers of each class, and vectors from each * train instance to its class center * */ public void precalculateParameters(){ calculateCenters(); calculateDiferences(); } //end-method /** * Calculates centers of each class. * */ private void calculateCenters(){ int insClass; for(int i=0;i<trainData.length;i++){ insClass=trainOutput[i]; for(int j=0;j<inputAtt;j++){ centers[insClass][j]+=trainData[i][j]; } } for(int i=0;i<nClasses;i++){ for(int j=0;j<inputAtt;j++){ centers[i][j]/=(double)nInstances[i]; } } } //end-method /** * Calculates diference vectors from each train instance * to its class center, and get its quadratic distance. * */ private void calculateDiferences(){ int insClass; double sum; for(int i=0;i<trainData.length;i++){ sum=0.0; insClass=trainOutput[i]; for(int j=0;j<inputAtt;j++){ diferences[i][j]=centers[insClass][j]-trainData[i][j]; sum+=(diferences[i][j]*diferences[i][j]); } quads[i]=sum; } } //end-method /** * Evaluates a instance to predict its class. * * @param example Instance evaluated * @return Class predicted * */ protected int evaluate (double example[]) { int output=-1; int insClass; double distance; double MU; double min; for(int i=0;i<nClasses;i++){ classDistance[i]=Double.MAX_VALUE; } //Get the minimun distance to each class for(int i=0;i<trainData.length;i++){ //leave-one-out if(euclideanDistance(example,trainData[i])>0.0){ insClass=trainOutput[i]; MU=calculateMu(example,i); //project test instance in the center vector for(int j=0;j<inputAtt;j++){ projection[j]=trainData[i][j]+ (MU * diferences[i][j]); } distance=euclideanDistance(example,projection); if(classDistance[insClass]>distance){ classDistance[insClass]=distance; } } } //Get the nearest class min=Double.MAX_VALUE; for(int i=0;i<nClasses;i++){ if(min>classDistance[i]){ min=classDistance[i]; output=i; } } return output; } //end-method /** * Calculates the position parameter (MU) for a given pair train/test instance * * @param example The test instance * @param instance Index of the train instance * @return Position parameter calculated */ private double calculateMu(double example[],int instance){ double mu; double sum=0.0; for(int i=0;i<inputAtt;i++){ separation[i]=example[i]-trainData[instance][i]; sum+=(separation[i]*diferences[instance][i]); } mu=sum/quads[instance]; return mu; } //end-method } //end-class