2

現在、あるデータセットから別のデータセットに一度に 1 つのインスタンスをコピーしています。文字列マッピングがそのまま残るようにこれを行う方法はありますか? mergeInstances は水平方向に機能しますが、同等の垂直方向のマージはありますか?

これは、複数の arff ファイルから同じ構造のデータセットを 1 つの大きなデータセットに読み込むために使用するループの 1 つのステップです。もっと簡単な方法があるはずです。

Instances iNew = new ConverterUtils.DataSource(name).getDataSet();
for (int i = 0; i < iNew.numInstances(); i++) {
    Instance nInst = iNew.instance(i);
    inst.add(nInst);
}
4

4 に答える 4

5

文字列および名義属性も適切にコピーする、完全に自動化された方法が必要な場合は、次の関数を使用できます。

public static Instances merge(Instances data1, Instances data2)
    throws Exception
{
    // Check where are the string attributes
    int asize = data1.numAttributes();
    boolean strings_pos[] = new boolean[asize];
    for(int i=0; i<asize; i++)
    {
        Attribute att = data1.attribute(i);
        strings_pos[i] = ((att.type() == Attribute.STRING) ||
                          (att.type() == Attribute.NOMINAL));
    }

    // Create a new dataset
    Instances dest = new Instances(data1);
    dest.setRelationName(data1.relationName() + "+" + data2.relationName());

    DataSource source = new DataSource(data2);
    Instances instances = source.getStructure();
    Instance instance = null;
    while (source.hasMoreElements(instances)) {
        instance = source.nextElement(instances);
        dest.add(instance);

        // Copy string attributes
        for(int i=0; i<asize; i++) {
            if(strings_pos[i]) {
                dest.instance(dest.numInstances()-1)
                    .setValue(i,instance.stringValue(i));
            }
        }
    }

    return dest;
}

次の条件が満たされている必要があることに注意してください (関数ではチェックされていません)。

  • データセットは同じ属性構造 (属性の数、属性のタイプ) を持っている必要があります
  • クラスのインデックスは同じでなければなりません
  • 公称値は​​正確に一致する必要があります

その場で data2 の公称属性の値を変更して、data1 の値と一致させるには、次を使用できます。

data2.renameAttributeValue(
    data2.attribute("att_name_in_data2"),
    "att_value_in_data2",
    "att_value_in_data1");
于 2012-09-10T21:32:01.180 に答える
1

元の両方のデータを含む新しい ARFF ファイルを作成してみませんか? シンプルな

cat 1.arff > tmp.arff
tail -n+20 2.arff >> tmp.arff

where20は、arff ヘッダーの行数に置き換えられます。これにより、必要なすべてのインスタンスを含む新しい arff ファイルが生成され、既存のコードでこの新しいファイルを読み取ることができます。

Instances iNew = new ConverterUtils.DataSource(name).getDataSet();

次のドキュメントを使用して、コマンド ラインで weka を呼び出すこともできます: http://old.nabble.com/how-to-merge-two-data-file-a.arff-and-b.arff-into-one-data -リスト--td22890856.html

java weka.core.Instances append filename1 filename2 > output-file 

ただし、ドキュメントhttp://weka.sourceforge.net/doc.dev/weka/core/Instances.html#main%28java.lang.Stringには、複数のarffファイルをネイティブに追加できる機能はありませんジャバコード。Weka 3.7.6 の時点で、2 つの arff ファイルを追加するコードは次のとおりです。

     // read two files, append them and print result to stdout
  else if ((args.length == 3) && (args[0].toLowerCase().equals("append"))) {
DataSource source1 = new DataSource(args[1]);
DataSource source2 = new DataSource(args[2]);
String msg = source1.getStructure().equalHeadersMsg(source2.getStructure());
if (msg != null)
  throw new Exception("The two datasets have different headers:\n" + msg);
Instances structure = source1.getStructure();
System.out.println(source1.getStructure());
while (source1.hasMoreElements(structure))
  System.out.println(source1.nextElement(structure));
structure = source2.getStructure();
while (source2.hasMoreElements(structure))
  System.out.println(source2.nextElement(structure));
  }

したがって、Weka 自体は、コードが使用するのと同じプロセスで、データ セット内のすべてのインスタンスを単純に反復処理して出力するように見えます。

于 2012-05-27T21:58:40.483 に答える
1

別の可能な解決策は、インスタンスが実装しているため、java.util.AbstractCollection から addAll を使用することです。

instances1.addAll(instances2);
于 2013-10-16T20:35:09.240 に答える
0

、、、、などのメソッドを持つ拡張weka.core.Instacesクラスを共有しました。innerJoinleftJoinfullJoinupdateunion

table1.makeIndex(table1.attribute("Continent_ID");
table2.makeIndex(table2.attribute("Continent_ID");
Instances result = table1.leftJoin(table2);

インスタンスは、必要に応じて、異なる数の属性、レベル、NOMINALおよびSTRING変数を持つことができます。

ソースといくつかの例は、GitHub: weka.joinにあります。

于 2015-02-09T10:14:30.463 に答える