Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: marf/Classification/Classification.java


1   package marf.Classification;
2   
3   import marf.MARF;
4   import marf.FeatureExtraction.IFeatureExtraction;
5   import marf.Storage.ResultSet;
6   import marf.Storage.StorageException;
7   import marf.Storage.StorageManager;
8   import marf.Storage.TrainingSet;
9   import marf.util.Debug;
10  
11  import java.util.Vector;
12  
13  
14  /**
15   * <p>Abstract Classification Module.
16   * A generic implementation of the IClassification interface.
17   * The derivatives must inherit from this module, and if they cannot,
18   * they should implement IClassification themselves. 
19   * </p>
20   *
21   * <p>$Id: Classification.java,v 1.39 2005/08/05 22:19:47 mokhov Exp $</p>
22   *
23   * @author Serguei Mokhov
24   * @version $Revision: 1.39 $
25   * @since 0.0.1
26   */
27  public abstract class Classification
28  extends StorageManager
29  implements IClassification
30  {
31    /* Data Members */
32  
33    /**
34     * Reference to the enclosed FeatureExtraction object.
35     */
36    protected IFeatureExtraction oFeatureExtraction = null;
37  
38    /**
39     * TrainingSet Container.
40     */
41    protected TrainingSet oTrainingSet = null;
42  
43    /**
44     * Classification result set. May contain
45     * one or more results (in case of similarity).
46     *
47     * @since 0.3.0.2
48     */
49    protected ResultSet oResultSet = new ResultSet();
50  
51    /* Constructors */
52  
53    /**
54     * Generic Classification Constructor.
55     * @param poFeatureExtraction FeatureExtraction module reference
56     */
57    protected Classification(IFeatureExtraction poFeatureExtraction)
58    {
59      // TODO: null validation?
60      this.oFeatureExtraction = poFeatureExtraction;
61  
62      // See if there is a request for dump format
63      if(MARF.getModuleParams() != null)
64      {
65        Vector oParams = MARF.getModuleParams().getClassificationParams();
66  
67        // TODO: Must be validated of what's coming in
68        if(oParams != null && oParams.size() > 0)
69          this.iCurrentDumpMode = ((Integer)oParams.elementAt(0)).intValue();
70      }
71    }
72  
73    /* Classification API */
74  
75    /**
76     * Generic training routine for building/updating
77     * mean vectors in the training set.
78     * Can be overridden, and if the overriding classifier is using
79     * <code>TrainingSet</code>, it should call <code>super.train();</code>
80     *
81     * @return <code>true</code> if training was successful
82     * (i.e. mean vector was updated); <code>false</code> otherwise
83     * @throws ClassificationException if there was a problem while training
84     * @see TrainingSet
85     */
86    public boolean train()
87    throws ClassificationException
88    {
89      // For exception handling
90      String strPhase = "[start]";
91  
92      /*
93       * It is important to use saveTrainingSet() and loadTrainingSet()
94       * throughout this method, as the dump() and restore() may easily
95       * (and likely) to be overridden by the derivatives.
96       */
97      try
98      {
99        if(this.oTrainingSet != null)
100       {
101         // Wrong global cluster loaded, reload the correct one.
102         if
103         (
104           (this.oTrainingSet.getPreprocessingMethod() != MARF.getPreprocessingMethod())
105           ||
106           (this.oTrainingSet.getFeatureExtractionMethod() != MARF.getFeatureExtractionMethod())
107         )
108         {
109           strPhase = "[dumping previous cluster]";
110 
111           saveTrainingSet();
112           this.oTrainingSet = null;
113         }
114       }
115 
116       strPhase = "[restoring training set]";
117       loadTrainingSet();
118 
119       // Add the new feature vector.
120       strPhase = "[adding feature vector]";
121 
122       boolean bVectorAdded = this.oTrainingSet.addFeatureVector
123       (
124         this.oFeatureExtraction.getFeaturesArray(),
125         MARF.getSampleFile(),
126         MARF.getCurrentSubject(),
127         MARF.getPreprocessingMethod(),
128         MARF.getFeatureExtractionMethod()
129       );
130 
131       // No point of doing I/O if we didn't add anything.
132       if(bVectorAdded)
133       {
134         strPhase = "[dumping updated training set]";
135         saveTrainingSet();
136       }
137 
138       return true;
139     }
140     catch(NullPointerException e)
141     {
142       throw new ClassificationException
143       (
144         "NullPointerException in Classification.train(): oTrainingSet = " + this.oTrainingSet +
145         ", oFeatureExtraction = " + this.oFeatureExtraction +
146         ", FeaturesArray = " + this.oFeatureExtraction.getFeaturesArray() +
147         ", phase: " + strPhase
148       );
149     }
150     catch(Exception e)
151     {
152       throw new ClassificationException("Phase: " + strPhase, e);
153     }
154   }
155 
156   /* From Storage Manager */
157 
158   /**
159    * Generic implementation of dump() to dump the TrainingSet.
160    * @since 0.2.0
161    * @throws StorageException if there's a problem saving training set to disk
162    */
163   public void dump()
164   throws StorageException
165   {
166     saveTrainingSet();
167   }
168 
169   /**
170    * Generic implementation of restore() for TrainingSet.
171    * @since 0.2.0
172    * @throws StorageException if there is a problem loading the training set from disk
173    */
174   public void restore()
175   throws StorageException
176   {
177     loadTrainingSet();
178   }
179 
180   /**
181    * Saves TrainingSet to a file. Called by <code>dump()</code>.
182    * @since 0.2.0
183    * @throws StorageException if there's a problem saving training set to disk
184    * @see #dump()
185    * @see TrainingSet
186    */
187   private final void saveTrainingSet()
188   throws StorageException
189   {
190     try
191     {
192       // Dump stuff is there's anything to dump
193       if(this.oTrainingSet != null)
194       {
195         this.oTrainingSet.setDumpMode(this.iCurrentDumpMode);
196         this.oTrainingSet.setFilename(getTrainingSetFilename());
197         this.oTrainingSet.dump();
198       }
199 
200       // TODO: if TrainingSet is null
201       else
202       {
203         // [SM, 2003-05-02] Should here be something? Like a debug() call or
204         // more severe things?
205         Debug.debug
206         (
207           "WARNING: Classification.saveTrainingSet() -- TrainingSet is null.\n" +
208           "         No TrainingSet is saved."
209         );
210       }
211     }
212     catch(Exception e)
213     {
214       throw new StorageException(e);
215     }
216   }
217 
218   /**
219    * Loads TrainingSet from a file. Called by <code>restore()</code>.
220    * @since 0.2.0
221    * @throws StorageException if there is a problem loading the training set from disk
222    */
223   private final void loadTrainingSet()
224   throws StorageException
225   {
226     try
227     {
228       if(this.oTrainingSet == null)
229       {
230         this.oTrainingSet = new TrainingSet();
231         this.oTrainingSet.setDumpMode(this.iCurrentDumpMode);
232         this.oTrainingSet.setFilename(getTrainingSetFilename());
233         this.oTrainingSet.restore();
234       }
235 
236       //TODO: if TrainingSet is not null
237       else
238       {
239         // [SM, 2003-05-02] Should here be something? Like a debug() call or
240         // more severe things?
241         Debug.debug
242         (
243           "WARNING: Classification.loadTrainingSet() -- TrainingSet is not null.\n" +
244           "         No TrainingSet is loaded."
245         );
246       }
247     }
248     catch(Exception e)
249     {
250       throw new StorageException(e);
251     }
252   }
253 
254   /**
255    * Retrieves the enclosed result set.
256    * @return the enclosed ResultSet object
257    * @since 0.3.0.2
258    */
259   public ResultSet getResultSet()
260   {
261     return this.oResultSet;
262   }
263 
264   /**
265    * Constructs a global cluster file name for the TrainingSet.
266    *
267    * <p>Filename is constructed using fully-qualified class of
268    * either TrainingSet or a classifier name with global
269    * clustering info such as preprocessing and feature
270    * extraction methods, so that ony that cluster can be reloaded
271    * after.</p>
272    *
273    * May be overridden by the drivatives when necessary.
274    *
275    * @return String, filename
276    * @since 0.2.0
277    */
278   protected String getTrainingSetFilename()
279   {
280     return
281       // Fully-qualified class name
282       this.oTrainingSet.getClass().getName() + "." +
283 
284       // Global cluster: <PR>.<FE>.<FVS>
285       // For the same FE method we may have different feature vector sizes
286       MARF.getPreprocessingMethod() + "." +
287       MARF.getFeatureExtractionMethod() + "." +
288       this.oFeatureExtraction.getFeaturesArray().length + "." +
289 
290       // Extension depending on the dump type
291       getDefaultExtension();
292   }
293 
294   /**
295    * Retrieves the features source.
296    * @return returns the FeatureExtraction reference
297    * @since 0.3.0.4
298    */
299   public IFeatureExtraction getFeatureExtraction()
300   {
301     return this.oFeatureExtraction;
302   }
303 
304   /**
305    * Allows setting the features surce.
306    * @param poFeatureExtraction the FeatureExtraction object to set
307    * @since 0.3.0.4
308    */
309   public void setFeatureExtraction(IFeatureExtraction poFeatureExtraction)
310   {
311     this.oFeatureExtraction = poFeatureExtraction;
312   }
313 
314   /**
315    * Retrieves class' revision.
316    * @return revision string
317    * @since 0.3.0.2
318    */
319   public static String getMARFSourceCodeRevision()
320   {
321     return "$Revision: 1.39 $";
322   }
323 }
324 
325 // EOF