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

如何解决WEKA调用evaluateModel时的NullPointerException错误?

问题:Weka调用evaluateModel时出现NullPointerException错误

现象

  • 交叉验证crossValidateModel可正常执行,但调用evaluateModel时抛出空指针异常
  • 更换测试集或改用J48分类器仍出现相同错误
  • 数据集无缺失值,由Matlab双精度数组转换生成,包含198个特征+1个类别属性,共3600个数值型实例

错误堆栈

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "weka.filters.unsupervised.attribute.ReplaceMissingValues.input(weka.core.Instance)" because "this.m_Missing" is null
    at weka.classifiers.functions.SMO.distributionForInstance(SMO.java:1443)
    at weka.classifiers.evaluation.Evaluation.evaluationForSingleInstance(Evaluation.java:2208)
    at weka.classifiers.evaluation.Evaluation.evaluateModelOnceAndRecordPrediction(Evaluation.java:2246)
    at weka.classifiers.evaluation.Evaluation.evaluateModel(Evaluation.java:2122)
    at weka.classifiers.Evaluation.evaluateModel(Evaluation.java:689)
    at ClassCleanSMO.main(ClassCleanSMO.java:78)

完整代码

import weka.core.Instances;
import weka.core.converters.ArffLoader;
import weka.filters.unsupervised.attribute.NumericToNominal;
import weka.filters.unsupervised.attribute.ClassAssigner;
import weka.filters.supervised.attribute.PartitionMembership;
import weka.filters.supervised.instance.ClassBalancer;
import weka.classifiers.Evaluation;
import java.util.Random;
import weka.classifiers.functions.SMO;


public class ClassCleanSMO {

   public static void main(String[] args) throws Exception{

       // Loader
       ArffLoader loader = new weka.core.converters.ArffLoader();
       loader.setFile(new java.io.File("C:/Users/redmello/Desktop/traininput2.arff")); 
       Instances ClassData= loader.getDataSet();
       
       // FILTERS
       
       // Nun2Nominal
       NumericToNominal N2N = new weka.filters.unsupervised.attribute.NumericToNominal();
       N2N.setInputFormat(ClassData);
       String[] options = new String[2];
       options[0] = "-R";
       options[1] = "last";  
       N2N.setOptions(options);
       ClassData = weka.filters.Filter.useFilter(ClassData, N2N);
       
       // ClassAssigner
       ClassAssigner MyClass= new weka.filters.unsupervised.attribute.ClassAssigner();
       MyClass.setInputFormat(ClassData);
       String[] options3 = new String[2];
       options3[0] = "-C";
       options3[1] = "last";
       MyClass.setOptions(options3);
       ClassData =  weka.filters.Filter.useFilter(ClassData, MyClass);
       
       // PartitionMembership
       PartitionMembership PartMemb = new weka.filters.supervised.attribute.PartitionMembership();
       PartMemb.setInputFormat(ClassData);
       ClassData = weka.filters.Filter.useFilter(ClassData, PartMemb);
       
       // ClassBalancer
       ClassBalancer ClassBal = new weka.filters.supervised.instance.ClassBalancer();
       ClassBal.setInputFormat(ClassData);
       String[] options4 = new String[1];
       options4[0] = "10";
       ClassBal.setOptions(options4);
       ClassData =  weka.filters.Filter.useFilter(ClassData, ClassBal);
       
       // DATA MINING
       
       // crossValidationFoldMaker + J48
       
       Evaluation eval = new Evaluation(ClassData);
       SMO svm = new SMO();
       eval.crossValidateModel(svm, ClassData, 10, new Random(1));
       System.out.println(eval.toSummaryString("\nResults\n\n",false));
       
       eval.evaluateModel(svm,ClassData);

    }

}

解决建议

  • 根本原因:crossValidateModel内部会创建分类器的副本进行训练,不会修改你定义的svm对象——这个原始SMO实例从未被训练过,内部的m_Missing过滤器未初始化,调用evaluateModel时触发空指针。
  • 方案1:显式训练模型后再评估
    修改代码,在调用evaluateModel前先执行训练:
    // 先训练SMO模型
    svm.buildClassifier(ClassData);
    // 再执行评估
    eval.evaluateModel(svm, ClassData);
    
  • 方案2:若无需额外评估,可直接使用交叉验证输出的结果,删除eval.evaluateModel(svm,ClassData)这一行
  • 额外检查:确认PartitionMembership和ClassBalancer的参数设置是否符合数据集需求,避免数据结构异常引发后续问题

内容的提问来源于stack exchange,提问作者Emiliano Rosso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:55:37