Search code examples
javamachine-learningwekadecision-treej48

Weka J48 classification not following tree


My original tree was much bigger, but since I'm stuck with this issue for quite some time I decided to try to simplify my tree. I Ended up with something like this:

arvore

As you can see, I only have a single attribute called "LarguraBandaRede" with 3 possible nominal values "Congestionado", "Livre" and "Merda".

After that I exported the j48.model from weka to use on my java code.

With this piece of code I import the model to use as a classifier:

ObjectInputStream objectInputStream = new ObjectInputStream(in);
classifier = (J48) objectInputStream.readObject();

After that I started to create a arraylist of my attributes and a Instances File

for (int i = 0; i <features.length; i++) {
        String feature = features[i];
        Attribute attribute;
        if (feature.equals("TamanhoDados(Kb)")) {
            attribute = new Attribute(feature);
        } else {
            String[] strings = null;
            if(i==0) strings = populateAttributes(7);
            if(i==1) strings = populateAttributes(10);
            ArrayList<String> attValues = new ArrayList<String>(Arrays.asList(strings));
            attribute = new Attribute(feature,attValues);
        }
        atts.add(attribute);
    }

where populateAttributes gives the possible values for each attribute, in this case "Livre, Merda, Congestionado;" for LarguraBandaRede and "Sim,Nao" for Resultado, my class attribute.

Instances instances = new Instances("header",atts,atts.size());
instances.setClassIndex(instances.numAttributes()-1);

After creating my instances is time to create my Instance File, that is, the instances that I'm trying to classify

Instance instanceLivre = new DenseInstance(features.length);
Instance instanceMediano = new DenseInstance(features.length);
Instance instanceCongestionado = new DenseInstance(features.length);
instanceLivre.setDataset(instances);
instanceMediano.setDataset(instances);
instanceCongestionado.setDataset(instances);

then I set each of this instances with the 3 possible values for "LarguraBandaRede". 'instanceLivre' with "Livre", 'instanceMediano' with "Merda" and 'instanceCongestionado' with "Congestionado".

After that I only classify this 3 instances using the classifyInstance method

System.out.println(instance.toString());
double resp = classifier.classifyInstance(instance);
System.out.println("valor: "+resp);

and this is my result:

result

As you can see, the instance that has Merda as "LarguraBandaRede" was classify to be the same class as Congestionado, the class 'Nao'. But that doesn't make any sense, since the tree above clearly show that when "LarguraBandaRede" is "Merda" or "Livre" the class should be the same.

So that's my question. How this happened and how to fix it?

Thanks in advance.

EDIT

I didn't know that this:

weka's index

made any difference in the way the model works. But we have to follow this order when feeding a nominal attribute with possible values.


Solution

  • Have you checked if the weka nominal attribute index is equal in order to your populateAttributes method?