协同过滤推荐算法-基于物品的协同过滤ItemCF及python实现

  • 基于物品(项目)的协同过滤推荐(item-based CF)

  •  ItemCF的基本思想:是预先根据所有用户的历史偏好数据计算物品之间的相似性,然后把与用户喜欢的物品相类似的物品推荐给用户。

  •  比如物品ac非常相似,因为喜欢a的用户同时也喜欢c,而用户A喜欢a,所以把c推荐给用户AItemCF算法并不利用物品的内容属性计算物品之间的相似度, 主要通过分析用户的行为记录计算物品之间的相似度, 该算法认为, 物品a和物品c具有很大的相似度是因为喜欢物品a的用户大都喜欢物品c

 基于项目的协同过滤算法基于这样的假设:一个用户会喜欢与他之前喜欢的项目相似的项      目。因此,基于项目的协同过滤推荐关键在于计算物品之间的相似度。Item-based CF 认为两个项目被 越多的用户同时喜欢,两个项目就越相似。

  • ItemCF算法主要包括两个步骤:

          1. 计算物品之间的相似度

          2.根据物品的相似度和用户的历史行为给用户生成推荐列表(购买了该商品的用户也经常购买的其他商品)

 

 

1.建立“用户→物品”的索引

  •       记录每个用户最近点击、交互过的物品ID。
  •       给定任意用户ID,可以找到他近期感兴趣的物品列表

  2.建立“物品→物品”的索引

  •      计算物品之间两两相似度。
  •     对于每个物品﹐索引它最相似的k个物品О
  •      给定任意物品ID,可以快速找到它最相似的k 个物品

 

 

ItemCF的python实现过程为: 

 

# 基于物品的协同过滤算法

import random
import math
from operator import itemgetter


def ReadData(file, data):
    ''' 读取评分数据
        @param file  评分数据文件
        @param data 储存评分数据的List
    '''
    for line in file:
        line = line.strip('\n')
        linelist = line.split("::")
        data.append([linelist[0], linelist[1]])


def SplitData(data, M, key, seed):
    ''' 将数据分为训练集和测试集
        @param data   储存训练和测试数据的List
        @param M      将数据分为M份
        @param key    选取第key份数据做为测试数据
        @param seed   随机种子
        @return train 训练数据集Dict
        @return test  测试数据集Dict
    '''
    test = dict()
    train = dict()
    random.seed(seed)
    for user, item in data:
        if random.randint(0, M) == key:
            if user in test:
                test[user].append(item)
            else:
                test[user] = []
        else:
            if user in train:
                train[user].append(item)
            else:
                train[user] = []
    return train, test


def UserSimilarityOld(train):
    W = dict()
    for u in train.keys():
        W[u] = dict()
        for v in train.keys():
            if u == v:
                continue
            W[u][v] = len(list(set(train[u]) & set(train[v])))
            W[u][v] /= math.sqrt(len(train[u]) * len(train[v]) * 1.0)
    return W


def ItemSimilarity(train):
    ''' 计算物品相似度
        @param train 训练数据集Dict
        @return W    记录用户相似度的二维矩阵
    '''
    C = dict()
    N = dict()
    # 计算没两个item共有的user数目
    for u, items in train.items():
        for i in items:
            if i not in N:
                N[i] = 0
            N[i] += 1
            for j in items:
                if i == j:
                    continue
                if i not in C:
                    C[i] = dict()
                if j not in C[i]:
                    C[i][j] = 0
                C[i][j] += 1

    W = dict()
    for i, related_items in C.items():
        for j, cij in related_items.items():
            if i not in W:
                W[i] = dict()
            W[i][j] = cij / math.sqrt(N[i] * N[j])

    return W


def Coverage(train, test, W, N, K):
    ''' 获取推荐结果
        @param user  输入的用户
        @param train 训练数据集Dict
        @param W     记录用户相似度的二维矩阵
        @param N     推荐结果的数目
        @param K     选取近邻的数目
    '''
    recommned_items = set()
    all_items = set()

    for user in train.keys():
        for item in train[user]:
            all_items.add(item)

        rank = GetRecommendation(user, train, W, N, K)
        for item, pui in rank:
            recommned_items.add(item)
    print('len: ', len(recommned_items), '\n')
    return len(recommned_items) / (len(all_items) * 1.0)


def GetRecommendation(user, train, W, N, K):
    ''' 获取推荐结果
        @param user  输入的用户
        @param train 训练数据集Dict
        @param W     记录用户相似度的二维矩阵
        @param N     推荐结果的数目
        @param K     选取近邻的数目
    '''
    rank = dict()
    ru = train[user]
    for i in ru:
        for j, wj in sorted(W[i].items(), key=itemgetter(1), \
                            reverse=True)[0:K]:
            if j in ru:
                continue
            if j in rank:
                rank[j] += wj
            else:
                rank[j] = 0

    rank = sorted(rank.items(), key=itemgetter(1), reverse=True)[0:N]
    return rank


