You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java调用预训练Bagging随机森林classifyInstance报数组越界错误求助

解决Weka Bagging随机森林classifyInstance数组越界异常

问题背景

在Java环境中调用预训练的Bagging随机森林模型执行classifyInstance方法时,抛出ArrayIndexOutOfBoundsException异常,但相同代码运行SMO、朴素贝叶斯模型完全正常。

错误栈信息

java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
    at weka.classifiers.meta.Bagging.distributionForInstance(Bagging.java:791)
    at weka.classifiers.AbstractClassifier.classifyInstance(AbstractClassifier.java:173)
    at com.msc.sinhalasongpredictorbackend.service.ClassifyService.runRandomForest(ClassifyService.java:97) 

相关代码片段

private Integer runRandomForest() throws Exception {
    Bagging randomForest = (Bagging) SerializationHelper.read(randomForestLocation);
    CSVLoader loader = new CSVLoader();
    try (InputStream fis = new FileInputStream(csvFeatureOutput)) {
        loader.setSource(fis);

        Instances trainingDataSet = loader.getDataSet();

        List values = new ArrayList();
        values.add("1.0");
        trainingDataSet.insertAttributeAt(new Attribute("label", values), trainingDataSet.numAttributes());
        trainingDataSet.setClassIndex(trainingDataSet.numAttributes() - 1);

        for (Instance i : trainingDataSet) {
            Double result = randomForest.classifyInstance(i);
            return result.intValue();
        }

        return -1;
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e.getMessage());
    }
}

输入CSV单条实例数据

13.46,0.1023,0.002532,221.9,0.001693,0.06354,0.05821,26.46,13.22,134.3,0.000406,0.0742,0.3509,0.2297,0.2114,0.1953,0.2013,0.1948,0.1646,0.1817,0,0.166,15.16,1359,107900,22360000,29.32,0.1582,0.001677,1679,0.00328,0.1308,0.5461,67.77,215.6,462.1,0.0095,-0.8899,0.4612,-0.04562,0.2517,-0.005843,-0.004694,0.01806,0.006126,0.02237,0,0.3106,58.65,3476,279200,51460000,?

错误原因分析

Weka模型对输入实例的属性结构有严格要求:预测时的实例属性数量、顺序、类型必须与模型训练时完全一致,包括类属性的位置和类别数量。

你的代码中手动插入了一个新的标称型label属性(仅包含"1.0"一个类别),并将其设为类索引,这导致输入实例的属性结构与预训练模型的训练数据集结构不匹配。Bagging在合并基分类器的预测分布时,会基于训练时的类类别数量分配数组长度,而当前输入实例的类属性只有1个类别,从而触发数组越界。

修复方案

移除手动插入label属性的代码,直接将CSV原有最后一列设为类索引,确保输入实例结构与预训练模型一致:

修改后的代码:

private Integer runRandomForest() throws Exception {
    Bagging randomForest = (Bagging) SerializationHelper.read(randomForestLocation);
    CSVLoader loader = new CSVLoader();
    try (InputStream fis = new FileInputStream(csvFeatureOutput)) {
        loader.setSource(fis);

        Instances trainingDataSet = loader.getDataSet();
        // 直接将原有最后一列设为类索引,无需新增属性
        trainingDataSet.setClassIndex(trainingDataSet.numAttributes() - 1);

        for (Instance i : trainingDataSet) {
            Double result = randomForest.classifyInstance(i);
            return result.intValue();
        }

        return -1;
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e.getMessage());
    }
}

额外验证点:

  • 确认预训练模型的训练数据集与当前CSV的属性数量、顺序、类型完全一致
  • CSV最后一列的?会被Weka识别为缺失值,不影响结构匹配,模型预测时会自动处理

内容的提问来源于stack exchange,提问作者Malinda Peiris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:17:20