深入理解协同过滤算法及其实现

导语

        个性化推荐系统在现代数字时代扮演着重要的角色,协助用户发现他们可能感兴趣的信息、产品或媒体内容。协同过滤是个性化推荐系统中最流行和有效的算法之一。

目录

协同过滤算法的原理

基于用户的协同过滤(User-Based Collaborative Filtering)

用户相似性计算

余弦相似度

Demo

皮尔逊相关系数

Demo

近邻用户选择

相似性度量方法

用户邻居的选择

阈值过滤

个性化相似性权重

评分预测

基于项目的协同过滤(Item-Based Collaborative Filtering)

协同过滤的不同变种

数据预处理

python示例

用户-项目评分矩阵的创建

基于用户的协同过滤

基于项目的协同过滤

性能优化和扩展


协同过滤算法的原理

基于用户的协同过滤(User-Based Collaborative Filtering)

用户相似性计算

当计算用户之间的相似性时,通常使用余弦相似度和皮尔逊相关系数等度量方法

余弦相似度

余弦相似度是一种用于测量两个非零向量之间夹角的相似性度量。在协同过滤中,用户可以被视为向量,其中每个维度代表一个项目,值表示用户对该项目的评分。

余弦相似度的计算步骤如下:

  1. 计算两个用户向量的点积(内积)。
  2. 计算每个用户向量的范数(模)。
  3. 使用点积和范数的乘积来计算余弦相似度。

余弦相似度公式如下:

Demo

import numpy as np

# 两个用户的评分向量
user1_ratings = np.array([5, 4, 0, 0, 1])
user2_ratings = np.array([0, 0, 5, 4, 2])

# 计算余弦相似度
cosine_similarity = np.dot(user1_ratings, user2_ratings) / (np.linalg.norm(user1_ratings) * np.linalg.norm(user2_ratings))

print(f"余弦相似度: {cosine_similarity}")

皮尔逊相关系数

皮尔逊相关系数是一种用于衡量两个变量之间线性关系强度和方向的统计度量。在协同过滤中,它被用来度量用户评分之间的相关性。

皮尔逊相关系数的计算步骤如下:

  1. 计算两个用户评分向量的均值。
  2. 计算每个用户评分向量与均值的差异。
  3. 计算差异的皮尔逊相关系数。

皮尔逊相关系数的公式如下:

Demo

import numpy as np

# 两个用户的评分向量
user1_ratings = np.array([5, 4, 0, 0, 1])
user2_ratings = np.array([0, 0, 5, 4, 2])

# 计算均值
mean_user1 = np.mean(user1_ratings)
mean_user2 = np.mean(user2_ratings)

# 计算差异
diff_user1 = user1_ratings - mean_user1
diff_user2 = user2_ratings - mean_user2

# 计算皮尔逊相关系数
pearson_correlation = np.sum(diff_user1 * diff_user2) / (np.sqrt(np.sum(diff_user1**2)) * np.sqrt(np.sum(diff_user2**2)))

print(f"皮尔逊相关系数: {pearson_correlation}")

近邻用户选择

相似性度量方法

        在选择相似用户时,首先需要定义相似性度量方法。常用的相似性度量方法包括余弦相似度、皮尔逊相关系数、Jaccard相似度等。选择合适的相似性度量方法取决于数据的性质和问题的特点。余弦相似度通常用于评分数据,而Jaccard相似度通常用于二进制数据(用户是否喜欢或点击某个项目)。

用户邻居的选择

        一旦选择了相似性度量方法,接下来需要确定要选择多少个相似用户。通常,选择的相似用户数量由一个参数 k 控制,称为 "近邻数"。增加 k 可以提高覆盖范围,但可能降低准确性,因为更多的用户可能包括不太相似的用户。选择合适的 k 是一个权衡的问题,可以通过交叉验证等技术来确定。

阈值过滤

        除了基于 k 的选择,还可以使用阈值过滤来选择相似用户。例如,只选择与目标用户相似度大于某个阈值的用户。这种方法可以帮助过滤掉不太相似的用户,提高推荐的准确性。阈值的选择通常需要基于实际问题和数据进行调整。

