machine-learning - 获取 ELKI OPTICSXi 的簇边界

标签 machine-learning cluster-analysis data-mining elki optics-algorithm

我有一个一维数据集,其直方图显示多个局部最大值,因此我知道我的一维空间中有多个区域的数据更密集。我想确定这些密集区域的边界,以便我对某个数据点所在的密集区域/簇进行分类。为此,我使用 OPTICS,因为它应该能够更好地处理相比簇之间的不同密度到 DBSCAN。

我在 Java 代码中使用 ELKI(版本 0.6.0)(我知道 ELKI 团队不建议在 Java 中嵌入 ELKI,但我需要对许多数据集重复我的工作流程,因此最好在我的情况)。下面的代码片段打印簇的开始项和结束项的索引。 ELKI documentation on OPTICSModel没有明确定义这些索引号对应的内容,但我假设这些是数据库的增强集群排序中开始和结束数据项的索引(如 OPTICS.run() 创建的 ClusterOrderResult 对象),如与数据库本身的开始和结束数据项的索引相反(无序)。

ListParameterization opticsParams = new ListParameterization();
opticsParams.addParameter(OPTICSXi.XI_ID, 0.01);
opticsParams.addParameter(OPTICS.MINPTS_ID, 100);
OPTICSXi<DoubleDistance> optics = ClassGenericsUtil.parameterizeOrAbort(OPTICSXi.class, opticsParams);

ArrayAdapterDatabaseConnection arrayAdapterDatabaseConnection = new ArrayAdapterDatabaseConnection(myListOfOneDimensionalFeatureVectors.toArray(new double[myListOfOneDimensionalFeatureVectors.size()][2]));
ListParameterization dbParams = new ListParameterization();
dbParams.addParameter(AbstractDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
dbParams.addParameter(RStarTreeFactory.Parameterizer.BULK_SPLIT_ID, SortTileRecursiveBulkSplit.class);
dbParams.addParameter(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, arrayAdapterDatabaseConnection);

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

result = optics.run(db);
List<Cluster<OPTICSModel>> clusters = result.getAllClusters();
    for(Cluster<OPTICSModel> cluster : clusters){
        if(!cluster.isNoise())
            System.out.println(cluster.getModel().getStartIndex() + ", "+ cluster.getModel().getEndIndex() +";  ");
    }

现在我想知道我的簇在我的一维空间中开始和结束的位置。因此,我想检索与上面的代码已经获得的开始和结束索引相对应的数据项。我假设我需要一个 ClusterOrderResult 对象,然后我可以从中检索获得的索引。然而,在文档中,似乎不可能从我通过调用 optics.run() 获得的聚类结果对象中检索这样的东西。由于似乎无法获取此有序数据库,因此我天真地尝试从原始输入数据集中获取索引,而不是将上面代码中的 println 替换为下面的 println:

System.out.println(myListOfOneDimensionalFeatureVectors.get(cluster.getModel().getStartIndex())[0] + ", "+ myListOfOneDimensionalFeatureVectors.get(cluster.getModel().getEndIndex())[0] +";  ";
然而,正如我所预料的那样,索引似乎不属于原始输入文件,因为这会定期打印一维空间中值低于结束边界的结束边界。有谁知道有什么方法可以获取与 OPTICS 聚类找到的起始索引和结束索引相对应的原始一维数据值吗?我想稍后在我的代码中使用这些值。

最佳答案

出于自动化的目的,从命令行调用 ELKI 确实效果很好。这是我更喜欢的方式,因为这样每次运行都可以很好地隔离在它自己的 JVM 中。

然后您就可以轻松地从输出文件访问这些数据。

您为什么使用版本的 ELKI?由于删除了泛型,0.6.5 版本要好得多。虽然我现在已经切换到github版本了。

如果您想要直接访问 ClusterOrder 对象,它会作为子结果附加到聚类对象。您应该能够使用它来获取它

ClusterOrder clusterOrder = ResultUtil.filterResults(clustering, ClusterOrder.class).get(0);

及其对象 ID 通过:

ArrayDBIDs ids = DBIDUtil.ensureArray(clusterOrder.getDBIDs());

(ensureArray 是开销,但无论如何它都是一个 noop - 这是一个转换或转换操作,这里它将是一个转换;至少在我的 ELKI 版本中,id 总是存储为 ArrayDBID)

数组迭代器 (DBIDArrayIter it = ids.iter()) 可以通过 seek(offset) 移动到某个位置。所以你应该能够使用类似的东西

DBIDArrayIter it = ids.iter();
NumberVector vec = relation.get(it.seek(model.getStartIndex()));

ELKI 中的迭代器对于 Java API 来说很奇怪,但如果您对所有访问使用单个迭代器,速度会非常快。

您的 ELKI 问题部分就到此为止。然而,从统计的角度来看在一维数据上使用OPTICS没有意义。对于一维数据,请使用适当的核密度估计。 OPTICS 是一种粗略的方法,当您的数据过于复杂而无法使用适当的统计工具进行建模时,该方法就有意义。 OPTICS 使用非常原始的核密度,xi 方法是从密度图中非常简单地提取簇......至少在一维数据上,统计学提供了更强大的工具。 ELKI 有一个名为 KNNKernelDensityMinimaClustering 的实现,但我还没有使用它。但是核密度估计应该在任何统计工具包中都可用,所以我会尝试一下这个类。

关于machine-learning - 获取 ELKI OPTICSXi 的簇边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29718307/

相关文章:

python - 使用 scikit 对文本进行分类

r - 如何将实验性聚类算法与预期结果进行比较

r - 有人在 R 中实现 Eureqa 的接口(interface)吗?

machine-learning - 访问经过训练的自动编码器的降维

python - tensorflow : DLL load failed: A dynamic link library (DLL) initialization routine failed

go - 如何使用go保存聚类模型?

algorithm - 生成像城市一样分布的随机点?

machine-learning - 在查找 k 簇方面比 Elbow 更有用的另一个函数

c# - Apache Mahout .net 模拟的机器学习库