我们如何从字典创建相似矩阵?

时间:2018-10-05 11:57:04

标签: python numpy scipy

我有一个字典,如下所示:

dic = {a1: [a,b,c], b1:[b,k,l]}.

我想为每个键的值列表创建一个相似度矩阵。例如,对于键a1,我想使用假设方法(a,b), (a,c) and (b,c)计算f之间的相似度。 f((a,a)) = 1。我们可以通过创建向量并通过(a,b), (a,c) and (b,c)之间的相似度值为其元素建立索引,并对b重复相同的过程(即(b,a), (b,b), and (b,c)等)来实现。但由于(b,a) =(a,b)的相似性,因此没有必要。那么如何解决呢?如何创建这样的矩阵呢? 然后将相同的方法应用于dic的每个键(例如b1等)

1 个答案:

答案 0 :(得分:1)

如果f价格昂贵且无法矢量化,则可以按照以下方式使用np.tri和朋友

>>> import numpy as np
>>> from operator import itemgetter as iget
>>> 
# set up an example
>>> a1, b1 = 'a1', 'b1'
>>> a, b, c, k, l = np.random.randint(0, 10, (5, 3))
>>> dic = {a1: [a,b,c], b1: [b,k,l]}
>>> f = np.dot
>>> 
# do the computation
>>> RES = {}
>>> for k, v in dic.items():
...     N = len(v)
...     res = np.ones((N, N))
...     I, J = np.triu_indices_from(res, 1)
...     res[I, J] = np.fromiter(map(f, iget(*I.tolist())(v), iget(*J.tolist())(v)), float, N*(N-1)//2)
...     np.copyto(res, res.T, where=np.tri(*res.shape, -1, bool))
...     RES[k] = res
... 
# check
>>> RES
{'a1': array([[  1., 108., 122.],
       [108.,   1., 120.],
       [122., 120.,   1.]]), 'b1': array([[ 1., 42., 66.],
       [42.,  1., 20.],
       [66., 20.,  1.]])}

您也可以使用map(f, iget(...代替itertools.starmap(f, itertools.combinations(v, 2))