5

Mahoutを使用してk-meansアルゴリズムを分析しています。いくつかのテストを実行し、パフォーマンスを観察し、得られた結果を使用していくつかの統計を実行します。

Mahout内で自分のプログラムを実行する方法がわかりません。ただし、コマンドラインインターフェイスで十分な場合があります。

サンプルプログラムを実行するには、

$ mahout seqdirectory --input uscensus --output uscensus-seq
$ mahout seq2sparse -i uscensus-seq -o uscensus-vec
$ mahout kmeans -i reuters-vec/tfidf-vectors -o uscensus-kmeans-clusters -c uscensus-kmeans-centroids -dm org.apache.mahout.common.distance.CosineDistanceMeasure -x 5 -ow -cl -k 25

データセットは1つの大きなCSVファイルです。各行はレコードです。機能はコンマで区切られます。最初のフィールドはIDです。入力形式が原因で、seqdirectoryをすぐに使用できません。この同様の質問に対する答えを実装しようとしています。CSVとして保存されたベクトルデータを使用してmahoutでk-meansクラスタリングを実行するにはどうすればよいですか?しかし、私はまだ2つの質問があります:

  1. CSVからSeqFileに変換するにはどうすればよいですか?Mahoutを使用して独自のプログラムを作成し、この変換を行ってから、その出力をseq2parseの入力として使用できると思います。CSVIterator(https://cwiki.apache.org/confluence/display/MAHOUT/File+Format+Integrations)を使用できると思います。読み書きにはどのクラスを使用すればよいですか?
  2. 新しいプログラムを作成して実行するにはどうすればよいですか?マハウトの本が実際に動いているか、ここで他の質問をしていると、私はそれを理解できませんでした。
4

5 に答える 5

5

データを SequenceFile 形式で取得するには、いくつかの方法があります。どちらも、厳密にはコマンドラインではなく、独自のコードを記述する必要があります。

戦略 1 Mahout の CSVVectorIterator クラスを使用します。java.io.Reader を渡すと、CSV ファイルが読み込まれ、各行が DenseVector に変換されます。私はこれを使用したことはありませんが、API で見ました。DenseVectors に問題がなければ、簡単に見えます。

戦略 2 独自のパーサーを作成します。「、」で各行を分割するだけで、ループできる配列があるため、これは非常に簡単です。各行の値の配列ごとに、次のようなものを使用してベクトルをインスタンス化します。

new DenseVector(<your array here>);

それをリストに追加します(たとえば)。

次に...ベクトルのリストを取得したら、次のようなものを使用してそれらをSequenceFilesに書き込むことができます(以下のコードではNamedVectorsを使用しています):

FileSystem fs = null;
SequenceFile.Writer writer;
Configuration conf = new Configuration();

List<NamedVector> vectors = <here's your List of vectors obtained from CSVVectorIterator>;

// Write the data to SequenceFile
try {
    fs = FileSystem.get(conf);

    Path path = new Path(<your path> + <your filename>);
    writer = new SequenceFile.Writer(fs, conf, path, Text.class, VectorWritable.class);

    VectorWritable vec = new VectorWritable();
    for (NamedVector vector : dataVector) {

        vec.set(vector);
        writer.append(new Text(vector.getName()), vec);

    }
    writer.close();

} catch (Exception e) {
    System.out.println("ERROR: "+e);
}

これで、K-means クラスタリングに使用できる SequenceFile 形式の「ポイント」のディレクトリができました。コマンド ライン Mahout コマンドをこのディレクトリに入力として指定できます。

とにかく、それが一般的な考えです。おそらく他のアプローチもあるでしょう。

于 2013-02-21T13:20:46.907 に答える
3

csv ファイルで kmeans を実行するには、まず、KmeansDriver で引数として渡す SequenceFile を作成する必要があります。次のコードは、CSV ファイル「points.csv」の各行を読み取り、ベクターに変換して、SequenceFile「points.seq」に書き込みます。

try (
            BufferedReader reader = new BufferedReader(new FileReader("testdata2/points.csv"));
            SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf,new Path("testdata2/points.seq"), LongWritable.class, VectorWritable.class)
        ) {
            String line;
            long counter = 0;
            while ((line = reader.readLine()) != null) {
                String[] c = line.split(",");
                if(c.length>1){
                    double[] d = new double[c.length];
                    for (int i = 0; i < c.length; i++)
                            d[i] = Double.parseDouble(c[i]);
                    Vector vec = new RandomAccessSparseVector(c.length);
                    vec.assign(d);

                VectorWritable writable = new VectorWritable();
                writable.set(vec);
                writer.append(new LongWritable(counter++), writable);
            }
        }
        writer.close();
    }

それが役に立てば幸い!!

于 2013-08-01T08:15:45.183 に答える
1

上記のコードを実行しているときにいくつかの問題があったため、構文を少し変更すると、動作するコードになります。

String inputfiledata = Input_file_path;
            String outputfile = output_path_for_sequence_file;
            FileSystem fs = null;
            SequenceFile.Writer writer;
            Configuration conf = new Configuration();
            fs = FileSystem.get(conf);
            Path path = new Path(outputfile);`enter code here`
            writer = new SequenceFile.Writer(fs, conf, path, Text.class, VectorWritable.class);
            VectorWritable vec = new VectorWritable();
            List<NamedVector> vects = new ArrayList<NamedVector>();
            try {
                fr = new FileReader(inputfiledata);
                br = new BufferedReader(fr);
                s = null;
                while((s=br.readLine())!=null){

                    // My columns are split by tabs with each entry in a new line as rows
                    String spl[] = s.split("\\t");
                    String key = spl[0];
                    Integer val = 0;
                    for(int k=1;k<spl.length;k++){
                                colvalues[val] = Double.parseDouble(spl[k]);
                                val++;
                        }
                    }
                    NamedVector nmv = new NamedVector(new DenseVector(colvalues),key);
                    vec.set(nmv);
                    writer.append(new Text(nmv.getName()), vec);
                }
                            writer.close();

            } catch (Exception e) {
                System.out.println("ERROR: "+e);
            }
        }
于 2013-03-26T22:04:26.837 に答える
0

CSV を mahout が受け入れるスパース ベクトル シーケンス ファイルに変換するプログラムを実装することをお勧めします。
必要なのは、InputDriver が、スペース区切りの浮動小数点数を含むテキスト ファイルを、特にクラスタリング ジョブへの入力に適した VectorWritable の Mahout シーケンス ファイルに変換する方法と、一般的にこの入力を必要とするすべての Mahout ジョブを理解することです。必要に応じてコードをカスタマイズします。
Mahout のソース コードをダウンロードした場合、InputDriver はパッケージ org.apache.mahout.clustering.conversion にあります。

于 2013-01-25T04:10:05.633 に答える