~ubuntu-branches/ubuntu/trusty/weka/trusty-proposed

« back to all changes in this revision

Viewing changes to weka/classifiers/mi/MIDD.java

  • Committer: Bazaar Package Importer
  • Author(s): Soeren Sonnenburg
  • Date: 2008-02-24 09:18:45 UTC
  • Revision ID: james.westby@ubuntu.com-20080224091845-1l8zy6fm6xipbzsr
Tags: upstream-3.5.7+tut1
ImportĀ upstreamĀ versionĀ 3.5.7+tut1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *    This program is free software; you can redistribute it and/or modify
 
3
 *    it under the terms of the GNU General Public License as published by
 
4
 *    the Free Software Foundation; either version 2 of the License, or
 
5
 *    (at your option) any later version.
 
6
 *
 
7
 *    This program is distributed in the hope that it will be useful,
 
8
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
 *    GNU General Public License for more details.
 
11
 *
 
12
 *    You should have received a copy of the GNU General Public License
 
13
 *    along with this program; if not, write to the Free Software
 
14
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
15
 */
 
16
 
 
17
/*
 
18
 * MIDD.java
 
19
 * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
 
20
 *
 
21
 */
 
22
 
 
23
package weka.classifiers.mi;
 
24
 
 
25
import weka.classifiers.Classifier;
 
26
import weka.core.Capabilities;
 
27
import weka.core.FastVector;
 
28
import weka.core.Instance;
 
29
import weka.core.Instances;
 
30
import weka.core.MultiInstanceCapabilitiesHandler;
 
31
import weka.core.Optimization;
 
32
import weka.core.Option;
 
33
import weka.core.OptionHandler;
 
34
import weka.core.SelectedTag;
 
35
import weka.core.Tag;
 
36
import weka.core.TechnicalInformation;
 
37
import weka.core.TechnicalInformationHandler;
 
38
import weka.core.Utils;
 
39
import weka.core.Capabilities.Capability;
 
40
import weka.core.TechnicalInformation.Field;
 
41
import weka.core.TechnicalInformation.Type;
 
42
import weka.filters.Filter;
 
43
import weka.filters.unsupervised.attribute.Normalize;
 
44
import weka.filters.unsupervised.attribute.ReplaceMissingValues;
 
45
import weka.filters.unsupervised.attribute.Standardize;
 
46
 
 
47
import java.util.Enumeration;
 
48
import java.util.Vector;
 
49
 
 
50
/**
 
51
 <!-- globalinfo-start -->
 
52
 * Re-implement the Diverse Density algorithm, changes the testing procedure.<br/>
 
53
 * <br/>
 
54
 * Oded Maron (1998). Learning from ambiguity.<br/>
 
55
 * <br/>
 
56
 * O. Maron, T. Lozano-Perez (1998). A Framework for Multiple Instance Learning. Neural Information Processing Systems. 10.
 
57
 * <p/>
 
58
 <!-- globalinfo-end -->
 
59
 * 
 
60
 <!-- technical-bibtex-start -->
 
61
 * BibTeX:
 
62
 * <pre>
 
63
 * &#64;phdthesis{Maron1998,
 
64
 *    author = {Oded Maron},
 
65
 *    school = {Massachusetts Institute of Technology},
 
66
 *    title = {Learning from ambiguity},
 
67
 *    year = {1998}
 
68
 * }
 
69
 * 
 
70
 * &#64;article{Maron1998,
 
71
 *    author = {O. Maron and T. Lozano-Perez},
 
72
 *    journal = {Neural Information Processing Systems},
 
73
 *    title = {A Framework for Multiple Instance Learning},
 
74
 *    volume = {10},
 
75
 *    year = {1998}
 
76
 * }
 
77
 * </pre>
 
78
 * <p/>
 
79
 <!-- technical-bibtex-end -->
 
80
 * 
 
81
 <!-- options-start -->
 
82
 * Valid options are: <p/>
 
83
 * 
 
84
 * <pre> -D
 
85
 *  Turn on debugging output.</pre>
 
86
 * 
 
87
 * <pre> -N &lt;num&gt;
 
88
 *  Whether to 0=normalize/1=standardize/2=neither.
 
89
 *  (default 1=standardize)</pre>
 
90
 * 
 
91
 <!-- options-end -->
 
92
 *
 
93
 * @author Eibe Frank (eibe@cs.waikato.ac.nz)
 
94
 * @author Xin Xu (xx5@cs.waikato.ac.nz)
 
95
 * @version $Revision: 1.3 $ 
 
96
 */
 
97
public class MIDD 
 
98
  extends Classifier 
 
99
  implements OptionHandler, MultiInstanceCapabilitiesHandler,
 
100
             TechnicalInformationHandler {
 
101
 
 
102
  /** for serialization */
 
103
  static final long serialVersionUID = 4263507733600536168L;
 
104
  
 
105
  /** The index of the class attribute */
 
106
  protected int m_ClassIndex;
 
107
 
 
108
  protected double[] m_Par;
 
109
 
 
110
  /** The number of the class labels */
 
111
  protected int m_NumClasses;
 
112
 
 
113
  /** Class labels for each bag */
 
114
  protected int[] m_Classes;
 
115
 
 
116
  /** MI data */ 
 
117
  protected double[][][] m_Data;
 
118
 
 
119
  /** All attribute names */
 
120
  protected Instances m_Attributes;
 
121
 
 
122
  /** The filter used to standardize/normalize all values. */
 
123
  protected Filter m_Filter = null;
 
124
 
 
125
  /** Whether to normalize/standardize/neither, default:standardize */
 
126
  protected int m_filterType = FILTER_STANDARDIZE;
 
127
 
 
128
  /** Normalize training data */
 
129
  public static final int FILTER_NORMALIZE = 0;
 
130
  /** Standardize training data */
 
131
  public static final int FILTER_STANDARDIZE = 1;
 
132
  /** No normalization/standardization */
 
133
  public static final int FILTER_NONE = 2;
 
134
  /** The filter to apply to the training data */
 
135
  public static final Tag [] TAGS_FILTER = {
 
136
    new Tag(FILTER_NORMALIZE, "Normalize training data"),
 
137
    new Tag(FILTER_STANDARDIZE, "Standardize training data"),
 
138
    new Tag(FILTER_NONE, "No normalization/standardization"),
 
139
  };
 
140
 
 
141
  /** The filter used to get rid of missing values. */
 
142
  protected ReplaceMissingValues m_Missing = new ReplaceMissingValues();
 
143
 
 
144
  /**
 
145
   * Returns a string describing this filter
 
146
   *
 
147
   * @return a description of the filter suitable for
 
148
   * displaying in the explorer/experimenter gui
 
149
   */
 
150
  public String globalInfo() {
 
151
    return 
 
152
        "Re-implement the Diverse Density algorithm, changes the testing "
 
153
      + "procedure.\n\n"
 
154
      + getTechnicalInformation().toString();
 
155
  }
 
156
 
 
157
  /**
 
158
   * Returns an instance of a TechnicalInformation object, containing 
 
159
   * detailed information about the technical background of this class,
 
160
   * e.g., paper reference or book this class is based on.
 
161
   * 
 
162
   * @return the technical information about this class
 
163
   */
 
164
  public TechnicalInformation getTechnicalInformation() {
 
165
    TechnicalInformation        result;
 
166
    TechnicalInformation        additional;
 
167
    
 
168
    result = new TechnicalInformation(Type.PHDTHESIS);
 
169
    result.setValue(Field.AUTHOR, "Oded Maron");
 
170
    result.setValue(Field.YEAR, "1998");
 
171
    result.setValue(Field.TITLE, "Learning from ambiguity");
 
172
    result.setValue(Field.SCHOOL, "Massachusetts Institute of Technology");
 
173
    
 
174
    additional = result.add(Type.ARTICLE);
 
175
    additional.setValue(Field.AUTHOR, "O. Maron and T. Lozano-Perez");
 
176
    additional.setValue(Field.YEAR, "1998");
 
177
    additional.setValue(Field.TITLE, "A Framework for Multiple Instance Learning");
 
178
    additional.setValue(Field.JOURNAL, "Neural Information Processing Systems");
 
179
    additional.setValue(Field.VOLUME, "10");
 
180
    
 
181
    return result;
 
182
  }
 
183
 
 
184
  /**
 
185
   * Returns an enumeration describing the available options
 
186
   *
 
187
   * @return an enumeration of all the available options
 
188
   */
 
189
  public Enumeration listOptions() {
 
190
    Vector result = new Vector();
 
191
 
 
192
    result.addElement(new Option(
 
193
          "\tTurn on debugging output.",
 
194
          "D", 0, "-D"));
 
195
 
 
196
    result.addElement(new Option(
 
197
          "\tWhether to 0=normalize/1=standardize/2=neither.\n"
 
198
          + "\t(default 1=standardize)",
 
199
          "N", 1, "-N <num>"));
 
200
 
 
201
    return result.elements();
 
202
  }
 
203
 
 
204
  /**
 
205
   * Parses a given list of options. <p/>
 
206
   *     
 
207
   <!-- options-start -->
 
208
   * Valid options are: <p/>
 
209
   * 
 
210
   * <pre> -D
 
211
   *  Turn on debugging output.</pre>
 
212
   * 
 
213
   * <pre> -N &lt;num&gt;
 
214
   *  Whether to 0=normalize/1=standardize/2=neither.
 
215
   *  (default 1=standardize)</pre>
 
216
   * 
 
217
   <!-- options-end -->
 
218
   *
 
219
   * @param options the list of options as an array of strings
 
220
   * @throws Exception if an option is not supported
 
221
   */
 
222
  public void setOptions(String[] options) throws Exception {
 
223
    setDebug(Utils.getFlag('D', options));
 
224
 
 
225
    String nString = Utils.getOption('N', options);
 
226
    if (nString.length() != 0) {
 
227
      setFilterType(new SelectedTag(Integer.parseInt(nString), TAGS_FILTER));
 
228
    } else {
 
229
      setFilterType(new SelectedTag(FILTER_STANDARDIZE, TAGS_FILTER));
 
230
    }     
 
231
  }
 
232
 
 
233
  /**
 
234
   * Gets the current settings of the classifier.
 
235
   *
 
236
   * @return an array of strings suitable for passing to setOptions
 
237
   */
 
238
  public String[] getOptions() {
 
239
    Vector        result;
 
240
    
 
241
    result = new Vector();
 
242
 
 
243
    if (getDebug())
 
244
      result.add("-D");
 
245
    
 
246
    result.add("-N");
 
247
    result.add("" + m_filterType);
 
248
 
 
249
    return (String[]) result.toArray(new String[result.size()]);
 
250
  }
 
251
 
 
252
  /**
 
253
   * Returns the tip text for this property
 
254
   *
 
255
   * @return tip text for this property suitable for
 
256
   * displaying in the explorer/experimenter gui
 
257
   */
 
258
  public String filterTypeTipText() {
 
259
    return "The filter type for transforming the training data.";
 
260
  }
 
261
 
 
262
  /**
 
263
   * Gets how the training data will be transformed. Will be one of
 
264
   * FILTER_NORMALIZE, FILTER_STANDARDIZE, FILTER_NONE.
 
265
   *
 
266
   * @return the filtering mode
 
267
   */
 
268
  public SelectedTag getFilterType() {
 
269
    return new SelectedTag(m_filterType, TAGS_FILTER);
 
270
  }
 
271
 
 
272
  /**
 
273
   * Sets how the training data will be transformed. Should be one of
 
274
   * FILTER_NORMALIZE, FILTER_STANDARDIZE, FILTER_NONE.
 
275
   *
 
276
   * @param newType the new filtering mode
 
277
   */
 
278
  public void setFilterType(SelectedTag newType) {
 
279
 
 
280
    if (newType.getTags() == TAGS_FILTER) {
 
281
      m_filterType = newType.getSelectedTag().getID();
 
282
    }
 
283
  }
 
284
 
 
285
  private class OptEng 
 
286
    extends Optimization {
 
287
 
 
288
    /** 
 
289
     * Evaluate objective function
 
290
     * @param x the current values of variables
 
291
     * @return the value of the objective function 
 
292
     */
 
293
    protected double objectiveFunction(double[] x){
 
294
      double nll = 0; // -LogLikelihood
 
295
      for(int i=0; i<m_Classes.length; i++){ // ith bag
 
296
        int nI = m_Data[i][0].length; // numInstances in ith bag
 
297
        double bag = 0.0;  // NLL of pos bag
 
298
 
 
299
        for(int j=0; j<nI; j++){
 
300
          double ins=0.0;
 
301
          for(int k=0; k<m_Data[i].length; k++)
 
302
            ins += (m_Data[i][k][j]-x[k*2])*(m_Data[i][k][j]-x[k*2])*
 
303
              x[k*2+1]*x[k*2+1];
 
304
          ins = Math.exp(-ins);
 
305
          ins = 1.0-ins;
 
306
 
 
307
          if(m_Classes[i] == 1)
 
308
            bag += Math.log(ins);
 
309
          else{
 
310
            if(ins<=m_Zero) ins=m_Zero;
 
311
            nll -= Math.log(ins);
 
312
          }   
 
313
        }               
 
314
 
 
315
        if(m_Classes[i] == 1){
 
316
          bag = 1.0 - Math.exp(bag);
 
317
          if(bag<=m_Zero) bag=m_Zero;
 
318
          nll -= Math.log(bag);
 
319
        }
 
320
      }         
 
321
      return nll;
 
322
    }
 
323
 
 
324
    /** 
 
325
     * Evaluate Jacobian vector
 
326
     * @param x the current values of variables
 
327
     * @return the gradient vector 
 
328
     */
 
329
    protected double[] evaluateGradient(double[] x){
 
330
      double[] grad = new double[x.length];
 
331
      for(int i=0; i<m_Classes.length; i++){ // ith bag
 
332
        int nI = m_Data[i][0].length; // numInstances in ith bag 
 
333
 
 
334
        double denom=0.0;       
 
335
        double[] numrt = new double[x.length];
 
336
 
 
337
        for(int j=0; j<nI; j++){
 
338
          double exp=0.0;
 
339
          for(int k=0; k<m_Data[i].length; k++)
 
340
            exp += (m_Data[i][k][j]-x[k*2])*(m_Data[i][k][j]-x[k*2])
 
341
              *x[k*2+1]*x[k*2+1];                       
 
342
          exp = Math.exp(-exp);
 
343
          exp = 1.0-exp;
 
344
          if(m_Classes[i]==1)
 
345
            denom += Math.log(exp);                                 
 
346
 
 
347
          if(exp<=m_Zero) exp=m_Zero;
 
348
          // Instance-wise update
 
349
          for(int p=0; p<m_Data[i].length; p++){  // pth variable
 
350
            numrt[2*p] += (1.0-exp)*2.0*(x[2*p]-m_Data[i][p][j])*x[p*2+1]*x[p*2+1]
 
351
              /exp;
 
352
            numrt[2*p+1] += 2.0*(1.0-exp)*(x[2*p]-m_Data[i][p][j])*(x[2*p]-m_Data[i][p][j])
 
353
              *x[p*2+1]/exp;
 
354
          }                                         
 
355
        }                   
 
356
 
 
357
        // Bag-wise update 
 
358
        denom = 1.0-Math.exp(denom);
 
359
        if(denom <= m_Zero) denom = m_Zero;
 
360
        for(int q=0; q<m_Data[i].length; q++){
 
361
          if(m_Classes[i]==1){
 
362
            grad[2*q] += numrt[2*q]*(1.0-denom)/denom;
 
363
            grad[2*q+1] += numrt[2*q+1]*(1.0-denom)/denom;
 
364
          }else{
 
365
            grad[2*q] -= numrt[2*q];
 
366
            grad[2*q+1] -= numrt[2*q+1];
 
367
          }
 
368
        }
 
369
      } // one bag
 
370
 
 
371
      return grad;
 
372
    }
 
373
  }
 
374
 
 
375
  /**
 
376
   * Returns default capabilities of the classifier.
 
377
   *
 
378
   * @return      the capabilities of this classifier
 
379
   */
 
380
  public Capabilities getCapabilities() {
 
381
    Capabilities result = super.getCapabilities();
 
382
 
 
383
    // attributes
 
384
    result.enable(Capability.NOMINAL_ATTRIBUTES);
 
385
    result.enable(Capability.RELATIONAL_ATTRIBUTES);
 
386
    result.enable(Capability.MISSING_VALUES);
 
387
 
 
388
    // class
 
389
    result.enable(Capability.BINARY_CLASS);
 
390
    result.enable(Capability.MISSING_CLASS_VALUES);
 
391
    
 
392
    // other
 
393
    result.enable(Capability.ONLY_MULTIINSTANCE);
 
394
    
 
395
    return result;
 
396
  }
 
397
 
 
398
  /**
 
399
   * Returns the capabilities of this multi-instance classifier for the
 
400
   * relational data.
 
401
   *
 
402
   * @return            the capabilities of this object
 
403
   * @see               Capabilities
 
404
   */
 
405
  public Capabilities getMultiInstanceCapabilities() {
 
406
    Capabilities result = super.getCapabilities();
 
407
    
 
408
    // attributes
 
409
    result.enable(Capability.NOMINAL_ATTRIBUTES);
 
410
    result.enable(Capability.NUMERIC_ATTRIBUTES);
 
411
    result.enable(Capability.DATE_ATTRIBUTES);
 
412
    result.enable(Capability.MISSING_VALUES);
 
413
 
 
414
    // class
 
415
    result.disableAllClasses();
 
416
    result.enable(Capability.NO_CLASS);
 
417
    
 
418
    return result;
 
419
  }
 
420
 
 
421
  /**
 
422
   * Builds the classifier
 
423
   *
 
424
   * @param train the training data to be used for generating the
 
425
   * boosted classifier.
 
426
   * @throws Exception if the classifier could not be built successfully
 
427
   */
 
428
  public void buildClassifier(Instances train) throws Exception {
 
429
    // can classifier handle the data?
 
430
    getCapabilities().testWithFail(train);
 
431
 
 
432
    // remove instances with missing class
 
433
    train = new Instances(train);
 
434
    train.deleteWithMissingClass();
 
435
    
 
436
    m_ClassIndex = train.classIndex();
 
437
    m_NumClasses = train.numClasses();
 
438
 
 
439
    int nR = train.attribute(1).relation().numAttributes();
 
440
    int nC = train.numInstances();
 
441
    FastVector maxSzIdx=new FastVector();
 
442
    int maxSz=0;
 
443
    int [] bagSize=new int [nC];
 
444
    Instances datasets= new Instances(train.attribute(1).relation(),0);
 
445
 
 
446
    m_Data  = new double [nC][nR][];              // Data values
 
447
    m_Classes  = new int [nC];                    // Class values
 
448
    m_Attributes = datasets.stringFreeStructure();      
 
449
    if (m_Debug) {
 
450
      System.out.println("Extracting data...");
 
451
    }
 
452
 
 
453
    for(int h=0; h<nC; h++)  {//h_th bag
 
454
      Instance current = train.instance(h);
 
455
      m_Classes[h] = (int)current.classValue();  // Class value starts from 0
 
456
      Instances currInsts = current.relationalValue(1);
 
457
      for (int i=0; i<currInsts.numInstances();i++){
 
458
        Instance inst=currInsts.instance(i);
 
459
        datasets.add(inst);
 
460
      }
 
461
 
 
462
      int nI = currInsts.numInstances();
 
463
      bagSize[h]=nI;
 
464
      if(m_Classes[h]==1){  
 
465
        if(nI>maxSz){
 
466
          maxSz=nI;
 
467
          maxSzIdx=new FastVector(1);
 
468
          maxSzIdx.addElement(new Integer(h));
 
469
        }
 
470
        else if(nI == maxSz)
 
471
          maxSzIdx.addElement(new Integer(h));
 
472
      }
 
473
 
 
474
    }
 
475
 
 
476
    /* filter the training data */
 
477
    if (m_filterType == FILTER_STANDARDIZE)  
 
478
      m_Filter = new Standardize();
 
479
    else if (m_filterType == FILTER_NORMALIZE)
 
480
      m_Filter = new Normalize();
 
481
    else 
 
482
      m_Filter = null; 
 
483
 
 
484
    if (m_Filter!=null) {
 
485
      m_Filter.setInputFormat(datasets);
 
486
      datasets = Filter.useFilter(datasets, m_Filter);  
 
487
    }
 
488
 
 
489
    m_Missing.setInputFormat(datasets);
 
490
    datasets = Filter.useFilter(datasets, m_Missing);
 
491
 
 
492
 
 
493
    int instIndex=0;
 
494
    int start=0;        
 
495
    for(int h=0; h<nC; h++)  {  
 
496
      for (int i = 0; i < datasets.numAttributes(); i++) {
 
497
        // initialize m_data[][][]
 
498
        m_Data[h][i] = new double[bagSize[h]];
 
499
        instIndex=start;
 
500
        for (int k=0; k<bagSize[h]; k++){
 
501
          m_Data[h][i][k]=datasets.instance(instIndex).value(i);
 
502
          instIndex ++;
 
503
        }
 
504
      }
 
505
      start=instIndex;
 
506
    }
 
507
 
 
508
 
 
509
    if (m_Debug) {
 
510
      System.out.println("\nIteration History..." );
 
511
    }
 
512
 
 
513
    double[] x = new double[nR*2], tmp = new double[x.length];
 
514
    double[][] b = new double[2][x.length]; 
 
515
 
 
516
    OptEng opt;
 
517
    double nll, bestnll = Double.MAX_VALUE;
 
518
    for (int t=0; t<x.length; t++){
 
519
      b[0][t] = Double.NaN; 
 
520
      b[1][t] = Double.NaN;
 
521
    }
 
522
 
 
523
    // Largest Positive exemplar
 
524
    for(int s=0; s<maxSzIdx.size(); s++){
 
525
      int exIdx = ((Integer)maxSzIdx.elementAt(s)).intValue();
 
526
      for(int p=0; p<m_Data[exIdx][0].length; p++){
 
527
        for (int q=0; q < nR;q++){
 
528
          x[2*q] = m_Data[exIdx][q][p];  // pick one instance
 
529
          x[2*q+1] = 1.0;
 
530
        }
 
531
 
 
532
        opt = new OptEng();     
 
533
        //opt.setDebug(m_Debug);
 
534
        tmp = opt.findArgmin(x, b);
 
535
        while(tmp==null){
 
536
          tmp = opt.getVarbValues();
 
537
          if (m_Debug)
 
538
            System.out.println("200 iterations finished, not enough!");
 
539
          tmp = opt.findArgmin(tmp, b);
 
540
        }
 
541
        nll = opt.getMinFunction();
 
542
 
 
543
        if(nll < bestnll){
 
544
          bestnll = nll;
 
545
          m_Par = tmp;
 
546
          tmp = new double[x.length]; // Save memory
 
547
          if (m_Debug)
 
548
            System.out.println("!!!!!!!!!!!!!!!!Smaller NLL found: "+nll);
 
549
        }
 
550
        if (m_Debug)
 
551
          System.out.println(exIdx+":  -------------<Converged>--------------");
 
552
      } 
 
553
    }
 
554
  }             
 
555
 
 
556
  /**
 
557
   * Computes the distribution for a given exemplar
 
558
   *
 
559
   * @param exmp the exemplar for which distribution is computed
 
560
   * @return the distribution
 
561
   * @throws Exception if the distribution can't be computed successfully
 
562
   */
 
563
  public double[] distributionForInstance(Instance exmp) 
 
564
    throws Exception {
 
565
 
 
566
    // Extract the data
 
567
    Instances ins = exmp.relationalValue(1);
 
568
    if(m_Filter!=null)
 
569
      ins = Filter.useFilter(ins, m_Filter);
 
570
 
 
571
    ins = Filter.useFilter(ins, m_Missing);
 
572
 
 
573
    int nI = ins.numInstances(), nA = ins.numAttributes();
 
574
    double[][] dat = new double [nI][nA];
 
575
    for(int j=0; j<nI; j++){
 
576
      for(int k=0; k<nA; k++){ 
 
577
        dat[j][k] = ins.instance(j).value(k);
 
578
      }
 
579
    }
 
580
 
 
581
    // Compute the probability of the bag
 
582
    double [] distribution = new double[2];
 
583
    distribution[0]=0.0;  // log-Prob. for class 0
 
584
 
 
585
    for(int i=0; i<nI; i++){
 
586
      double exp = 0.0;
 
587
      for(int r=0; r<nA; r++)
 
588
        exp += (m_Par[r*2]-dat[i][r])*(m_Par[r*2]-dat[i][r])*
 
589
          m_Par[r*2+1]*m_Par[r*2+1];
 
590
      exp = Math.exp(-exp);
 
591
 
 
592
      // Prob. updated for one instance
 
593
      distribution[0] += Math.log(1.0-exp);
 
594
    }
 
595
 
 
596
    distribution[0] = Math.exp(distribution[0]);
 
597
    distribution[1] = 1.0-distribution[0];
 
598
 
 
599
    return distribution;
 
600
  }
 
601
 
 
602
  /**
 
603
   * Gets a string describing the classifier.
 
604
   *
 
605
   * @return a string describing the classifer built.
 
606
   */
 
607
  public String toString() {
 
608
 
 
609
    //double CSq = m_LLn - m_LL;
 
610
    //int df = m_NumPredictors;
 
611
    String result = "Diverse Density";
 
612
    if (m_Par == null) {
 
613
      return result + ": No model built yet.";
 
614
    }
 
615
 
 
616
    result += "\nCoefficients...\n"
 
617
      + "Variable       Point       Scale\n";
 
618
    for (int j = 0, idx=0; j < m_Par.length/2; j++, idx++) {
 
619
      result += m_Attributes.attribute(idx).name();
 
620
      result += " "+Utils.doubleToString(m_Par[j*2], 12, 4); 
 
621
      result += " "+Utils.doubleToString(m_Par[j*2+1], 12, 4)+"\n";
 
622
    }
 
623
 
 
624
    return result;
 
625
  }
 
626
 
 
627
  /**
 
628
   * Main method for testing this class.
 
629
   *
 
630
   * @param argv should contain the command line arguments to the
 
631
   * scheme (see Evaluation)
 
632
   */
 
633
  public static void main(String[] argv) {
 
634
    runClassifier(new MIDD(), argv);
 
635
  }
 
636
}