python3实现基于用户的协同过滤

Python3实现基于用户的协同过滤

协同过滤是推荐系统中应用广泛的一种算法,其中基于用户的协同过滤是其中的一种常见方法。对于一个用户来说,根据他之前观看的电影或听过的歌曲,我们可以发现他喜欢哪些类型的电影或歌曲。对于相似的用户,我们可以基于他们相同或类似的偏好来推荐他们喜欢的电影或歌曲。下面是一个实现基于用户的协同过滤推荐系统的完整攻略。

数据集准备

在实现协同过滤算法之前,需要准备好一个数据集。以下是一个简单的例子,其中包含了5个用户以及他们的偏好值。

电影1 电影2 电影3 电影4 电影5
A 5 3 2 4 1
B 2 1 4 2 5
C 3 4 4 5 2
D 1 2 4 3 3
E 4 5 1 2 1

计算用户之间的相似度

计算用户之间的相似度是协同过滤算法的核心。我们可以使用“皮尔逊相关系数”或“余弦相似度”等方法计算用户之间的相似度。下面我们使用余弦相似度计算用户之间的相似度。

首先,我们需要对数据进行“归一化”,将偏好值从0到1之间的值。这里我们假设每个用户的偏好值均为非负整数。对于用户A,假设他总共评价了n部电影,$p_{i, A}$表示用户A对电影i的偏好值,$w_{i,A}$表示用户A对电影i的归一化偏好值,我们可以使用下面的公式将$p_{i, A}$转换为$w_{i,A}$:
$$w_{i,A}=\frac{p_{i,A}}{\sqrt{\sum_{k=1}^np_{k,A}^2}}$$

接下来,我们可以计算用户与用户之间的余弦相似度。假设用户A和用户B分别评价了n部电影,$w_{i,A}$表示用户A给电影i的归一化偏好值,$w_{i,B}$表示用户B给电影i的归一化偏好值,$s_{A,B}$表示用户A和用户B之间的相似度,则有以下公式:
$$s_{A,B}=\frac{\sum_{i=1}^{n}w_{i,A}w_{i,B}}{\sqrt{\sum_{i=1}^{n}(w_{i,A})^2}\sqrt{\sum_{i=1}^{n}(w_{i,B})^2}}$$

通过上面的公式,我们可以计算出每对用户之间的相似度。下面是一个示例代码:

import math

def cos_sim(pref1, pref2):
    """
    计算两个用户的余弦相似度
    :param pref1: 用户1的偏好字典
    :param pref2: 用户2的偏好字典
    :return: 余弦相似度
    """
    shared_items = set(pref1.keys()) & set(pref2.keys())
    if len(shared_items) == 0:
        return 0

    # 计算偏好向量的长度
    length1 = math.sqrt(sum([pow(pref1[item], 2) for item in shared_items]))
    length2 = math.sqrt(sum([pow(pref2[item], 2) for item in shared_items]))

    # 计算余弦相似度
    dot_product = sum([pref1[item] * pref2[item] for item in shared_items])
    return dot_product / (length1 * length2)

生成推荐结果

有了用户之间的相似度,我们就可以开始为每个用户生成推荐结果了。对于每个用户,我们可以找到与他相似度最高的K个用户,并从这K个用户中选出他没有评价过的电影作为推荐结果。

下面是一个示例代码:

def recommend(user, data, sim_func=cos_sim, k=3):
    """
    为用户推荐电影
    :param user: 用户
    :param data: 数据集
    :param sim_func: 相似度计算函数
    :param k: 取Top K个相似用户
    :return: 推荐结果
    """
    scores = {}
    total_sim = {}

    # 遍历所有用户
    for other in data.keys():
        if other == user:
            continue

        sim = sim_func(data[user], data[other])
        # 相似度小于等于0的用户不考虑
        if sim <= 0:
            continue

        # 遍历与用户其他相似的用户
        for item in data[other]:
            # 如果该用户已经评价过该电影,则不考虑
            if item in data[user]:
                continue

            # 计算评分总和和相似度总和
            scores.setdefault(item, 0)
            scores[item] += data[other][item] * sim
            total_sim.setdefault(item, 0)
            total_sim[item] += sim

    # 归一化评分
    rankings = [(item, round(score / total_sim[item], 2)) for item, score in scores.items()]

    # 按评分从高到低排序
    rankings.sort(key=lambda x: -x[1])

    # 选出前k个电影作为推荐结果
    return rankings[:k]

示例

下面是一个基于上述代码实现的简单示例。

