numpy :: 計算特徵之間的餘弦距離

 餘弦距離在計算類似度的應用中常常使用,好比:html

  • 文本類似度檢索
  • 人臉識別檢索
  • 類似圖片檢索

原理簡述

下面是餘弦類似度的計算公式(圖來自wikipedia):機器學習

餘弦類似度的計算公式,來自維基百科

可是,餘弦類似度和經常使用的歐式距離的有所區別。學習

  • 餘弦類似度的取值範圍在-1到1之間。徹底相同時數值爲1,相反反向時爲-1,正交或不相關是爲0。(以下圖,來源
  • 歐式距離通常爲正值,歸一化以後在0~1之間。距離越小,越類似。

歐式距離用於類似度檢索更符合直覺。所以在使用時,須要將餘弦類似度轉化成相似歐氏距離的餘弦距離。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(about=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 or b is preferred.

爲了保持一致性,都使用了轉置操做。以下圖所示,矩陣乘法按線性代數定義,必須是 行 × 列才能完成乘法運算。舉例 32張128維特徵進行運算,則應該是 32x128 * 128x32 才行。

  

參考文章

相關文章
相關標籤/搜索