个性化相似性权重

        在某些情况下,不同用户之间的相似性可能有不同的重要性。例如,某些用户可能与目标用户在特定领域或时间段内的行为更相关。因此,可以为每个相似用户分配个性化的相似性权重,以更好地反映他们的贡献。

评分预测

        首先,我们需要选择一组相似用户,这些用户与目标用户在过去的行为上相似。我们可以使用之前计算的相似性度量(如余弦相似度或皮尔逊相关系数)来衡量用户之间的相似性。

        一旦选择了相似用户,我们需要获取这些相似用户对于尚未评分的项目的历史评分数据。这些评分数据将用于预测目标用户的评分。

        接下来,我们使用相似用户的历史评分数据来计算目标用户对于尚未评分项目的预测评分。

可以使用加权平均法或者基于加权回归的方法:

        

注:以下各部分不再详细展开,可在入门基础情况下自行扩展

基于项目的协同过滤(Item-Based Collaborative Filtering)

  • 项目相似性计算:详细讨论如何计算项目之间的相似性,使用余弦相似度等度量。
  • 近邻项目选择:深入讨论如何为目标用户找到他们已评分项目的相似项目,以生成更精准的推荐。
  • 评分预测:解释如何基于这些相似项目的历史评分来生成最终的推荐。

协同过滤的不同变种

  • 基于隐式反馈的协同过滤:处理隐式反馈数据,如用户浏览历史和点击记录。
  • 深度学习中的协同过滤:使用深度学习模型来改进协同过滤的性能。
  • 时序协同过滤:考虑时间因素来预测用户行为和兴趣的演变。

数据预处理

  • 数据准备:准备用户-项目评分数据,通常以DataFrame的形式表示。
  • 数据清洗:处理缺失值、异常值和重复数据,以确保数据质量。
  • 数据分割:将数据集分为训练集、验证集和测试集,以进行模型训练和评估。

python示例

用户-项目评分矩阵的创建

import pandas as pd

# 创建用户-项目评分矩阵
ratings = pd.DataFrame({
    'User1': [5, 4, 0, 0, 1],
    'User2': [0, 0, 5, 4, 2],
    'User3': [4, 5, 0, 0, 0],
    'User4': [0, 0, 4, 5, 0]
}, index=['Item1', 'Item2', 'Item3', 'Item4', 'Item5'])

基于用户的协同过滤

from sklearn.metrics.pairwise import cosine_similarity

# 计算用户之间的相似性(余弦相似度)
user_similarity = cosine_similarity(ratings.fillna(0))

# 选择目标用户和要推荐的项目
target_user = 'User1'
target_item = 'Item3'

# 预测目标用户对目标项目的评分
target_user_ratings = ratings.loc[:, target_user]
similar_users = user_similarity[ratings.index == target_item]
predicted_rating = (similar_users @ target_user_ratings) / sum(similar_users[0])

print(f"预测用户{target_user}对项目{target_item}的评分为: {predicted_rating[0]}")

基于项目的协同过滤

# 预测目标用户对目标项目的评分
target_item_ratings = ratings.loc[target_item, :]
similar_items = item_similarity[ratings.columns == target_item]
predicted_rating = (similar_items @ target_item_ratings) / sum(similar_items[0])

print(f"预测用户{target_user}对项目{target_item}的评分为: {predicted_rating[0]}")

性能优化和扩展

        在示例基础上还可以在以下方向做出优化

  • 模型改进:改进协同过滤模型,包括使用加权评分、考虑时间因素等方法,以提高推荐质量。
  • 大规模数据处理:处理大规模数据集,包括分布式计算和分布式存储的使用,以处理海量用户和项目的评分数据。
  • 实时推荐:介绍如何将协同过滤算法应用于实时推荐系统,以满足用户的即时需求。

猜你喜欢

转载自blog.csdn.net/qq_52213943/article/details/132627353