Weka:在没有 headers 的情况下加载 CSV 文件
Weka: loading CSV file without headers
如何在 Weka 中不使用 headers 加载 CSV 文件?
有一些相关的问题,但是none似乎进入了重点。
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个。如果我添加 headers,那么它可以正常工作。
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"});
直接APIloader.setNoHeaderRowPresent(true);
我也试过,但是Weka 3.6.13好像没有。
参考文献:
编辑: 事实证明这是 3.6.13 中的问题。该代码适用于 3.7.10。
我不确定 3.6.13,但 3.7.10 的代码显示,如果设置了 setNoHeaderRowPresent,则会添加第一行数据 true。
您正在设置 false,将其设置为来自 CSVLoader grepcode 的 true.Refrence
Set whether there is no header row in the data.
Parameters: b true if
there is no header row in the data
public void setNoHeaderRowPresent(boolean b) {
m_noHeaderRow = b; 293
}
if (m_noHeaderRow) {
m_rowBuffer.add(firstRow);
}
所以在你的代码中使用
loader.setNoHeaderRowPresent(true)
而不是 loader.setNoHeaderRowPresent(false) 以包含数据集中的第一行。
作为解决方法,这会读取 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);
}
}
}
如何在 Weka 中不使用 headers 加载 CSV 文件?
有一些相关的问题,但是none似乎进入了重点。
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个。如果我添加 headers,那么它可以正常工作。
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"});
直接APIloader.setNoHeaderRowPresent(true);
我也试过,但是Weka 3.6.13好像没有。
参考文献:
编辑: 事实证明这是 3.6.13 中的问题。该代码适用于 3.7.10。
我不确定 3.6.13,但 3.7.10 的代码显示,如果设置了 setNoHeaderRowPresent,则会添加第一行数据 true。
您正在设置 false,将其设置为来自 CSVLoader grepcode 的 true.Refrence
Set whether there is no header row in the data.
Parameters: b true if there is no header row in the data
public void setNoHeaderRowPresent(boolean b) {
m_noHeaderRow = b; 293
}
if (m_noHeaderRow) {
m_rowBuffer.add(firstRow);
}
所以在你的代码中使用
loader.setNoHeaderRowPresent(true)
而不是 loader.setNoHeaderRowPresent(false) 以包含数据集中的第一行。
作为解决方法,这会读取 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);
}
}
}