为啥在 Weka 中使用 libsvm 时会出现“NoClassDefFoundError:libsvm/svm_print_interface”错误?

Posted

技术标签:

【中文标题】为啥在 Weka 中使用 libsvm 时会出现“NoClassDefFoundError:libsvm/svm_print_interface”错误?【英文标题】:Why does "NoClassDefFoundError:libsvm/svm_print_interface" error occur when using libsvm in Weka?为什么在 Weka 中使用 libsvm 时会出现“NoClassDefFoundError:libsvm/svm_print_interface”错误? 【发布时间】:2018-11-02 09:35:41 【问题描述】:

我的任务是在 weka 中使用 libsvm 对 Iris 数据集进行分类。首先,我在 weka explorer 中运行它并得到理想的结果。

然后我在eclipse中编码,希望得到与weka explorer下面显示的相同的结果。这是我的代码(你可以忽略除main函数之外的任何代码)。

    package weka;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.util.Vector;

    import weka.classifiers.AbstractClassifier;
    import weka.classifiers.Classifier;
    import weka.classifiers.Evaluation;
    import weka.core.Instances;
    import weka.core.OptionHandler;
    import weka.core.Utils;
    import weka.filters.Filter;

    import weka.classifiers.functions.LibSVM;

    public class ClassifyIriswithLibsvm 
     /** the classifier used internally */
      protected Classifier m_Classifier = null;

      /** the filter to use */
      protected Filter m_Filter = null;

      /** the training file */
      protected String m_TrainingFile = null;

      /** the training instances */
      protected Instances m_Training = null;

      /** for evaluating the classifier */
      protected Evaluation m_Evaluation = null;

      /**
       * initializes the demo
       */
      public ClassifyIriswithLibsvm () 
        super();
      

      /**
       * sets the classifier to use
       * 
       * @param name the classname of the classifier
       * @param options the options for the classifier
       */
      public void setClassifier(String name, String[] options) throws Exception 
        m_Classifier = AbstractClassifier.forName(name, options);
      

      /**
       * sets the filter to use
       * 
       * @param name the classname of the filter
       */
      public void setFilter(String name) throws Exception 
        m_Filter = (Filter) Class.forName(name).newInstance();
        if (m_Filter instanceof OptionHandler) 
          ((OptionHandler) m_Filter).setOptions(options);
        
      

      /**
       * sets the file to use for training
       */
      public void setTraining(String name) throws Exception 
        m_TrainingFile = name;
        m_Training = new Instances(new BufferedReader(
          new FileReader(m_TrainingFile)));
        m_Training.setClassIndex(m_Training.numAttributes() - 1);
      

      /**
       * runs 10fold CV over the training file
       */
      public void execute() throws Exception 
        // run filter
        m_Filter.setInputFormat(m_Training);
        Instances filtered = Filter.useFilter(m_Training, m_Filter);

        // train classifier on complete file for tree
        m_Classifier.buildClassifier(filtered);

        // 10fold CV with seed=1
        m_Evaluation = new Evaluation(filtered);
        m_Evaluation.crossValidateModel(m_Classifier, filtered, 10,
          m_Training.getRandomNumberGenerator(1));
      

      /**
       * outputs some data about the classifier
       */
      @Override
      public String toString() 
        StringBuffer result;

        result = new StringBuffer();
        result.append("Weka - Demo\n===========\n\n");

        result.append("Classifier...: " + Utils.toCommandLine(m_Classifier) + "\n");
        if (m_Filter instanceof OptionHandler) 
          result.append("Filter.......: " + m_Filter.getClass().getName() + " "
            + Utils.joinOptions(((OptionHandler) m_Filter).getOptions()) + "\n");
         else 
          result.append("Filter.......: " + m_Filter.getClass().getName() + "\n");
        
        result.append("Training file: " + m_TrainingFile + "\n");
        result.append("\n");

        result.append(m_Classifier.toString() + "\n");
        result.append(m_Evaluation.toSummaryString() + "\n");
        try 
          result.append(m_Evaluation.toMatrixString() + "\n");
         catch (Exception e) 
          e.printStackTrace();
        
        try 
          result.append(m_Evaluation.toClassDetailsString() + "\n");
         catch (Exception e) 
          e.printStackTrace();
        

        return result.toString();
      

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


          String classifier = "weka.classifiers.functions.LibSVM" ;
          String options = ( "-S 0 -K 0 -D 3 -G 0.0 -R 0.0 -N 0.5 -M 40.0 -C 1.0 -E 0.001 -P 0.1" );
          String[] classifierOptions = options.split( " " );
          String filter = "weka.filters.unsupervised.instance.Randomize ";

          String dataset = "D:\\SoftWare\\weka3.8.2\\Weka-3-8\\data\\iris.arff";

        // run
        ClassifyIriswithLibsvm demo = new ClassifyIriswithLibsvm();
        demo.setClassifier(classifier,
          classifierOptions);
        demo.setFilter(filter);
        demo.setTraining(dataset);
        demo.execute();
        System.out.println(demo.toString());
      

但是错误打印出来是这样的

`Exception in thread "main" java.lang.NoClassDefFoundError: libsvm/svm_print_interface
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at weka.core.WekaPackageClassLoaderManager.forName(WekaPackageClassLoaderManager.java:198)
    at weka.core.WekaPackageClassLoaderManager.forName(WekaPackageClassLoaderManager.java:178)
    at weka.core.WekaPackageClassLoaderManager.objectForName(WekaPackageClassLoaderManager.java:162)
    at weka.Run.findSchemeMatch(Run.java:90)
    at weka.core.ResourceUtils.forName(ResourceUtils.java:76)
    at weka.core.Utils.forName(Utils.java:1045)
    at weka.classifiers.AbstractClassifier.forName(AbstractClassifier.java:91)
    at weka.ClassifyIriswithLibsvm.setClassifier(ClassifyIriswithLibsvm.java:46)
    at weka.ClassifyIriswithLibsvm.main(ClassifyIriswithLibsvm.java:221)
Caused by: java.lang.ClassNotFoundException: libsvm.svm_print_interface
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 11 more
`

我不知道为什么会出错。我是 libsvm 和 weka 的新手。如何在 weka 中成功运行使用 libsvm 的 classiyier 程序?

【问题讨论】:

【参考方案1】:

您需要确保 libsvm.jar 在您的类路径中可用(在 Eclipse 中)。

您可以在 *** 上检查 this answer 以获取所有必要的依赖项,它们是 libsvm.jarwlsvm.jar 和(当然)weka.jar

【讨论】:

以上是关于为啥在 Weka 中使用 libsvm 时会出现“NoClassDefFoundError:libsvm/svm_print_interface”错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 weka 中使用 libsvm

在 Weka 中使用 libsvm 分类器和堆大小

如何在我的 Java 代码中使用带有 Weka 的 LibSVM?

带有 IKVM 的 C# 中 Weka 的 LIbSVM

LibSVM 使用 Weka 命令行

如何从 libSVM 中使用的数据集转换为 weka 中使用的格式数据(*.arff 或 *.csv)