我在使用SciPy的pdist计算成对相似度方面存在问题。
这是我的相似函数
>>>def custom_metric(p1,p2):
'''Calculate the similarity of two vectors
For vectors [10, 20, 30] and [5, 10, 15], the results is 0.5 similarity
'''
mins = np.sum(np.minimum(p1,p2))
maxes = np.sum(np.maximum(p1,p2))
return mins/maxes
这是一个示例数据(虚拟dum
)
>>> dum = pd.DataFrame([[10,20,30,40],
[10,20,30,40],
[5, 10,15,20],
[5,0,0,0]],
index=['product_{}'.format(i) for i in range(1,5)],
columns=['ingredient_{}'.format(i) for i in range(1,5)])
>>> dum.head()
ingredient_1 ingredient_2 ingredient_3 ingredient_4
product_1 10 20 30 40
product_2 10 20 30 40
product_3 5 10 15 20
product_4 5 0 0 0
如果我手动计算相似度,它可以正常工作。
>>> custom_metric(dum.ix['product_2'],dum.ix['product_3'])
... 0.5
>>> custom_metric(dum.ix['product_2'],dum.ix['product_2'])
... 1.0
然而,使用pdist产生了这个:
>>> similarities = pd.DataFrame(squareform(pdist(dum, custom_metric)), index=dum.index, columns=dum.index); similarities
product_1 product_2 product_3 product_4
product_1 0.00 1.00 0.5 0.05
product_2 1.00 0.00 0.5 0.05
product_3 0.50 0.50 0.0 0.10
product_4 0.05 0.05 0.1 0.00
除了应该为1的对角线外,这是可以的。
现在我明白了这样一个事实,pdist
用于计算“一件事物”与0
的距离和距离,但我很惊讶即使使用自定义功能它仍然可以这样工作。我甚至检查了source for pdist,但没有找到对角线元素的手动处理。
如果我这样做是否可以
>>> np.eye(similarities.shape[0]) + similarities
将1添加到对角线上,还是会弄乱它?