返回

ELKI RepresentativeUncertainClustering算法问题排查与解决

java

ELKI 中 RepresentativeUncertainClustering 算法使用问题及排查

最近刚接触 ELKI,想跑一下RepresentativeUncertainClustering这个算法,结果遇到了一些问题, 卡了好久, 记录下我的踩坑经历,顺便给出解决方法。

一、 问题

我主要是想用 ELKI 的 RepresentativeUncertainClustering 跑一个 demo。改了meta.ExternalClusteringpwc.clustering 这些参数,但还是不行。

1.1 第一个报错

一开始,我尝试执行下面的命令:

KDDCLIApplication -dbc.in "E:\\User\\Downloads\\IRIS1.csv" -algorithm clustering.uncertain.RepresentativeUncertainClustering -kmeans.k 3 -parallel.clusteroutline.straight

结果,蹦出来一个错误:

Task is not completely configured:

Parameter 'pwc.metaclustering' The meta clustering algorithm (as configured) does not accept clustering results.
Read: kmedoids.PAM
Expected: Algorithm used to aggregate clustering results. Must be a distance-based clustering algorithm.
The parameter pwc.clustering is required.

我寻思着,kmedoids.PAM 不就是个基于距离的聚类算法吗?这咋回事?

1.2 第二个报错

然后,我修改了命令:

KDDCLIApplication -dbc.in "E:\\User\\Downloads\\iris (1).csv" -dbc.filter typeconversions.UncertainifyFilter -uofilter.generator SimpleGaussianUncertainifier -uo.uncertainty.max3sigma 1.0 -algorithm clustering.uncertain.RepresentativeUncertainClustering -pwc.metaclustering meta.ExternalClustering -externalcluster.file "E:\\User\\Downloads\\IRIS11.xlsx" -pwc.clustering kmeans.SortMeans -kmeans.k 3

这次 ELKI 倒是让命令跑起来了,但是任务失败了,报了另一个错:

Task failed
java.lang.NullPointerException: Cannot invoke "elki.clustering.ClusteringAlgorithm.autorun(elki.database.Database)" because "this.samplesAlgorithm" is null
    at elki.clustering.uncertain.RepresentativeUncertainClustering.runClusteringAlgorithm(RepresentativeUncertainClustering.java:301)
    at elki.clustering.uncertain.RepresentativeUncertainClustering.run(RepresentativeUncertainClustering.java:187)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at elki.Algorithm$Utils.autorun(Algorithm.java:126)
    at elki.clustering.ClusteringAlgorithm.autorun(ClusteringAlgorithm.java:51)
    at elki.clustering.ClusteringAlgorithm.autorun(ClusteringAlgorithm.java:47)
    at elki.workflow.AlgorithmStep.runAlgorithms(AlgorithmStep.java:97)
    at elki.KDDTask.run(KDDTask.java:103)
    at elki.application.KDDCLIApplication.run(KDDCLIApplication.java:58)
    at [...]

看起来是 this.samplesAlgorithm 是空的,但我搞不清楚是哪里出了问题。

二、 问题原因分析及解决方案

下面,针对上面这两个问题, 分别说下我的解决过程和理解。

2.1 第一个报错的原因及解决方案:-pwc.clustering 参数缺失

原因分析:

仔细看第一个报错信息,除了提示 kmedoids.PAM 不符合预期外,最后一句 "The parameter pwc.clustering is required." 才是关键。RepresentativeUncertainClustering 需要两个主要的聚类算法:

  1. pwc.clustering: 用于对每个不确定对象生成 multiple samples(多个样本)的聚类算法。 这些样本随后会被用来代表原始的不确定对象。
  2. pwc.metaclustering: 用于对上一步产生的 samples 集合进行聚类的算法。

报错信息很明显:我们没有指定 pwc.clustering 参数。 ELKI 不知道用哪个算法来生成样本,自然就报错了。 虽然错误信息里提到了 kmedoids.PAM,但这其实是指 ELKI 尝试读取或使用了某个默认值 (可能是之前配置残留的),而这个默认值不适用于 pwc.metaclustering 的参数要求, 但根本问题不是这个,而是我们少了 -pwc.clustering 参数!

解决方案:

我们需要在命令行中明确指定 pwc.clustering 参数。常用的算法,比如 kmeans.KMeansSortMeansUmbrella (它包含了多种 KMeans 变体) 可以用来生成样本。

修改后的命令示例:

KDDCLIApplication -dbc.in "E:\\User\\Downloads\\IRIS1.csv" -algorithm clustering.uncertain.RepresentativeUncertainClustering -pwc.clustering kmeans.KMeansSortMeansUmbrella -kmeans.k 3 -parallel.clusteroutline.straight

解释

  • -pwc.clustering kmeans.KMeansSortMeansUmbrella: 指定使用 KMeansSortMeansUmbrella 作为生成样本的聚类算法。
  • -kmeans.k 3: 指定 KMeans 算法的 k 值。 这会同时作用于pwc.clustering指定的KMeans和可能指定的pwc.metaclustering中的KMeans算法(如果也用了KMeans)。

