如何使用ELKI的DBSCAN获取群集所包含的原始点?

时间:2018-01-16 04:27:54

标签: elki

我对以下代码有2个问题:

  1. 如何获得积分'在结果中的每个群集中?

  2. 结果如何包含3个群集,其中一个群集的大小为0?

    import de.lmu.ifi.dbs.elki.data.model.Model;
    import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
    import de.lmu.ifi.dbs.elki.datasource.ArrayAdapterDatabaseConnection;
    import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
    import de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction;
    import de.lmu.ifi.dbs.elki.math.geodesy.WGS84SpheroidEarthModel;
    import java.util.List;
    import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
    import de.lmu.ifi.dbs.elki.data.Cluster;
    import de.lmu.ifi.dbs.elki.data.Clustering;
    import de.lmu.ifi.dbs.elki.data.DoubleVector;
    
    /**
     *
     * @author Paul Z. Wu Jan 14, 2018
     */
    public class DBScan {
    public static void main(String args[]) {
        final double[][] data = new double[][]{{48.774332, -78.532054}, {40.774032, -73.531154},
        {40.774232, -73.531084}, {48.774332, -78.531054}};
        DatabaseConnection dbc = new ArrayAdapterDatabaseConnection(data);
        DBSCAN<DoubleVector> scan = new DBSCAN<>(new LatLngDistanceFunction(WGS84SpheroidEarthModel.STATIC), 2000, 1);
        StaticArrayDatabase db = new StaticArrayDatabase(dbc, null);
        db.initialize();
        Clustering<Model> c = scan.run(db);
    
    
        System.out.println(c.getAllClusters().isEmpty());
        List<Cluster<Model>> list = c.getAllClusters();
        for (Cluster<Model> cl : list) {
            System.out.println("size=" + cl.size());
            System.out.println("...." + cl.getIDs() + "..." + cl.getModel() + "  ");
            //How to get the original 'points' in this cluster? One of them should
            //contain {40.774032, -73.531154},{40.774232, -73.531084}
        }
    }
    

1 个答案:

答案 0 :(得分:1)

请参阅tutorial.javaapi.PassingDataToELKI line 73

Relation<NumberVector> rel = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);

并参见tutorial.javaapi.PassingDataToELKI lines 102-104

for(DBIDIter it = clu.getIDs().iter(); it.valid(); it.advance()) {
    // To get the vector use:
    NumberVector v = rel.get(it);
}

ELKI使用“整洁数据”架构。大多数算法都期望向量的数据库关系(思考:列或表)。实际上,与列存储没有什么不同,但在连续密集数据的压缩方面没有任何东西是gainen。通常具有固定的维度(=向量字段)。对于地理数据,您甚至可以将其指定为具有两个维度。

标签将存储在第二个关系/表/列中。

另请参阅GeoIndexing示例以将DBSCAN扩展为更大的数据集。我在2300万地理坐标上使用了OPTICS,但显然需要一段时间才能运行(不过几天)。我建议为大型数据集启用进度日志记录,甚至会尝试估计剩余时间。