2

Weka ARFF ファイルを SparseInstance オブジェクトで繰り返し拡張する必要があります。新しい SparseInstance が追加されるたびに、新しいインスタンスが追加の属性を追加する可能性があるため、ヘッダーが変更される可能性があります。mergeInstances メソッドで問題が解決すると思っていましたが、そうではありません。両方のデータセットに共有属性がないことが必要です。

これが完全に明確でない場合は、次の例を見てください。

Dataset1
a b c
1 2 3
4 5 6

Dataset2
c d
7 8

Merged result:
a b c d
1 2 3 ?
4 5 6 ?
? ? 7 8

現時点で唯一の解決策は、arff ファイルを手動で解析し、文字列処理を使用してマージすることです。誰もがより良い解決策を知っていますか?

4

1 に答える 1

3

Ok。私は自分で解決策を見つけました。ソリューションの中心部分はメソッドInstances#insertAttributeAtで、2 番目のパラメーターが の場合、最後の属性として新しい属性を挿入しますmodel.numAttributes()。数値属性のコード例を次に示します。他のタイプの属性にも簡単に適応できます。

    Map<String,String> currentInstanceFeatures = currentInstance.getFeatures();
    Instances model = null;
    try {
        if (targetFile.exists()) {
            FileReader in = new FileReader(targetFile);
            try {
                BufferedReader reader = new BufferedReader(in);
                ArffReader arff = new ArffReader(reader);
                model = arff.getData();
            } finally {
                IOUtils.closeQuietly(in);
            }
        } else {
            FastVector schema = new FastVector();
            model = new Instances("model", schema, 1);
        }
        Instance newInstance = new SparseInstance(0);
        newInstance.setDataset(model);

        for(Map.Entry<String,String> feature:currentInstanceFeatures.entrySet()) {
            Attribute attribute = model.attribute(feature.getKey());
                if (attribute == null) {
                    attribute = new Attribute(feature.getKey());
                    model.insertAttributeAt(attribute, model.numAttributes());
                    attribute = model.attribute(feature.getKey());
                }
            newInstance.setValue(attribute, feature.getValue());
        }

        model.add(newInstance);
        model.compactify();
        ArffSaver saver = new ArffSaver();
        saver.setInstances(model);
        saver.setFile(targetFile);
        LOGGER.debug("Saving dataset to: " + targetFile.getAbsoluteFile());
        saver.writeBatch();
    } catch (IOException e) {
        throw new IllegalArgumentException(e);
    }
于 2012-06-17T18:01:18.907 に答える