4

我需要以编程方式使用 ELKI 来运行 k-medoids 聚类算法。我有一个相似度矩阵,希望输入到算法中。

是否有任何代码片段可用于如何运行 ELKI 算法?我基本上需要知道如何创建对象DatabaseRelation创建自定义距离函数以及读取算法输出。

不幸的是,ELKI 教程 ( http://elki.dbs.ifi.lmu.de/wiki/Tutorial ) 侧重于 GUI 版本和实现新算法,并且尝试通过查看 Javadoc 来编写代码令人沮丧。

如果有人知道任何易于使用的 k-medoids 库,那么这也可能是这个问题的一个很好的答案。

4

2 回答 2

5

我们非常感谢文档贡献!(更新:我现在已经把这篇文章变成了一个新的 ELKI 教程条目。)

出于多种原因,ELKI 确实主张不要将其嵌入到其他 Java 应用程序中。这就是我们推荐使用 MiniGUI(或它构建的命令行)的原因。添加自定义代码最好作为自定义代码ResultHandler或仅通过使用ResultWriter并解析生成的文本文件来完成。

如果您真的想将它嵌入到您的代码中(在许多情况下它很有用,特别是当您需要多个关系并希望相互评估不同的索引结构时),这里是获取DatabaseRelation

// Setup parameters:
ListParameterization params = new ListParameterization();
params.addParameter(FileBasedDatabaseConnection.INPUT_ID, filename);
// Add other parameters for the database here!

// Instantiate the database:
Database db = ClassGenericsUtil.parameterizeOrAbort(
    StaticArrayDatabase.class,
    params);
// Don't forget this, it will load the actual data...
db.initialize();

Relation<DoubleVector> vectors = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
Relation<LabelList> labels = db.getRelation(TypeUtil.LABELLIST);

如果您想进行更通用的编程,请使用NumberVector<?>.

为什么我们(目前)不建议将 ELKI 用作“库”:

  1. API 仍在发生很大变化。我们继续添加选项,我们(还)不能提供稳定的 API。命令行/MiniGUI/参数化更加稳定,因为默认值的处理——参数化只列出了非默认参数,所以只有当这些改变你会注意到。

    在上面的代码示例中,请注意我也使用了这种模式。对解析器、数据库等的更改可能不会影响这个程序!

  2. 内存使用:数据挖掘非常消耗内存。如果您使用 MiniGUI 或命令行,您可以在任务完成后进行很好的清理。如果您从 Java 调用它,更改会非常高,以至于您在某处保留了一些引用,最终导致大量内存泄漏。所以不要在没有确保完成后正确清理对象的情况下使用上述模式

    通过从命令行运行 ELKI,您可以免费获得两件事:

    1. 没有内存泄漏。任务完成后,进程退出并释放所有内存。

    2. 无需为相同的数据重新运行两次。后续分析不需要重新运行算法。

  3. ELKI没有被设计为可嵌入库是有充分理由的。ELKI 有大量的选项和功能,这是有代价的,无论是在运行时(尽管它可以轻松胜过 R 和 Weka,例如!)内存使用,尤其是在代码复杂性方面。ELKI 是为研究数据挖掘算法而设计的,而不是为了让它们易于包含在任意应用程序中。相反,如果您遇到特定问题,您应该使用 ELKI 找出哪种方法效果好,然后以针对您的问题优化的方式重新实现该方法

使用 ELKI 的最佳方法

以下是一些提示和技巧:

  1. 使用 MiniGUI 构建命令行。请注意,在“GUI”的日志记录窗口中,它显示了相应的命令行参数 - 从命令行运行 ELKI 很容易编写脚本,并且可以轻松地分发到多台计算机,例如通过 Grid Engine。

    #!/bin/bash
    for k in $( seq 3 39 ); do
        java -jar elki.jar KDDCLIApplication \
            -dbc.in whatever \
            -algorithm clustering.kmeans.KMedoidsEM \
            -kmeans.k $k \
            -resulthandler ResultWriter -out.gzip \
            -out output/k-$k 
    done
    
  2. 使用索引。对于许多算法,索引结构可以产生巨大的影响!(但是你需要做一些研究哪些索引可以用于哪些算法!)

  3. 考虑使用扩展点,例如ResultWriter. 挂接到此 API 可能是最简单的方法,然后用于ResultUtil选择要以自己喜欢的格式输出或分析的结果:

    List<Clustering<? extends Model>> clusterresults =
        ResultUtil.getClusteringResults(result);
    
  4. 要识别对象,请使用标签和LabelList关系。默认解析器会在它看到带有数字属性的文本时执行此操作,即文件,例如

    1.0 2.0 3.0 ObjectLabel1
    

    将通过其标签轻松识别对象!

更新:请参阅此帖子创建的 ELKI 教程以获取更新。

于 2013-03-11T09:19:56.620 回答
3

ELKI 的文档非常稀少(我不知道为什么它们在示例中没有包含一个简单的“hello world”程序)

你可以试试 Java-ML。它的文档对用户更加友好,并且确实具有 K-medoid。

Java-ML 的聚类示例 | http://java-ml.sourceforge.net/content/clustering-basics

K-medoid | http://java-ml.sourceforge.net/api/0.1.7/

于 2013-03-11T05:05:11.857 回答