[推荐系统] 两种协同过滤

两种协同过滤

coding

import numpy as np
import itertools

def cos_likelyhood(x,y):
    assert x.shape == y.shape

    return x.dot(y.T) / np.sqrt(x.dot(x.T)) / np.sqrt(y.dot(y.T))


class Mine_CF():
    def __init__(self,M):
        self.M = M
        self.num_persons,self.num_items = M.shape[:2]
        likelyhood_user = np.zeros((self.num_persons,self.num_persons))
        for i in range(self.num_persons):
            for j in range(self.num_persons):
                likelyhood_user[i,j] = cos_likelyhood(self.M[i,:],self.M[j,:])
        self.likelyhood_user = likelyhood_user

        likelyhood_item = np.zeros((self.num_items,self.num_items))
        for i in range(self.num_items):
            for j in range(self.num_items):
                likelyhood_item[i,j] = cos_likelyhood(self.M[:,i].T,self.M[:,j].T)
        self.likelyhood_item = likelyhood_item
    def user_predection(self,user_id,top_k = 1):
        # 基于用户
        # 计算每个用户的相似度,得到相似度矩阵
        # 对每个物品利用用户相似度与该用户评分加权得到最终评价
        # 最终argmax得到商品
        item_scores = np.zeros(self.num_items)
        for j in range(self.num_items):
            if not self.M[user_id,j] == 0: # 不推荐重复的书,已经买过了
                continue
            for i in range(self.num_persons):
                item_scores[j] += self.likelyhood_user[user_id,i] * self.M[i,j]
        item_scores = item_scores / self.num_items
        
        return np.argpartition(item_scores,top_k)[::-1][:top_k]
            
    def item_prediction(self,user_id,top_k = 1):
        # 基于商品
        # 计算商品之间的相似度,得到相似度矩阵
        # 计算用户对新item的得分需要新item与所有老item相似度与得分乘积求和平均。
        item_scores = np.zeros(self.num_items)
        for i in range(self.num_items):
            if not self.M[user_id,i] == 0: # 不推荐重复的书,已经买过了
                continue
            for j in range(self.num_items):
                if i == j :
                    continue
                item_scores[i] += self.likelyhood_item[i,j] * self.M[user_id,i]
        item_scores = item_scores / self.num_items
        return np.argpartition(item_scores,top_k)[::-1][:top_k]
if __name__ == "__main__":
    cf = Mine_CF(M = np.array([[1,2,3],[0,1,2],[1,2,0]]))
    print(cf.user_predection(2))
    print(cf.item_prediction(2))
posted @ 2019-08-13 23:33  aoru45  阅读(265)  评论(0编辑  收藏  举报