機器學習中那些相似度的計算方法及實現

AnneQiQi發表於2017-03-30

在推薦系統中,我們需要計算兩個物品的相似度,對於物品的描述,一般都可以量化為一個向量,於是兩個物品之間的相似度就可以用兩個向量的相關性來描述,這是概率論的範疇了。


假如我們希望相似度的值在0~1之間,並且越相似,值越大,有哪些辦法?

1、計算歐式距離,然後根據“相似度=1/(1+距離)”計算相似度。

2、皮爾遜相關係數,在numpy中可以用線性代數模組linalg中的corrcoef()來計算相關係數(correlation coefficient)。得出結果的取值範圍是-1~1,可通過“0.5+0.5*corrcoef()”將其縮放到0~1之間。

3、餘弦相似度,計算的是兩個向量的夾角的餘弦值。餘弦值=A*B/(||A||*||B||)。||A||表示A的2範數,可以用linalg模組中的norm()計算。餘弦值在-1~1之間,同樣需要縮放。


程式碼:

[python] view plain copy
  1. """ 
  2. Created on Sun Dec 28 10:33:42 2014 
  3.  
  4. @author: wepon 
  5.  
  6. """  
  7.   
  8. #相似度計算,inA、inB都是行向量  
  9. import numpy as np  
  10. from numpy import linalg as la  
  11.   
  12. #歐式距離  
  13. def euclidSimilar(inA,inB):  
  14.     return 1.0/(1.0+la.norm(inA-inB))  
  15. #皮爾遜相關係數  
  16. def pearsonSimilar(inA,inB):  
  17.     if len(inA)<3:  
  18.         return 1.0  
  19.     return 0.5+0.5*np.corrcoef(inA,inB,rowvar=0)[0][1]  
  20. #餘弦相似度  
  21. def cosSimilar(inA,inB):  
  22.     inA=np.mat(inA)  
  23.     inB=np.mat(inB)  
  24.     num=float(inA*inB.T)  
  25.     denom=la.norm(inA)*la.norm(inB)  
  26.     return 0.5+0.5*(num/denom)  

測試:

[python] view plain copy
  1. >>> inA=array([1,2,3])  
  2. >>> inB=array([2,4,6])  
  3. >>> euclidSimilar(inA,inB)  
  4. 0.21089672205953397  
  5. >>> pearsonSimilar(inA,inB)  
  6. 1.0  
  7. >>> cosSimilar(inA,inB)  
  8. 1.0  


感覺這幾種度量方法都比較粗糙,最終選擇哪種相似度度量方式還是得看具體問題吧。

相關文章