web-dev-qa-db-ja.com

DBSCAN on spark:どの実装

SparkでDBSCANを実行したいと思います。私は現在2つの実装を見つけました:

私はそのgithubで与えられたsbt構成で最初のものをテストしましたが:

  • jar内の関数は、ドキュメントまたはgithubのソース内の関数と同じではありません。たとえば、jarファイルにtrain関数が見つかりません

  • fit関数(jarにあります)を使用してテストを実行できましたが、イプシロンの構成が不適切(少しから大きい)でコードが挿入されました無限ループ。

コード:

val model = DBSCAN.fit(eps, minPoints, values, parallelism)

誰かが最初のライブラリで何かをすることができましたか?

誰かが2番目のものをテストしましたか?

9
Benjamin

[〜#〜] elki [〜#〜] を試してください。これはJavaなので、Scalaから簡単に呼び出すことができます。

ELKIは非常によく最適化されており、インデックスを使用すると、非常に大きなデータセットに拡張できます。

これらのSpark実装の1つをベンチマーク調査に含めようとしましたが、メモリが不足しました(そして、メモリが不足した唯一の実装でした...のk-means = SparkとMahoutも最も遅い)の中にありました:

ハンス・ペーター・クリーゲル、エーリヒ・シューベルト、アーサー・ジメク。
ランタイム評価の(黒)技術:アルゴリズムまたは実装を比較していますか?
In:知識と情報システム(KAIS)。 2016、1〜38

Neukirchen教授は、このテクニカルレポートでDBSCANの並列実装のベンチマークを行いました。

Helmut Neukirchen
ビッグデータおよび高性能コンピューティングパラダイムのためのDBSCAN空間クラスタリング実装の調査およびパフォーマンス評価

どうやら彼はいくつかのSpark実装を機能させましたが、次のことに注意しました:

結果は壊滅的です:Apache Sparkの実装はHPC実装に近いところはありません。特に、より大きな(しかしまだかなり小さい)データセットでは、それらのほとんどは完全に失敗し、正しい結果さえ提供しません

以前:

クラスタで使用可能なすべてのコアを使用しながら「SparkDBSCAN」実装のいずれかを実行すると、メモリ不足の例外が発生しました。

(また、「Spark DBSCAN」は928コアで2406秒かかり、ELKIは小さいベンチマークの1コアで997秒かかりました-他のSpark実装もうまくいきませんでした、特にそれ正しい結果が返されませんでした...)

「DBSCANonSpark」はクラッシュしませんでしたが、完全に間違ったクラスターを返しました。

「DBSCANonSpark」はより速く終了しますが、完全に間違ったクラスタリング結果をもたらしました。 Sparkはすでにコア数が最大であるため、DBSCAN実装の実行時間が絶望的に​​長いため、コア数が少ない測定は実行しませんでした。

_double[][]_配列をELKIデータベースとしてラップできます。

_// Adapter to load data from an existing array.
DatabaseConnection dbc = new ArrayAdapterDatabaseConnection(data);
// Create a database (which may contain multiple relations!)
Database db = new StaticArrayDatabase(dbc, null);
// Load the data into the database (do NOT forget to initialize...)
db.initialize();

// Squared Euclidean is faster than Euclidean.
Clustering<Model> c = new DBSCAN<NumberVector>(
  SquaredEuclideanDistanceFunction.STATIC, eps*eps, minpts).run(db);

for(Cluster<KMeansModel> clu : c.getAllClusters()) {
  // Process clusters
}
_

参照: Java APIの例 (特に、DBIDを行インデックスにマップする方法)。パフォーマンスを向上させるには、インデックスファクトリ(new CoverTree.Factory(...)など)を2番目のパラメーターとしてStaticArrayDatabaseコンストラクターに渡します。

9
Erich Schubert

プロジェクトで2番目のライブラリ( https://github.com/alitouka/spark_dbscan )を正常に使用しました。実際、次のように使用することはできません。

libraryDependencies += "org.alitouka" % "spark_dbscan_2.10" % "0.0.4"

resolvers += "Aliaksei Litouka's repository" at "http://alitouka-public.s3-website-us-east-1.amazonaws.com/"

代わりに、コードをダウンロードしてspark 2.2.1バージョンに更新します。さらに、いくつかのライブラリを追加する必要があります。最後に、コードをプロジェクトに追加すると、機能します。

3
Yilan Zhang

私はテストしました https://github.com/irvingc/dbscan-on-spark そしてそれは多くのメモリを消費すると言うことができます。スムーズに分散された400Kデータセットの場合、-Xmx12084mを使用しましたが、この場合でも動作が長すぎます(> 20分)。また、2Dのみです。私はsbtではなくMavenでプロジェクトを使用しました。

2番目の実装もテストしました。これはまだ私が見つけた最高です。残念ながら、作成者は2015年以降サポートしていません。Sparkのバージョンを上げて、バージョンの競合を解決するのに本当に時間がかかりました。awsにデプロイする必要がありました。

1
Valeriy K.

DBSCANの実装を提供する smile の使用を検討することもできます。最も直接的な方法でgroupBymapGroupsまたはflatMapGroupsと組み合わせて使用​​する必要があり、そこでdbscanを実行します。次に例を示します。

  import smile.clustering._

  val dataset: Array[Array[Double]] = Array(
    Array(100, 100),
    Array(101, 100),
    Array(100, 101),
    Array(100, 100),
    Array(101, 100),
    Array(100, 101),

    Array(0, 0),
    Array(1, 0),
    Array(1, 2),
    Array(1, 1)
  )

  val dbscanResult = dbscan(dataset, minPts = 3, radius = 5)
  println(dbscanResult)

  // output
  DBSCAN clusters of 10 data points:
  0     6 (60.0%)
  1     4 (40.0%)
  Noise     0 ( 0.0%)

パフォーマンスを向上させる必要がある場合は、ユーザー定義集計関数(UDAF)を作成することもできます。

私はこのアプローチを使用して時系列データのクラスタリングを行っているため、Sparkのタイムウィンドウ関数を使用してグループ化し、各ウィンドウ内でDBSCANを実行できるようにすることで、実装を並列化できます。

私はこれを行うために次の 記事 に触発されました

0
Cal