Weka: 无标题加载CSV文件

3
如何在Weka中加载没有标题的CSV文件?
有一些相关的问题,但似乎没有一个能够切入要点。
MWE
这是test.csv文件:
20,1,"+"
30,2,"+"
30,1,"+"
15,1,"-"
10,0,"-"

这里是Test.java代码:

// javac -Xlint -cp weka.jar Test.java && java -cp .:weka.jar Test

import weka.core.converters.CSVLoader;
import weka.core.Instances;
import weka.classifiers.Classifier;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.Evaluation;
import java.io.File;

class Test
{
    public static void main(String[] args) {
        try {
            CSVLoader loader = new CSVLoader();
            loader.setOptions(new String[] {"-H"});
            loader.setSource(new File("test.csv"));

            Instances tr = loader.getDataSet();
            tr.setClassIndex(tr.numAttributes() - 1);

            Classifier m = (Classifier) new NaiveBayes();
            m.buildClassifier(tr);

            Evaluation eval = new Evaluation(tr);
            eval.evaluateModel(m, tr);

            System.out.println(eval.toSummaryString());
        }
        catch(Exception ex) {
            System.out.println(ex);
        }
    }
}

运行时,它只报告 4 个实例,而不是 5 。如果我添加标题,则可以正常工作。
Correctly Classified Instances           4              100      %
Incorrectly Classified Instances         0                0      %
Kappa statistic                          1     
Mean absolute error                      0.0065
Root mean squared error                  0.0112
Relative absolute error                  1.3088 %
Root relative squared error              2.2477 %
Total Number of Instances                4     

请注意我使用了:

            loader.setOptions(new String[] {"-H"});

我也尝试了直接使用API loader.setNoHeaderRowPresent(true);,但在Weka 3.6.13中似乎不可用。
参考资料: 编辑:事实证明这是3.6.13的问题。该代码在3.7.10中运行良好。
2个回答

3

对于3.6.13我不确定,但3.7.10的代码显示,如果设置setNoHeaderRowPresent为true,则添加数据的第一行。

您将其设置为false,请将其设置为true。来自CSVLoader的grepcode

设置数据中是否存在无标题行。
参数:如果数据中没有标题行,则为true
public void setNoHeaderRowPresent(boolean b) {
m_noHeaderRow = b; 293
}

if (m_noHeaderRow) {    
  m_rowBuffer.add(firstRow);  
 }

所以在您的代码中使用

loader.setNoHeaderRowPresent(true)

而不是loader.setNoHeaderRowPresent(false),以包含数据集中的第一行。


谢谢,我阅读文档太快了。但问题是它似乎没有为3.6.13实现:Test.java:16: error: cannot find symbol loader.setNoHeaderRowPresent(true);。但奇怪的是,loader.setOptions(new String[] {"-H"}); 对我也不起作用。我会发布一个解决方法作为替代答案... - Ricardo Magalhães Cruz
好的,我已经尝试了开发者版本3.7.10,两个版本都可以工作:无论是setNoHeaderRowPresent()还是setOption()。看起来是稳定版本3.6.13的一个bug。http://www.cs.waikato.ac.nz/ml/weka/downloading.html - Ricardo Magalhães Cruz
我正在使用 3.8.4,尝试使用 Explorer GUI 应用程序打开无标题的 CSV 文件。即使将 setNoHeaderRowPresent 指定为 true,也无法工作或显示“无效流头”错误。 - Rafs

0
作为变通方法,这会读取CSV文件并将其作为ARFF文件传递:
// javac -Xlint -cp weka.jar Test.java && java -cp .:weka.jar Test

import weka.core.converters.CSVLoader;
import weka.core.Instances;
import weka.classifiers.Classifier;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.Evaluation;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.StringReader;
import java.lang.StringBuffer;

class Test
{
    public static void main(String[] args) {
        try {
            String filename = "test.csv";
            BufferedReader br = new BufferedReader(new FileReader(filename));
            String line = br.readLine();
            int cols = line.length() - line.replace(",", "").length() + 1;

            StringBuilder arff = new StringBuilder("@RELATION test\n");
            for(int i = 0; i < cols-1; i++) {
                arff.append("@ATTRIBUTE ");
                arff.append(String.valueOf((char)(i + 'a')));
                arff.append(" NUMERIC\n");
            }
            arff.append("@ATTRIBUTE class {+,-}\n");
            arff.append("@DATA\n");

            while(line != null) {
                arff.append(line);
                arff.append("\n");
                line = br.readLine();
            }

            System.out.println(arff.toString());
            Instances tr = new Instances(new StringReader(arff.toString()));

            tr.setClassIndex(tr.numAttributes() - 1);

            Classifier m = (Classifier) new NaiveBayes();
            m.buildClassifier(tr);

            Evaluation eval = new Evaluation(tr);
            eval.evaluateModel(m, tr);

            System.out.println(eval.toSummaryString());
        }
        catch(Exception ex) {
            System.out.println(ex);
        }
    }
}

@Naruto,显然这是一个黑客行为,而且是一个最小化可执行示例(MWE)的黑客行为。如果你在暗示我要编辑原始的CSV文件,那是不可能的。这个模型必须集成到我们的研究框架中,其中包括其他语言。我们不会仅仅为了一个Weka模型而编辑CSV文件。 - Ricardo Magalhães Cruz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接