![](/img/trans.png)
[英]How to calculate pairwise cosine distance of matrix using broadcasting in python
[英]Calculate weighted pairwise distance matrix in Python
我試圖找到在 Python 中執行以下成對距離計算的最快方法。 我想使用距離按相似性對list_of_objects
進行排名。
list_of_objects
中的每一項都以四個度量 a、b、c、d 為特征,這些度量是在非常不同的尺度上進行的,例如:
object_1 = [0.2, 4.5, 198, 0.003]
object_2 = [0.3, 2.0, 999, 0.001]
object_3 = [0.1, 9.2, 321, 0.023]
list_of_objects = [object_1, object_2, object_3]
目的是獲得list_of_objects
對象的成對距離矩陣。 但是,我希望能夠通過權重向量在我的距離計算中指定每個度量的“相對重要性”,每個度量一個權重,例如:
weights = [1, 1, 1, 1]
表示所有測量值的權重相等。 在這種情況下,我希望每次測量對物體之間的距離的貢獻相等,而不管測量比例如何。 或者:
weights = [1, 1, 1, 10]
表示我希望測量 d 對物體之間的距離的貢獻比其他測量多 10 倍。
我當前的算法如下所示:
weights
的適當權weights
list_of_objects
的對象對的排名列表這很好用,並為我提供了對象之間城市街區距離的加權版本。
我有兩個問題:
在不改變算法的情況下,在 SciPy、NumPy 或 SciKit-Learn 中執行初始距離矩陣計算的最快實現是什么。
是否有現有的多維距離方法可以為我完成所有這些工作?
對於 Q 2,我已經查看過,但找不到任何以我想要的方式執行“相對重要性”的內置步驟。
歡迎其他建議。 很高興澄清我是否遺漏了細節。
scipy.spatial.distance
是您想要查看的模塊。 它有很多不同的規范,可以很容易地應用。
我建議使用加權 Monkowski Metrik
您可以使用此包中的pdist
方法進行成對距離計算。
例如
import numpy as np
from scipy.spatial.distance import pdist, wminkowski, squareform
object_1 = [0.2, 4.5, 198, 0.003]
object_2 = [0.3, 2.0, 999, 0.001]
object_3 = [0.1, 9.2, 321, 0.023]
list_of_objects = [object_1, object_2, object_3]
# make a 3x4 array from the list of objects
X = np.array(list_of_objects)
#calculate pairwise distances, using weighted Minkowski norm
distances = pdist(X,wminkowski,2, [1,1,1,10])
#make a square matrix from result
distances_as_2d_matrix = squareform(distances)
print distances
print distances_as_2d_matrix
這將打印
[ 801.00390786 123.0899671 678.0382942 ]
[[ 0. 801.00390786 123.0899671 ]
[ 801.00390786 0. 678.0382942 ]
[ 123.0899671 678.0382942 0. ]]
將成對距離除以最大值的歸一化步驟似乎是非標准的,並且可能很難找到一個現成的函數來滿足您的要求。 雖然自己做很容易。 一個起點是將你的list_of_objects
變成一個數組:
>>> obj_arr = np.array(list_of_objects)
>>> obj_arr.shape
(3L, 4L)
然后,您可以使用廣播獲得成對距離。 這有點低效,因為它沒有利用度量的對稱性,而是對每個距離計算兩次:
>>> dists = np.abs(obj_arr - obj_arr[:, None])
>>> dists.shape
(3L, 3L, 4L)
標准化很容易做到:
>>> dists /= dists.max(axis=(0, 1))
您的最終稱重可以通過多種方式完成,您可能希望以最快的方式進行基准測試:
>>> dists.dot([1, 1, 1, 1])
array([[ 0. , 1.93813131, 2.21542674],
[ 1.93813131, 0. , 3.84644195],
[ 2.21542674, 3.84644195, 0. ]])
>>> np.einsum('ijk,k->ij', dists, [1, 1, 1, 1])
array([[ 0. , 1.93813131, 2.21542674],
[ 1.93813131, 0. , 3.84644195],
[ 2.21542674, 3.84644195, 0. ]])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.