data = {"A": {"电影1": 5, "电影2": 3, "电影3": 2, "电影4": 4, "电影5": 1},
        "B": {"电影1": 2, "电影2": 1, "电影3": 4, "电影4": 2, "电影5": 5},
        "C": {"电影1": 3, "电影2": 4, "电影3": 4, "电影4": 5, "电影5": 2},
        "D": {"电影1": 1, "电影2": 2, "电影3": 4, "电影4": 3, "电影5": 3},
        "E": {"电影1": 4, "电影2": 5, "电影3": 1, "电影4": 2, "电影5": 1}}

print(recommend("A", data, k=2))
# 输出 [('电影3', 0.94), ('电影2', 0.81)]

上述代码中,我们传入了数据集以及要查询的用户A,并设置了k=2,表示要返回Top2的推荐结果。程序运行后,会返回评分最高的两个电影,即“电影3”和“电影2”,以及他们的预测分值。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python3实现基于用户的协同过滤 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • Python常用数据类型之间的转换总结

    当我们在Python中进行编程时,常常需要将一个数据类型转换为另一个数据类型。Python提供了多种数据类型之间的转换方法,包括int()、float()、str()、list()、tuple()和dict()等。以下是Python常用数据类型之间的转换总结。 int()函数 int()用于将其他数据类型转换为整数类型。以下是一个示例,演示如何使用int()…

    python 2023年5月13日
    00
  • python 3x上的属性错误[关闭]

    【问题标题】:Attribute Error on python 3x [closed]python 3x上的属性错误[关闭] 【发布时间】:2023-04-03 20:25:01 【问题描述】: 我正在使用 tensorflow api 进行对象检测。我在 githup 上编写代码并尝试进行调试,然后我将面对这个错误。 File “<ipython-…

    Python开发 2023年4月8日
    00
  • Python实现列表拼接和去重的三种方式

    在Python中,列表(List)是一种常用的数据类型,它可以存储多个元素,并且这些元素可以是同一种或不同的数据类型。本文将详细讲解实现列表接和去重的三种,包括使用+运算符、extend()方法、set()函数等方法,同时提供多示例如下: 列表拼接 方法一:使用+运算符 在Python中,可以使用+运算符将两个列表合成一个新的列表例如: # 合并两个列表 l…

    python 2023年5月13日
    00
  • 详解Python中的路径问题

    详解Python中的路径问题 在Python编程中,路径问题是一个常见的问题。本文将详细讲解Python中的路径问题,包括的类型、路径的表示方法、路径的操作方法和两个示例。 路径类型 在Python中,路径可以分为以下两种类型: 相对路径:相对于当前工作目录的路径。 绝对路径:从根目录开始的完整路径。 路径表示方法 在Python中,路径可以使用以下两种表示…

    python 2023年5月13日
    00
  • numpy中三维数组中加入元素后的位置详解

    下面我就给您详细讲解一下“numpy中三维数组中加入元素后的位置详解”的完整攻略。 简介 NumPy是一个强大的数学库,主要用于进行数值计算。它是Python科学计算的核心库之一,提供了高性能的多维数组(ndarray)对象,并且在这些数组上操作的一系列函数。 三维数组是NumPy中最常用的数组类型之一。通过三维数组,我们可以处理多维数据,如图片、时间序列等…

    python 2023年6月5日
    00
  • Python docutils文档编译过程方法解析

    Python docutils文档编译过程方法解析 1. 引言 Python docutils是一个强大的文档工具,它可以将文本文件转换成多种格式,如HTML、LaTeX、ODT和PDF等。在本文中,我们将详细讲解Python docutils文档编译过程及其方法解析,包括准备工作、安装、使用及示例说明等。 2. 准备工作 在开始之前,我们需要做一些准备工作…

    python 2023年6月5日
    00
  • python中日期和时间格式化输出的方法小结

    Python中日期和时间格式化输出的方法小结 在Python中,我们可以使用datetime模块来处理日期和时间。在输出日期和时间时,我们通常需要将其格式化为特定的字符串格式。本文将详细讲解Python中日期和时间格式化输出的方法,并提供两个示例说明。 strftime()函数 在Python中,我们可以使用strftime()函数将日期和时间格式化为字符串…

    python 2023年5月14日
    00
  • Python爬虫获取数据保存到数据库中的超详细教程(一看就会)

    下面我将为您详细讲解“Python爬虫获取数据保存到数据库中的超详细教程(一看就会)”这篇文章的内容。 一、前置知识 在学习这篇文章之前,您需要掌握以下知识: Python基础语法 数据库基础知识 爬虫基础知识 如果您还不熟悉以上知识,可以先学习一下相关的教程。 二、Python爬虫获取数据保存到数据库中的步骤 确定需要爬取的网站和数据 首先,我们需要确定需…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部