首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ELKI中存储索引?

如何在ELKI中存储索引?
EN

Stack Overflow用户
提问于 2018-03-13 11:55:36
回答 2查看 107关注 0票数 1

我使用Elki0.7.2(主)来运行DBSCAN,并在一个大数据集中使用R*树。之后,我需要持久化地存储树,以便在评估新的数据点是否为噪声时,它可以重新加载到内存中。为此,我尝试了PersistentPageFileFactory并得到了以下错误

代码语言:javascript
复制
java.lang.ClassCastException: de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode cannot be cast to de.lmu.ifi.dbs.elki.persistent.ExternalizablePage

尽管我只是简单地修改了RStarTreeNode以实现接口ExternalizablePage,但这并没有帮助。当我使用OnDiskArrayPageFileFactory时,我得到另一个错误,如下所示

代码语言:javascript
复制
java.lang.RuntimeException: IOException occurred during reading of page 0
at de.lmu.ifi.dbs.elki.persistent.OnDiskArrayPageFile.readPage(OnDiskArrayPageFile.java:113)

是否有方法将索引(例如R* tree )存储到文件中并从文件中加载?

事先非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-14 09:51:33

磁盘反序列化代码已被使用多年,因此很可能会中断。

我甚至不确定它是否完全支持从磁盘独立读取索引;我假设它只是为了基准测试目的而模拟磁盘上的索引(也就是说,它将从磁盘读取和写入数据,但可能无法读取现有的索引)。

这并不是我所需要的功能,所以除了重构之外,我从未在这段代码上工作过。实际上,我一直试图慢慢删除这些代码(特别是ExternalizablePage),因为我没有印象它是可用的。

我有一个重写版本的R-树某处,更适合实际的磁盘上使用。但是它还没有完成,它还不支持R*树的重新插入。因此,代码还没有发布(不幸的是,可能永远也不会完成)。

因此,您可能需要重写该代码的大部分以使其可用。

如果你这样做了,请分享你的修改在Github上。

票数 0
EN

Stack Overflow用户

发布于 2018-10-09 14:00:24

我也想问同样的问题。我的案子是一样的。如果数据集为10k或100 K,则不需要存储群集,但如果要为1M数据集或更多数据集获取群集,则需要超过1个小时。我几乎没有找到如何将模型存储在磁盘上的解决办法。要检测异常值,您必须从数据集中获取KnnQuery,那里没有噪音。它比集群计数花费的时间更短( 1M数据集的时间为1-3分钟)。因此,您可以对集群进行计数,只存储属于集群的元素并使用它。

首先,像这里描述的那样计算集群。api处理结果(只保留没有噪音的点):

代码语言:javascript
复制
    List<String> clusterPoints = new ArrayList<>(); // List which will be stored in file

    for (Cluster<Model> cluster : clusters.getAllClusters()) {
        if (!cluster.isNoise()) { // write to output only not noises

            for (DBIDIter iterator = cluster.getIDs().iter(); iterator.valid(); iterator.advance()) {
                NumberVector vector = relation.get(iterator);

                for (int i = 0; i < vector.toArray().length; i++) {
                    clusterPoints.add(String.valueOf(vector.toArray()[i]));
                }
            }
        }
    }

将此clusterPoints保存在文件中。要恢复集群,从文件中获取点的关系,如所描述的api#creating-a-database

代码语言:javascript
复制
    double[] pointToDetect = YOUR_POINT_TO_DETECT_OUTLIER;
    // get db as described here: https://elki-project.github.io/howto/java_api#creating-a-database
    Relation<NumberVector> relation = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
    NumberVector vector = DoubleVector.FACTORY.newNumberVector(pointToDetect);

    KNNQuery<NumberVector> knnQuery = QueryUtil.getKNNQuery(relation, EuclideanDistanceFunction.STATIC); // or any other DistanceFunction
    KNNList list = model.getKnnQuery().getKNNForObject(vector, NEAREST_NEIGHBORS_NUMBER);

    DoubleDBIDPair pairNearest = list.get(0);
    double distanceNearest = pairNearest.doubleValue();
    if (distanceNearest > EPSILON) {
        log.warn("Outlier detected!");
    }

它工作得很好,但我发现在某些数据集群上,恢复需要太长时间。这就是集群存储实现仍然需要的原因。

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

https://stackoverflow.com/questions/49255547

复制
相关文章

相似问题

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