いくつかの地理空間データをクラスター化しようとしていますが、以前にWEKAライブラリーを試しました。このベンチマークを見つけて、 ELKIを試してみることにしました。
ELKI を Java ライブラリとして使用しないようにというアドバイス(UI よりもメンテナンスが少ないと思われます) にもかかわらず、私は ELKI をアプリケーションに組み込みました。その結果には非常に満足していると言えます。データを保存するために使用する構造は、Weka が使用するものよりもはるかに効率的であり、空間インデックスを使用するオプションがあるという事実は、明らかにプラスです.
しかし、Weka の DBSCANの結果とELKI の DBSCANの結果を比較すると、少し戸惑います。実装が異なるとわずかに異なる結果が生じる可能性があることは認めますが、これらの違いの大きさから、アルゴリズムに(おそらく私のコードに)何か問題があると思います。クラスタの数とそのジオメトリは、2 つのアルゴリズムで大きく異なります。
記録のために、ELKI の最新バージョン (0.6.0) を使用しています。シミュレーションに使用したパラメーターは次のとおりです。
minpts=50 イプシロン=0.008
2 つの DBSCAN 関数 (Weka と ELKI 用) をコーディングしました。ここで、「エントリ ポイント」はポイントを含む csv であり、両方の「出力」も同じです: ポイント セットの凹包を計算する関数 (クラスタごとに 1 つ)。csvファイルをELKI「データベース」に読み込む機能は比較的単純なので、私の問題は次のようになると思います。
a) アルゴリズムのパラメータ化。b) 結果の読み取り (ほとんどの場合)。
DBSCAN をパラメーター化しても問題は発生しません。以前に UI でテストした 2 つの必須パラメーターを使用します。
ListParameterization params2 = new ListParameterization();
params2.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.MINPTS_ID, minPoints);
params2.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.EPSILON_ID, epsilon);
クラスターを格納する構造の構成を完全には理解していないため、結果を読み取るのは少し難しいです。私の考えは、ポリゴンを生成するために、各クラスターを反復処理し、ポイントのリストを取得し、それを凹包を計算する関数に渡すことです。
ArrayList<Clustering<?>> cs = ResultUtil.filterResults(result, Clustering.class);
for (Clustering<?> c : cs) {
System.out.println("clusters: " + c.getAllClusters().size());
for (de.lmu.ifi.dbs.elki.data.Cluster<?> cluster : c.getAllClusters()) {
if (!cluster.isNoise()){
Coordinate[] ptList=new Coordinate[cluster.size()];
int ct=0;
for (DBIDIter iter = cluster.getIDs().iter(); iter.valid(); iter.advance()) {
ptList[ct]=dataMap.get(DBIDUtil.toString(iter));
++ct;
}
//there are no "empty" clusters
assertTrue(ptList.length>0);
GeoPolygon poly=getBoundaryFromCoordinates(ptList);
if (poly.getCoordinates().getGeometryType()==
"Polygon"){
try {
out.write(poly.coordinates.toText()+"\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else
System.out.println(
poly.getCoordinates().getGeometryType());
}//!noise
}
}
「ノイズ」がクラスターとして発生していることに気付いたので、このクラスターを無視しました (描画したくありません)。多くの例が見つからないため、これがクラスターを読み取る正しい方法であるかどうかはわかりません。また、いくつかの質問がありますが、まだ答えが見つかりません。
- getAllClusters() と getTopLevelClusters() の違いは何ですか?
- DBSCAN クラスターは「ネスト」されていますか?つまり、同時に多くのクラスターに属するポイントを持つことができますか? なんで?
- ELKI の内部使用のため、ポイントを識別するためにデータベース ID を使用すべきではないことをどこかで読みましたが、各クラスター内のポイントのリストを取得する他の方法はありますか? ラベルにリレーションを使用できると読みましたが、実際にこれを実装する方法がわかりません...
私を正しい方向に導くことができるコメント、または ELKI の DBSCAN の結果セットを反復処理するためのコードの提案は、本当に歓迎されます! また、コードで ELKI の OPTICSxi を使用しました。これらの結果についてさらに質問がありますが、それは別の投稿に譲ると思います。