我最初的树要大得多,但由于我已经在这个问题上卡了很长时间,我决定尝试简化我的树。最后我得到了类似这样的结果:
如你所见,我只有一个名为”LarguraBandaRede”的属性,它有三个可能的标称值:”Congestionado”(拥塞)、”Livre”(自由)和”Merda”(糟糕)。
之后,我从Weka中导出了j48.model,以便在我的Java代码中使用。
我使用以下代码导入模型以用作分类器:
ObjectInputStream objectInputStream = new ObjectInputStream(in);classifier = (J48) objectInputStream.readObject();
然后,我开始创建一个属性数组列表和一个Instances文件
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); }
其中populateAttributes函数为每个属性提供可能的值,在本例中”LarguraBandaRede”的值为”Livre, Merda, Congestionado;”,而我的类属性”Resultado”的值为”Sim,Nao”。
Instances instances = new Instances("header",atts,atts.size());instances.setClassIndex(instances.numAttributes()-1);
创建我的实例后,是时候创建我的实例文件了,也就是我要尝试分类的实例
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);
然后,我为”LarguraBandaRede”的三个可能值分别设置这些实例。’instanceLivre’设置为”Livre”,’instanceMediano’设置为”Merda”,’instanceCongestionado’设置为”Congestionado”。
之后,我只需使用classifyInstance方法对这三个实例进行分类
System.out.println(instance.toString());double resp = classifier.classifyInstance(instance);System.out.println("valor: "+resp);
这是我的结果:
如你所见,”LarguraBandaRede”为”Merda”的实例被分类为与”Congestionado”相同的类,即’Nao’。但这没有任何意义,因为上面的树显然显示当”LarguraBandaRede”为”Merda”或”Livre”时,类应该是相同的。
所以,这就是我的问题。这怎么会发生,又该如何解决呢?
提前感谢。
编辑
我不知道这个:
对模型的工作方式有任何影响。但是在为标称属性提供可能值时,我们必须遵循这个顺序。
回答:
你检查过Weka的标称属性索引是否与你的populateAttributes方法的顺序一致吗?