在ELKI中运行聚类算法

时间:2013-03-10 19:26:50

标签: java cluster-analysis k-means elki

我需要通过编程方式使用ELKI来运行k-medoids聚类算法。我有一个相似矩阵,我想输入算法。

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

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

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

2 个答案:

答案 0 :(得分:4)

我们非常感谢文档贡献! (更新:我暂时将这篇文章改为new ELKI tutorial entry。)

出于多种原因,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 / Parameterization更稳定,因为处理默认值 - 参数化仅列出非默认参数,所以只有在这些改变时你才会注意到。

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

  2. 内存使用情况:数据挖掘占用大量内存。如果您使用MiniGUI或命令行,则在任务完成时您有一个很好的清理。如果您从Java调用它,那么非常高的更改会让您在某处保留一些引用,并最终泄漏 lot 内存。所以在没有确保完成后正确清理对象时不要使用上面的模式

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

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

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

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

  4. 使用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
      

      可以通过标签轻松识别对象!

    5. 更新:有关更新,请参阅ELKI tutorial created out of this post

答案 1 :(得分:2)

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/