我正在尝试对一些地理空间数据进行聚类,我之前尝试过WEKA库。我找到了这个基准,并决定尝试ELKI。
尽管有人建议不要将 ELKI 用作 Java 库(假设它的维护比 UI 少),但我还是将它合并到了我的应用程序中,我可以说我对结果感到非常满意。它用于存储数据的结构比 Weka 使用的结构要高效得多,而且它可以选择使用空间索引这一事实无疑是一个加分项。
但是,当我将Weka 的 DBSCAN的结果与ELKI 的 DBSCAN的结果进行比较时,我有点困惑。我会接受不同的实现可以产生稍微不同的结果,但是这些差异让我认为算法有问题(可能是我的代码)。两种算法中簇的数量及其几何形状非常不同。
作为记录,我使用的是最新版本的 ELKI (0.6.0),我用于模拟的参数是:
minpts=50 ε=0.008
我编写了两个 DBSCAN 函数(用于 Weka 和 ELKI),其中“入口点”是带有点的 csv,它们的“输出”也是相同的:一个计算一组点的凹壳的函数(每个集群一个)。由于将 csv 文件读入 ELKI“数据库”的功能相对简单,我认为我的问题可能是:
a) 在算法的参数化中;b) 阅读结果(很可能)。
参数化 DBSCAN 不会带来任何挑战,我使用了我之前通过 UI 测试过的两个强制参数:
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 集群是否“嵌套”,即:我们可以同时拥有属于多个集群的点吗?为什么?
- 我在某处读到我们不应该使用数据库 ID 来识别点,因为它们是供 ELKI 内部使用的,但是还有什么其他方法可以获取每个集群中的点列表?我读到您可以对标签使用关系,但我不确定如何实际实现它......
任何可以为我指明正确方向的评论,或任何迭代 ELKI DBSCAN 结果集的代码建议都将受到欢迎!我还在我的代码中使用了 ELKI 的 OPTICSxi,我对这些结果还有更多疑问,但我想我会将其保存到另一篇文章中。