/*********************************************************************** 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/ **********************************************************************/ /** Fuzzy classifiers induction using LogitBoost algorithm */ package keel.Algorithms.Fuzzy_Rule_Learning.Genetic.Shared.Boosting; import java.io.*; import org.core.*; import java.util.Vector; import java.util.StringTokenizer; class FitnessABD extends Fitness { int nentradas; int nlabels; int Nsalidas; int Clase; double []W; double [][][]Mu; double []Dsigno; AdaBoost ad; FitnessABD(AdaBoost vad, int vnentradas,int nsalidas,int nl,int clase, double []w, double[][][]mu, double []dsigno) { ad=vad; nentradas=vnentradas; nlabels=nl; Nsalidas=nsalidas; Clase=clase; W=w; Mu=mu; Dsigno=dsigno; } FuzzyRule ConstruyeRegla(GenotypeBoosting g) { FuzzyRule TestRegla= new FuzzyRule(new int[g.x.length],new double[Nsalidas]); for (int i=0;i<g.x.length;i++) TestRegla.antecedente[i]=g.x[i]; TestRegla.consecuente[Clase]=1; return TestRegla; } public double evalua(GenotypeBoosting g) { FuzzyRule ref[]=new FuzzyRule[1]; ref[0]=ConstruyeRegla(g); double fc=ad.CambiaConsReglaABD(ref,W,Clase,Mu,Dsigno); return fc; } } class FitnessABDMaxMin extends Fitness { int nentradas; int nlabels; int Nsalidas; double [][][]Mu; double [][]alpha; boolean []entra; AdaBoostMaxMin ad; static Randomize r; FitnessABDMaxMin(AdaBoostMaxMin vad, int vnentradas,int nsalidas,int nl, double[][][]mu, Randomize vr) { ad=vad; nentradas=vnentradas; nlabels=nl; Nsalidas=nsalidas; Mu=mu; alpha=new double[ad.BaseConocimiento.length+1][Nsalidas]; entra=new boolean[ad.BaseConocimiento.length+1]; Cuentait=new int[4]; r=vr; } public double evalua(GenotypeBoosting g) { // a chromosome will be composed of the antecedent + initial points of all consequents GenotypeBoostingMaxMin gmm=(GenotypeBoostingMaxMin)g; // New rule creation FuzzyRule TestRegla=new FuzzyRule(new int[nentradas],new double[Nsalidas]); // Store antecedent values for (int i=0;i<nentradas;i++) TestRegla.antecedente[i]=gmm.x[i]; // Store initial value of alpha int k=0; for (int i=0;i<ad.BaseConocimiento.length+1;i++) for (int j=0;j<Nsalidas;j++) alpha[i][j]=gmm.alpha[k++]; // ------------------------------------------------------------------------ // Experiment: random alpha values for (int i=0;i<ad.BaseConocimiento.length+1;i++) for (int j=0;j<Nsalidas;j++) alpha[i][j]=5.0f*(r.Rand()-0.5f); // ------------------------------------------------------------------------ for (int i=0;i<ad.BaseConocimiento.length+1;i++) // entra[i]=gmm.entra[i]; // Con GA entra[i]=true; // Automatic // fitness calculation double fc=ad.MinimizaFitness(TestRegla,alpha,Mu,entra,true,r); // Change alpha value k=0; for (int i=0;i<ad.BaseConocimiento.length+1;i++) for (int j=0;j<Nsalidas;j++) gmm.alpha[k++]=alpha[i][j]; if (fc==Fitness.ITERACIONES) Fitness.Cuentait[0]++; if (fc==Fitness.NEGATIVO) Fitness.Cuentait[1]++; if (fc==Fitness.SINGULAR) Fitness.Cuentait[2]++; if (fc==Fitness.NOCUBRE) Fitness.Cuentait[3]++; if (fc>=Fitness.NOELEGIR) fc=Fitness.NOELEGIR; return fc; } public double evalua_sin_optimizar(GenotypeBoosting g) { // a chromosome will be composed of the antecedent + initial points of all consequents GenotypeBoostingMaxMin gmm=(GenotypeBoostingMaxMin)g; // New rule creation FuzzyRule TestRegla=new FuzzyRule(new int[nentradas],new double[Nsalidas]); // store antecedent values for (int i=0;i<nentradas;i++) TestRegla.antecedente[i]=gmm.x[i]; // store initial alpha values int k=0; for (int i=0;i<ad.BaseConocimiento.length+1;i++) for (int j=0;j<Nsalidas;j++) alpha[i][j]=gmm.alpha[k++]; for (int i=0;i<ad.BaseConocimiento.length+1;i++) // entra[i]=gmm.entra[i]; // Con GA entra[i]=true; // Automatico // fitness calculation double fc=ad.MinimizaFitness(TestRegla,alpha,Mu,entra,false,r); if (fc==Fitness.ITERACIONES) Fitness.Cuentait[0]++; if (fc==Fitness.NEGATIVO) Fitness.Cuentait[1]++; if (fc==Fitness.SINGULAR) Fitness.Cuentait[2]++; if (fc==Fitness.NOCUBRE) Fitness.Cuentait[3]++; if (fc>=Fitness.NOELEGIR) fc=Fitness.NOELEGIR; return fc; } } class AdaBoost extends FuzzyClassifier { static Randomize r; AdaBoost(double [][]vejemplos, double [][]vdeseado, Randomize vr) { super(vejemplos,vdeseado); r=vr; } void CalculaPesosEjemplosABD(double []w, int Clase, double [][][]Mu,double[]dsigno) { double rr[]=InferenciaBanco(Clase,Mu); for (int i=0;i<nelem;i++) w[i]=1; for (int i=0;i<nelem;i++) { if (Math.abs(rr[i])>ACT_MIN) // It must be ACT_MIN*w[i] !! w[i]=w[i]*(double)Math.exp(-dsigno[i]*rr[i]); else w[i]=w[i]*(double)Math.exp(PENAL_CUB); } // Normalization weights double suma=0; for (int i=0;i<nelem;i++) suma+=w[i]; for (int i=0;i<nelem;i++) w[i]/=suma; // for (int i=0;i<nelem;i++) { // --------------------------------------- // System.out.print("Ejemplo "+i+":"); // for (int j=0;j<ejemplos[i].length;j++) // System.out.print(ejemplos[i][j]+" "); // System.out.print("->"); // for (int j=0;j<deseado[i].length;j++) // System.out.print(deseado[i][j]+" "); // System.out.print(" r="); // System.out.print(rr[i]+" "); // if (rr[i]*dsigno[i]>0) { // System.out.print("BIEN"); // } else if (rr[i]*dsigno[i]<0) { // System.out.print("MAL"); // } else System.out.print("NO OPINA"); // System.out.println(" Peso="+w[i]); // --------------------------------------- // } } double Z(FuzzyRule regla,double w[],int Clase,double alpha, double[][][]Mu, double[]dsigno) { double fitness=0.0f; double ca[]=CertezaAntecedente(regla,Mu); for (int i=0;i<nelem;i++) { if (Math.abs(ca[i])>ACT_MIN) // It must be ACT_MIN*w[i] !! fitness+=w[i]*Math.exp(-alpha*ca[i]*dsigno[i]); else fitness+=w[i]*Math.exp(Math.abs(alpha)*PENAL_CUB); } return fitness; } class ZFun extends Fun { // Wrapper for Z(alpha) optimization FuzzyRule r; double w[]; double Mu[][][]; int C; double dsigno[]; ZFun(FuzzyRule vr,double vw[],int vC, double [][][]vMu, double []vdsigno) { r=vr; w=vw; C=vC; Mu=vMu; dsigno=vdsigno; } public double evalua(double []alpha) { return Z(r,w,C,alpha[0],Mu,dsigno); } } double CambiaConsReglaABD(FuzzyRule r[], double w[], int Clase, double Mu[][][], double []dsigno) { // we use a Brent's method simplified version double alphaminimo=0; ZFun MinZ=new ZFun(r[0],w,Clase,Mu,dsigno); double XBus[]=new double[1]; XBus[0]=0; double DBus[]=new double[1]; DBus[0]=1; LinearSearchBrent BL=new LinearSearchBrent(MinZ,DBus,XBus); alphaminimo=BL.EncuentraMinimoSimple(); double fitness=Z(r[0],w,Clase,alphaminimo,Mu,dsigno); for (int i=0;i<r[0].consecuente.length;i++) r[0].consecuente[i]=0; r[0].consecuente[Clase]=alphaminimo; return fitness; } int argmaxabs(double []x) { double max=Math.abs(x[0]); int imax=0; for (int i=1;i<x.length;i++) if (Math.abs(x[i])>max) { max=Math.abs(x[i]); imax=i; } return imax; } void AnadeReglaABD2C(int c,double [][][]Mu, double[]w, double[]dsigno) { // Find the best rule according to 'Adaboost descriptive' method // in a two classes problem int []antecedente = new int[nentradas]; double []consecuente = new double[nsalidas]; FuzzyRule result = new FuzzyRule(new int[nentradas], new double[nsalidas]); // Recalculate the importance of the examples double minfit=0; FuzzyRule TestRegla=new FuzzyRule(antecedente,consecuente); // ---------------------------------------------------------- int permutaciones=1; boolean maxint=false; for (int i=0;i<result.antecedente.length;i++){ // prevents int overflow if (permutaciones < Integer.MAX_VALUE/(Etiquetas[i].vertices.length+1)) permutaciones*=(Etiquetas[i].vertices.length+1); else maxint=true; } if (maxint==true) { System.out.println("Total permutaciones > "+Integer.MAX_VALUE); permutaciones=Integer.MAX_VALUE; } else System.out.println("Total permutaciones="+permutaciones); if (permutaciones<1000) { // Exhaustive search double fc=0, minfc=0; int q=1, perc=0; for (int p=0;p<permutaciones;p++) { q++; if (permutaciones>100) { if (q>permutaciones/100) { System.out.println("Terminado "+perc+"%"); q=0; perc++; } } int cp=p; for (int i=0;i<result.antecedente.length;i++) { TestRegla.antecedente[i]=cp%(Etiquetas[i].vertices.length+1); cp=cp/(Etiquetas[i].vertices.length+1); } TestRegla.consecuente[c]=1; FuzzyRule ref[]=new FuzzyRule[1]; ref[0]=TestRegla; fc=CambiaConsReglaABD(ref,w,c,Mu,dsigno); // System.out.print("Probando regla "+p+" Ct"); // for (int i=0;i<TestRegla.antecedente.length;i++) // System.out.print(TestRegla.antecedente[i]+" "); // System.out.print("->"); // for (int i=0;i<TestRegla.consecuente.length;i++) // System.out.print(TestRegla.consecuente[i]+" "); // System.out.println(": Fitness="+fc); if (fc<minfc || p==0) { for (int i=0;i<result.antecedente.length;i++) result.antecedente[i]=TestRegla.antecedente[i]; for (int i=0;i<result.consecuente.length;i++) result.consecuente[i]=TestRegla.consecuente[i]; minfc=fc; } } //------------------------------------------------------ } else { // it is necessary to review the shutdown conditions!!! int nlabels=Etiquetas[0].vertices.length; FitnessABD fitness=new FitnessABD(this,nentradas,nsalidas, nlabels,c,w,Mu,dsigno); GeneticAlgorithmForBoosting AG=new GeneticAlgorithmForBoosting(new GenotypeBoosting(nentradas,nlabels,r)); GenotypeBoosting gen=AG.EncuentraMinimo( nentradas,nlabels,fitness,250,r); FuzzyRule ref[]=new FuzzyRule[1]; ref[0]=fitness.ConstruyeRegla(gen); double fc=CambiaConsReglaABD(ref,w,c,Mu,dsigno); System.out.println("Z="+fc); result=ref[0]; } // If the importance of rule is smaller than minimum allowed, // the rule is not added to the base if (Math.abs(result.consecuente[argmaxabs(result.consecuente)])<MIN_CONS) { System.out.println("No se incorpora la regla"); return; } // incorporate the rule to the knowledge base FuzzyRule NuevoBanco[]= new FuzzyRule[BaseConocimiento.length+1]; for (int i=0;i<BaseConocimiento.length;i++) { NuevoBanco[i]=BaseConocimiento[i]; } NuevoBanco[BaseConocimiento.length]= new FuzzyRule(new int[nentradas],new double[nsalidas]); for (int i=0;i<nentradas;i++) NuevoBanco[BaseConocimiento.length].antecedente[i]= result.antecedente[i]; for (int i=0;i<nsalidas;i++) NuevoBanco[BaseConocimiento.length].consecuente[i]= result.consecuente[i]; BaseConocimiento = NuevoBanco; System.out.println("Regla anadida"+ AString(result.antecedente)+ "->"+AString(result.consecuente)); } } class AdaBoostMaxMin extends FuzzyClassifier { final int MAX_NIT=4; // If it does not finish in MAX_NIT iterations, aborts final double MAXLIMALPHA=1.0f; // Maximum difference allowed in alpha int cdeseado[]; double w[]; static Randomize r; AdaBoostMaxMin(double [][]vejemplos, double [][]vdeseado, Randomize vr) { super(vejemplos,vdeseado); cdeseado=new int[vejemplos.length]; for (int i=0;i<cdeseado.length;i++) { for (int j=0;j<nsalidas;j++) if (vdeseado[i][j]!=0) { cdeseado[i]=j; break; } } w=new double[1]; r=vr; } private int[] duplica(int []a) { int [] result=new int[a.length]; for (int i=0;i<a.length;i++) result[i]=a[i]; return result; } private double[] duplica(double []a) { double [] result=new double[a.length]; for (int i=0;i<a.length;i++) result[i]=a[i]; return result; } private double[][] duplica(double [][]a) { double [][] result=new double[a.length][]; for (int i=0;i<a.length;i++) result[i]=duplica(a[i]); return result; } private void asigna(double result[],double []a) { for (int i=0;i<a.length;i++) result[i]=a[i]; } private void asigna(double result[][],double [][]a) { for (int i=0;i<a.length;i++) asigna(result[i],a[i]); } public int fuzzyclasificamaxmin(int ej, double [][][]Mu, double[]Peso) { int nsalidas=BaseConocimiento[0].consecuente.length; // double maximos[]=new double[nsalidas]; double max=0; int imax=-1; int cmax=0; boolean primera=true; for (int r=0;r<BaseConocimiento.length;r++) { double act=0; int cmaxr=-1; double tr=CertezaAntecedenteEj(ej,BaseConocimiento[r],Mu); if (tr==0) continue; for (int c=0;c<BaseConocimiento[r].consecuente.length;c++) { double cact=tr*BaseConocimiento[r].consecuente[c]; if (cact>act || c==0) { act=cact; cmaxr=c; } } // System.out.println("ejemplo="+i+" act="+act); if (act>max || primera) { primera=false; max=act; imax=r; cmax=cmaxr; } } Peso[0]=max; return cmax; // calculate the probabilities codified in the rule // for (int i=0;i<nsalidas;i++) { // if (imax==-1) { // maximos[i]=1.0f/nsalidas; // if (i==0) maximos[i]+=0.01f; // else maximos[i]-=0.01f/(nsalidas-1); // } // else maximos[i]=BaseConocimiento[imax].consecuente[i]; // } // double den=0; // for (int i=0;i<nsalidas;i++) den+=(double)Math.exp(maximos[i]); // for (int i=0;i<nsalidas;i++) // maximos[i]=(double)Math.exp(maximos[i])/den; // return maximos; } double FuncionCosteChi(double Mu[][][]) { // Chi square criterion double L=0,po,pd; for (int i=0;i<nelem;i++) { int o=fuzzyclasificamaxmin(i,Mu,w); int d=cdeseado[i]; double ew=(double)Math.exp(w[0]); double ew1=(double)Math.exp(-w[0]/(nsalidas-1)); double den=ew+(nsalidas-1)*ew1; for (int s=0;s<nsalidas;s++) { if (s==o) po=ew/den; else po=ew1/den; if (s==d) pd=1; else pd=0; L+=(po-pd)*(po-pd); } } return L; } double FuncionCosteRMS(double Mu[][][]) { double L=0,po,pd; for (int i=0;i<nelem;i++) { int o=fuzzyclasificamaxmin(i,Mu,w); int d=cdeseado[i]; double ew=w[0]; double ew1=-w[0]/(nsalidas-1); for (int s=0;s<nsalidas;s++) { if (s==o) po=ew; else po=ew1; if (s==d) pd=2; else pd=-2; L+=(po-pd)*(po-pd); } } return L; } double FuncionCosteERR(double Mu[][][]) { double L=0,po,pd; for (int i=0;i<nelem;i++) { int o=fuzzyclasificamaxmin(i,Mu,w); int d=cdeseado[i]; if (o!=d) L++; } return L; } double FuncionCoste(double Mu[][][]) { return FuncionCosteRMS(Mu); } double MinimizaFitness(FuzzyRule regla,double [][]alpha, double[][][]Mu, boolean entra[], boolean optimiza, Randomize rand) { // fitness of the new bank when adding the new rule "regla" // If the new rule does not cover any example we do not waste the time // System.out.println("Evaluando "+AString(alpha)); boolean cubrir=false; for (int i=0;i<nelem;i++) { if (CertezaAntecedenteEj(i,regla,Mu)!=0) { cubrir=true; break; } } if (cubrir==false) { return Fitness.NOCUBRE; } int [][]I=new int[nelem][BaseConocimiento.length+1]; int [][]I_old=new int[I.length][I[0].length]; double [][]Y=new double[nsalidas][nelem]; double [][]F=new double[BaseConocimiento.length+1][nelem]; // store the previous base FuzzyRule GuardaBanco[]=BaseConocimiento; // we prove the new rule adding it to the previous base FuzzyRule MiNuevoBanco[]= new FuzzyRule[BaseConocimiento.length+1]; // we copy the base for (int i=0;i<BaseConocimiento.length;i++) { MiNuevoBanco[i]=new FuzzyRule( duplica(BaseConocimiento[i].antecedente), duplica(BaseConocimiento[i].consecuente)); } // we add the new rule MiNuevoBanco[BaseConocimiento.length]= new FuzzyRule(new int[nentradas],new double[nsalidas]); for (int i=0;i<nentradas;i++) MiNuevoBanco[BaseConocimiento.length].antecedente[i]= regla.antecedente[i]; for (int i=0;i<nsalidas;i++) MiNuevoBanco[BaseConocimiento.length].consecuente[i]= regla.consecuente[i]; // we set the initial alpha values for (int i=0;i<entra.length;i++) { for (int Clase=0;Clase<nsalidas;Clase++) MiNuevoBanco[i].consecuente[Clase]=alpha[i][Clase]; } // we replace the knowledge base BaseConocimiento = MiNuevoBanco; double [][]NuevoAlpha=duplica(alpha); double fitness=0,Rfitness=0; // we calculate the values of I if (optimiza) I=CalculaI(Mu,MiNuevoBanco); int nit=0; do { // System.out.println("nit="+nit+" "+AString(NuevoAlpha)); if (nit==0 && !optimiza) { // System.out.println("Optim nit="+nit+" f="+fitness); fitness=FuncionCoste(Mu); break; } for (int i=0;i<F.length;i++) { for (int j=0;j<nelem;j++) { for (int Clase=0;Clase<nsalidas;Clase++) { F[i][j]=CertezaAntecedenteEj(j,MiNuevoBanco[i],Mu)*I[j][i]; Y[Clase][j]=(double)((deseado[j][Clase]-0.5f)/(0.25f)); } } } // we eliminate the null rows int ientra=0; for (int i=0;i<entra.length;i++) { entra[i]=false; for (int j=0;j<nelem;j++){ if (F[i][j]!=0) { entra[i]=true; break; } } if (entra[i]) ientra++; } double Fentra[][]=new double[ientra][]; double NuevoAlphaEntra[][]=new double[ientra][nsalidas]; ientra=0; for (int i=0;i<entra.length;i++) { if (entra[i]) { Fentra[ientra]=F[i]; ientra++; } } double [][]NA=duplica(NuevoAlpha); if (ientra==0) { asigna(alpha,NuevoAlpha); // System.out.println("Sing 1 nit="+nit+" f="+fitness); fitness=Fitness.SINGULAR; break; } else { try { NuevoAlphaEntra= MatrixCalcs.tr(MatrixCalcs.matmul(Y, MatrixCalcs.matmul(MatrixCalcs.tr(Fentra), MatrixCalcs.inv(MatrixCalcs.matmul( Fentra,MatrixCalcs.tr(Fentra)))))); } catch(MatrixCalcs.ErrorDimension e) { System.err.println(e); System.exit(0); } catch(MatrixCalcs.ErrorSingular e) { asigna(alpha,NuevoAlpha); // System.out.println("Sing 2 nit="+nit+" f="+fitness); fitness=Fitness.SINGULAR; break; } } ientra=0; for (int i=0;i<entra.length;i++) { if (entra[i]) { for (int j=0;j<nsalidas;j++) { NuevoAlpha[i][j]=NuevoAlphaEntra[ientra][j]; } ientra++; } else { for (int j=0;j<nsalidas;j++) { NuevoAlpha[i][j]=0.0f; } } } // smoothing double lambda=0.75f; double maxdifalpha=0.0f; if (nit>0) for (int Clase=0;Clase<nsalidas;Clase++) for (int i=0;i<NuevoAlpha.length;i++) { double dif=Math.abs(NuevoAlpha[i][Clase]-NA[i][Clase]); if (dif>maxdifalpha) maxdifalpha=dif; NuevoAlpha[i][Clase]= lambda*NA[i][Clase]+(1.0f-lambda)*NuevoAlpha[i][Clase]; } // we return as fitness the residual from the approach |y-alpha*F| // Rfitness=0; // for (int i=0;i<nelem;i++) { // double out=0; // for (int Clase=0;Clase<nsalidas;Clase++) { // out=0; // for (int r=0;r<alpha.length;r++) { // out+=F[r][i]*NuevoAlpha[r][Clase]; // } // double err=out-Y[Clase][i]; // Rfitness+=err*err; // } // } // we update alphas in the base copy for (int i=0;i<alpha.length;i++) for (int Clase=0;Clase<nsalidas;Clase++) { MiNuevoBanco[i].consecuente[Clase]=NuevoAlpha[i][Clase]; } for (int i=0;i<I.length;i++) for (int j=0;j<I[0].length;j++) I_old[i][j]=I[i][j]; I=CalculaI(Mu,MiNuevoBanco); int distintos=0; for (int i=0;i<I.length;i++) for (int j=0;j<I[0].length;j++) { if (I_old[i][j]!=I[i][j]) distintos++; } // we verify that at least one of the weights is positive // in all base rows boolean negativo=true; for (int r=0;r<MiNuevoBanco.length;r++) { negativo=true; for (int i=0;i<nsalidas;i++) if (MiNuevoBanco[r].consecuente[i]>0) { negativo=false; break; } if (negativo) break; } if (negativo) { fitness=Fitness.NEGATIVO; break; } if (nit>=MAX_NIT) { fitness=FuncionCoste(Mu); asigna(alpha,NuevoAlpha); // fitness=Fitness.ITERACIONES; // fitness*=10; break; } if (distintos==0 && maxdifalpha<=MAXLIMALPHA) { fitness=FuncionCoste(Mu); asigna(alpha,NuevoAlpha); break; } nit++; } while (true); // we leave unchanged the knowledge base BaseConocimiento = GuardaBanco; // System.out.println("Coste="+fitness); return fitness; } int argmaxabs(double []x) { double max=Math.abs(x[0]); int imax=0; for (int i=1;i<x.length;i++) if (Math.abs(x[i])>max) { max=Math.abs(x[i]); imax=i; } return imax; } double AnadeReglaABDMM(double [][][]Mu) { // Find the best rule according to 'Adaboost max-min descriptive' method // in a 'nsalidas' classes problem (n outputs) int []antecedente = new int[nentradas]; double []consecuente = new double[nsalidas]; double [][]minalpha = new double[nelem][nsalidas]; FuzzyRule result = new FuzzyRule(new int[nentradas], new double[nsalidas]); double minfit=0, minfc=0; FuzzyRule TestRegla=new FuzzyRule(antecedente,consecuente); // it is necessary to review the shutdown conditions!!! int nlabels=Etiquetas[0].vertices.length; FitnessABDMaxMin fitness=new FitnessABDMaxMin(this,nentradas,nsalidas,nlabels,Mu,r); GenotypeBoostingMaxMin gen; // if (BaseConocimiento.length>0) { GeneticAlgorithmForBoosting AG= new GeneticAlgorithmForBoosting(new GenotypeBoostingMaxMin(nentradas,nlabels, nsalidas,BaseConocimiento.length+1,r)); gen=(GenotypeBoostingMaxMin)AG.EncuentraMinimo( nentradas,nlabels,fitness,250,r); // gen=(GenotypeBoostingMaxMin)AG.EncuentraMinimoSA( // fitness,10000,10.0f,0.9999f); System.out.println("Convergencias="+fitness.Cuentait[0]); System.out.println("Negativos="+fitness.Cuentait[1]); System.out.println("Singulares="+fitness.Cuentait[2]); System.out.println("No cubre="+fitness.Cuentait[3]); // } else { // // null first rule // gen=new GenotypeBoostingMaxMin(nentradas,nlabels,nsalidas,1); // for (int i=0;i<gen.x.length;i++) gen.x[i]=0; // for (int i=0;i<gen.entra.length;i++) gen.entra[i]=true; // for (int i=0;i<gen.alpha.length;i++) gen.alpha[i]=0; // double fc=fitness.evalua(gen); // System.out.println("Fitness de la primera regla: "+fc); // } // calculate new rule from solution FuzzyRule solucion=new FuzzyRule(new int[nentradas],new double[nsalidas]); // store antecedent and consequent values for (int i=0;i<nentradas;i++) solucion.antecedente[i]=gen.x[i]; for (int i=0;i<nsalidas;i++) solucion.consecuente[i]=gen.alpha[BaseConocimiento.length*nsalidas+i]; // calculate the knowledge base consequents and fitness of the solution double fc=fitness.evalua_sin_optimizar(gen); System.out.println("Candidato= "+AString(solucion.antecedente)+" -> "+AString(solucion.consecuente)+" Z="+fc); // Add rule to base FuzzyRule NuevoBanco[]=new FuzzyRule[BaseConocimiento.length+1]; NuevoBanco[BaseConocimiento.length]= new FuzzyRule(new int[nentradas],new double[nsalidas]); // update the alphas for (int i=0;i<BaseConocimiento.length;i++) { NuevoBanco[i]=BaseConocimiento[i]; } for (int r=0;r<BaseConocimiento.length;r++) { for (int Clase=0;Clase<nsalidas;Clase++) NuevoBanco[r].consecuente[Clase]=gen.alpha[r*nsalidas+Clase]; } // Add the new rule for (int i=0;i<nentradas;i++) NuevoBanco[BaseConocimiento.length].antecedente[i]= solucion.antecedente[i]; for (int i=0;i<nsalidas;i++) NuevoBanco[BaseConocimiento.length].consecuente[i]= solucion.consecuente[i]; BaseConocimiento = NuevoBanco; return fc; } } class FitnessLGB extends Fitness { final double FITNESS_MALO=1000f; // worst Fitness int nentradas; int nlabels; int Nsalidas; int Clase; double []eta; double [][][]Mu; double []Dsigno; double []AjusteAlpha; LogitBoost lg; FitnessLGB(LogitBoost vlg, int vnentradas,int nsalidas,int nl,int clase, double []veta, double[][][]mu, double []dsigno, double[]AA) { lg=vlg; nentradas=vnentradas; nlabels=nl; Nsalidas=nsalidas; Clase=clase; eta=veta; Mu=mu; Dsigno=dsigno; AjusteAlpha=AA; } FuzzyRule ConstruyeRegla(GenotypeBoosting g) { FuzzyRule TestRegla= new FuzzyRule(new int[g.x.length],new double[Nsalidas]); for (int i=0;i<g.x.length;i++) TestRegla.antecedente[i]=g.x[i]; TestRegla.consecuente[Clase]=1; return TestRegla; } public double evalua(GenotypeBoosting g) { FuzzyRule ref[]=new FuzzyRule[1]; ref[0]=ConstruyeRegla(g); boolean rz=true; for (int i=0;i<ref[0].antecedente.length;i++) { if (ref[0].antecedente[i]!=0) { rz=false; break; } } double fc=FITNESS_MALO; if (!rz) fc=lg.CambiaConsReglaLGB(ref,eta,Clase,Mu,Dsigno,AjusteAlpha); return fc; } } class LogitBoost extends FuzzyClassifier { final double FITNESS_MALO=1000f; // worst Fitness boolean VersionBasica; static Randomize r; LogitBoost(double [][]vejemplos, double [][]vdeseado, boolean VB, Randomize vr) { super(vejemplos,vdeseado); VersionBasica=VB; r=vr; } void CalculaResiduosLGB(double []rr, int Clase, double [][][]Mu,double[]dsigno) { } double CambiaConsReglaLGB(FuzzyRule regla[], double eta[], int Clase, double Mu[][][], double []dsigno, double []NuevasAlphas) { // determine analiticaly the alpha of the rule // calculate the residual final double CERO=0.000001f; double r[]=new double [dsigno.length]; double p[]=new double [dsigno.length]; for (int i=0;i<nelem;i++) { double expr=(double)Math.exp(eta[i]); p[i]=(double)(expr/(1.0+expr)); if (dsigno[i]>0) { r[i]+=(1.0f+expr)/expr; } else { r[i]-=(1.0f+expr); } } // and certainty of the consequent double ca[]=CertezaAntecedente(regla[0],Mu); double sumasy=0, sumas2=0, medias=0, mediay=0, sumapeso=0; for (int i=0;i<ca.length;i++) { double peso=p[i]*(1-p[i]); mediay+=r[i]*peso; medias+=ca[i]*peso; sumapeso+=peso; } // assure that sumapeso is not zero double fitness=0, mediaerr=0, alphaminimo=0; if (Math.abs(sumapeso)>=CERO) { mediay/=sumapeso; medias/=sumapeso; // System.out.println("mediay="+mediay); // System.out.println("medias="+medias); for (int i=0;i<ca.length;i++) { double peso=p[i]*(1-p[i]); sumasy+=(r[i]-mediay)*(ca[i]-medias)*peso; sumas2+=(ca[i]-medias)*(ca[i]-medias)*peso; } if (Math.abs(sumas2)>CERO) alphaminimo=sumasy/sumas2; // System.out.println("alpha="+alphaminimo); // Now we calculate the approach error for (int i=0;i<ca.length;i++) { double peso=p[i]*(1-p[i]); double err=(r[i]-alphaminimo*ca[i])*peso; mediaerr+=err; } mediaerr/=sumapeso; // without considering that weak learners have null average if (VersionBasica) mediaerr=0; double debugerr=0; for (int i=0;i<ca.length;i++) { double peso=p[i]*(1-p[i]); double err=(r[i]-alphaminimo*ca[i]-mediaerr)*peso; fitness+=err*err*p[i]*(1-p[i]); debugerr+=err; } fitness/=sumapeso; // System.out.println("Debugerr="+debugerr); } // update the rule consequent if (Math.abs(sumas2)<=CERO) alphaminimo=mediaerr; for (int i=0;i<regla[0].consecuente.length;i++) regla[0].consecuente[i]=0; regla[0].consecuente[Clase]=alphaminimo; // Recalculate the weights of the other rules // with the same class in the base // in this version, we only update average value boolean PrimeraRegla=true; for (int i=0;i<BaseConocimiento.length;i++) { if (argmaxabs(BaseConocimiento[i].consecuente)==Clase) { NuevasAlphas[i]=BaseConocimiento[i].consecuente[Clase]; if (PrimeraRegla) { PrimeraRegla=false; NuevasAlphas[i]+=mediaerr; } } } return fitness; } int argmaxabs(double []x) { double max=Math.abs(x[0]); int imax=0; for (int i=1;i<x.length;i++) if (Math.abs(x[i])>max) { max=Math.abs(x[i]); imax=i; } return imax; } void AnadeReglaLGB2C(int c,double [][][]Mu, double[]w, double[]dsigno) { // Find the best rule according to 'Logitboost descriptive' method // in a two classes problem int []antecedente = new int[nentradas]; double []consecuente = new double[nsalidas]; FuzzyRule result = new FuzzyRule(new int[nentradas], new double[nsalidas]); double [] AjusteAlphas = new double[BaseConocimiento.length]; // Recalculate the importance of the examples double minfit=0; FuzzyRule TestRegla=new FuzzyRule(antecedente,consecuente); double [] NuevasAlphas = new double[BaseConocimiento.length]; boolean PrimeraRegla=true; for (int i=0;i<BaseConocimiento.length;i++) if (argmaxabs(BaseConocimiento[i].consecuente)==c) { PrimeraRegla=false; break; } if (VersionBasica) PrimeraRegla=false; // ---------------------------------------------------------- int permutaciones=1; boolean maxint=false; for (int i=0;i<result.antecedente.length;i++){ // prevents int overflow if (permutaciones < Integer.MAX_VALUE/(Etiquetas[i].vertices.length+1)) permutaciones*=(Etiquetas[i].vertices.length+1); else maxint=true; } if (maxint==true) { System.out.println("Total permutaciones > "+Integer.MAX_VALUE); permutaciones=Integer.MAX_VALUE; } else System.out.println("Total permutaciones="+permutaciones); if (permutaciones<1000 || PrimeraRegla) { // Exhaustive Search double fc=0, minfc=0; int q=1, perc=0; for (int p=0;p<permutaciones;p++) { q++; if (permutaciones>100) { if (q>permutaciones/100) { System.out.println("Terminado "+perc+"%"); q=0; perc++; } } int cp=p; for (int i=0;i<result.antecedente.length;i++) { TestRegla.antecedente[i]=cp%(Etiquetas[i].vertices.length+1); cp=cp/(Etiquetas[i].vertices.length+1); } TestRegla.consecuente[c]=1; FuzzyRule ref[]=new FuzzyRule[1]; ref[0]=TestRegla; double eta[]=InferenciaBanco(c,Mu); fc=CambiaConsReglaLGB(ref,eta,c,Mu,dsigno,NuevasAlphas); // don't allow that the rule [000..00] appears twice if (!PrimeraRegla && p==0) fc=FITNESS_MALO; System.out.print("Probando regla "+p+" Ct"); for (int i=0;i<TestRegla.antecedente.length;i++) System.out.print(TestRegla.antecedente[i]+" "); System.out.print("->"); for (int i=0;i<TestRegla.consecuente.length;i++) System.out.print(TestRegla.consecuente[i]+" "); System.out.println(": Fitness="+fc); if (fc<minfc || p==0) { for (int i=0;i<result.antecedente.length;i++) result.antecedente[i]=TestRegla.antecedente[i]; for (int i=0;i<result.consecuente.length;i++) result.consecuente[i]=TestRegla.consecuente[i]; for (int i=0;i<AjusteAlphas.length;i++) AjusteAlphas[i]=NuevasAlphas[i]; minfc=fc; } if (PrimeraRegla) { PrimeraRegla=false; break; } } //------------------------------------------------------ } else { // it is necessary to review the shutdown conditions!!! int nlabels=Etiquetas[0].vertices.length; double eta[]=InferenciaBanco(c,Mu); FitnessLGB fitness=new FitnessLGB(this,nentradas,nsalidas, nlabels,c,eta,Mu,dsigno,NuevasAlphas); GeneticAlgorithmForBoosting AG=new GeneticAlgorithmForBoosting( new GenotypeBoosting(nentradas,nlabels,r)); GenotypeBoosting gen=AG.EncuentraMinimo( nentradas,nlabels,fitness,250,r); FuzzyRule ref[]=new FuzzyRule[1]; ref[0]=fitness.ConstruyeRegla(gen); double fc=CambiaConsReglaLGB(ref,eta,c,Mu,dsigno,AjusteAlphas); System.out.println("ECM Regla="+fc); result=ref[0]; } // If the importance of rule is smaller than minimum allowed, // the rule is not added to the base if (Math.abs(result.consecuente[argmaxabs(result.consecuente)])<MIN_CONS) { System.out.println("No se incorpora la regla"); return; } // incorporate the rule to the knowledge base FuzzyRule NuevoBanco[]= new FuzzyRule[BaseConocimiento.length+1]; for (int i=0;i<BaseConocimiento.length;i++) { NuevoBanco[i]=BaseConocimiento[i]; if (!VersionBasica) NuevoBanco[i].consecuente[c]=AjusteAlphas[i]; } NuevoBanco[BaseConocimiento.length]= new FuzzyRule(new int[nentradas],new double[nsalidas]); for (int i=0;i<nentradas;i++) NuevoBanco[BaseConocimiento.length].antecedente[i]= result.antecedente[i]; for (int i=0;i<nsalidas;i++) { NuevoBanco[BaseConocimiento.length].consecuente[i]= result.consecuente[i]; } BaseConocimiento = NuevoBanco; System.out.println("Regla anadida"+ AString(result.antecedente)+ "->"+AString(result.consecuente)); } } public class FB { static double W[][]; static Randomize r; public static void fuzzycreavacio( int nentradas, // inputs number int nsalidas, // outputs number int nlabels, // labels number double [] train, // training inputs double [] ytrain, // training outputs double [] bancoreglas, // weights Randomize vr ) { // Creates an empty base of rules // common to all the fuzzy-boosting classification algorithms r=vr; int nelem=train.length/nentradas; System.out.println("Numero entradas="+nentradas); System.out.println("Numero salidas="+nsalidas); System.out.println("Dimension train="+train.length); System.out.println("Dimension ytrain="+ytrain.length); System.out.println("Dimension bancoreglas="+bancoreglas.length); System.out.println("Numero ejemplos="+nelem); System.out.println("Numero de etiquetas por variable="+nlabels); double errf=0; double[][] ejemplos=new double[nelem][nentradas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nentradas;j++) { ejemplos[i][j]=(double)train[i*nentradas+j]; } } double[][] deseado=new double[nelem][nsalidas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nsalidas;j++) { deseado[i][j]=(double)ytrain[i+j*nelem]; } } // AdaBoost cf=new AdaBoost(ejemplos,deseado); FuzzyClassifier cf=new FuzzyClassifier(ejemplos,deseado); // System.out.println("ejemplos="+cf.AString(ejemplos)); // System.out.println("deseado="+cf.AString(deseado)); // Particion linguistica uniforme cf.EstimaParticiones(nlabels); // Store all parameters in vector (of R) cf.AlmacenaParametros(bancoreglas); // System.out.println("BancoReglas="+cf.AString(bancoreglas)); } public static double[] fuzzyclasifica( double [] x, // imput int nsalidas, // outputs number double [] bancoreglas // weights ) { // pattern classification with a Fuzzy Classifier // common to all the fuzzy-boosting classification algorithms double [][]ejemplos = new double[1][]; ejemplos[0]=x; double [][]deseado = new double[1][nsalidas]; // Load R vector parameters // AdaBoost cf=new AdaBoost(ejemplos,deseado); FuzzyClassifier cf=new FuzzyClassifier(ejemplos,deseado); cf.RecuperaParametros(bancoreglas); double Mu[][][]=new double[1][cf.Etiquetas.length][]; for (int i=0;i<cf.nelem;i++) { for (int v=0;v<cf.Etiquetas.length;v++) { Mu[i][v]=cf.Etiquetas[v].pertenencia(cf.ejemplos[i][v]); } } double suma[]=new double[nsalidas]; for (int r=0;r<cf.BaseConocimiento.length;r++) { double tr=cf.CertezaAntecedenteEj(0,cf.BaseConocimiento[r],Mu); for (int k=0;k<nsalidas;k++) suma[k]+=cf.BaseConocimiento[r].consecuente[k]*tr; } return suma; } public static double[] fuzzyclasificamaxmin( double [] x, // input int nsalidas, // outputs number double [] bancoreglas // weights ) { // pattern classification with a Fuzzy Classifier // common to all the fuzzy-boosting classification algorithms double [][]ejemplos = new double[1][]; ejemplos[0]=x; double [][]deseado = new double[1][nsalidas]; // Load R vector parameters // AdaBoost cf=new AdaBoost(ejemplos,deseado); AdaBoostMaxMin cf=new AdaBoostMaxMin(ejemplos,deseado,r); cf.RecuperaParametros(bancoreglas); double Mu[][][]=new double[1][cf.Etiquetas.length][]; for (int i=0;i<cf.nelem;i++) { for (int v=0;v<cf.Etiquetas.length;v++) { Mu[i][v]=cf.Etiquetas[v].pertenencia(cf.ejemplos[i][v]); } } double maximos[]=new double[nsalidas]; double W[]=new double[1]; int cmax=cf.fuzzyclasificamaxmin(0,Mu,W); maximos[cmax]=W[0]; return maximos; } public static void fadaboostinc( int nentradas, // inputs number int nsalidas, // outputs number double [] train, // training inputs double [] ytrain, // training outputs double [] bancoreglas // weights ) { // Add a new rule to the base using AdaBoost algorithm int nelem=train.length/nentradas; System.out.println("Numero entradas="+nentradas); System.out.println("Numero salidas="+nsalidas); System.out.println("Dimension train="+train.length); System.out.println("Dimension ytrain="+ytrain.length); System.out.println("Dimension bancoreglas="+bancoreglas.length); System.out.println("Numero ejemplos="+nelem); double errf=0; double[][] ejemplos=new double[nelem][nentradas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nentradas;j++) { ejemplos[i][j]=(double)train[i*nentradas+j]; } } double[][] deseado=new double[nelem][nsalidas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nsalidas;j++) { deseado[i][j]=(double)ytrain[i+j*nelem]; } } AdaBoost cf=new AdaBoost(ejemplos,deseado,r); // Reload Classifier parameters cf.RecuperaParametros(bancoreglas); double Mu[][][]=new double[cf.nelem][cf.Etiquetas.length][]; for (int i=0;i<cf.nelem;i++) { for (int v=0;v<cf.Etiquetas.length;v++) { Mu[i][v]=cf.Etiquetas[v].pertenencia(cf.ejemplos[i][v]); } } W=new double[nsalidas][nelem]; int limite=nsalidas; if (limite==2) limite=1; int Clase=-1; double maxerr=0; double []total=new double[nsalidas]; // the rule of the class with smaller average weight is added // int []fallos=new int[nsalidas]; // for (int i=0;i<nelem;i++) { // double[] segs=fuzzyclasifica(ejemplos[i],nsalidas,bancoreglas); // if (argmax(segs)!=argmax(deseado[i])) fallos[argmax(deseado[i])]++; // total[argmax(deseado[i])]++; // } // for (int c=0;c<limite;c++) { // System.out.println("Error "+c+"="+fallos[c]/(double)total[c]); // if (fallos[c]/(double)total[c] > maxerr) { // maxerr=fallos[c]/(double)total[c]; // Clase=c; // } // } // the rule of the class with less number of rules for (int r=0;r<cf.BaseConocimiento.length;r++) { total[cf.argmaxabs(cf.BaseConocimiento[r].consecuente)]++; } Clase=argmin(total); // In two classes problems -> class=0 // this way the same rules are not repeated twice if (nsalidas==2) Clase=0; System.out.println("PROCESANDO CLASE "+Clase); double []dsigno=cf.CalculaSignoDeseado(Clase); cf.CalculaPesosEjemplosABD(W[Clase],Clase,Mu,dsigno); cf.AnadeReglaABD2C(Clase,Mu,W[Clase],dsigno); // store parameters in R vector cf.AlmacenaParametros(bancoreglas); // Test cf.MuestraBase(); } public static void flogitboostinc( int nentradas, // inputs number int nsalidas, // outputs number double [] train, // training inputs double [] ytrain, // training outputs double [] bancoreglas, // weights boolean VB // Basic version - Prefitting ) { // Add a new rule to the base using LogitBoost algorithm int nelem=train.length/nentradas; System.out.println("Numero entradas="+nentradas); System.out.println("Numero salidas="+nsalidas); System.out.println("Dimension train="+train.length); System.out.println("Dimension ytrain="+ytrain.length); System.out.println("Dimension bancoreglas="+bancoreglas.length); System.out.println("Numero ejemplos="+nelem); double errf=0; double[][] ejemplos=new double[nelem][nentradas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nentradas;j++) { ejemplos[i][j]=(double)train[i*nentradas+j]; } } double[][] deseado=new double[nelem][nsalidas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nsalidas;j++) { deseado[i][j]=(double)ytrain[i+j*nelem]; } } LogitBoost cf=new LogitBoost(ejemplos,deseado,VB,r); // Reload Classifier cf.RecuperaParametros(bancoreglas); double Mu[][][]=new double[cf.nelem][cf.Etiquetas.length][]; for (int i=0;i<cf.nelem;i++) { for (int v=0;v<cf.Etiquetas.length;v++) { Mu[i][v]=cf.Etiquetas[v].pertenencia(cf.ejemplos[i][v]); } } W=new double[nsalidas][nelem]; int limite=nsalidas; if (limite==2) limite=1; int Clase=-1; double maxerr=0; double []total=new double[nsalidas]; // a rule of the class with smaller average weight is added // int []fallos=new int[nsalidas]; // for (int i=0;i<nelem;i++) { // double[] segs=fuzzyclasifica(ejemplos[i],nsalidas,bancoreglas); // if (argmax(segs)!=argmax(deseado[i])) fallos[argmax(deseado[i])]++; // total[argmax(deseado[i])]++; // } // for (int c=0;c<limite;c++) { // System.out.println("Error "+c+"="+fallos[c]/(double)total[c]); // if (fallos[c]/(double)total[c] > maxerr) { // maxerr=fallos[c]/(double)total[c]; // Clase=c; // } // } // the rule of the class with less number of rules is added for (int r=0;r<cf.BaseConocimiento.length;r++) { total[cf.argmaxabs(cf.BaseConocimiento[r].consecuente)]++; } Clase=argmin(total); // In two classes problems -> class=0 // this way the same rules are not repeated twice if (nsalidas==2) Clase=0; System.out.println("PROCESANDO CLASE "+Clase); double []dsigno=cf.CalculaSignoDeseado(Clase); cf.AnadeReglaLGB2C(Clase,Mu,W[Clase],dsigno); // Store parameters in R vector cf.AlmacenaParametros(bancoreglas); // Test cf.MuestraBase(); } public static void fadaboostincmaxmin( int nentradas, // inputs number int nsalidas, // outputs number double [] train, // training inputs double [] ytrain, // training outputs double [] bancoreglas, // weights double [] oldfit ) { // Add a new rule to the base using AdaBoostMaxMin algorithm int nelem=train.length/nentradas; System.out.println("Numero entradas="+nentradas); System.out.println("Numero salidas="+nsalidas); System.out.println("Dimension train="+train.length); System.out.println("Dimension ytrain="+ytrain.length); System.out.println("Dimension bancoreglas="+bancoreglas.length); System.out.println("Numero ejemplos="+nelem); double errf=0; double[][] ejemplos=new double[nelem][nentradas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nentradas;j++) { ejemplos[i][j]=(double)train[i*nentradas+j]; } } double[][] deseado=new double[nelem][nsalidas]; for (int i=0;i<nelem;i++) { for (int j=0;j<nsalidas;j++) { deseado[i][j]=(double)ytrain[i+j*nelem]; } } AdaBoostMaxMin cf=new AdaBoostMaxMin(ejemplos,deseado,r); // Reload classifier cf.RecuperaParametros(bancoreglas); // Pre-calculate the ownership of each example/label to optimize time double Mu[][][]=new double[cf.nelem][cf.Etiquetas.length][]; for (int i=0;i<cf.nelem;i++) { for (int v=0;v<cf.Etiquetas.length;v++) { Mu[i][v]=cf.Etiquetas[v].pertenencia(cf.ejemplos[i][v]); } } double newfit=cf.AnadeReglaABDMM(Mu); // store parameters in R vector // the rule is added if it improves fitness if (oldfit[0]>0 && newfit>=oldfit[0]) { System.out.println("No se almacena la regla!"); return; } else cf.AlmacenaParametros(bancoreglas); // Test cf.MuestraBase(); oldfit[0]=newfit; } // ------------------------------------------------------ // TEST TEST TEST // ------------------------------------------------------ static double train[][]; static int ctrain[]; // training static int nfeatures; // inputs number static int nclases; // classes number static double test[][]; static int ctest[]; // Test static double f[][]; static int c[]; private static void CargaDatosClasifGranada(String nombre) { // Read a data file with Paco's group format: // First line: number of examples // Second line: characteristics number + 1 // One example by line // The classes are coded using integers. First class = 0 int nejemplos; nclases=1; try { BufferedReader in = new BufferedReader(new FileReader(nombre)); String linea=in.readLine(); nejemplos=Integer.parseInt(linea); linea=in.readLine(); // An only exit, the mid-value of class nfeatures=Integer.parseInt(linea)-1; f=new double[nejemplos][nfeatures]; c=new int[nejemplos]; for (int i=0;i<nejemplos;i++) { linea=in.readLine(); if (linea==null) break; StringTokenizer tokens=new StringTokenizer(linea," ,"); for (int j=0;j<nfeatures;j++) { f[i][j]=Double.parseDouble(tokens.nextToken()); } c[i]=Integer.parseInt(tokens.nextToken()); // Number of classes. if (c[i]+1>nclases) nclases=c[i]+1; } } catch(FileNotFoundException e) { System.err.println(e+" Fichero "+nombre+" no encontrado"); } catch(IOException e) { System.err.println(e+" Error lectura"); } } public static int argmax(double []x) { double max=x[0]; int imax=0; for (int i=1;i<x.length;i++) if (x[i]>max) { max=x[i]; imax=i; } return imax; } private static int argmin(double []x) { double min=x[0]; int imin=0; for (int i=1;i<x.length;i++) if (x[i]<min) { min=x[i]; imin=i; } return imin; } public static void main(String argv[]) { // Test Rutine if (argv.length==0) { System.out.println("Falta fichero de train"); System.exit(1); } if (argv.length==1) { System.out.println("Falta fichero de test"); System.exit(1); } if (argv.length==2) { System.out.println("Falta numero de reglas"); System.exit(1); } if (argv.length==3) { System.out.println("Falta numero de etiquetas"); System.exit(1); } // Load training file CargaDatosClasifGranada(argv[0]); train=f; ctrain=c; CargaDatosClasifGranada(argv[1]); test=f; ctest=c; int nreglas = Integer.parseInt(argv[2]); int nlabels = Integer.parseInt(argv[3]); // remake !!! double []bancoreglas=new double[2000]; int nentradas=nfeatures; int nsalidas=nclases; double ytrain[][]=new double[train.length][nsalidas]; double ytest[][]=new double[test.length][nsalidas]; for (int i=0;i<ytrain.length;i++) ytrain[i][ctrain[i]]=1; for (int i=0;i<ytest.length;i++) ytest[i][ctest[i]]=1; int p=0; double lintrain[]=new double[train.length*train[0].length]; for (int i=0;i<train.length;i++) for (int j=0;j<train[i].length;j++) lintrain[p++]=train[i][j]; p=0; double lintest[]=new double[test.length*test[0].length]; for (int i=0;i<test.length;i++) for (int j=0;j<test[i].length;j++) lintest[p++]=test[i][j]; p=0; double linytrain[]=new double[ytrain.length*ytrain[0].length]; for (int j=0;j<ytrain[0].length;j++) for (int i=0;i<ytrain.length;i++) linytrain[p++]=ytrain[i][j]; p=0; double linytest[]=new double[ytest.length*ytest[0].length]; for (int j=0;j<ytest[0].length;j++) for (int i=0;i<ytest.length;i++) linytest[p++]=ytest[i][j]; FB fb=new FB(); // % training accuracy double fallos=0; fb.fuzzycreavacio(nentradas,nsalidas,nlabels, lintrain,linytrain,bancoreglas,r); int limite=0; if (nsalidas==2) limite=1; else limite=nsalidas; double fit[]=new double[1]; for (int r=0;r<nreglas;r++) { fallos=0; // fb.fadaboostinc(nentradas,nsalidas,lintrain,linytrain,bancoreglas); // fb.flogitboostinc(nentradas,nsalidas,lintrain,linytrain,bancoreglas,false); fb.fadaboostincmaxmin( nentradas,nsalidas,lintrain,linytrain,bancoreglas,fit); for (int i=0;i<train.length;i++) { // double[] segs=fuzzyclasifica(train[i],nsalidas,bancoreglas); double[] segs=fuzzyclasificamaxmin(train[i],nsalidas,bancoreglas); for (int k=0;k<segs.length;k++) System.out.print(segs[k]+" "); System.out.print("Clase="+ctrain[i]); int ac=argmax(segs); if (ac!=(int)ctrain[i]) { fallos++; System.out.println(" Fallo"); } else { System.out.println(" Acierto"); } } System.out.println("Error Train: ="+fallos/train.length); // % test accuracy fallos=0; for (int i=0;i<test.length;i++) { double[] segs=fuzzyclasificamaxmin(test[i],nsalidas,bancoreglas); if (argmax(segs)!=ctest[i]) fallos++; } System.out.println("Test completo: "+fallos/test.length); } } }