1. 程式人生 > 其它 >基於python實現計算物品之間的相似度矩陣演算法二

基於python實現計算物品之間的相似度矩陣演算法二

計算物品之間的相似度矩陣

例如現在有A、B、C、D四個使用者,分別對a、b、c、d、e五個物品表達了自己喜好程度(通過評分高低來表現自己的偏好程度高低),計算物品之間的相似度矩陣
在這裡插入圖片描述

演算法

1、建立使用者物品倒排表

A a b d
B a c e
C b e
D b d e

2、構建同現矩陣

同現矩陣表示同時喜歡兩個物品的使用者數,根據使用者物品倒排表計算出來
在這裡插入圖片描述

3、統計每個物品有行為的使用者數

在這裡插入圖片描述

4、計算物品之間的相似度,得到物品之間的相似度矩陣

在這裡插入圖片描述
上面公式演算法實現可以參考:python實現基於使用者的協同過濾演算法一
上述公式雖然看起來很有道理,但存在一個問題,如果物品j很熱門,很多人喜歡•那麼 就會很大,接近1.因此,該公式會造成任何物品都會和熱門的物品有很大的相似度,這對於致力於挖掘長尾資訊的推薦系統來說顯然不是一個很好的特性,為了避免推薦出熱門物品,可以用以下公式。

在這裡插入圖片描述

分母 是喜歡物品i的使用者數;
分子 是同時喜歡物品i和物品j的使用者數。

在這裡插入圖片描述
參考程式碼:

import math
class ItemCF:
    def __init__(self):
        self.user_score_dict = self.initUserScore()
        self.items_sim = self.ItemSimilarity()
    # 初始化使用者評分資料
    def initUserScore(self):
        user_score_dict = {
            "A": {"a": 3.0, "b": 4.0, "c": 0.0, "d": 3.5, "e": 0.0},
            "B": {"a": 4.0, "b": 0.0, "c": 4.5, "d": 0.0, "e": 3.5},
            "C": {"a": 0.0, "b": 3.5, "c": 0.0, "d": 0.0, "e": 3.0},
            "D": {"a": 0.0, "b": 4.0, "c": 0.0, "d": 3.5, "e": 3.0},
        }
        return user_score_dict

    #  計算item之間的相似度
    def ItemSimilarity(self):
        itemSim = dict()
        # 得到每個物品有多少使用者產生過行為
        item_user_count = dict()
        # 同現矩陣
        count = dict()
        for user, item in self.user_score_dict.items():
            for i in item.keys():
                item_user_count.setdefault(i, 0)
                if self.user_score_dict[user][i] > 0.0:
                    item_user_count[i] += 1
                for j in item.keys():
                    count.setdefault(i, {}).setdefault(j, 0)
                    if (
                        self.user_score_dict[user][i] > 0.0
                        and self.user_score_dict[user][j] > 0.0
                        and i != j
                    ):
                        count[i][j] += 1
         # 共現矩陣 -> 相似度矩陣
        for i, related_items in count.items():
            itemSim.setdefault(i, dict())
            for j, cuv in related_items.items():
                itemSim[i].setdefault(j, 0)
                itemSim[i][j] = cuv / math.sqrt(item_user_count[i]*item_user_count[j])
        return itemSim

if __name__ == "__main__":
    m=ItemCF()
print(m.ItemSimilarity())

執行結果:
在這裡插入圖片描述

本文參考項亮的《推薦系統實踐》中基於使用者的協同過濾演算法內容