3

ヒストグラム プロットが複数の極大値を示す 1 次元データ セットがあるため、1 次元空間にはデータがより密集している領域が複数あることがわかっています。特定のデータポイントが含まれる密集領域/クラスターを分類できるように、これらの密集領域の境界を決定したいと考えています。これには、比較するクラスター間の異なる密度をより適切に処理できるはずである OPTICS を使用しています。 DBSCANに。

JavaコードでELKI(バージョン0.6.0)を使用しています(ELKIチームがELKIをJavaに埋め込むことを推奨していないことは知っていますが、多くのデータセットに対してワークフローを繰り返す必要があるため、私の場合はこれを自動化することをお勧めします) . 以下のコード スニペットは、クラスターの開始項目と終了項目のインデックスを出力します。OPTICSModelに関するELKI ドキュメントでは、これらのインデックス番号が何に対応するかを明確に定義していませんが、これらはデータベースの拡張クラスター順序付けにおける開始データ項目と終了データ項目のインデックスであると想定しています (OPTICS.run() の ClusterOrderResult オブジェクトなど)。データベース自体の開始データ項目と終了データ項目のインデックス (順不同) とは対照的です。

ListParameterization opticsParams = new ListParameterization();
opticsParams.addParameter(OPTICSXi.XI_ID, 0.01);
opticsParams.addParameter(OPTICS.MINPTS_ID, 100);
OPTICSXi<DoubleDistance> optics = ClassGenericsUtil.parameterizeOrAbort(OPTICSXi.class, opticsParams);

ArrayAdapterDatabaseConnection arrayAdapterDatabaseConnection = new ArrayAdapterDatabaseConnection(myListOfOneDimensionalFeatureVectors.toArray(new double[myListOfOneDimensionalFeatureVectors.size()][2]));
ListParameterization dbParams = new ListParameterization();
dbParams.addParameter(AbstractDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
dbParams.addParameter(RStarTreeFactory.Parameterizer.BULK_SPLIT_ID, SortTileRecursiveBulkSplit.class);
dbParams.addParameter(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, arrayAdapterDatabaseConnection);

Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, dbParams);
db.initialize();

result = optics.run(db);
List<Cluster<OPTICSModel>> clusters = result.getAllClusters();
    for(Cluster<OPTICSModel> cluster : clusters){
        if(!cluster.isNoise())
            System.out.println(cluster.getModel().getStartIndex() + ", "+ cluster.getModel().getEndIndex() +";  ");
    }

ここで、1 次元空間のどこでクラスターが開始および終了するかを知りたいと考えています。したがって、上記のコードが既に取得している開始インデックスと終了インデックスに対応するデータ項目を取得したいと思います。取得したインデックスを取得できる ClusterOrderResult オブジェクトが必要になると思います。ただし、ドキュメントでは、optics.run() を呼び出して取得したクラスタリング結果オブジェクトからそのようなものを取得することはできないようです。この順序付けられたデータベースを取得する方法がないように思われたため、上記のコードの println を以下の println に置き換えることにより、代わりに元の入力データセットからインデックスを取得しようと単純に試みました。

System.out.println(myListOfOneDimensionalFeatureVectors.get(cluster.getModel().getStartIndex())[0] + ", "+ myListOfOneDimensionalFeatureVectors.get(cluster.getModel().getEndIndex())[0] +";  ";

ただし、既に予想していたように、インデックスは元の入力ファイルに属していないようです。これは、1 次元空間で終了境界よりも低い値で終了境界を定期的に出力するためです。OPTICS クラスタリングで見つかった開始インデックスと終了インデックスに対応する元の 1 次元データ値を取得する方法を知っている人はいますか? これらの値を後でコードで使用したいと考えています。

4

1 に答える 1

3

自動化のために、コマンド ラインから ELKI を呼び出すと非常にうまく機能します。この方法は、各実行が独自の JVM で適切に分離されるため、私の好みの方法です。

その後、出力ファイルからこのデータに簡単にアクセスできます。

古いバージョンの ELKIを使用しているのはなぜですか? 0.6.5 バージョンは、ジェネリックが削除されているため、はるかに優れています。私は今githubバージョンに切り替えましたが。

オブジェクトに直接アクセスする場合は、子の結果ClusterOrderとしてクラスタリング オブジェクトにアタッチされます。を使用して取得できるはずです

ClusterOrder clusterOrder = ResultUtil.filterResults(clustering, ClusterOrder.class).get(0);

およびそのオブジェクト ID:

ArrayDBIDs ids = DBIDUtil.ensureArray(clusterOrder.getDBIDs());

(これensureArrayはオーバーヘッドですが、とにかくそれはヌープです-それはキャストまたは変換操作であり、ここではキャストになります;少なくとも私のELKIバージョンでは、IDは常にArrayDBIDとして保存されます)

配列反復子 ( DBIDArrayIter it = ids.iter()) は、 を介して位置に移動できますseek(offset)。したがって、次のようなものを使用できるはずです

DBIDArrayIter it = ids.iter();
NumberVector vec = relation.get(it.seek(model.getStartIndex()));

ELKI の反復子は Java API には奇妙ですが、すべてのアクセスに対して単一の反復子を使用すると非常に高速です。

ELKI の質問の部分は以上です。ただし、統計的な観点からは、1 次元データに対して OPTICS を使用することは意味がありません。1 次元データでは、代わりに適切なカーネル密度推定を使用してください。OPTICS は、データが複雑すぎて適切な統計ツールを使用してモデル化できない場合に有効な大まかな方法​​です。OPTICS は非常に原始的なカーネル密度を使用し、xi メソッドは密度プロットからのクラスターの非常に単純な抽出です...少なくとも 1 次元データでは、統計はより強力なツールを提供します。ELKIには という実装がありますが、KNNKernelDensityMinimaClusteringまだ使っていません。しかし、カーネル密度推定はどの統計ツールキットでも利用できるはずなので、このクラスを試してみます。

于 2015-04-19T12:22:02.360 に答える