def Recall(train, test, W, N, K):
    ''' 计算推荐结果的召回率
        @param train 训练数据集Dict
        @param test  测试数据集Dict
        @param W     记录用户相似度的二维矩阵
        @param N     推荐结果的数目
        @param K     选取近邻的数目
    '''
    hit = 0
    all = 0
    for user in train.keys():
        if user in test:
            tu = test[user]
            rank = GetRecommendation(user, train, W, N, K)
            for item, pui in rank:
                if item in tu:
                    hit += 1
            all += len(tu)
    print(hit)
    print(all)
    return hit / (all * 1.0)


def Precision(train, test, W, N, K):
    ''' 计算推荐结果的准确率
        @param train 训练数据集Dict
        @param test  测试数据集Dict
        @param W     记录用户相似度的二维矩阵
        @param N     推荐结果的数目
        @param K     选取近邻的数目
    '''
    hit = 0
    all = 0
    for user in train.keys():
        if user in test:
            tu = test[user]
            rank = GetRecommendation(user, train, W, N, K)
            for item, pui in rank:
                if item in tu:
                    hit += 1
            all += N
    print(hit)
    print(all)
    return hit / (all * 1.0)


def Popularity(train, test, W, N, K):
    ''' 计算推荐结果的流行度
        @param train 训练数据集Dict
        @param test  测试数据集Dict
        @param W     记录用户相似度的二维矩阵
        @param N     推荐结果的数目
        @param K     选取近邻的数目
    '''
    item_popularity = dict()
    for user, items in train.items():
        for item in items:
            if item not in item_popularity:
                item_popularity[item] = 0
            item_popularity[item] += 1

    ret = 0
    n = 0
    for user in train.keys():
        rank = GetRecommendation(user, train, W, N, K)
        for item, pui in rank:
            ret += math.log(1 + item_popularity[item])
            n += 1
    ret /= n * 1.0
    return ret


if __name__ == '__main__':
    data = []
    M = 7
    key = 1
    seed = 1
    N = 10
    K = 10
    W = dict()
    rank = dict()

    print("this is the main function")
    file = open('../ml-1m/ratings.dat')
    ReadData(file, data)
    train, test = SplitData(data, M, key, seed)
    W = ItemSimilarity(train)
    recall = Recall(train, test, W, N, K)
    precision = Precision(train, test, W, N, K)
    popularity = Popularity(train, test, W, N, K)
    coverage = Coverage(train, test, W, N, K)
    print('recall: ', recall, '\n')
    print('precision: ', precision, '\n')
    print('Popularity: ', popularity, '\n')
    print('coverage: ', coverage, '\n')
else:
    print("this is not the main function")

 

  • 4
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于itemcf算法的图书推荐系统是一种利用用户对图书的行为数据(如购买、阅读、评分等)来实现个性化推荐的系统。 首先,系统会收集用户对图书的行为数据,并将其转化为用户-图书的倒排表。然后,根据用户的历史行为数据,找到与用户行为相似的其他用户集合,并推荐这些用户喜欢的图书。 itemcf算法的核心思想是基于图书之间的相似度来进行推荐。系统会计算图书之间的相似度,一般采用余弦相似度或Pearson相似度等计算方法。相似度高的图书会被认为是相似的,因此,当用户对某个图书表现出兴趣时,系统会根据该图书的相似图书来推荐给用户。 具体而言,基于itemcf算法的推荐系统会根据用户历史行为信息,计算用户对每本图书的兴趣度。首先,系统会根据用户历史行为数据计算图书之间的相似度,然后根据用户的历史行为,对相似图书的兴趣度进行加权计算,得到用户对每本图书的兴趣度评分。最后,系统会根据用户的兴趣度评分,给用户推荐兴趣度最高的图书。 基于itemcf算法的图书推荐系统具有以下优点:首先,可以根据用户的个性化需求进行精准的推荐。其次,该算法只需计算图书之间的相似度,而不需要考虑用户的个人特征,因此计算复杂度较低。另外,该算法能够发现用户潜在的兴趣点,帮助用户发现新的内容。 然而,基于itemcf算法的图书推荐系统也存在一些缺点,例如对于新用户或冷启动问题,由于缺乏用户的历史行为数据,推荐结果可能不准确。此外,由于该算法主要基于图书之间的相似度,可能忽略了用户的个人偏好和特征。 总的来说,基于itemcf算法的图书推荐系统能够根据用户行为数据实现个性化推荐,并可通过不断优化相似度计算和兴趣度评分算法来为用户提供更准确的推荐结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子瑜是橘子味

大大预言家,谢谢你的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值