我很快就解决了这个问题:
注意:这是在 C# 中(我通过 ikvm 使用 weka)。但是,任何人都应该非常简单地转换为 Java。
注意2:唯一重要的一行是这一行:if (sparse) continue
我还在下面用注释突出显示了这一行。其他所有内容都是我通过 grepcode 和 google 找到的 weka 源代码的直接副本。甚至不确定它是否是我复制的最新版本,所以请谨慎使用。
我还进行了测试以确保标准 XRFFLoader 正确处理此问题,并且看起来确实如此。
肿瘤坏死因子
// Usage
var saver = new EfficientXRFFSaver();
saver.setCompressOutput(file.EndsWith(".gz"));
saver.setInstances(Instances);
saver.setFile(new java.io.File(file));
saver.writeBatch();
// Implementation
public class EfficientXRFFSaver : XRFFSaver
{
public override void resetOptions() {
base.resetOptions();
setFileExtension(getCompressOutput() ? XRFFLoader.FILE_EXTENSION_COMPRESSED : XRFFLoader.FILE_EXTENSION);
try { m_XMLInstances = new EfficientXMLInstances(); }
catch { m_XMLInstances = null; }
}
}
public class EfficientXMLInstances : XMLInstances
{
protected override void addInstance(Element parent, Instance inst) {
var node = m_Document.createElement(TAG_INSTANCE);
parent.appendChild(node);
var sparse = inst is SparseInstance;
if (sparse) { node.setAttribute(ATT_TYPE, VAL_SPARSE); }
if (inst.weight() != 1.0) { node.setAttribute(ATT_WEIGHT, Utils.doubleToString(inst.weight(), m_Precision)); }
for (var i = 0; i < inst.numValues(); i++) {
var index = inst.index(i);
var value = m_Document.createElement(TAG_VALUE);
if (inst.isMissing(index)) {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!! IMPORTANT !!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This line will not add this element if its missing and sparse.
if (sparse) continue;
value.setAttribute(ATT_MISSING, VAL_YES);
} else {
if (inst.attribute(index).isRelationValued()) {
var child = m_Document.createElement(TAG_INSTANCES);
value.appendChild(child);
for (var n = 0; n < inst.relationalValue(i).numInstances(); n++) {
addInstance(child, inst.relationalValue(i).instance(n));
}
} else {
value.appendChild(inst.attribute(index).type() == weka.core.Attribute.NUMERIC ?
m_Document.createTextNode(Utils.doubleToString(inst.value(index), m_Precision)) :
m_Document.createTextNode(validContent(inst.stringValue(index))));
}
}
node.appendChild(value);
if (sparse) { value.setAttribute(ATT_INDEX, "" + (index + 1)); }
}
}
}