欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算矩阵A与矩阵B的欧式距离

程序员文章站 2022-07-12 19:55:55
...

1. 从向量的欧式距离谈起

向量x为1x3的行向量,向量y为1x3的行向量,求向量x与向量y的欧式距离
x=(a11a12a13)x = \begin{pmatrix}a_{11} & a_{12} & a_{13}\\\end{pmatrix}
y=(b11b12b13)y = \begin{pmatrix}b_{11} & b_{12} & b_{13}\\\end{pmatrix}

distx,y=(a11b11)2+(a12b12)2+(a13b13)2dist_{x,y}=\sqrt{(a_{11} - b_{11})^2 + (a_{12} - b_{12})^2 + (a_{13} - b_{13})^2}

变形为:
distx,y=a112+a122+a132+b112+b122+b1322a11b112a12b122a13b13dist_{x,y}=\sqrt{a_{11}^2 + a_{12}^2 + a_{13}^2 + b_{11}^2 + b_{12}^2 + b_{13}^2 - 2a_{11}b_{11} - 2a_{12}b_{12} - 2a_{13}b_{13} }

从变形后的公式我们可以看出相当于(ab)2=a2+b22ab(a-b)^2=a^2+b^2-2ab

我们可以变形为下列计算(两个向量的L2范数):
distx,y=xy2dist_{x,y}=\left \| x-y \right \|_2
第一种方式

import numpy as np

x = np.mat([1.0, 2.0, 3.0])
y = np.mat([4.0, 5.0, 6.0])

dist = np.sqrt(np.sum(np.power(x - y, 2)))
print(dist)
# 5.196152422706632
dist = np.sqrt(np.power(x, 2).sum() + np.power(y, 2).sum() - 2 * np.dot(x, y.T)).sum()
print(dist)
# 5.196152422706632

2. 从向量的欧式距离扩展到矩阵的欧式距离

向量A为2x3的行向量,向量B为3x3的行向量,求向量A与向量B的欧式距离
A=(a1a2)=(a11a12a13a21a22a23)A = \begin{pmatrix} a_{1} \\ a_{2} \end{pmatrix} = \begin{pmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23} \end{pmatrix}

B=(b1b2b3)=(b11b12b13b21b22b23b31b32b33)B = \begin{pmatrix} b_{1} \\ b_{2}\\ b_{3} \end{pmatrix} = \begin{pmatrix} b_{11} & b_{12} & b_{13}\\ b_{21} & b_{22} & b_{23}\\ b_{31} & b_{32} & b_{33} \end{pmatrix}
矩阵A与矩阵B的欧式距离,会形成矩阵C,其维度为2x3
C=(c1c2)=(c11c12c13c21c22c23)C = \begin{pmatrix} c_{1} \\ c_{2} \end{pmatrix}= \begin{pmatrix} c_{11} & c_{12} & c_{13}\\ c_{21} & c_{22} & c_{23} \end{pmatrix}

distc11=(a11b11)2+(a12b12)2+(a13b13)2=a1b12dist_{c_{11}}=\sqrt{(a_{11} - b_{11})^2 + (a_{12} - b_{12})^2 + (a_{13} - b_{13})^2} = \left \| a_1-b_1 \right \|_2
distc12=(a11b21)2+(a12b22)2+(a13b23)2=a1b22dist_{c_{12}}=\sqrt{(a_{11} - b_{21})^2 + (a_{12} - b_{22})^2 + (a_{13} - b_{23})^2} = \left \| a_1-b_2 \right \|_2
distc13=(a11b31)2+(a12b32)2+(a13b33)2=a1b32dist_{c_{13}}=\sqrt{(a_{11} - b_{31})^2 + (a_{12} - b_{32})^2 + (a_{13} - b_{33})^2} = \left \| a_1-b_3 \right \|_2

distc21=(a21b11)2+(a22b12)2+(a23b13)2=a2b12dist_{c_{21}}=\sqrt{(a_{21} - b_{11})^2 + (a_{22} - b_{12})^2 + (a_{23} - b_{13})^2} = \left \| a_2-b_1 \right \|_2
distc22=(a21b21)2+(a22b22)2+(a23b23)2=a2b22dist_{c_{22}}=\sqrt{(a_{21} - b_{21})^2 + (a_{22} - b_{22})^2 + (a_{23} - b_{23})^2}= \left \| a_2-b_2 \right \|_2
distc23=(a21b31)2+(a22b32)2+(a23b33)2=a2b32dist_{c_{23}}=\sqrt{(a_{21} - b_{31})^2 + (a_{22} - b_{32})^2 + (a_{23} - b_{33})^2}= \left \| a_2-b_3 \right \|_2

可以看出A中的每个行向量使用了3次(B的行数)和B中的每一行列向量使用了2次(A的行数):
参照向量的欧式距离计算,转化成
(ab)2=a2+b22ab(a-b)^2=a^2+b^2-2ab
C=sum(A2,axis=1)ones((1,3))+ones((1,3))sum(B2,axis=1)T2ABTC=sum(A^2, axis=1) * ones((1, 3)) + ones((1, 3)) * sum(B^2, axis=1)^T - 2AB^T

# 矩阵欧式距离计算
# 矩阵计算方法
A = np.mat([[1.0, 2.0, 3.0], [2.0, 3.0, 4.0]])
B = np.mat([[3.0, 4.0, 5.0], [4.0, 5.0, 6.0], [5.0, 6.0, 7.0]])
C = np.sum(np.power(A, 2), 1) * np.ones((1, 3)) + np.ones((2, 1)) * np.sum(np.power(B, 2), 1).T        - 2 * A * B.T
print(C)
# [[12. 27. 48.] [ 3. 12. 27.]]
 # 逐行向量计算方法(用于验证)
C = np.mat(np.zeros((2, 3), dtype=float))
for i in range(2):
    for j in range(3):
        C[i, j] = np.sum(np.power(A[i] - B[j], 2))
print(C)

#[[12. 27. 48.] [ 3. 12. 27.]]