首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Mongodb中使用ELKI

在Mongodb中使用ELKI
EN

Stack Overflow用户
提问于 2015-10-28 21:12:58
回答 1查看 255关注 0票数 0

通过使用测试用例,我能够看到如何从Java语言中直接使用ELKI,但是现在我想从MongoDB中读取我的数据,然后使用ELKI来集群地理(经度、经度)数据。

我只能使用ELKI对CSV文件中的数据进行集群。是否可以使用MongoDB连接de.lmu.ifi.dbs.elki.database.Database?我可以从java调试器中看到,在de.lmu.ifi.dbs.elki.database.Database中有一个数据库连接字段。

我查询MongoDB,为每一行创建POJO,现在我想使用ELKI对这些对象进行集群。

可以从MongoDB读取数据并将其写入CSV文件,然后使用ELKI读取CSV文件,但我想知道是否有更简单的解决方案。

-调查结果_1:

ELKI - Use List of objects to populate the Database中,我发现我需要实现de.lmu.ifi.dbs.elki.datasource.DatabaseConnection,特别是覆盖loadData()方法,该方法返回MultiObjectsBundle的一个实例。

所以我想我应该用MultiObjectsBundle包装一个POJO列表。现在我看一下MultiObjectsBundle,看起来数据应该保存在列中。为什么列的数据类型是List>,不应该是List吗?只是一个你想要集群的项目列表?

我有点困惑。ELKI如何知道它应该关注POJO的长期和后期?我该在哪里告诉ELKI做这件事?使用de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation?

-调查结果_2:

我尝试过使用ArrayAdapterDatabaseConnection,也尝试过实现DatabaseConnection。对不起,我需要用非常简单的术语让我理解。

这是我的集群代码:

代码语言:javascript
复制
    int minPts=3;
    double eps=0.08; 
    double[][] data1 = {{-0.197574246, 51.49960695}, {-0.084605692, 51.52128377}, {-0.120973687, 51.53005939}, {-0.156876, 51.49313}, 
            {-0.144228881, 51.51811784}, {-0.1680743, 51.53430039}, {-0.170134484,51.52834133}, { -0.096440751, 51.5073853}, 
            {-0.092754157, 51.50597426}, {-0.122502346, 51.52395143}, {-0.136039674, 51.51991453}, {-0.123616824, 51.52994371}, 
            {-0.127854211, 51.51772703}, {-0.125979294, 51.52635795}, {-0.109006325, 51.5216612}, {-0.12221963, 51.51477076}, {-0.131161087, 51.52505093} };


    //      ArrayAdapterDatabaseConnection dbcon = new ArrayAdapterDatabaseConnection(data1);
    DatabaseConnection dbcon = new MyDBConnection();

    ListParameterization params = new ListParameterization();
    params.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.MINPTS_ID, minPts);
    params.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.EPSILON_ID, eps);
    params.addParameter(DBSCAN.DISTANCE_FUNCTION_ID, EuclideanDistanceFunction.class);
    params.addParameter(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, dbcon);
    params.addParameter(AbstractDatabase.Parameterizer.INDEX_ID,
            RStarTreeFactory.class);
    params.addParameter(RStarTreeFactory.Parameterizer.BULK_SPLIT_ID, 
            SortTileRecursiveBulkSplit.class);
    params.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 1000);

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

    GeneralizedDBSCAN dbscan = ClassGenericsUtil.parameterizeOrAbort(GeneralizedDBSCAN.class, params);

    Relation<DoubleVector> rel = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
    Relation<ExternalID> relID = db.getRelation(TypeUtil.EXTERNALID);

    DBIDRange ids = (DBIDRange) rel.getDBIDs();
    Clustering<Model> result = dbscan.run(db);  

    int i =0;
    for(Cluster<Model> clu : result.getAllClusters()) {
        System.out.println("#" + i + ": " + clu.getNameAutomatic());
        System.out.println("Size: " + clu.size());

        System.out.print("Objects: ");
        for(DBIDIter it = clu.getIDs().iter(); it.valid(); it.advance()) {
           DoubleVector v = rel.get(it);
           ExternalID exID = relID.get(it);
           System.out.print("DoubleVec: ["+v+"]");
           System.out.print("ExID: ["+exID+"]");

           final int offset = ids.getOffset(it);
           System.out.print(" " + offset);
        }
        System.out.println();
        ++i;
    } 

ArrayAdapterDatabaseConnection生成两个集群,当我设置epsilon=0.008数据库扫描开始创建集群时,我只需要处理epsilon的值。当我设置epsilon=0.04时,所有的项目都在一个集群中。

我还尝试实现了DatabaseConnection:

代码语言:javascript
复制
@Override
public MultipleObjectsBundle loadData() { 
    MultipleObjectsBundle bundle = new MultipleObjectsBundle(); 

    List<Station> stations = getStations();
    List<DoubleVector> vecs = new ArrayList<DoubleVector>();
    List<ExternalID> ids = new ArrayList<ExternalID>();

    for (Station s : stations){

        String strID = Integer.toString(s.getId());
        ExternalID i = new ExternalID(strID);
        ids.add(i);     

        double[] st = {s.getLongitude(), s.getLatitude()};
        DoubleVector dv = new DoubleVector(st); 
        vecs.add(dv);
    } 

    SimpleTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<>(DoubleVector.FACTORY, 2, 2, DoubleVector.FACTORY.getDefaultSerializer());

    bundle.appendColumn(type, vecs);      
    bundle.appendColumn(TypeUtil.EXTERNALID, ids);
    return bundle;
} 

这些长/纬度与一个ID相关联,我需要将它们链接回此ID和值。使用ID偏移(在上面的代码中)是唯一的方法吗?我试图添加ExternalID列,但我不知道如何检索特定NumberVector的ExternalID?

此外,在看到Using ELKI's Distance Function之后,我尝试使用Elki的longLatDistance,但它不起作用,而且我找不到任何实现它的示例。

EN

回答 1

Stack Overflow用户

发布于 2015-10-29 20:37:55

数据源的接口称为DatabaseConnection

JavaDoc of DatabaseConnection

您可以实现一个基于MongoDB的接口来获取数据。

它不是复杂的接口,它只有一个方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33392006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档