Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
GeneticFitter.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Peter Speckmayer
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : GeneticFitter *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation *
12  * *
13  * Authors (alphabetical): *
14  * Peter Speckmayer <speckmay@mail.cern.ch> - CERN, Switzerland *
15  * *
16  * Copyright (c) 2005: *
17  * CERN, Switzerland *
18  * MPI-K Heidelberg, Germany *
19  * *
20  * Redistribution and use in source and binary forms, with or without *
21  * modification, are permitted according to the terms listed in LICENSE *
22  * (http://tmva.sourceforge.net/LICENSE) *
23  **********************************************************************************/
24 
25 /*! \class TMVA::GeneticFitter
26 \ingroup TMVA
27 
28 Fitter using a Genetic Algorithm.
29 
30 */
31 
32 #include "TMVA/GeneticFitter.h"
33 
34 #include "TMVA/Configurable.h"
35 #include "TMVA/GeneticAlgorithm.h"
36 #include "TMVA/Interval.h"
37 #include "TMVA/FitterBase.h"
38 #include "TMVA/MsgLogger.h"
39 #include "TMVA/Timer.h"
40 #include "TMVA/Types.h"
41 
42 #include "Rtypes.h"
43 #include "TString.h"
44 
45 #include <iostream>
46 
47 ClassImp(TMVA::GeneticFitter);
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// constructor
51 
52 TMVA::GeneticFitter::GeneticFitter( IFitterTarget& target,
53  const TString& name,
54  const std::vector<TMVA::Interval*>& ranges,
55  const TString& theOption )
56 : FitterBase( target, name, ranges, theOption )
57 {
58  // default parameters settings for Genetic Algorithm
59  DeclareOptions();
60  ParseOptions();
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// declare GA options
65 
66 void TMVA::GeneticFitter::DeclareOptions()
67 {
68  DeclareOptionRef( fPopSize=300, "PopSize", "Population size for GA" );
69  DeclareOptionRef( fNsteps=40, "Steps", "Number of steps for convergence" );
70  DeclareOptionRef( fCycles=3, "Cycles", "Independent cycles of GA fitting" );
71  DeclareOptionRef( fSC_steps=10, "SC_steps", "Spread control, steps" );
72  DeclareOptionRef( fSC_rate=5, "SC_rate", "Spread control, rate: factor is changed depending on the rate" );
73  DeclareOptionRef( fSC_factor=0.95, "SC_factor", "Spread control, factor" );
74  DeclareOptionRef( fConvCrit=0.001, "ConvCrit", "Convergence criteria" );
75 
76  DeclareOptionRef( fSaveBestFromGeneration=1, "SaveBestGen",
77  "Saves the best n results from each generation. They are included in the last cycle" );
78  DeclareOptionRef( fSaveBestFromCycle=10, "SaveBestCycle",
79  "Saves the best n results from each cycle. They are included in the last cycle. The value should be set to at least 1.0" );
80 
81  DeclareOptionRef( fTrim=kFALSE, "Trim",
82  "Trim the population to PopSize after assessing the fitness of each individual" );
83  DeclareOptionRef( fSeed=100, "Seed", "Set seed of random generator (0 gives random seeds)" );
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// set GA configuration parameters
88 
89 void TMVA::GeneticFitter::SetParameters( Int_t cycles,
90  Int_t nsteps,
91  Int_t popSize,
92  Int_t SC_steps,
93  Int_t SC_rate,
94  Double_t SC_factor,
95  Double_t convCrit)
96 {
97  fNsteps = nsteps;
98  fCycles = cycles;
99  fPopSize = popSize;
100  fSC_steps = SC_steps;
101  fSC_rate = SC_rate;
102  fSC_factor = SC_factor;
103  fConvCrit = convCrit;
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Execute fitting
108 
109 Double_t TMVA::GeneticFitter::Run( std::vector<Double_t>& pars )
110 {
111  Log() << kHEADER << "<GeneticFitter> Optimisation, please be patient "
112  << "... (inaccurate progress timing for GA)" << Endl;
113 
114  GetFitterTarget().ProgressNotifier( "GA", "init" );
115 
116  GeneticAlgorithm gstore( GetFitterTarget(), fPopSize, fRanges);
117  // gstore.SetMakeCopies(kTRUE); // commented out, because it reduces speed
118 
119  // timing of GA
120  Timer timer( 100*(fCycles), GetName() );
121  if (fIPyMaxIter) *fIPyMaxIter = 100*(fCycles);
122  timer.DrawProgressBar( 0 );
123 
124  Double_t progress = 0.;
125 
126  for (Int_t cycle = 0; cycle < fCycles; cycle++) {
127  if (fIPyCurrentIter) *fIPyCurrentIter = 100*(cycle);
128  if (fExitFromTraining && *fExitFromTraining) break;
129  GetFitterTarget().ProgressNotifier( "GA", "cycle" );
130  // ---- perform series of fits to achieve best convergence
131 
132  // "m_ga_spread" times the number of variables
133  GeneticAlgorithm ga( GetFitterTarget(), fPopSize, fRanges, fSeed );
134  // ga.SetMakeCopies(kTRUE); // commented out, because it reduces speed
135 
136  if ( pars.size() == fRanges.size() ){
137  ga.GetGeneticPopulation().GiveHint( pars, 0.0 );
138  }
139  if (cycle==fCycles-1) {
140  GetFitterTarget().ProgressNotifier( "GA", "last" );
141  ga.GetGeneticPopulation().AddPopulation( gstore.GetGeneticPopulation() );
142  }
143 
144  GetFitterTarget().ProgressNotifier( "GA", "iteration" );
145 
146  ga.CalculateFitness();
147  ga.GetGeneticPopulation().TrimPopulation();
148 
149  Double_t n=0.;
150  do {
151  GetFitterTarget().ProgressNotifier( "GA", "iteration" );
152  ga.Init();
153  ga.CalculateFitness();
154  if ( fTrim ) ga.GetGeneticPopulation().TrimPopulation();
155  ga.SpreadControl( fSC_steps, fSC_rate, fSC_factor );
156 
157  // monitor progrss
158  if (ga.fConvCounter > n) n = Double_t(ga.fConvCounter);
159  progress = 100*((Double_t)cycle) + 100*(n/Double_t(fNsteps));
160 
161  timer.DrawProgressBar( (Int_t)progress );
162 
163  // Copy the best genes of the generation
164  ga.GetGeneticPopulation().Sort();
165  for ( Int_t i = 0; i<fSaveBestFromGeneration && i<fPopSize; i++ ) {
166  gstore.GetGeneticPopulation().GiveHint( ga.GetGeneticPopulation().GetGenes(i)->GetFactors(),
167  ga.GetGeneticPopulation().GetGenes(i)->GetFitness() );
168  }
169  } while (!ga.HasConverged( fNsteps, fConvCrit ));
170 
171  timer.DrawProgressBar( 100*(cycle+1) );
172 
173  ga.GetGeneticPopulation().Sort();
174  for ( Int_t i = 0; i<fSaveBestFromGeneration && i<fPopSize; i++ ) {
175  gstore.GetGeneticPopulation().GiveHint( ga.GetGeneticPopulation().GetGenes(i)->GetFactors(),
176  ga.GetGeneticPopulation().GetGenes(i)->GetFitness() );
177  }
178  }
179 
180  // get elapsed time
181  Log() << kINFO << "Elapsed time: " << timer.GetElapsedTime()
182  << " " << Endl;
183 
184  Double_t fitness = gstore.CalculateFitness();
185  gstore.GetGeneticPopulation().Sort();
186  pars.swap( gstore.GetGeneticPopulation().GetGenes(0)->GetFactors() );
187 
188  GetFitterTarget().ProgressNotifier( "GA", "stop" );
189  return fitness;
190 }