在 Python 中查找将一个集群列表转换为另一个集群的映射
Posted
技术标签:
【中文标题】在 Python 中查找将一个集群列表转换为另一个集群的映射【英文标题】:Find mapping that translates one list of clusters to another in Python 【发布时间】:2019-08-11 00:15:39 【问题描述】:我正在使用 scikit-learn 对一些数据进行聚类,我想比较不同聚类技术的结果。我立即面临一个问题,即集群的标签在不同的运行中是不同的,所以即使它们的集群完全相同,列表的相似性仍然很低。
说我有
list1 = [1, 1, 0, 5, 5, 1, 8, 1]
list2 = [3, 3, 1, 2, 2, 3, 8, 3]
我会(理想情况下)喜欢一个以翻译字典形式返回最佳映射的函数,如下所示:
findMapping(list1, list2)
>>> 0:1, 1:3, 5:2, 8:8
我说“最佳映射”是因为假设list3 = [3, 3, 1, 2, 2, 3, 8, 4]
然后findMapping(list1, list3)
仍会返回相同的映射,即使最终的1
变成4
而不是3
。
因此,最好的映射是最小化两个列表之间差异数量的映射。我认为这是一个很好的标准,但可能会有更好的标准。
我可以编写一个试错优化算法来做到这一点,但我并不是第一个想要比较聚类算法结果的人。我希望这样的东西已经存在,我只是不知道它叫什么。但是我四处寻找并没有找到任何答案。
关键是,在应用最佳翻译后,我将测量列表之间的差异,所以也许有一种方法可以测量不同索引的数字列表之间的差异,而无需将翻译作为中间步骤,这也很好.
====================================
根据 Pallie 的回答,我能够创建 findMapping 函数,然后我更进一步创建了一个翻译函数,该函数将第二个列表转换为第一个列表的标签。
def translateLabels(masterList, listToConvert):
contMatrix = contingency_matrix(masterList, listToConvert)
labelMatcher = munkres.Munkres()
labelTranlater = labelMatcher.compute(contMatrix.max() - contMatrix)
uniqueLabels1 = list(set(masterList))
uniqueLabels2 = list(set(listToConvert))
tranlatorDict =
for thisPair in labelTranlater:
tranlatorDict[uniqueLabels2[thisPair[1]]] = uniqueLabels1[thisPair[0]]
return [tranlatorDict[label] for label in listToConvert]
即使使用这种转换(我需要一致地绘制集群颜色),使用 Rand 索引和/或标准化互信息似乎也是比较不需要共享标签的差异的好方法。
我也喜欢第一个 sorting both lists according the values in the data 的想法,但在比较来自非常不同数据的集群时,这可能行不通。
【问题讨论】:
我认为这个问题证明了一定程度的优点,即使据称有人认为它是重复的。我赞成它。 【参考方案1】:您可以尝试计算两个结果之间的adjusted Rand index。这给出了 -1 和 1 之间的分数,其中 1 表示完美匹配。
或者通过混淆矩阵的argmax:
list1 = ['a', 'a', 'b', 'c', 'c', 'a', 'd', 'a']
list2 = [3, 3, 1, 2, 2, 3, 8, 3]
np.argmax(contingency_matrix(list1, list2), axis=1)
array([2, 0, 1, 3])
2 表示第 2 行(值 2,簇 3)与“a”列 0(2 的索引)最佳匹配。然后第 0 行匹配第 1 列等。
对于匈牙利方法:
m = Munkres()
contmat = contingency_matrix(list1, list2)
m.compute(contmat.max() - contmat)
[(0, 2), (1, 0), (2, 1), (3, 3)]
使用:https://github.com/bmc/munkres
【讨论】:
是的,这就是我所期望的存在。它确实满足了我在不找到翻译的情况下测量列表之间距离的需要。如果可能的话,我仍然希望有“翻译图”,这样我就可以识别哪些项目是不同的,并为绘图生成一个全局配色方案。 有关该信息,请尝试应急矩阵:scikit-learn.org/stable/modules/generated/… 我相信您,权变矩阵可以提供将一组标签转换为另一组标签所需的信息,但是仅凭该文档而找不到示例,完全不清楚如何做到这一点。 采用列联矩阵的 np.argmax 应该得到一个列表,其中索引是键,值是映射的值。一个好的映射。 我认为如果两个分区具有不同的基数(例如,一个ground-truth集群被给定的聚类过程分成两部分),Munkres 算法可能不是一个好主意。在这种情况下,Munkres 算法会留下一些不匹配的集群,如果需要完整的分配图,那么 argmax 技术(尽管不是最理想的)是一个不错的方法。以上是关于在 Python 中查找将一个集群列表转换为另一个集群的映射的主要内容,如果未能解决你的问题,请参考以下文章
列表推导(list comprehension)--Python
在给定列表中搜索将字符串转换为另一个字符串的最短方法,一次一个字符