我正在使用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?
答案 0 :(得分:0)
我设法通过强制每个实例成为DenseInstance
来找到解决方法,如下所示:
for (Instance instance : csvSaver.getInstances()) {
csvSaver.writeIncremental(new DenseInstance(instance));
}
这很有效,当然,csv输出也是正确的。
这个解决方案只是一种解决方法,如果有人发现这个错误背后的真正原因,我宁愿这样做。