Question

New small question: trying to test my code now but I'm getting an error.

java.lang.NullPointerException
    at DecisionTree.TestTree.main(TestTree.java:6)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

TestTree:

package DecisionTree;

public class TestTree {
  public static void main(String[] args) {
    Instance[] a = new Instance[5];
    a[0].attribute = 0;
    a[1].attribute = 1;
    a[2].attribute = 2;
    a[3].attribute = 3;
    a[4].attribute = 4;
    a[0].label = true;
    a[1].label = false;
    a[2].label = true;
    a[3].label = false;
    a[4].label = true;
    DecisionTree work = new DecisionTree(a);
    System.out.println(work.root.cutoff);
  }
}

In all my calls to DTNode() I'm getting errors. Any clue where I'm going wrong? I'm trying to recursion to create a Decision Tree, with the instance array. Here are the errors:

File: DecisionTree\DecisionTree.java  [line: 8]
Error: The method DTNode(DecisionTree.Instance[], int, int) is undefined for the type DecisionTree.DecisionTree
File: DecisionTree\DTNode.java  [line: 45]
Error: The method DTNode(DecisionTree.Instance[], int, int) is undefined for the type DecisionTree.DTNode
File: DecisionTree\DTNode.java  [line: 46]
Error: The method DTNode(DecisionTree.Instance[], int, int) is undefined for the type DecisionTree.DTNode

DecisionTree.java:

package DecisionTree;

public class DecisionTree {

  DTNode root;

  public DecisionTree(Instance[] instance) {
    root = DTNode.DTNode(instance, 0, instance.length);

  }

}

DTNode.java:

package DecisionTree;

public class DTNode {

    Instance[] instances;
    double cutoff;
    DTNode left, right;

    public DTNode (Instance[] instance, int l, int r) {
      this.instances = instance;
      int i;
      int j = 0;
      int k = 0;
      int getIndex;
      double[] cutoff = new double[instance.length/2];
      double[] entropy = new double[instance.length/2];
      int[] split = new int[instance.length/2+1];
      double smallestEntropy;

      for(i=0; i<instance.length-1; i++) {
        if(instance[i].label != instance[i+1].label) {
          cutoff[j] = (instance[i].attribute + instance[i+1].attribute)/2;
          split[j] = (2*i+1)/2;
          j++;
        }
      }

      if (j == 0) {
        this.left = null;
        this.right = null;
      }

      for(k=0; k<j; k++) {
        entropy[k] = calcEntropy(instance, l, cutoff[k], r);
      }

      for(k=0; k<j; k++) {
        if (entropy[k] < smallestEntropy) {
          smallestEntropy = entropy[k];
          getIndex = k;
        }
      }

      this.cutoff = cutoff[getIndex];
      this.left = DTNode(instance, l, split[getIndex]);
      this.right = DTNode(instance, split[getIndex]+1, r);
    }

    public double calcEntropy(Instance[] inst, int a, double b, int c) {
      int i;
      double leftSideCounter = 0;
      double rightSideCounter = 0;
      double leftTrue = 0;
      double rightTrue = 0;
      double leftSideEntropy = 0;
      double rightSideEntropy = 0;
      double entropy;

      for(i=a; i<=c; i++){
        if(inst[i].attribute < b) {
          leftSideCounter++;
        }
        else {
          rightSideCounter++;
        }
      }

      for(i=0; i<leftSideCounter; i++) {
        if(inst[i].label = true) {
          leftTrue++;
        }
      }

      for(i=0; i<rightSideCounter; i++) {
        if(inst[i].label = true) {
          rightTrue++;
        }
      }

      leftSideEntropy = -leftTrue/leftSideCounter*Math.log(leftTrue/leftSideCounter)/Math.log(2)-(leftSideCounter-leftTrue)/leftSideCounter*Math.log((leftSideCounter-leftTrue)/leftSideCounter)/Math.log(2); 
      rightSideEntropy = -rightTrue/rightSideCounter*Math.log(rightTrue/rightSideCounter)/Math.log(2)-(rightSideCounter-rightTrue)/rightSideCounter*Math.log((rightSideCounter-rightTrue)/rightSideCounter)/Math.log(2); 
      entropy = leftSideEntropy*leftSideCounter/(leftSideCounter+rightSideCounter)+rightSideEntropy*rightSideCounter/(leftSideCounter+rightSideCounter);        
      return entropy;
    }


}

Instance.java:

package DecisionTree;

public class Instance {

    double attribute;
    boolean label;

    public Instance(double a, boolean c) {
 attribute = a;
 label  = c;
    }

    public double getAttribute() {
 return attribute;
    }

    public void setAttribute(double a) {
 attribute = a;
    }

    public boolean getLabel() {
 return label;
    }

    public void setLabel(boolean c) {
 label = c;
    }
}
Was it helpful?

Solution 2

To call the constructor, you use the new keyword. Currently you call it two ways:

root = DTNode.DTNode( instance, 0, instance.length );
this.left = DTNode(instance, l, split[getIndex]);
// and again like this for right.

Currently these are interpreted as methods with the following signature:

DTNode DTNode( Instance[], int, int );
// Note: when you call it as DTNode.DTNode(...) then it would have to be a static method

Since there is no method that has this signature, it gives you the errors you see. Instead, call the constructor like this:

root = new DTNode( instance, 0, instance.length );
this.left = new DTNode(instance, l, split[getIndex]);
// and again like this for right.

OTHER TIPS

You can't call a constructor the way you call an ordinary method. You have to use the new operator instead:

root = new DTNode(instance, 0, instance.length);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top