協同過濾中相似度的計算方式


協同過濾中相似度的計算很有技巧性,下面對比幾種計算的方式。

 

假設輸入的Item-User矩陣為:

  $U_1$ $U_2$ $U_3$
$I_1$ 3   4
$I_2$   3 2
$I_3$ 2  
$I_4$   4  2

 

設用戶共有M個,Item共有N個,在本例子中,$M=3,N=4$。矩陣中為空的元素代表對應的用戶對Item沒有行為,也可以認為該用戶對該Item的評分為0.

一、用二維數組依次計算

這種方式的實現步驟如下:

1、遍歷User,依次取出$U_1,U_2,U_3$。當取到$U_1$的時候,計算所有item之間的相似度,此處以余弦方式度量相似度。因為相似度矩陣是一個對稱矩陣,所以只計算上三角或者下三角即可。當計算$U_2$的時候,需要累加$U_1$的計算結果,$U_3$同樣要累加前面的計算結果,這樣當user遍歷完成之后,即可得到兩個Item之間的內積,當然余弦相似度還要除以兩個Item的模長的乘積。模長的計算可以在遍歷User的時候同步計算。

計算內積的具體過程為:

$$U_1\Rightarrow \begin{cases} I_1\Rightarrow \begin{cases} cos(I_1,I_2) = 3 \times 0 \cr cos(I_1,I_3) = 3 \times 2 \cr cos(I_1,I_4) = 3 \times 0 \cr \end{cases} \cr I_2\Rightarrow \begin{cases} cos(I_2,I_3) = 0 \times 2 \cr cos(I_2,I_4) = 0 \times 0 \cr \end{cases} \cr
I_3\Rightarrow \begin{cases} cos(I_3,I_4) = 2 \times 0 \cr \end{cases} \end{cases}$$

$$U_2\Rightarrow \begin{cases} I_1\Rightarrow \begin{cases} cos(I_1,I_2) += 0 \times 3 \cr cos(I_1,I_3) += 0 \times 3 \cr cos(I_1,I_4) += 0 \times 4 \cr \end{cases} \cr I_2\Rightarrow \begin{cases} cos(I_2,I_3) += 3 \times 3 \cr cos(I_2,I_4) += 3 \times 4 \cr \end{cases} \cr
I_3\Rightarrow \begin{cases} cos(I_3,I_4) += 3 \times 4 \cr \end{cases} \end{cases}$$

$$U_3\Rightarrow \begin{cases} I_1\Rightarrow \begin{cases} cos(I_1,I_2) += 4 \times 2 \cr cos(I_1,I_3) += 4 \times 0 \cr cos(I_1,I_4) += 4 \times 2 \cr \end{cases} \cr I_2\Rightarrow \begin{cases} cos(I_2,I_3) += 2 \times 0 \cr cos(I_2,I_4) += 2 \times 2 \cr \end{cases} \cr
I_3\Rightarrow \begin{cases} cos(I_3,I_4) += 0 \times 2 \cr \end{cases} \end{cases}$$

 

2、用內積除以模長得到余弦相似度,這一步比較簡單,不詳細討論。

 

現在來分析一下這種方法的時間復雜度。很明顯要遍歷User,上面已經假設User的數量為M,而對每一個User而言,要計算所有Item兩兩之間的相似度,因之需要計算相似度矩陣的上三角或下三角,所以其計算的次數為:

$$\frac{N \cdot (N-1)}{2}$$

考慮所有的用戶,還要在上面的基礎上再乘以$M$,所以最后的次數為:

$$\frac{M\cdot N \cdot (N-1)}{2}$$

 

二、采用HashMap查找計算

 

這種方法只計算User-Item矩陣中值不為空的元素,對稀疏的矩陣而言,沒有冗余的計算。但是需要額外構造一個ItemHashMap,從遍歷ItemHashMap開始。

在ItemHashMap中,Item為key,User為value。

 

1、遍歷ItemHashMap,依次取出$I_1,I_2,I_3,I_4$。取到$I_1$的時候,先從ItemHashMap中查找看過該Item的User有哪些,在本例子中為$U_1,U_3$。然后再分別計算這些User中每個User看過的Item之間的相似度,這一步很重要,是為了避免計算User-Item矩陣中為空的元素。

2、用戶$U_1$看過的Item有$I_1,I_3$,用戶$U_3$看過的Item有$I_1,I_2,I_4$。那么作如下計算:

$$I_1\Rightarrow \begin{cases} U_1\Rightarrow \begin{cases} cos(I_1,I_3) = 3 \times 2  \end{cases}  \cr U_3\Rightarrow \begin{cases} cos(I_1,I_2) = 4 \times 2 \cr cos(I_1,I_4) = 4 \times 2 \cr \end{cases} \end{cases}$$

3、同理,可以這樣計算$I_2,I_3,I_4$。因為是對稱矩陣,只需要計算相似度矩陣上三角或者下三角即可。如下所示:

$$I_2\Rightarrow \begin{cases} U_2\Rightarrow \begin{cases} cos(I_2,I_3) = 3 \times 3 \cr cos(I_2,I_4) = 3 \times 4  \end{cases}  \cr U_3\Rightarrow \begin{cases} cos(I_2,I_4) = 2 \times 2  \end{cases} \end{cases}$$

$$I_2\Rightarrow \begin{cases} U_2\Rightarrow \begin{cases} cos(I_3,I_4) = 3 \times 4 \end{cases} \end{cases}$$

 

假設平均每個Item被P個用戶看過,平均每個用戶看過Q個Item,那么應當有:

$$N \cdot P=M \cdot Q$$

 

分析上面的過程,不難發現,這種方式的計算次數為:

$$\frac{N \cdot P \cdot (Q-1)}{2}$$

 

在實際的數據中,User-Item矩陣必然是稀疏,如果User-Item矩陣一點都不稀疏,也即沒有不為空的元素,那么也就失去了推薦的意義,因為對於每一個用戶而言,他把所有的Item都看過了,那還給他推薦什么呢?正常情況下,應該有$P \ll M$,所以這種算法是有意義的。

 

上面兩種方法計算的相似度矩陣是一致的,如下所示:

  $I_1$ $I_2$ $I_3$ $I_4$
$I_1$   8 6 8
$I_2$     9 16
$I_3$       12
$I_4$        

 

 

三、只使用UserHashMap實現

這種方式在實現第二種方式達到的效果之外,還可以節省空間。大概的思想是,遍歷UserHashMap,每取到一個User之后,先獲取該User所看過的Item,然后計算這些看過的Item兩兩之間的相似度,然后將結果保存在相似度矩陣中,后面的User生成的相似度直接累加上去即可,這樣最終的結果也就生成了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM