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

« back to all changes in this revision

Viewing changes to weka/classifiers/lazy/kstar/KStarNominalAttribute.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
 *    KStarNominalAttribute.java
 
19
 *    Copyright (C) 1995 Univeristy of Waikato
 
20
 *    Java port to Weka by Abdelaziz Mahoui (am14@cs.waikato.ac.nz).
 
21
 *
 
22
 */
 
23
 
 
24
 
 
25
package weka.classifiers.lazy.kstar;
 
26
 
 
27
import java.io.*;
 
28
import java.util.*;
 
29
import weka.core.*;
 
30
import weka.classifiers.*;
 
31
 
 
32
/**
 
33
 * A custom class which provides the environment for computing the
 
34
 * transformation probability of a specified test instance nominal
 
35
 * attribute to a specified train instance nominal attribute.
 
36
 *
 
37
 * @author Len Trigg (len@reeltwo.com)
 
38
 * @author Abdelaziz Mahoui (am14@cs.waikato.ac.nz)
 
39
 * @version $Revision 1.0 $
 
40
 */
 
41
public class KStarNominalAttribute implements KStarConstants {
 
42
  
 
43
  /** The training instances used for classification. */
 
44
  protected Instances m_TrainSet;
 
45
 
 
46
  /** The test instance */
 
47
  protected Instance m_Test;
 
48
 
 
49
  /** The train instance */
 
50
  protected Instance m_Train;
 
51
 
 
52
  /** The index of the nominal attribute in the test and train instances */
 
53
  protected int m_AttrIndex;
 
54
 
 
55
  /** The stop parameter */
 
56
  protected double m_Stop = 1.0;
 
57
 
 
58
  /** Probability of test attribute transforming into train attribute 
 
59
      with missing value */
 
60
  protected double m_MissingProb = 1.0;
 
61
 
 
62
  /** Average probability of test attribute transforming into train 
 
63
      attribute */
 
64
  protected double m_AverageProb = 1.0;
 
65
 
 
66
  /** Smallest probability of test attribute transforming into 
 
67
      train attribute */
 
68
  protected double m_SmallestProb = 1.0;
 
69
 
 
70
  /** Number of trai instances with no missing attribute values */
 
71
  protected int m_TotalCount;
 
72
 
 
73
  /** Distribution of the attribute value in the train dataset */
 
74
  protected int [] m_Distribution;
 
75
 
 
76
  /** Set of colomns: each colomn representing a randomised version 
 
77
      of the train dataset class colomn */
 
78
  protected int [][] m_RandClassCols;
 
79
 
 
80
  /** A cache for storing attribute values and their corresponding 
 
81
      stop parameters */
 
82
  protected KStarCache m_Cache;
 
83
 
 
84
  // KStar Global settings
 
85
 
 
86
  /** The number of instances in the dataset */
 
87
  protected int m_NumInstances;
 
88
 
 
89
  /** The number of class values */
 
90
  protected int m_NumClasses;
 
91
 
 
92
  /** The number of attributes */
 
93
  protected int m_NumAttributes;
 
94
 
 
95
  /** The class attribute type */
 
96
  protected int m_ClassType;
 
97
 
 
98
  /** missing value treatment */
 
99
  protected int m_MissingMode = M_AVERAGE;
 
100
 
 
101
  /** B_SPHERE = use specified blend, B_ENTROPY = entropic blend setting */
 
102
  protected int m_BlendMethod = B_SPHERE ;
 
103
 
 
104
  /** default sphere of influence blend setting */
 
105
  protected int m_BlendFactor = 20;
 
106
  
 
107
  /**
 
108
   * Constructor
 
109
   */
 
110
  public KStarNominalAttribute(Instance test, Instance train, int attrIndex,
 
111
                               Instances trainSet, int [][] randClassCol, 
 
112
                               KStarCache cache)
 
113
  {
 
114
    m_Test = test;
 
115
    m_Train = train;
 
116
    m_AttrIndex = attrIndex;
 
117
    m_TrainSet = trainSet;
 
118
    m_RandClassCols = randClassCol;
 
119
    m_Cache = cache;
 
120
    init();
 
121
  }
 
122
 
 
123
  /**
 
124
   * Initializes the m_Attributes of the class.
 
125
   */
 
126
  private void init() {
 
127
    try {
 
128
      m_NumInstances  = m_TrainSet.numInstances();
 
129
      m_NumClasses    = m_TrainSet.numClasses();
 
130
      m_NumAttributes = m_TrainSet.numAttributes();
 
131
      m_ClassType     = m_TrainSet.classAttribute().type();
 
132
    } catch(Exception e) {
 
133
      e.printStackTrace();
 
134
    }
 
135
  }
 
136
 
 
137
  /**
 
138
   * Calculates the probability of the indexed nominal attribute of the test
 
139
   * instance transforming into the indexed nominal attribute of the training 
 
140
   * instance.
 
141
   *
 
142
   * @return the value of the transformation probability.
 
143
   */
 
144
  public double transProb() {
 
145
    String debug = "(KStarNominalAttribute.transProb) ";
 
146
    double transProb = 0.0;
 
147
    // check if the attribute value has been encountred before
 
148
    // in which case it should be in the nominal cache
 
149
    if (m_Cache.containsKey(m_Test.value(m_AttrIndex))) {
 
150
      KStarCache.TableEntry te = 
 
151
        m_Cache.getCacheValues(m_Test.value(m_AttrIndex));
 
152
      m_Stop = te.value;
 
153
      m_MissingProb = te.pmiss;
 
154
    }
 
155
    else {
 
156
      generateAttrDistribution();
 
157
      // we have to compute the parameters
 
158
      if (m_BlendMethod == B_ENTROPY) {
 
159
        m_Stop = stopProbUsingEntropy();
 
160
      }
 
161
      else { // default is B_SPHERE
 
162
        m_Stop = stopProbUsingBlend();
 
163
      }
 
164
      // store the values in cache
 
165
      m_Cache.store( m_Test.value(m_AttrIndex), m_Stop, m_MissingProb );
 
166
    }
 
167
    // we've got our m_Stop, then what?
 
168
    if (m_Train.isMissing(m_AttrIndex)) {
 
169
      transProb = m_MissingProb;
 
170
    }
 
171
    else {
 
172
      try {
 
173
        transProb = (1.0 - m_Stop) / m_Test.attribute(m_AttrIndex).numValues();
 
174
        if ( (int)m_Test.value(m_AttrIndex) == 
 
175
             (int)m_Train.value(m_AttrIndex) )
 
176
          {
 
177
            transProb += m_Stop;
 
178
          }
 
179
      } catch (Exception e) {
 
180
        e.printStackTrace();
 
181
      }
 
182
    }
 
183
    return transProb;
 
184
  }
 
185
  
 
186
  /**
 
187
   * Calculates the "stop parameter" for this attribute using
 
188
   * the entropy method: the value is computed using a root finder
 
189
   * algorithm. The method takes advantage of the calculation to
 
190
   * compute the smallest and average transformation probabilities
 
191
   * once the stop factor is obtained. It also sets the transformation
 
192
   * probability to an attribute with a missing value.
 
193
   *
 
194
   * @return the value of the stop parameter.
 
195
   *
 
196
   */
 
197
  private double stopProbUsingEntropy() {
 
198
    String debug = "(KStarNominalAttribute.stopProbUsingEntropy)";
 
199
    if ( m_ClassType != Attribute.NOMINAL ) {
 
200
      System.err.println("Error: "+debug+" attribute class must be nominal!");
 
201
      System.exit(1);
 
202
    }
 
203
    int itcount = 0;
 
204
    double stopProb;
 
205
    double lower, upper, pstop;
 
206
    double bestminprob = 0.0, bestpsum = 0.0;
 
207
    double bestdiff = 0.0, bestpstop = 0.0;
 
208
    double currentdiff, lastdiff, stepsize, delta;
 
209
    
 
210
    KStarWrapper botvals = new KStarWrapper();
 
211
    KStarWrapper upvals = new KStarWrapper();
 
212
    KStarWrapper vals = new KStarWrapper();
 
213
 
 
214
    // Initial values for root finder
 
215
    lower = 0.0 + ROOT_FINDER_ACCURACY/2.0;
 
216
    upper = 1.0 - ROOT_FINDER_ACCURACY/2.0;
 
217
    
 
218
    // Find (approx) entropy ranges
 
219
    calculateEntropy(upper, upvals);
 
220
    calculateEntropy(lower, botvals);
 
221
    
 
222
    if (upvals.avgProb == 0) {
 
223
      // When there are no training instances with the test value:
 
224
      // doesn't matter what exact value we use for pstop, just acts as
 
225
      // a constant scale factor in this case.
 
226
      calculateEntropy(lower, vals);
 
227
    }
 
228
    else
 
229
      {
 
230
        // Optimise the scale factor
 
231
        if ( (upvals.randEntropy - upvals.actEntropy < 
 
232
              botvals.randEntropy - botvals.actEntropy) &&
 
233
             (botvals.randEntropy - botvals.actEntropy > FLOOR) )
 
234
          {
 
235
            bestpstop = pstop = lower;
 
236
            stepsize = INITIAL_STEP;
 
237
            bestminprob = botvals.minProb;
 
238
            bestpsum = botvals.avgProb;
 
239
          }
 
240
        else {
 
241
          bestpstop = pstop = upper;
 
242
          stepsize = -INITIAL_STEP;
 
243
          bestminprob = upvals.minProb;
 
244
          bestpsum = upvals.avgProb;
 
245
        }
 
246
        bestdiff = currentdiff = FLOOR;
 
247
        itcount = 0;
 
248
        /* Enter the root finder */
 
249
        while (true)
 
250
          {
 
251
            itcount++;  
 
252
            lastdiff = currentdiff;
 
253
            pstop += stepsize;
 
254
            if (pstop <= lower) {
 
255
              pstop = lower;
 
256
              currentdiff = 0.0;
 
257
              delta = -1.0;
 
258
            }
 
259
            else if (pstop >= upper) {
 
260
              pstop = upper;
 
261
              currentdiff = 0.0;
 
262
              delta = -1.0;
 
263
            }
 
264
            else {
 
265
              calculateEntropy(pstop, vals);
 
266
              currentdiff = vals.randEntropy - vals.actEntropy;
 
267
 
 
268
              if (currentdiff < FLOOR) {
 
269
                currentdiff = FLOOR;
 
270
                if ((Math.abs(stepsize) < INITIAL_STEP) && 
 
271
                    (bestdiff == FLOOR)) {
 
272
                  bestpstop = lower;
 
273
                  bestminprob = botvals.minProb;
 
274
                  bestpsum = botvals.avgProb;
 
275
                  break;
 
276
                }
 
277
              }
 
278
              delta = currentdiff - lastdiff;
 
279
            }
 
280
            if (currentdiff > bestdiff) {
 
281
              bestdiff = currentdiff;
 
282
              bestpstop = pstop;
 
283
              bestminprob = vals.minProb;
 
284
              bestpsum = vals.avgProb;
 
285
            }
 
286
            if (delta < 0) {
 
287
              if (Math.abs(stepsize) < ROOT_FINDER_ACCURACY) {
 
288
                break;
 
289
              }
 
290
              else {
 
291
                stepsize /= -2.0;
 
292
              }
 
293
            }
 
294
            if (itcount > ROOT_FINDER_MAX_ITER) {
 
295
              break;
 
296
            }
 
297
          }
 
298
      }
 
299
    
 
300
    m_SmallestProb = bestminprob;
 
301
    m_AverageProb = bestpsum;
 
302
    // Set the probability of transforming to a missing value
 
303
    switch ( m_MissingMode )
 
304
      {
 
305
      case M_DELETE:
 
306
        m_MissingProb = 0.0;
 
307
        break;
 
308
      case M_NORMAL:
 
309
        m_MissingProb = 1.0;
 
310
        break;
 
311
      case M_MAXDIFF:
 
312
        m_MissingProb = m_SmallestProb;
 
313
        break;
 
314
      case M_AVERAGE:
 
315
        m_MissingProb = m_AverageProb;
 
316
        break;
 
317
      }
 
318
 
 
319
    if ( Math.abs(bestpsum - (double)m_TotalCount) < EPSILON) { 
 
320
      // No difference in the values
 
321
      stopProb = 1.0;
 
322
    }
 
323
    else {
 
324
      stopProb = bestpstop;
 
325
    }
 
326
    return stopProb;
 
327
  }
 
328
 
 
329
  /**
 
330
   * Calculates the entropy of the actual class prediction
 
331
   * and the entropy for random class prediction. It also
 
332
   * calculates the smallest and average transformation probabilities.
 
333
   *
 
334
   * @param stop the stop parameter
 
335
   * @param params the object wrapper for the parameters:
 
336
   * actual entropy, random entropy, average probability and smallest 
 
337
   * probability.
 
338
   * @return the values are returned in the object "params".
 
339
   *
 
340
   */
 
341
  private void calculateEntropy( double stop, KStarWrapper params) {
 
342
    String debug = "(KStarNominalAttribute.calculateEntropy)";
 
343
    int i,j,k;
 
344
    Instance train;
 
345
    double actent = 0.0, randent=0.0;
 
346
    double pstar, tprob, psum=0.0, minprob=1.0;
 
347
    double actClassProb, randClassProb;
 
348
    double [][] pseudoClassProb = new double[NUM_RAND_COLS+1][m_NumClasses];
 
349
    // init ...
 
350
    for(j = 0; j <= NUM_RAND_COLS; j++) {
 
351
      for(i = 0; i < m_NumClasses; i++) {
 
352
        pseudoClassProb[j][i] = 0.0;
 
353
      }
 
354
    }
 
355
    for (i=0; i < m_NumInstances; i++) {
 
356
      train = m_TrainSet.instance(i);
 
357
      if (!train.isMissing(m_AttrIndex)) {
 
358
        pstar = PStar(m_Test, train, m_AttrIndex, stop);
 
359
        tprob = pstar / m_TotalCount;
 
360
        if (pstar < minprob) {
 
361
          minprob = pstar;
 
362
        }
 
363
        psum += tprob;
 
364
        // filter instances with same class value
 
365
        for (k=0 ; k <= NUM_RAND_COLS ; k++) {
 
366
          // instance i is assigned a random class value in colomn k;
 
367
          // colomn k = NUM_RAND_COLS contains the original mapping: 
 
368
          // instance -> class vlaue
 
369
          pseudoClassProb[k][ m_RandClassCols[k][i] ] += tprob;
 
370
        }
 
371
      }
 
372
    }
 
373
    // compute the actual entropy using the class probs
 
374
    // with the original class value mapping (colomn NUM_RAND_COLS)
 
375
    for (j=m_NumClasses-1; j>=0; j--) {
 
376
      actClassProb = pseudoClassProb[NUM_RAND_COLS][j] / psum;
 
377
      if (actClassProb > 0) {
 
378
        actent -= actClassProb * Math.log(actClassProb) / LOG2;
 
379
      }
 
380
    }
 
381
    // compute a random entropy using the pseudo class probs
 
382
    // excluding the colomn NUM_RAND_COLS
 
383
    for (k=0; k < NUM_RAND_COLS;k++) {
 
384
      for (i = m_NumClasses-1; i >= 0; i--) {
 
385
        randClassProb = pseudoClassProb[k][i] / psum;
 
386
        if (randClassProb > 0) {
 
387
          randent -= randClassProb * Math.log(randClassProb) / LOG2;
 
388
        }
 
389
      }
 
390
    }
 
391
    randent /= NUM_RAND_COLS;
 
392
    // return the results ... Yuk !!!
 
393
    params.actEntropy = actent;
 
394
    params.randEntropy = randent;
 
395
    params.avgProb = psum;
 
396
    params.minProb = minprob;
 
397
  }
 
398
  
 
399
  /**
 
400
   * Calculates the "stop parameter" for this attribute using
 
401
   * the blend method: the value is computed using a root finder
 
402
   * algorithm. The method takes advantage of this calculation to
 
403
   * compute the smallest and average transformation probabilities
 
404
   * once the stop factor is obtained. It also sets the transformation
 
405
   * probability to an attribute with a missing value.
 
406
   *
 
407
   * @return the value of the stop parameter.
 
408
   *
 
409
   */
 
410
  private double stopProbUsingBlend() {
 
411
    String debug = "(KStarNominalAttribute.stopProbUsingBlend) ";
 
412
    int itcount = 0;
 
413
    double stopProb, aimfor;
 
414
    double lower, upper, tstop;
 
415
 
 
416
    KStarWrapper botvals = new KStarWrapper();
 
417
    KStarWrapper upvals = new KStarWrapper();
 
418
    KStarWrapper vals = new KStarWrapper();
 
419
 
 
420
    int testvalue = (int)m_Test.value(m_AttrIndex);
 
421
    aimfor = (m_TotalCount - m_Distribution[testvalue]) * 
 
422
      (double)m_BlendFactor / 100.0 + m_Distribution[testvalue];
 
423
 
 
424
    // Initial values for root finder
 
425
    tstop = 1.0 - (double)m_BlendFactor / 100.0;
 
426
    lower = 0.0 + ROOT_FINDER_ACCURACY/2.0;
 
427
    upper = 1.0 - ROOT_FINDER_ACCURACY/2.0;
 
428
 
 
429
    // Find out function border values
 
430
    calculateSphereSize(testvalue, lower, botvals);
 
431
    botvals.sphere -= aimfor;
 
432
    calculateSphereSize(testvalue, upper, upvals);
 
433
    upvals.sphere -= aimfor;
 
434
    
 
435
    if (upvals.avgProb == 0) {
 
436
      // When there are no training instances with the test value:
 
437
      // doesn't matter what exact value we use for tstop, just acts as
 
438
      // a constant scale factor in this case.
 
439
      calculateSphereSize(testvalue, tstop, vals);
 
440
    }
 
441
    else if (upvals.sphere > 0) {
 
442
      // Can't include aimfor instances, going for min possible
 
443
      tstop = upper;
 
444
      vals.avgProb = upvals.avgProb;
 
445
    }
 
446
    else {
 
447
      // Enter the root finder
 
448
      for (;;) {
 
449
        itcount++;
 
450
        calculateSphereSize(testvalue, tstop, vals);
 
451
        vals.sphere -= aimfor;
 
452
        if ( Math.abs(vals.sphere) <= ROOT_FINDER_ACCURACY ||
 
453
             itcount >= ROOT_FINDER_MAX_ITER )
 
454
          {
 
455
            break;
 
456
          }
 
457
        if (vals.sphere > 0.0) {
 
458
          lower = tstop;
 
459
          tstop = (upper + lower) / 2.0;
 
460
        }
 
461
        else {
 
462
          upper = tstop;
 
463
          tstop = (upper + lower) / 2.0;
 
464
        }
 
465
      }
 
466
    }
 
467
 
 
468
    m_SmallestProb = vals.minProb;
 
469
    m_AverageProb = vals.avgProb;
 
470
    // Set the probability of transforming to a missing value
 
471
    switch ( m_MissingMode )
 
472
      {
 
473
      case M_DELETE:
 
474
        m_MissingProb = 0.0;
 
475
        break;
 
476
      case M_NORMAL:
 
477
        m_MissingProb = 1.0;
 
478
        break;
 
479
      case M_MAXDIFF:
 
480
        m_MissingProb = m_SmallestProb;
 
481
        break;
 
482
      case M_AVERAGE:
 
483
        m_MissingProb = m_AverageProb;
 
484
        break;
 
485
      }
 
486
    
 
487
    if ( Math.abs(vals.avgProb - m_TotalCount) < EPSILON) { 
 
488
      // No difference in the values
 
489
      stopProb = 1.0;
 
490
    }
 
491
    else {
 
492
      stopProb = tstop;
 
493
    }
 
494
    return stopProb;
 
495
  }
 
496
  
 
497
  /**
 
498
   * Calculates the size of the "sphere of influence" defined as:
 
499
   * sphere = sum(P^2)/sum(P)^2
 
500
   * P(i|j) = (1-tstop)*P(i) + ((i==j)?tstop:0).
 
501
   * This method takes advantage of the calculation to compute the values of
 
502
   * the "smallest" and "average" transformation probabilities when using
 
503
   * the specified stop parameter.
 
504
   *
 
505
   * @param testValue the value of the test instance
 
506
   * @param stop the stop parameter
 
507
   * @param params a wrapper of the parameters to be computed:
 
508
   * "sphere" the sphere size
 
509
   * "avgprob" the average transformation probability
 
510
   * "minProb" the smallest transformation probability
 
511
   * @return the values are returned in "params" object.
 
512
   *
 
513
   */
 
514
  private void calculateSphereSize(int testvalue, double stop, 
 
515
                                   KStarWrapper params) {
 
516
    String debug = "(KStarNominalAttribute.calculateSphereSize) ";
 
517
    int i, thiscount;
 
518
    double tprob, tval = 0.0, t1 = 0.0;
 
519
    double sphere, minprob = 1.0, transprob = 0.0;
 
520
 
 
521
    for(i = 0; i < m_Distribution.length; i++) {
 
522
      thiscount = m_Distribution[i];
 
523
      if ( thiscount != 0 ) {
 
524
        if ( testvalue == i ) {
 
525
          tprob = (stop + (1 - stop) / m_Distribution.length) / m_TotalCount;
 
526
          tval += tprob * thiscount;
 
527
          t1 += tprob * tprob * thiscount;
 
528
        }
 
529
        else {
 
530
          tprob = ((1 - stop) / m_Distribution.length) / m_TotalCount;
 
531
          tval += tprob * thiscount;
 
532
          t1 += tprob * tprob * thiscount;
 
533
        }
 
534
        if ( minprob > tprob * m_TotalCount ) {
 
535
          minprob = tprob * m_TotalCount;
 
536
        }
 
537
      }
 
538
    }
 
539
    transprob = tval;
 
540
    sphere = (t1 == 0) ? 0 : ((tval * tval) / t1);
 
541
    // return values ... Yck!!!
 
542
    params.sphere = sphere;
 
543
    params.avgProb = transprob;
 
544
    params.minProb = minprob;
 
545
  }
 
546
  
 
547
  /**
 
548
   * Calculates the nominal probability function defined as:
 
549
   * P(i|j) = (1-stop) * P(i) + ((i==j) ? stop : 0)
 
550
   * In this case, it calculates the transformation probability of the
 
551
   * indexed test attribute to the indexed train attribute.
 
552
   *
 
553
   * @param test the test instance
 
554
   * @param train the train instance
 
555
   * @param col the attribute index
 
556
   * @return the value of the tranformation probability.
 
557
   *
 
558
   */
 
559
  private double PStar(Instance test, Instance train, int col, double stop) {
 
560
    String debug = "(KStarNominalAttribute.PStar) ";
 
561
    double pstar;
 
562
    int numvalues = 0;
 
563
    try {
 
564
      numvalues = test.attribute(col).numValues();
 
565
    } catch (Exception ex) {
 
566
      ex.printStackTrace();
 
567
    }
 
568
    if ( (int)test.value(col) == (int)train.value(col) ) {
 
569
      pstar = stop + (1 - stop) / numvalues;
 
570
    }
 
571
    else {
 
572
      pstar = (1 - stop) / numvalues;
 
573
    }
 
574
    return pstar;
 
575
  }
 
576
  
 
577
  /**
 
578
   * Calculates the distribution, in the dataset, of the indexed nominal
 
579
   * attribute values. It also counts the actual number of training instances
 
580
   * that contributed (those with non-missing values) to calculate the 
 
581
   * distribution.
 
582
   */
 
583
  private void generateAttrDistribution() {
 
584
    String debug = "(KStarNominalAttribute.generateAttrDistribution)";
 
585
    m_Distribution = new int[ m_TrainSet.attribute(m_AttrIndex).numValues() ];
 
586
    int i;
 
587
    Instance train;
 
588
    for (i=0; i < m_NumInstances; i++) {
 
589
      train = m_TrainSet.instance(i);
 
590
      if ( !train.isMissing(m_AttrIndex) ) {
 
591
        m_TotalCount++;
 
592
        m_Distribution[(int)train.value(m_AttrIndex)]++;
 
593
      }
 
594
    }
 
595
  }
 
596
 
 
597
  /**
 
598
   * Sets the options.
 
599
   *
 
600
   */
 
601
  public void setOptions(int missingmode, int blendmethod, int blendfactor) {
 
602
    m_MissingMode = missingmode;
 
603
    m_BlendMethod = blendmethod;
 
604
    m_BlendFactor = blendfactor;
 
605
  }
 
606
 
 
607
 
 
608
} // class
 
609
 
 
610
 
 
611
 
 
612
 
 
613