Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 给定属性索引,WEKA生成的模型似乎无法预测类别和分布 概述_Java_Machine Learning_Weka_Decision Tree_Prediction - Fatal编程技术网

Java 给定属性索引,WEKA生成的模型似乎无法预测类别和分布 概述

Java 给定属性索引,WEKA生成的模型似乎无法预测类别和分布 概述,java,machine-learning,weka,decision-tree,prediction,Java,Machine Learning,Weka,Decision Tree,Prediction,我正在使用WEKA API 3.7.10(开发人员版本)来使用我预先制作的.model文件 我做了25个模型:五个算法的五个结果变量 交替决策树 随机森林 后勤推进 随机子空间 我在J48、随机子空间和随机森林方面有问题 必要文件 以下是创建后我的数据的ARFF表示: @relation WekaData @attribute ageDiagNum numeric @attribute raceGroup {Black,Other,Unknown,White} @attribute st

我正在使用WEKA API 3.7.10(开发人员版本)来使用我预先制作的
.model
文件

我做了25个模型:五个算法的五个结果变量

  • 交替决策树
  • 随机森林
  • 后勤推进
  • 随机子空间
我在J48、随机子空间和随机森林方面有问题

必要文件 以下是创建后我的数据的
ARFF
表示:

@relation WekaData

@attribute ageDiagNum numeric
@attribute raceGroup {Black,Other,Unknown,White}
@attribute stage3 {0,I,IIA,IIB,IIIA,IIIB,IIIC,IIINOS,IV,'UNK Stage'}
@attribute m3 {M0,M1,MX}
@attribute reasonNoCancerSurg {'Not performed, patient died prior to recommended surgery','Not recommended','Not recommended, contraindicated due to other conditions','Recommended but not performed, patient refused','Recommended but not performed, unknown reason','Recommended, unknown if performed','Surgery performed','Unknown; death certificate or autopsy only case'}
@attribute ext2 {00,05,10,11,13,14,15,16,17,18,20,21,23,24,25,26,27,28,30,31,33,34,35,36,37,38,40,50,60,70,80,85,99}
@attribute time2 {}
@attribute time4 {}
@attribute time6 {}
@attribute time8 {}
@attribute time10 {}

@data
65,White,IIA,MX,'Not recommended, contraindicated due to other conditions',14,?,?,?,?,?
我需要从各自的模型中获取二进制属性
time2
time10


下面是我用来从所有模型文件中获取预测的代码片段:

private static Map<String, Object> predict(Instances instances,
        Classifier classifier, int attributeIndex) {
    Map<String, Object> map = new LinkedHashMap<String, Object>();
    int instanceIndex = 0; // do not change, equal to row 1
    double[] percentage = { 0 };
    double outcomeValue = 0;
    AbstractOutput abstractOutput = null;

    if(classifier.getClass() == RandomForest.class || classifier.getClass() == RandomSubSpace.class) {
        // has problems predicting time2 to time10
        instances.setClassIndex(5); 
    } else {
        // works as intended in LogitBoost and ADTree
        instances.setClassIndex(attributeIndex);    
    }

    try {
        outcomeValue = classifier.classifyInstance(instances.instance(0));
        percentage = classifier.distributionForInstance(instances
                .instance(instanceIndex));
    } catch (Exception e) {
        e.printStackTrace();
    }

    map.put("Class", outcomeValue);

    if (percentage.length > 0) {
        double percentageRaw = 0;
        if (outcomeValue == new Double(1)) {
            percentageRaw = percentage[1];
        } else {
            percentageRaw = 1 - percentage[0];
        }
        map.put("Percentage", percentageRaw);
    } else {
        // because J48 returns an error if percentage[i] because it's empty
        map.put("Percentage", new Double(0));
    }

    return map;
}
问题
  • 正如我之前所说的,
    LogitBoost
    ADTree
    与其他三种方法相比,在这个简单的方法中没有问题,因为我遵循了教程

  • [Solved]基于我的调整,并返回
    边界异常排列
    如果被告知预测
    time2
    time10

    java.lang.ArrayIndexOutOfBoundsException: 0
        at weka.classifiers.meta.Bagging.distributionForInstance(Bagging.java:586)
        at weka.classifiers.trees.RandomForest.distributionForInstance(RandomForest.java:602)
        at weka.classifiers.AbstractClassifier.classifyInstance(AbstractClassifier.java:70)
    
    堆栈跟踪将根错误指向以下行:

    outcomeValue = classifier.classifyInstance(instances.instance(0));
    
    解决方案:我在为二进制变量
    time2
    time10
    创建
    FastVector()
    FastVector赋值过程中出现了一些复制粘贴错误,现在出现了一个新问题。它不再提供任何预测,而是返回一个错误:

    java.lang.ArrayIndexOutOfBoundsException: 11
        at weka.core.DenseInstance.value(DenseInstance.java:332)
        at weka.core.AbstractInstance.isMissing(AbstractInstance.java:315)
        at weka.classifiers.trees.j48.C45Split.whichSubset(C45Split.java:494)
        at weka.classifiers.trees.j48.ClassifierTree.getProbs(ClassifierTree.java:670)
        at weka.classifiers.trees.j48.ClassifierTree.classifyInstance(ClassifierTree.java:231)
        at weka.classifiers.trees.J48.classifyInstance(J48.java:266)
    
    它可以追溯到这条线

    outcomeValue = classifier.classifyInstance(instances.instance(0));
    
    解决方案:事实上,我用
    J48
    随机运行了这个程序,它成功了——给出了结果变量和相关分布


