在ELKI中运行聚类算法

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

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

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

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

我们非常感谢文献贡献! ( 更新:我现在把这篇文章变成了一个新的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 vectors = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD); Relation labels = db.getRelation(TypeUtil.LABELLIST); 

如果要编程更通用,请使用NumberVector

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

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

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

  2. 内存使用:数据挖掘非常耗费内存。 如果使用MiniGUI或命令行,则在任务完成时可以进行良好的清理 。 如果你从Java调用它,那么你在某个地方保留一些引用的变化真的很高 ,最终会泄漏大量的内存。 因此, 如果没有确保在完成后正确清理对象,请不要使用上面的模式

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

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

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

  3. 出于好的理由, ELKI 并非设计为可嵌入库 。 ELKI有很多选项和function,这在运行时(虽然它可以轻松地胜过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> clusterresults = ResultUtil.getClusteringResults(result); 
  4. 要标识对象,请使用标签和LabelList关系。 默认解析器在看到数字属性的文本时会执行此操作,即文件如

     1.0 2.0 3.0 ObjectLabel1 

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

更新:请参阅本文中创建的ELKI教程以获取更新。

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/