public void observeAttributeClass()

in samoa-api/src/main/java/org/apache/samoa/moa/classifiers/core/attributeclassobservers/VFMLNumericAttributeClassObserver.java [72:177]


  public void observeAttributeClass(double attVal, int classVal, double weight) {
    if (!Utils.isMissingValue(attVal)) {
      if (this.binList.size() < 1) {
        // create the first bin
        Bin newBin = new Bin();
        newBin.classWeights.addToValue(classVal, weight);
        newBin.boundaryClass = classVal;
        newBin.boundaryWeight = weight;
        newBin.upperBound = attVal;
        newBin.lowerBound = attVal;
        this.binList.add(newBin);
      } else {
        // find bin containing new example with binary search
        int index = 0;
        boolean found = false;
        int min = 0;
        int max = this.binList.size() - 1;
        while ((min <= max) && !found) {
          int i = (min + max) / 2;
          Bin bin = this.binList.get(i);
          if (((attVal >= bin.lowerBound) && (attVal < bin.upperBound))
              || ((i == this.binList.size() - 1)
                  && (attVal >= bin.lowerBound) && (attVal <= bin.upperBound))) {
            found = true;
            index = i;
          } else if (attVal < bin.lowerBound) {
            max = i - 1;
          } else {
            min = i + 1;
          }
        }
        boolean first = false;
        boolean last = false;
        if (!found) {
          // determine if it is before or after the existing range
          Bin bin = this.binList.get(0);
          if (bin.lowerBound > attVal) {
            // go before the first bin
            index = 0;
            first = true;
          } else {
            // if we haven't found it yet value must be > last bins
            // upperBound
            index = this.binList.size() - 1;
            last = true;
          }
        }
        Bin bin = this.binList.get(index); // VLIndex(ct->bins, index);
        if ((bin.lowerBound == attVal)
            || (this.binList.size() >= this.numBinsOption.getValue())) {// Option.getValue())
          // {//1000)
          // {
          // if this is the exact same boundary and class as the bin
          // boundary or we aren't adding new bins any more then
          // increment
          // boundary counts
          bin.classWeights.addToValue(classVal, weight);
          if ((bin.boundaryClass == classVal)
              && (bin.lowerBound == attVal)) {
            // if it is also the same class then special case it
            bin.boundaryWeight += weight;
          }
        } else {
          // create a new bin
          Bin newBin = new Bin();
          newBin.classWeights.addToValue(classVal, weight);
          newBin.boundaryWeight = weight;
          newBin.boundaryClass = classVal;
          newBin.upperBound = bin.upperBound;
          newBin.lowerBound = attVal;

          double percent = 0.0;
          // estimate initial counts with a linear interpolation
          if (!((bin.upperBound - bin.lowerBound == 0) || last || first)) {
            percent = 1.0 - ((attVal - bin.lowerBound) / (bin.upperBound - bin.lowerBound));
          }

          // take out the boundry points, they stay with the old bin
          bin.classWeights.addToValue(bin.boundaryClass,
              -bin.boundaryWeight);
          DoubleVector weightToShift = new DoubleVector(
              bin.classWeights);
          weightToShift.scaleValues(percent);
          newBin.classWeights.addValues(weightToShift);
          bin.classWeights.subtractValues(weightToShift);
          // put the boundry examples back in
          bin.classWeights.addToValue(bin.boundaryClass,
              bin.boundaryWeight);

          // insert the new bin in the right place
          if (last) {
            bin.upperBound = attVal;
            newBin.upperBound = attVal;
            this.binList.add(newBin);
          } else if (first) {
            newBin.upperBound = bin.lowerBound;
            this.binList.add(0, newBin);
          } else {
            newBin.upperBound = bin.upperBound;
            bin.upperBound = attVal;
            this.binList.add(index + 1, newBin);
          }
        }
      }
    }
  }