Weka J48 分类不遵循树
Weka J48 classification not following tree
我原来的树要大得多,但由于我被这个问题困扰了很长一段时间,所以我决定尝试简化我的树。我结束了这样的事情:
如您所见,我只有一个名为 "LarguraBandaRede" 的属性,具有 3 个可能的标称值 "Congestionado"、"Livre" 和 "Merda"。
之后我从 weka 导出了 j48.model 用于我的 java 代码。
通过这段代码,我导入了模型以用作 classifier:
ObjectInputStream objectInputStream = new ObjectInputStream(in);
classifier = (J48) objectInputStream.readObject();
之后我开始创建我的属性数组列表和实例文件
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 给出了每个属性的可能值,在本例中,"Livre, Merda, Congestionado;" 用于 LarguraBandaRede,"Sim,Nao" 用于 Resultado,我的 class 属性。
Instances instances = new Instances("header",atts,atts.size());
instances.setClassIndex(instances.numAttributes()-1);
在创建我的实例之后是时候创建我的实例文件了,也就是我试图 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);
然后我为每个实例设置 "LarguraBandaRede" 的 3 个可能值。 'instanceLivre' 与 "Livre"、'instanceMediano' 与 "Merda" 和 'instanceCongestionado' 与 "Congestionado".
之后我只使用 classifyInstance 方法 classify 这 3 个实例
System.out.println(instance.toString());
double resp = classifier.classifyInstance(instance);
System.out.println("valor: "+resp);
这是我的结果:
如您所见,Merda 为 "LarguraBandaRede" 的实例 class 与 Congestionado 相同 class, class 'Nao'.但这没有任何意义,因为上面的树清楚地表明当 "LarguraBandaRede" 是 "Merda" 或 "Livre" 时 class 应该是相同的。
这就是我的问题。这是怎么发生的以及如何解决它?
提前致谢。
编辑
我不知道这个:
模型的工作方式有所不同。但是我们在给一个标称属性提供可能的值时必须遵循这个顺序。
您是否检查过 weka 名义属性索引是否与您的 populateAttributes 方法相等?
我原来的树要大得多,但由于我被这个问题困扰了很长一段时间,所以我决定尝试简化我的树。我结束了这样的事情:
如您所见,我只有一个名为 "LarguraBandaRede" 的属性,具有 3 个可能的标称值 "Congestionado"、"Livre" 和 "Merda"。
之后我从 weka 导出了 j48.model 用于我的 java 代码。
通过这段代码,我导入了模型以用作 classifier:
ObjectInputStream objectInputStream = new ObjectInputStream(in);
classifier = (J48) objectInputStream.readObject();
之后我开始创建我的属性数组列表和实例文件
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 给出了每个属性的可能值,在本例中,"Livre, Merda, Congestionado;" 用于 LarguraBandaRede,"Sim,Nao" 用于 Resultado,我的 class 属性。
Instances instances = new Instances("header",atts,atts.size());
instances.setClassIndex(instances.numAttributes()-1);
在创建我的实例之后是时候创建我的实例文件了,也就是我试图 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);
然后我为每个实例设置 "LarguraBandaRede" 的 3 个可能值。 'instanceLivre' 与 "Livre"、'instanceMediano' 与 "Merda" 和 'instanceCongestionado' 与 "Congestionado".
之后我只使用 classifyInstance 方法 classify 这 3 个实例
System.out.println(instance.toString());
double resp = classifier.classifyInstance(instance);
System.out.println("valor: "+resp);
这是我的结果:
如您所见,Merda 为 "LarguraBandaRede" 的实例 class 与 Congestionado 相同 class, class 'Nao'.但这没有任何意义,因为上面的树清楚地表明当 "LarguraBandaRede" 是 "Merda" 或 "Livre" 时 class 应该是相同的。
这就是我的问题。这是怎么发生的以及如何解决它?
提前致谢。
编辑
我不知道这个:
模型的工作方式有所不同。但是我们在给一个标称属性提供可能的值时必须遵循这个顺序。
您是否检查过 weka 名义属性索引是否与您的 populateAttributes 方法相等?