如何对字典中的冗余条目进行分组

问题描述 投票:0回答:1

我有一个这样的条目字典:

{
    'A': {
        'HUE_SAT': 1,
        'GROUP_INPUT': 1,
        'GROUP_OUTPUT': 1
    },
    'D': {
        'HUE_SAT': 1,
        'GROUP_INPUT': 1,
        'GROUP_OUTPUT': 1
    },
    'T': {
        'HUE_SAT': 1,
        'GROUP_INPUT': 1,
        'GROUP_OUTPUT': 1
    },
    'O': {
        'GROUP_INPUT': 3,
        'MAPPING': 2,
        'TEX_NOISE': 2,
        'UVMAP': 2,
        'VALTORGB': 3,
        'GROUP_OUTPUT': 1,
        'AMBIENT_OCCLUSION': 1,
        'MIX': 4,
        'REROUTE': 1,
        'NEW_GEOMETRY': 1,
        'VECT_MATH': 1
    },

每个项目都会相互比较,并给出相似度分数。然后创建一个字典,其中两个比较条目的元组作为键,它们的相似度分数作为值。问题是我收到了很多这样的冗余条目:

{
    ('A', 'D'): 1.0,
    ('A', 'C'): 1.0,
    ('D', 'A'): 1.0,
    ('D', 'C'): 1.0,
    ('C', 'A'): 1.0,
    ('C', 'D'): 1.0,

如果它们在相互比较时都给出相同的相似性分数,我想对它们进行分组,如下所示:

{
    ('A', 'D', 'C'): 1.0,
    ('O', 'L', 'S', 'N', 'P'): 0.412

代码:

# Cosine similarity function from here:
# https://stackoverflow.com/a/35981085/22855942

def square_root(x):
    return round(sqrt(sum([a * a for a in x])), 3)

def cosine_similarity(a, b):

    input1 = {}
    input2 = {}

    vector1 = []
    vector2 = []

    if len(a) > len(b):
        input1 = a
        input2 = b
    else:
        input1 = b
        input2 = a

    vector1 = list(input1.values())

    for k in input1.keys():
        if k in input2:
            vector2.append(float(input2[k]))
        else:
            vector2.append(float(0))

    numerator = sum(a * b for a, b in zip(vector2, vector1))
    denominator = square_root(vector1) * square_root(vector2)
    return round(numerator / float(denominator), 3)


keys = tuple(my_dict.keys())
results = {}

for k in keys:
    for l in keys:
        if l != k:
            results[(k, l)] = results.get((l, k), cosine_similarity(my_dict[k], my_dict[l]))

results = {key: value for key, value in sorted(results.items(), key=lambda item: item[1], reverse=True)}

我尝试创建一种比较对的“缓冲区”,将当前项目与缓冲区列表的最后一项进行比较,根据相似性分数进行附加 - 但这很快就变成了一堆嵌套的 for 循环、条件和子列表,当我觉得必须有一个更优雅的解决方案时?

python dictionary sorting similarity
1个回答
0
投票

我没有足够的分数(堆栈分数)来将其写为评论,所以我将其写为答案。

该问题适用于:

('A', 'D', 'C'): 1.0
,因为所有 A = D 并且所有 D = C。

但对于

('O', 'L', 'S'):0.42
来说可能不是这样,因为 O=0.42 x L 和 L=0.42 x S 并不意味着 O = 0.42 x S,特别是当我们谈论相似性时(这是向量中向量的点积)显示的感觉)。

除非问题指的是评论中已经提到的派系问题https://en.wikipedia.org/wiki/Clique_problem.

© www.soinside.com 2019 - 2024. All rights reserved.