java - Elki GDBSCAN Java/Scala - 如何修改 CorePredicate
问题描述
elki 中的广义 dbscan (gdbscan) 是如何在 Java/Scala 中实现的?我目前正在尝试找到一种在 elki 上实现加权 dbscan 的有效方法,以抵消加权 dbscan 的 sklearn 实现带来的低效率。
我现在这样做的原因是因为 sklearn 很糟糕,无法在 TB 级数据集的集群上实现 dbscan(在云上,在这种情况下我就是这样)。
例如,我使用数据库创建函数和读取数组数组的 dbscan 函数编写了以下代码,并吐出集群索引的索引。
/* Libraries imported from the ELKI library - https://elki-project.github.io/releases/current/doc/overview-summary.html */
import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansElkan
import de.lmu.ifi.dbs.elki.data.model.{ClusterModel, DimensionModel, KMeansModel, Model}
import de.lmu.ifi.dbs.elki.data.model
import de.lmu.ifi.dbs.elki.data.{Clustering, DoubleVector, NumberVector}
import de.lmu.ifi.dbs.elki.database.{Database, StaticArrayDatabase}
import de.lmu.ifi.dbs.elki.datasource.ArrayAdapterDatabaseConnection
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction
import de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction
import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN
// Imports for generalized DBSCAN
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan // Generalized dbscan function here required for weighted dbscan
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate // THIS IS IMPORTANT TO GET GENERALIZED DBSCAN
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN
import de.lmu.ifi.dbs.elki.utilities.ELKIBuilder
import de.lmu.ifi.dbs.elki.database.relation.Relation
import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter
import de.lmu.ifi.dbs.elki.index.tree.metrical.covertree.SimplifiedCoverTree
import de.lmu.ifi.dbs.elki.data.{`type`=>TYPE} // Need to import in this way as 'type' is a class method in Scala
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeFactory // Important
def createDatabaseWeighted(data: Array[Array[Double]], distanceFunction: NumberVectorDistanceFunction[NumberVector]): Database = {
val indexFactory = new SimplifiedCoverTree.Factory[NumberVector](distanceFunction, 0, 30)
// Create a database
val db = new StaticArrayDatabase(new ArrayAdapterDatabaseConnection(data), java.util.Arrays.asList(indexFactory))
// Load the data into the database
val CustomPredicate = CorePredicate
db
}
def dbscanClusteringOriginalTest(data: Array[Array[Double]], distanceFunction: NumberVectorDistanceFunction[NumberVector] = SquaredEuclideanDistanceFunction.STATIC, epsilon: Double = 10, minpts: Int = 10) = {
// Use the same `distanceFunction` for the database and DBSCAN <- is it required??
val db = createDatabaseWeighted(data, distanceFunction)
val rel = db.getRelation(TYPE.TypeUtil.NUMBER_VECTOR_FIELD) // Create the required relational database
val dbscan = new DBSCAN[DoubleVector](distanceFunction, epsilon, minpts) // Epsilon and minpoints needed - either you define in the function input, or will use default values
val result: Clustering[Model] = dbscan.run(db)
var ClusterCounter = 0 // Indexing the number of datapoints allocated from DBSCAN
result.getAllClusters.asScala.zipWithIndex.foreach { case (cluster, idx) =>
println("The type is " + cluster.getNameAutomatic)
/* Isolate only the clusters and store the median from the DBSCAN results */
if (cluster.getNameAutomatic == "Cluster" || cluster.getNameAutomatic == "Noise") {
ClusterCounter += 1
val ArrayMedian = Array[Double]()
println(s"# $idx: ${cluster.getNameAutomatic}")
println(s"Size: ${cluster.size()}")
println(s"Model: ${cluster.getModel}")
println(s"ids: ${cluster.getIDs.iter().toString}")
}
}
}
我可以让它非常有效地运行,但我目前正在努力研究如何使用 gdbscan 函数获得类似的效果。例如,有一个答案表明这可以通过修改 ELKI 上的 CorePredicate (DBSCAN 的 ELKI 实现中的 sample_weight 选项)来完成,但我不确定如何实现。
任何指针将不胜感激!
解决方案
实现您自己的 GDBSCAN 核心谓词。
与其在标准实现中计算邻居,不如添加它们的权重。
然后你就有了加权 DBSCAN。
推荐阅读
- visual-studio - 在 Visual Studio 2019 中找不到 nuget 安装的模板
- java - 为什么我的 FTP 列表返回错误回复代码 425
- java - ExecutorService 线程在 RxJava 代码中未按预期工作
- android - RemoteServiceException 在 MIUI 11 上使我的应用程序崩溃
- docker - 为什么会出错:“docker build”需要 1 个参数
- c++ - 为什么地图的大小在比较时会发生变化?
- python - 遵循某些步骤后更改值的布尔值
- oracle - 如何加密 FireDAC 连接以在 Delphi 中使用 TLS/SSL?
- c++ - 如何解决在 n 个数中查找最大数时的运行时错误
- wso2 - 如何配置 wso2 api manager 发布者以加载自定义 local.json 以更改语言