2.2 第二个报错的原因及解决方案:-pwc.clustering-pwc.metaclustering 参数设置问题

原因分析:

第二个错误是一个空指针异常,this.samplesAlgorithm 为 null。 这通常意味着 RepresentativeUncertainClustering 算法没有正确地初始化用于生成样本的聚类算法 (pwc.clustering)。

再看我们的第二个命令:

KDDCLIApplication -dbc.in "E:\\User\\Downloads\\iris (1).csv" -dbc.filter typeconversions.UncertainifyFilter -uofilter.generator SimpleGaussianUncertainifier -uo.uncertainty.max3sigma 1.0 -algorithm clustering.uncertain.RepresentativeUncertainClustering -pwc.metaclustering meta.ExternalClustering -externalcluster.file "E:\\User\\Downloads\\IRIS11.xlsx" -pwc.clustering kmeans.SortMeans -kmeans.k 3

问题出在 -pwc.metaclustering meta.ExternalClustering 这里。meta.ExternalClustering 并不是一个真正的聚类算法,它只是一个“外部”聚类结果的读取器。 我们用它来告诉 ELKI 从一个文件 (-externalcluster.file) 里读取预先计算好的聚类结果。 RepresentativeUncertainClustering 中的 pwc.metaclustering 需要的是一个能实际执行聚类操作的算法,而不是一个读取器!

解决方案:

我们需要为 -pwc.metaclustering 指定一个真正的聚类算法,例如 kmeans.KMeansSortMeansUmbrella (与-pwc.clustering使用相同或不同的算法都可以, 取决于实际需求). 另外,kmeans.SortMeans 属于旧版本写法, ELKI 新版本建议使用kmeans.KMeansSortMeansUmbrella

修改后的命令示例:

KDDCLIApplication -dbc.in "E:\\User\\Downloads\\iris (1).csv" -dbc.filter typeconversions.UncertainifyFilter -uofilter.generator SimpleGaussianUncertainifier -uo.uncertainty.max3sigma 1.0 -algorithm clustering.uncertain.RepresentativeUncertainClustering -pwc.clustering kmeans.KMeansSortMeansUmbrella  -pwc.metaclustering kmeans.KMeansSortMeansUmbrella -kmeans.k 3

解释

  • -dbc.filter typeconversions.UncertainifyFilter -uofilter.generator SimpleGaussianUncertainifier -uo.uncertainty.max3sigma 1.0: 这部分配置用于将确定性数据转换为不确定性数据。SimpleGaussianUncertainifier 使用高斯分布来模拟不确定性。-uo.uncertainty.max3sigma 1.0控制了高斯分布的标准差,影响生成的不确定性范围。
  • -pwc.clustering kmeans.KMeansSortMeansUmbrella: 对每个不确定对象进行采样聚类。
  • -pwc.metaclustering kmeans.KMeansSortMeansUmbrella: 对-pwc.clustering产生的样本集合, 进行"元聚类"。
  • -kmeans.k 3: 再次强调,它会影响到上面两个 KMeans 算法的 k 值。

进阶技巧和安全建议

  1. 算法选择: KMeansSortMeansUmbrella 包含了多种 KMeans 的优化变体, ELKI 会自动选择合适的。 如果你有特定的算法需求,可以明确指定,例如 kmeans.KMeans.
  2. 参数调整: -kmeans.k 的值 (簇的数量) 需要根据你的数据和业务需求来确定。 可以尝试不同的 k 值,然后评估聚类结果。 对于不确定性数据, -uo.uncertainty.max3sigma 参数也很重要, 它决定了生成样本的分散程度, 需要仔细调整。
  3. 数据预处理: 在使用聚类算法前, 强烈建议对数据进行标准化或归一化, 保证不同特征的尺度一致, 避免某些特征对距离计算产生过大影响。ELKI 也提供了多种数据预处理的 filter 可以使用。
  4. 内存问题: 如果数据集非常大, 或者生成的不确定样本数量很多 (由 -uo.uncertainty.max3sigma 等参数控制),可能会导致内存溢出。 这时,可能需要考虑减少样本数量,或者使用更节省内存的算法。另外,可以通过调整 Java 虚拟机的内存设置(-Xmx 等参数)来增加 ELKI 可用的内存。
  5. 多次运行: 因为 KMeans 算法对初始中心点的选择比较敏感, 建议对相同的参数设置多次运行, 然后评估结果的稳定性。
  6. 认真看文档: ELKI 的文档相对比较完善 (虽然有时也不太好找), 遇到问题, 先仔细查阅文档是个好习惯, 可以解决很多疑惑. 特别是算法的参数说明部分, 要仔细阅读, 理解每个参数的含义和作用.
  7. 合理使用uncertainty数据 : 由于是对原始数据增加了UncertainifyFilter, 应该针对具体业务含义确定是否应使用。

通过上面的分析和修改,这两个问题就都解决了. RepresentativeUncertainClustering 算法也能正常跑起来了。 关键是要理解这个算法需要两个聚类算法分别做什么, 然后正确配置相应的参数.