推荐算法的Python实现——ItemCF(基于物品的协同过滤)

简介: 推荐算法的Python实现——ItemCF(基于物品的协同过滤)

1. 数据集


本博客用Movielens-1m数据集的ratings.dat作为推荐数据来训练ItemCF推荐模型。第一列是用户id(user_id)、第二列是物品id(item_id)、第三列是用户对物品的评分(score)、第四列是时间戳(timestamp)。


在Movielens-1m的原素数据集中,ratings.dat是用::作为分隔符的。在本次的python实现中,提前将分隔符::替换为了,,文件名ratings.dat改为了ratings.csv。


如果嫌麻烦不想改ratings.dat文件的内容,改代码也可以,主要替换以下两行:


userid, itemid, record, _ = line.split(",")
# 替换为
userid, itemid, record, _ = line.split("::")


ibcf = ItemBasedCF('ratings.csv')
# 替换为
ibcf = ItemBasedCF('ratings.dat')


2. 代码


import math
class ItemBasedCF:
    def __init__(self, datafile):
        self.datafile = datafile
        self.data = []
        self.trainData = {}
        self.itemSimMatrix = []
    def readData(self):
        """
        在Movielens数据集中读取数据
        """
        datalist = []
        for line in open(self.datafile):
            userid, itemid, record, _ = line.split(",") # 用逗号分割
            datalist.append((int(userid), int(itemid), int(record)))
        self.data = datalist
    def preprocessData(self):
        """
        把读入的数据转换为训练ICF模型需要的格式
        """
        traindata_list = {}
        for user, item, record in self.data:
            traindata_list.setdefault(user, {})
            traindata_list[user][item] = record
        self.trainData = traindata_list
    def itemSimilarity(self):
        """
        生成用户相似度矩阵
        """
        # 物品相似度矩阵
        self.itemSimMatrix = dict()
        # 物品-物品矩阵 格式:物品ID1:{物品ID2:同时给两件物品评分的人数}
        item_item_matrix = dict()
        # 物品-用户矩阵 格式:物品ID:给物品评分的人数
        item_user_matrix = dict()
        for user, items in self.trainData.items():
            for itemId, source in items.items():
                item_user_matrix.setdefault(itemId, 0) # 初始化item_user_matrix[itemId]
                item_user_matrix[itemId] += 1 # 给物品打分的人数+1
                item_item_matrix.setdefault(itemId, {})
                for i in items.keys():
                    if i == itemId:
                        continue
                    item_item_matrix[itemId].setdefault(i, 0)
                    # 计算同时给两个物品打分的人数,并对活跃用户进行惩罚
                    item_item_matrix[itemId][i] += 1 / math.log(1 + len(items) * 1.0)
        # 将物品-物品矩阵转换为物品相似度矩阵
        for itemId, relatedItems in item_item_matrix.items():
            self.itemSimMatrix.setdefault(itemId, dict()) # 初始化self.itemSimMatrix[itemId]
            for relatedItemId, count in relatedItems.items():
                self.itemSimMatrix[itemId][relatedItemId] = count / math.sqrt(item_user_matrix[itemId] * item_user_matrix[relatedItemId])
            # 归一化
            sim_max = max(self.itemSimMatrix[itemId].values())
            for item in self.itemSimMatrix[itemId].keys():
                self.itemSimMatrix[itemId][item] /= sim_max
    def recommend(self, user_id, k, N):
        """给用户推荐物品列表
            Args:
                userId:用户ID
                k:取和物品j最相似的K个物品
                N:推荐N个物品
            Return:
                推荐列表
            """
        rank = dict()
        interacted_items = self.trainData.get(user_id, {}) # 当前用户已经交互过的item
        # 遍历用户评分的物品列表
        for itemId, score in interacted_items.items(): # 取出每一个当前用户交互过的item
            # 取出与物品itemId最相似的K个物品及其评分
            for i, sim_ij in sorted(self.itemSimMatrix[itemId].items(), key=lambda x: x[1], reverse=True)[0:k]:
                # 如果这个物品j已经被用户评分了,舍弃
                if i in interacted_items.keys():
                    continue
                # 对物品ItemID的评分*物品itemId与j的相似度 之和
                rank.setdefault(i, 0)
                rank[i] += score * sim_ij
        # 堆排序,推荐权重前N的物品
        return dict(sorted(rank.items(), key=lambda x:x[1], reverse=True)[0:N])
if __name__ == "__main__":
    ibcf = ItemBasedCF('ratings.csv')
    ibcf.readData() # 读取数据
    ibcf.preprocessData() # 预处理数据
    ibcf.itemSimilarity() # 计算物品相似度矩阵
    # ------ 为用户 i 产生推荐 ------ #
    i = 1
    topN = ibcf.recommend(i, k=3, N=10)  # 输出格式item的id和评分
    topN_list = list(topN.keys())  # 只取对应的item的id
    print("------ i ------")
    print(i)
    print("------ topN_list ------")
    print(topN_list)
    # ------ 为全部用户产生推荐 ------ #
    # topN_list = {} # 存储为每一个用户推荐的列表
    # for each_user in ibcf.trainData:
    #     topN = ibcf.recommend(each_user, k=3, N=10) # item的id和评分
    #     topN_list[each_user] = list(topN.keys()) # 只取对应的item的id
    #
    #     print("------ topN ------")
    #     print(topN)
    #     print("------ topN_list[each_user] ------")
    #     print(topN_list[each_user])
    # print("------ topN_list ------")
    # print(topN_list)


对用户1(user_id=1)产生一次推荐的输出结果:


------ i ------
1
------ topN_list ------
[318, 1196, 364, 2858, 2096, 1302, 593, 1265, 1198, 1704]
相关文章
|
19天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
214 55
|
8天前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
102 66
|
2月前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
139 67
|
2月前
|
存储 搜索推荐 Python
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
128 61
|
2月前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
118 63
|
29天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
155 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
5天前
|
算法 网络协议 Python
探秘Win11共享文件夹之Python网络通信算法实现
本文探讨了Win11共享文件夹背后的网络通信算法,重点介绍基于TCP的文件传输机制,并提供Python代码示例。Win11共享文件夹利用SMB协议实现局域网内的文件共享,通过TCP协议确保文件传输的完整性和可靠性。服务器端监听客户端连接请求,接收文件请求并分块发送文件内容;客户端则连接服务器、接收数据并保存为本地文件。文中通过Python代码详细展示了这一过程,帮助读者理解并优化文件共享系统。
|
10天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
41 5
|
10天前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
45 0
|
2月前
|
机器学习/深度学习 算法 大数据
蓄水池抽样算法详解及Python实现
蓄水池抽样是一种适用于从未知大小或大数据集中高效随机抽样的算法,确保每个元素被选中的概率相同。本文介绍其基本概念、工作原理,并提供Python代码示例,演示如何实现该算法。
36 1