餘弦距離在計算類似度的應用中常常使用,好比:html
下面是餘弦類似度的計算公式(圖來自wikipedia):機器學習
可是,餘弦類似度和經常使用的歐式距離的有所區別。學習
歐式距離用於類似度檢索更符合直覺。所以在使用時,須要將餘弦類似度轉化成相似歐氏距離的餘弦距離。spa
維基頁面中給出的角距離計算公式以下(圖來自wikipedia):3d
因爲在計算圖片或者文本類似度時,提取的特徵沒有負值,餘弦類似度的取值爲0~1,所以採用更簡便的方法,直接定義爲:code
餘弦距離 = 1- 餘弦類似度orm
根據輸入數據的不一樣,分爲兩種模式處理。htm
1 import numpy as np
2 def cosine_distance(a, b): 3 if a.shape != b.shape: 4 raise RuntimeError("array {} shape not match {}".format(a.shape, b.shape)) 5 if a.ndim==1: 6 a_norm = np.linalg.norm(a) 7 b_norm = np.linalg.norm(b) 8 elif a.ndim==2: 9 a_norm = np.linalg.norm(a, axis=1, keepdims=True) 10 b_norm = np.linalg.norm(b, axis=1, keepdims=True) 11 else: 12 raise RuntimeError("array dimensions {} not right".format(a.ndim)) 13 similiarity = np.dot(a, b.T)/(a_norm * b_norm) 14 dist = 1. - similiarity 15 return dist
6~7 行 , np.linalg.norm 操做是求向量的範式,默認是L2範式,等同於求向量的歐式距離。blog
9~10行 ,設置參數 axis=1 。對於歸一化二維向量時,將數據按行向量處理,至關於單獨對每張圖片特徵進行歸一化處理。圖片
13行,np.dot 操做能夠支持兩種模式的運算,來自官方文檔的解釋:
numpy.
dot
(a, b, out=None)Dot product of two arrays. Specifically,
If both a and b are 1-D arrays, it is inner product of vectors (without complex conjugation).
If both a and b are 2-D arrays, it is matrix multiplication, but using
matmul
ora @ b
is preferred.
爲了保持一致性,都使用了轉置操做。以下圖所示,矩陣乘法按線性代數定義,必須是 行 × 列才能完成乘法運算。舉例 32張128維特徵進行運算,則應該是 32x128 * 128x32 才行。