我使用Elki0.7.2(主)来运行DBSCAN,并在一个大数据集中使用R*树。之后,我需要持久化地存储树,以便在评估新的数据点是否为噪声时,它可以重新加载到内存中。为此,我尝试了PersistentPageFileFactory并得到了以下错误
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时,我得到另一个错误,如下所示
java.lang.RuntimeException: IOException occurred during reading of page 0
at de.lmu.ifi.dbs.elki.persistent.OnDiskArrayPageFile.readPage(OnDiskArrayPageFile.java:113)是否有方法将索引(例如R* tree )存储到文件中并从文件中加载?
事先非常感谢!
发布于 2018-03-14 09:51:33
磁盘反序列化代码已被使用多年,因此很可能会中断。
我甚至不确定它是否完全支持从磁盘独立读取索引;我假设它只是为了基准测试目的而模拟磁盘上的索引(也就是说,它将从磁盘读取和写入数据,但可能无法读取现有的索引)。
这并不是我所需要的功能,所以除了重构之外,我从未在这段代码上工作过。实际上,我一直试图慢慢删除这些代码(特别是ExternalizablePage),因为我没有印象它是可用的。
我有一个重写版本的R-树某处,更适合实际的磁盘上使用。但是它还没有完成,它还不支持R*树的重新插入。因此,代码还没有发布(不幸的是,可能永远也不会完成)。
因此,您可能需要重写该代码的大部分以使其可用。
如果你这样做了,请分享你的修改在Github上。
发布于 2018-10-09 14:00:24
我也想问同样的问题。我的案子是一样的。如果数据集为10k或100 K,则不需要存储群集,但如果要为1M数据集或更多数据集获取群集,则需要超过1个小时。我几乎没有找到如何将模型存储在磁盘上的解决办法。要检测异常值,您必须从数据集中获取KnnQuery,那里没有噪音。它比集群计数花费的时间更短( 1M数据集的时间为1-3分钟)。因此,您可以对集群进行计数,只存储属于集群的元素并使用它。
首先,像这里描述的那样计算集群。api处理结果(只保留没有噪音的点):
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
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!");
}它工作得很好,但我发现在某些数据集群上,恢复需要太长时间。这就是集群存储实现仍然需要的原因。
https://stackoverflow.com/questions/49255547
复制相似问题