ELKI RepresentativeUncertainClustering算法问题排查与解决
2025-03-08 00:09:46
ELKI 中 RepresentativeUncertainClustering 算法使用问题及排查
最近刚接触 ELKI,想跑一下RepresentativeUncertainClustering
这个算法,结果遇到了一些问题, 卡了好久, 记录下我的踩坑经历,顺便给出解决方法。
一、 问题
我主要是想用 ELKI 的 RepresentativeUncertainClustering
跑一个 demo。改了meta.ExternalClustering
和 pwc.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
需要两个主要的聚类算法:
pwc.clustering
: 用于对每个不确定对象生成 multiple samples(多个样本)的聚类算法。 这些样本随后会被用来代表原始的不确定对象。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 值。
进阶技巧和安全建议
- 算法选择:
KMeansSortMeansUmbrella
包含了多种 KMeans 的优化变体, ELKI 会自动选择合适的。 如果你有特定的算法需求,可以明确指定,例如kmeans.KMeans
. - 参数调整:
-kmeans.k
的值 (簇的数量) 需要根据你的数据和业务需求来确定。 可以尝试不同的 k 值,然后评估聚类结果。 对于不确定性数据,-uo.uncertainty.max3sigma
参数也很重要, 它决定了生成样本的分散程度, 需要仔细调整。 - 数据预处理: 在使用聚类算法前, 强烈建议对数据进行标准化或归一化, 保证不同特征的尺度一致, 避免某些特征对距离计算产生过大影响。ELKI 也提供了多种数据预处理的
filter
可以使用。 - 内存问题: 如果数据集非常大, 或者生成的不确定样本数量很多 (由
-uo.uncertainty.max3sigma
等参数控制),可能会导致内存溢出。 这时,可能需要考虑减少样本数量,或者使用更节省内存的算法。另外,可以通过调整 Java 虚拟机的内存设置(-Xmx
等参数)来增加 ELKI 可用的内存。 - 多次运行: 因为 KMeans 算法对初始中心点的选择比较敏感, 建议对相同的参数设置多次运行, 然后评估结果的稳定性。
- 认真看文档: ELKI 的文档相对比较完善 (虽然有时也不太好找), 遇到问题, 先仔细查阅文档是个好习惯, 可以解决很多疑惑. 特别是算法的参数说明部分, 要仔细阅读, 理解每个参数的含义和作用.
- 合理使用uncertainty数据 : 由于是对原始数据增加了UncertainifyFilter, 应该针对具体业务含义确定是否应使用。
通过上面的分析和修改,这两个问题就都解决了. RepresentativeUncertainClustering
算法也能正常跑起来了。 关键是要理解这个算法需要两个聚类算法分别做什么, 然后正确配置相应的参数.