【问题标题】:What's the best way to find the similarity among these vectors?找到这些向量之间相似性的最佳方法是什么?
【发布时间】:2011-07-13 12:24:56
【问题描述】:
v1 = [33, 24, 55, 56]
v2 = [32, 25, 51, 40]
v3 = [ ... ]
v4 = [ ... ]

通常,要找到与 v1 最相似的向量,我会使用 余弦相似度算法 对其他向量运行 v1。

现在,我有一组结构更复杂的向量:

v1 = [ { 'a': 4, 'b':9, 'c': 12 ... },
       { 'a', 3, 'g':3, 'b': 33 ... },
       { 'b', 1, 'k': 6, 'n': 19 ... },
       ...
     ]
v2 = [ {}, {}, {} ... ]
v3 = [ {}, {}, {} ... ]
v4 = [ {}, {}, {} ... ]

给定这个结构,你将如何计算相似度? (一个好的匹配应该是一个包含许多类似于 v1 的键的向量,这些键的值与 v1 的值非常相似

btilly 的回答:

def cosine_sim_complex(v, w):
    '''
    Complex version of cosine similarity
    '''
    def complicated_dot(v, w):
        dot = 0
        for (v_i, w_i) in zip(v, w):
            #{ _, _ }, {_, _}
            for x in v_i:
                if x in w_i:
                    dot += v_i[x] * w_i[x]
        return float(dot)
    length_v = float(complicated_dot(v, v) ** 0.5)
    length_w = float(complicated_dot(w, w) ** 0.5)
    score = complicated_dot(v, w) /  length_v / length_w
    return score


v1 = [ {'a':44, 'b':21 }, { 'a': 55, 'c': 22 } ]
v2 = [ {'a':99, 'b':21 }, { 'a': 55, 'c': 22 } ]
cosine_sim_complex(v1, v2)
1.01342687531

【问题讨论】:

  • 你不能只应用与以前相同的方法,而只使用它们共有的键吗?

标签: python algorithm computer-science


【解决方案1】:

你在更多维度上做同样的事情。

以前您只有 4 个维度。现在,您拥有一组更大的维度,其中包含索引的二维标签。但数学保持不变。你有一个像这样未经测试的代码的点积:

def complicated_dot(v, w):
    dot = 0
    for (v_i, w_i) in zip(v, w):
        for x in v_i.iterkeys():
            if x in w_i:
                dot += v_i[x] * w_i[x]
    return dot

然后你就可以应用你已经知道的余弦相似度算法了。

【讨论】:

  • 所以我将v1和v2传入complicatd_dot,输出是点积吗?单位向量呢?我将如何计算?你能再具体一点吗?谢谢! (还是很模糊,很难拼凑起来)
  • @Owalla 向量的长度是sqrt(complicated_dot(v, v))。此时您有两个选择。一种是定义cosine(v, w) = complicated_dot(v, w)/length(v)/length(w) 并使用角度进行处理。另一种是最小化length(v, w)
  • 嗨,btilly,谢谢,它似乎有效。但是你能帮我看看吗?为什么 cosine_similarity 返回大于 1 的数字?它不应该返回一个介于 0 和 1 之间的数字吗? ~谢谢
  • @Owalla:对不起,我有一个严重的错字。我有v_i[x] + w_i[x] 我需要v_i[x] * w_i[x]。通过该修复,它会返回正确范围内的答案。
【解决方案2】:

您可以对每个项目使用集合和操作 ixor (^)。我假设所有 dicts 的大小都是相等的。

diffs = []
vs = (v2, v3, v4)
for vcmp in vs:
    diff = 0
    for v_item_index in range(len(vcmp)):
        diff += set(vcmp[v_item_index]) ^ set(v[v_item_index])
    diffs.append(diff)

print diffs

现在差异中包含低值的项目具有索引最相似向量。

【讨论】:

    猜你喜欢
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2013-12-22
    • 2018-03-21
    • 1970-01-01
    • 2013-03-13
    相关资源
    最近更新 更多