1. 程式人生 > >python 學習筆記(相似性計算方法)

python 學習筆記(相似性計算方法)

實在不能理解為啥搜狗輸入法每次我打biji的時候總是給我跳出荸薺(qi) (づ ̄ 3 ̄)づ,還有biaoshi,總是出標識(zhi)..╭(╯^╰)╮哼

  • 基於距離的相似度計算
    prefs[person][item]
    資料集格式如下:
    這裡寫圖片描述
    example:
    aaaa={‘WANG’:{‘Lady in the Water’:3,’HAHA story’:2},…}
    from math import sqrt
    傳入引數:
    prefs person1 person2

我們要計算兩個人的品味相似程度,首先要找到有沒有相同的item,如果沒有,那麼則返回0

si={}
for
item in prefs[person1]: if item in prefs[person2]: si[item]=1 if len(si)==0: return 0

如果有相同的item,我們得到相應的score,可以計算其歐式距離:

totalsum=sum([pow(prefs[person1][item]-prefs[person2][item],2) for item in prefs[person1] if item in prefs[person]])

因為要返回一個0-1值的函式,0代表很差,1代表口味完全相同,而上述的歐式距離是距離越小口味越相近,距離為0時口味相同

return 1/(1+sqrt(totalsum))
  • pearson相關係數
    僅僅計算距離是不夠的,假設person1對item評價為1.2,2.3,3.6,person2對item評價為:2.2,3.3,4.6,實際上這兩個人的口味相同,但是person2評價稍高,用上述方法計算則會出現很大的誤差,這時候我們引入一個相關係數的概念來修正“誇大分值”的情況。
    (PS:為啥我打xishu總是出現洗漱,╭(╯^╰)╮)
    pearson相關係數是判斷兩組資料與某一直線擬合程度的一種度量,它在資料不是很規範的時候,會傾向於給出更好的結果
    pearson相關係數
    採用第四種計算方法:
def pearson_distance(prefs,p1,p2):
    si={}
    for
item in prefs[p1]: if item in prefs[p2]: si[item]=1 n=len(si) if n==0: return 0 sum1=sum([prefs[p1][it] for it in si]) sum2=sum([prefs[p2][it] for it in si]) sum1sq=sum([pow(prefs[p1][it],2) for it in si]) sum2sq=sum([pow(prefs[p2][it],2) for it in si]) sumco=sum([prefs[p1][it]*prefs[p2][it] for it in si]) num=sumco-sum1*sum2/n num2=sqrt((sum1sq-pow(sum1,2)/n)*(sum2sq-pow(sum2,2)/n)) r=num/num2 return r
  • Jaccard相關係數
    Jaccard(A,B)=(AB)/(AB)
    計算公式如上,缺點也很明顯,就是根本不考慮對item的評分,如此粗暴T^T
def jaccard_distance(prefs,p1,p2):
    si={}
    for item in prefs[p1]:
        if item in prefs[p2]:
            si[item]=1
    n=len(si)
    if n==0:
        return 0
    return n/(len(prefs[p1])+len(prefs[p2])-n)
  • Tanimoto係數:
    Tanimoto係數,又稱為廣義Jaccard係數:
    Tanimoto(A,B)=AB/(||A||2+||B||2AB)
def Tanimoto_distance(prefs,p1,p2):
    si={}
    for item in prefs[p1]:
        if item in prefs[p2]:
            si[item]=1
    n=len(si)
    if n==0:
        return 0
    sum1=sum([pow(prefs[p1][it],2) for it in prefs[p1]])
    sum2=sum([pow(prefs[p2][it],2) for it in prefs[p2]])
    sumco=sum([prefs[p1][it]*prefs[p2][it] for it in si])
    return sumco/(sum1+sum2-sumco)

餘弦:0.294298055086
pearson: 0.396059017191
jaccard: 1
Tanimoto:0.911877394636

summary
相似度和距離成反相關,相似度為0,則距離最大,相似度為1,則距離為0,相似度和距離可以互相轉換。

Question
Q:在何種情況下,用何種相似度度量方法?