/*********************************************************************** 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/ **********************************************************************/ /* APSSC.java Isaac Triguero Velazquez. Created by Isaac Triguero Velazquez 11-1-2011 Copyright (c) 2008 __MyCompanyName__. All rights reserved. */ package keel.Algorithms.Semi_Supervised_Learning.APSSC; import keel.Algorithms.Semi_Supervised_Learning.Basic.PrototypeSet; import keel.Algorithms.Semi_Supervised_Learning.Basic.PrototypeGenerator; import keel.Algorithms.Semi_Supervised_Learning.Basic.Prototype; import keel.Algorithms.Semi_Supervised_Learning.Basic.PrototypeGenerationAlgorithm; import keel.Algorithms.Semi_Supervised_Learning.*; import java.util.*; import keel.Algorithms.Semi_Supervised_Learning.utilities.*; import keel.Algorithms.Semi_Supervised_Learning.utilities.KNN.*; import keel.Dataset.Attributes; import org.core.*; import org.core.*; import java.util.StringTokenizer; /** * This class implements the Self-traning wrapper. You can use: Knn, C4.5, SMO and Ripper as classifiers. * @author triguero * */ public class APSSCGenerator extends PrototypeGenerator { /*Own parameters of the algorithm*/ private int numberOfselectedExamples; private double spreadGaussian; private double evaporation; private double MT; //confidence protected int numberOfPrototypes; // Particle size is the percentage protected int numberOfClass; /** Parameters of the initial reduction process. */ private String[] paramsOfInitialReducction = null; /** * Build a new APSSCGenerator Algorithm * @param t Original prototype set to be reduced. * @param perc Reduction percentage of the prototype set. */ public APSSCGenerator(PrototypeSet _trainingDataSet, int neigbors,int poblacion, int perc, int iteraciones, double c1, double c2, double vmax, double wstart, double wend) { super(_trainingDataSet); algorithmName="APSSC"; } /** * Build a new APSSCGenerator Algorithm * @param t Original prototype set to be reduced. * @param unlabeled Original unlabeled prototype set for SSL. * @param params Parameters of the algorithm (only % of reduced set). */ public APSSCGenerator(PrototypeSet t, PrototypeSet unlabeled, PrototypeSet test, Parameters parameters) { super(t,unlabeled, test, parameters); algorithmName="APSSC"; this.spreadGaussian = parameters.getNextAsDouble(); this.evaporation = parameters.getNextAsDouble(); this.MT = parameters.getNextAsDouble(); //Last class is the Unknown this.numberOfClass = trainingDataSet.getPosibleValuesOfOutput().size(); // System.out.print("\nIsaacSSL dice: " + this.numberOfselectedExamples+ ", "+ this.numberOfClass +"\n"); } /** * Apply the Generator method. * @return */ public Pair<PrototypeSet, PrototypeSet> applyAlgorithm() { System.out.print("\nThe algorithm APSSC is starting...\n Computing...\n"); PrototypeSet ANTlabeled, ANTunlabeled; ANTlabeled = new PrototypeSet(trainingDataSet.getAllDifferentFromClass(this.numberOfClass)); // Selecting labeled prototypes from the training set. ANTunlabeled = new PrototypeSet(trainingDataSet.getFromClass(this.numberOfClass)); // Accuracy with initial labeled data. // System.out.println("Labeled size = " +ANTlabeled.size()); // System.out.println("Unlabeled size = " + ANTunlabeled.size()); // pheromone that the labeled ant i emitted to the j unlabeled ant. double pheromone[][] = new double [ANTunlabeled.size()][this.numberOfClass]; for(int i=0; i< ANTlabeled.size(); i++){ Arrays.fill(pheromone[i], 0); } double aggregation[] = new double[ANTunlabeled.size()]; double membership[][]= new double[ANTunlabeled.size()][this.numberOfClass]; boolean stoppingCriteria = false; Prototype ColonyCenters[] = new Prototype[this.numberOfClass]; Prototype newColonyCenters[] = new Prototype[this.numberOfClass]; for(int i=0 ; i< this.numberOfClass; i++){ ColonyCenters[i] = ANTlabeled.getFromClass(i).avg(); } while(!stoppingCriteria){ for(int p=0; p<ANTunlabeled.size(); p++){ //First Step: calculate aggregation and update pheromone. for(int q=0; q<this.numberOfClass; q++){ aggregation[p] =0; PrototypeSet Cj = new PrototypeSet(ANTlabeled.getFromClass(q)); if(Cj!=null){ // At least one prototpye of this class in the training Set! for(int z=0; z< Cj.size(); z++){ // Average Aggregation aggregation[p] += Math.exp(-1*((Distance.distance(Cj.get(z), ANTunlabeled.get(p))))/(2*this.spreadGaussian*this.spreadGaussian)); } aggregation[p]/= Cj.size(); } // update pheromone pheromone[p][q] = this.evaporation*pheromone[p][q] + aggregation[p]; } // Second Step: compute membership double sumatoria = 0; for(int z=0; z< this.numberOfClass; z++){ sumatoria+= pheromone[p][z]; } double max_j = Double.MIN_VALUE; double clasej =0; for(int q=0; q<this.numberOfClass; q++){ membership[p][q]= pheromone[p][q]/sumatoria; if(membership[p][q]> max_j){ max_j = membership[p][q]; clasej= q; } } // Step 3: Determine if we are going to add the new ant //System.out.println("Max_j = " + max_j); if(max_j > this.MT){ // We do not add the unlabeled data, but we assign the appropriate labeled data. //System.out.println("Añado"); ANTunlabeled.get(p).setFirstOutput(clasej); } } //Checking stopping criteria boolean checking = true; PrototypeSet Union = new PrototypeSet(ANTlabeled.clone()); Union.add(ANTunlabeled.getAllDifferentFromClass(this.numberOfClass)); // we add all the unlabeled ants that has a class label. for(int i=0 ; i< this.numberOfClass; i++){ if(ColonyCenters[i]!=null){ newColonyCenters[i] = Union.getFromClass(i).avg(); if(!newColonyCenters[i].equals(ColonyCenters[i])){ checking = false; // we do not stop } } } if(!checking){ // si voy a seguir for(int i=0 ; i< this.numberOfClass; i++){ ColonyCenters[i] = new Prototype(newColonyCenters[i]); } } stoppingCriteria = checking; } ANTlabeled.add(ANTunlabeled.getAllDifferentFromClass(this.numberOfClass)); // we add the labeled ants // System.out.println("Labeled size = " +ANTlabeled.size()); // System.out.println("Unlabeled size = " + ANTunlabeled.size()); // begin testing PrototypeSet tranductive = new PrototypeSet(this.transductiveDataSet.clone()); PrototypeSet test = new PrototypeSet(this.testDataSet.clone()); double pheromoneTrs[][] = new double [this.transductiveDataSet.size()][this.numberOfClass]; double pheromoneTst[][] = new double [this.testDataSet.size()][this.numberOfClass]; int aciertoTrs = 0; int aciertoTst = 0; //We have to return the classification done. for(int i=0; i<this.transductiveDataSet.size(); i++){ for(int q=0; q<this.numberOfClass; q++){ pheromoneTrs[i][q] = 0; for(int z=0; z<ANTlabeled.getFromClass(q).size() ; z++){ pheromoneTrs[i][q] += Math.exp(-1*((Distance.distance(ANTlabeled.getFromClass(q).get(z), transductiveDataSet.get(i))))/(2*this.spreadGaussian*this.spreadGaussian)); } pheromoneTrs[i][q]/= ANTlabeled.getFromClass(q).size(); } double maxpheromone = Double.MIN_VALUE; double ColonyLabel = 0; for(int q=0; q<this.numberOfClass; q++){ if(pheromoneTrs[i][q] > maxpheromone){ maxpheromone = pheromoneTrs[i][q]; ColonyLabel = q; } } tranductive.get(i).setFirstOutput(ColonyLabel); if(ColonyLabel == transductiveDataSet.get(i).getOutput(0)){ aciertoTrs++; } } System.out.println("% de acierto TRS = "+ (aciertoTrs*100.)/transductiveDataSet.size()); for(int i=0; i<this.testDataSet.size(); i++){ for(int q=0; q<this.numberOfClass; q++){ pheromoneTst[i][q] = 0; for(int z=0; z<ANTlabeled.getFromClass(q).size() ; z++){ pheromoneTst[i][q] += Math.exp(-1*((Distance.distance(ANTlabeled.getFromClass(q).get(z), testDataSet.get(i))))/(2*this.spreadGaussian*this.spreadGaussian)); } pheromoneTst[i][q]/= ANTlabeled.getFromClass(q).size(); } double maxpheromone = Double.MIN_VALUE; double ColonyLabel = 0; for(int q=0; q<this.numberOfClass; q++){ if(pheromoneTst[i][q] > maxpheromone){ maxpheromone = pheromoneTst[i][q]; ColonyLabel = q; } } test.get(i).setFirstOutput(ColonyLabel); if(ColonyLabel == testDataSet.get(i).getOutput(0)){ aciertoTst++; } } System.out.println("% de acierto TST = "+ (aciertoTst*100.)/testDataSet.size()); return new Pair<PrototypeSet,PrototypeSet>(tranductive,test); } /** * General main for all the prototoype generators * Arguments: * 0: Filename with the training data set to be condensed. * 1: Filename which contains the test data set. * 3: Seed of the random number generator. Always. * ************************** * @param args Arguments of the main function. */ public static void main(String[] args) { } }