我希望有人能帮我解决这个问题。我真的不知道这段代码出了什么问题,因为我已经在线检查了Javadocs和示例,并且持续的预测仍然存在


(我目前正在检查WEKA GUI的主程序,但请在这里帮助我:-)

我现在只研究了RandomForest问题。那是因为装袋课 从数据实例本身而不是从模型中提取不同类的数量。 你在你的文本中说time2到time10是二进制的,但你只是没有在你的ARFF文件中说, 所以Bagging类不知道有多少类

因此,您只需在ARFF文件中指定time2是二进制的,例如: @属性time2{0,1}

你再也不会有例外了

我没有研究J48问题,因为它可能与ARFF定义是同一个问题

测试代码:

  public static void main(String [] argv) {
      try {
        Classifier cls = (Classifier) weka.core.SerializationHelper.read("bosom.100k.2.j48.MODEL");
        J48 c = (J48)cls;

        DataSource source = new DataSource("data.arff");
        Instances data = source.getDataSet();
        data.setClassIndex(6);        

        try {
            double outcomeValue = c.classifyInstance(data.instance(0));
            System.out.println("outcome "+outcomeValue);
            double[] p = c.distributionForInstance(data.instance(0));
            System.out.println(Arrays.toString(p));
        } catch (Exception e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

我现在就试试,谢谢你的回复,完成后我会更新你。我刚刚用你的J48型号试过,没有任何异常:它返回0?是的,它给我[1.0;0.0],这与它的答案0是一致的。决策树不返回概率,所以有这样的值是可以的。我不确定问题是否来自J48模型,但我怀疑它来自于您在测试时创建的实例。您能否将失败的实例保存在磁盘上并发布它们?是的,因为决策树不会生成评分;他们只是做了一系列艰难的决定,所以你不能像其他分类器那样得到真正的值。不管怎样,我不知道如何在stackoverflow中正确地格式化我的代码……好吧,即使有像决策树这样的艰难决策,也有可能输出实数;虽然我现在不知道在Weka中J48实现的所有细节,但我知道C4.5算法在语料库上运行时,实际上计算了语料库中实例的比率;所以我怀疑你在J48中看到的实数实际上对应于这样的语料库比率,这不能真正被认为是概率。我怀疑基于决策树的算法能否从一个例子中给出可靠的概率分布。至少,我不会将它们解释为pdf:-)
  public static void main(String [] argv) {
      try {
        Classifier cls = (Classifier) weka.core.SerializationHelper.read("bosom.100k.2.j48.MODEL");
        J48 c = (J48)cls;

        DataSource source = new DataSource("data.arff");
        Instances data = source.getDataSet();
        data.setClassIndex(6);        

        try {
            double outcomeValue = c.classifyInstance(data.instance(0));
            System.out.println("outcome "+outcomeValue);
            double[] p = c.distributionForInstance(data.instance(0));
            System.out.println(Arrays.toString(p));
        } catch (Exception e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }