Weka CSVSaver索引问题

时间:2014-01-13 21:21:55

标签: java weka indexoutofboundsexception

我正在使用Weka来实现一堆NLP算法。为此,我想将我创建的数据集(从纯文本)写入csv文件。实例已正确创建。我已经通过手动检查数据集的非常小的部分来测试实例创建过程(例如,只有两个文本,每个文本有10个单词)。我还在我创建的实例上直接使用了Weka的k-means clusterer,它运行得很完美。

但是,当我尝试使用CSVSaver将实例保存到文件时,我得到一个indexOutOfBoundsException。据我所知,方法Saver#writeBatch()Saver#writeIncremental()一直循环到包括实例的长度。那令我困惑! Java是0索引的,instance对象也是0索引的。那么为什么Weka会循环到size()而不是size() - 1?我错过了一些非常明显的东西吗?

代码的相关部分如下:

CSVSaver csvSaver = new CSVSaver();
csvSaver.setFieldSeparator("\t");
csvSaver.setFile(new File(optionSet.valueOf("doc-output").toString()));
csvSaver.setMaxDecimalPlaces(3);
csvSaver.setNoHeaderRow(false);
csvSaver.setInstances(documentInstances);
csvSaver.setRetrieval(AbstractSaver.INCREMENTAL);
for (Instance instance : csvSaver.getInstances())
    csvSaver.writeIncremental(instance);

for循环的第一次迭代写入标题行,其中包含346个元素(索引从0到345)。 Weka写下所有这些,然后抛出以下错误:

java.lang.IndexOutOfBoundsException: Index: 346, Size: 346
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.get(ArrayList.java:411)
    at weka.core.Instances.attribute(Instances.java:341)
    at weka.core.AbstractInstance.toString(AbstractInstance.java:744)
    at weka.core.converters.CSVSaver.instanceToString(CSVSaver.java:578)
    at weka.core.converters.CSVSaver.writeIncremental(CSVSaver.java:472)

为什么Weka会一直到索引346,甚至Java初学者都知道停在345?

1 个答案:

答案 0 :(得分:0)

我设法通过强制每个实例成为DenseInstance来找到解决方法,如下所示:

for (Instance instance : csvSaver.getInstances()) {
    csvSaver.writeIncremental(new DenseInstance(instance));
}

这很有效,当然,csv输出也是正确的。

这个解决方案只是一种解决方法,如果有人发现这个错误背后的真正原因,我宁愿这样做。