协同过滤推荐(Collaborative Filtering Recommendation)是一种常用的推荐系统算法,用于根据用户的行为和偏好来预测他们可能喜欢的物品或内容。该算法基于两个基本假设:用户会倾向于与兴趣相似的其他用户有相似的行为模式,以及用户过去喜欢的物品或内容可能会预示他们将来的偏好。在本章的内容中,将详细讲解协同过滤推荐的知识和用法。
3.1 协同过滤推荐介绍
协同过滤推荐(Collaborative Filtering Recommendation)算法基于用户行为数据或偏好信息进行计算,并建立用户之间或物品之间的关联性模型。根据这些模型,可以进行如下两种类型的协同过滤推荐:
- 基于用户的协同过滤推荐:该方法首先找到与目标用户具有相似兴趣的其他用户,然后利用这些用户的行为数据来预测目标用户可能感兴趣的物品或内容。例如,如果用户A和用户B在过去喜欢了相似的电影,那么当用户A喜欢新电影时,可以推荐给用户B。
- 基于物品的协同过滤推荐:该方法首先计算物品之间的相似度,然后根据用户的行为数据,推荐与用户过去喜欢的物品相似的其他物品。例如,如果用户A过去购买了一本特定的书籍,而书籍B与该书籍在内容或类别上相似,那么可以将书籍B推荐给用户A。
协同过滤推荐算法不需要事先了解物品的详细特征或用户的个人信息,而是通过分析用户之间的行为和偏好的相似性来进行推荐。这种算法的优点是能够发现潜在的兴趣和关联性,即使用户和物品之间没有显式的关联。然而,它也存在一些挑战,如冷启动问题(针对新用户或新物品如何进行推荐)和稀疏性问题(用户和物品之间的行为数据往往是不完整的)等。因此,在实际应用中,通常会将协同过滤与其他推荐算法和技术相结合,以提高推荐的准确性和效果。
3.2 基于用户的协同过滤
基于用户的协同过滤(User-Based Collaborative Filtering)是一种协同过滤推荐算法,通过寻找与目标用户具有相似兴趣的其他用户,来进行个性化推荐。
3.2.1 基于用户的协同过滤算法的基本步骤
(1)数据收集:首先,需要收集用户的行为数据,如用户的购买记录、评分、点击历史等。这些数据用于建立用户之间的相似性模型。
(2)相似度计算:通过计算用户之间的相似度来度量它们的兴趣相似程度。常用的相似度度量方法包括余弦相似度、皮尔逊相关系数等。相似度计算通常基于用户之间的行为数据,比如共同购买过的物品、评分的相似性等。
(3)目标用户选择:根据目标用户的历史行为,选择与其相似度较高的一组邻居用户。通常会设定一个阈值或选取前K个相似用户作为邻居。
(4)预测推荐:对于目标用户未曾接触过的物品或内容,根据邻居用户的行为进行预测推荐。常用的预测方法有加权平均和加权求和。具体来说,可以根据邻居用户对物品的评分或行为进行加权平均,得到目标用户对物品的预测评分。然后根据这些评分,为目标用户生成推荐列表。
(5)推荐结果过滤和排序:对生成的推荐列表进行过滤和排序,以提供最相关和个性化的推荐结果。可以考虑一些策略,比如去除目标用户已经购买或评分过的物品、根据评分排序推荐列表等。
基于用户的协同过滤算法的关键在于相似度计算和邻居选择。相似度计算方法的选择对推荐结果的准确性有重要影响。同时,邻居选择的合理性也需要权衡准确性和计算效率之间的平衡。
注意:基于用户的协同过滤算法在面对大规模用户和物品数据时可能面临计算复杂度和存储开销的挑战。此外,算法还可能受到冷启动问题和稀疏性问题的影响。因此,在实际应用中,可以结合其他推荐算法和技术,以提高推荐效果和系统的可扩展性。
3.2.2 Python的用户的协同过滤算法
在Python程序中实现基于用户的协同过滤算法时,可以使用NumPy和Pandas等库来进行数据处理和计算。例如下面是一个简单的例子,演示了使用Python实现基于用户的协同过滤推荐的过程。
源码路径:daima/3/yongxie.py
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
# 读取电影评分数据集
ratings = pd.read_csv('ratings.csv')
# 创建用户-电影评分矩阵
user_movie_matrix = ratings.pivot_table(index='userId', columns='movieId', values='rating')
# 计算用户之间的相似度(余弦相似度)
user_similarity = cosine_similarity(user_movie_matrix.fillna(0))
# 为目标用户生成推荐列表
def user_based_collaborative_filtering(target_user_id, top_n=5):
target_user_index = ratings[ratings['userId'] == target_user_id].index[0]
target_user_similarities = user_similarity[target_user_index]
similar_users_indices = target_user_similarities.argsort()[:-top_n-1:-1]
similar_users_ratings = user_movie_matrix.iloc[similar_users_indices].mean()
recommended_movies = similar_users_ratings.drop(user_movie_matrix.loc[target_user_id].dropna().index)
return recommended_movies.sort_values(ascending=False)[:top_n]
# 示例调用
target_user_id = 1
recommendations = user_based_collaborative_filtering(target_user_id, top_n=3)
print("Recommendations for User", target_user_id)
for movie_id, rating in recommendations.iteritems():
print("Movie", movie_id, "(Predicted Rating:", round(rating, 2), ")")
对上述代码的具体说明如下:
- 首先,读取了包含用户对电影评分的数据集(如MovieLens数据集)。
- 然后,将数据集转换为用户-电影评分矩阵,其中行表示用户,列表示电影,每个元素表示用户对电影的评分。接下来,使用函数cosine_similarity()计算用户之间的相似度矩阵。然后,定义了函数user_based_collaborative_filtering(),它接收目标用户的ID和要推荐的电影数量作为参数。在函数user_based_collaborative_filtering()中找到目标用户的索引,并根据相似度矩阵选择与目标用户最相似的用户。然后,计算这些相似用户对电影的平均评分,并过滤掉目标用户已经评分过的电影。
- 最后,根据评分排序,返回前N个推荐电影。在本实例中调用函数user_based_collaborative_filtering(),指定目标用户ID为1,并打印出推荐的电影和预测评分。
执行后会输出:
Recommendations for User 1:
Movie 4 (Predicted Rating: 5.0 )
Movie 3 (Predicted Rating: 4.5 )
Movie 2 (Predicted Rating: 4.0 )
这针对用户1的基于用户的协同过滤推荐结果。推荐列表显示了推荐的电影及其预测评分。在这个示例中,推荐了3部电影,按预测评分降序排列。对于用户1,根据与其他用户的相似度,预测为用户1推荐了电影4、电影3和电影2。其中,电影4的预测评分最高,为5.0。
3.3 基于物品的协同过滤
基于物品的协同过滤是一种推荐算法,它基于物品之间的相似性来进行推荐。与基于用户的协同过滤不同,基于物品的协同过滤是通过分析物品之间的关联性来进行推荐,而不是分析用户之间的相似性。
3.3.1 计算物品之间的相似度
计算物品之间的相似度是基于物品的协同过滤中的重要步骤。常见的计算相似度的方法包括余弦相似度、皮尔逊相关系数和欧氏距离等。
(1)余弦相似度(Cosine Similarity)
余弦相似度衡量两个向量之间的夹角余弦值,值域在[-1, 1]之间。计算步骤如下:
- 将物品向量表示为评分向量或二进制向量。
- 计算两个物品向量的内积。
- 计算每个物品向量的范数(向量长度)。
- 使用内积和范数计算余弦相似度。
(2)皮尔逊相关系数(Pearson Correlation)
皮尔逊相关系数衡量两个变量之间的线性相关性,值域在[-1, 1]之间。计算步骤如下:
- 将物品向量表示为评分向量。
- 计算两个物品向量的均值。
- 计算两个物品向量的差值与均值之间的协方差。
- 计算两个物品向量的标准差。
- 使用协方差和标准差计算皮尔逊相关系数。
(3)欧氏距离(Euclidean Distance)
欧氏距离衡量两个向量之间的距离,值越小表示越相似。计算步骤如下:
- 将物品向量表示为评分向量或二进制向量。
- 计算两个物品向量的差的平方和。
- 对平方和进行开方。
在实际应用中,可以使用Python的科学计算库(如NumPy)来计算这些相似度指标。例如是一个简单的例子,展示如何使用NumPy计算余弦相似度。
源码路径:daima/3/yu.py
import numpy as np
# 两个物品的评分向量
item1_ratings = [5, 4, 3, 0, 2]
item2_ratings = [4, 5, 0, 1, 3]
# 计算余弦相似度
similarity = np.dot(item1_ratings, item2_ratings) / (np.linalg.norm(item1_ratings) * np.linalg.norm(item2_ratings))
print("Cosine Similarity:", similarity)
在上述代码中,使用NumPy的dot函数计算两个物品评分向量的内积,然后使用linalg.norm函数计算每个物品向量的范数,最后计算余弦相似度。执行后会输出:
Cosine Similarity: 0.8765483240617117
注意:以上实例只是使用了计算相似度的一种方法,具体使用哪种相似度度量方法取决于数据集的特点和算法的要求。
3.3.2 进行推荐
在本节的内容中,将通过下面的实例展示使用基于物品的协同过滤为用户推荐电影的过程。
源码路径:daima/3/wu.py
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 读取电影评分数据集
ratings = pd.read_csv('ratings.csv')
# 读取电影数据集
movies = pd.read_csv('movies.csv')
# 创建用户-电影评分矩阵
user_movie_matrix = ratings.pivot_table(index='userId', columns='movieId', values='rating')
# 计算物品之间的相似度(余弦相似度)
item_similarity = cosine_similarity(user_movie_matrix.fillna(0).T)
# 为用户生成电影推荐列表
def item_based_collaborative_filtering(user_id, top_n=5):
user_ratings = user_movie_matrix.loc[user_id].fillna(0)
weighted_ratings = np.dot(item_similarity, user_ratings)
similarity_sums = np.sum(item_similarity, axis=1)
normalized_ratings = weighted_ratings / (similarity_sums + 1e-10)
sorted_indices = np.argsort(normalized_ratings)[::-1][:top_n]
recommended_movies = movies.loc[sorted_indices]
return recommended_movies
# 示例调用
target_user_id = 1
recommendations = item_based_collaborative_filtering(target_user_id, top_n=3)
print("Recommendations for User", target_user_id)
for index, row in recommendations.iterrows():
print("Movie:", row['title'])
在上述代码中,假设已经有了用户对电影的评分数据集(ratings.csv)和电影信息数据集(movies.csv)。首先,将评分数据集转换为“用户-电影”评分矩阵,并使用余弦相似度计算物品之间的相似度矩阵。然后,定义了函数item_based_collaborative_filtering(),它接收目标用户ID和要推荐的电影数量作为参数。在函数中,根据目标用户的评分向量和物品相似度矩阵计算加权评分,并将加权评分归一化。然后,根据归一化评分排序,选取前N个推荐电影。最后调用函数item_based_collaborative_filtering(),指定目标用户ID为1,并打印出推荐的电影。执行后会输出:
Recommendations for User 1:
Movie: The Shawshank Redemption (1994)
Movie: The Godfather (1972)
Movie: Pulp Fiction (1994)
这是针对用户1的基于物品的协同过滤推荐结果。推荐列表显示了推荐的电影。在这个示例中,推荐了3部电影,根据与用户1已评分的电影的相似度进行推荐。根据相似度计算,预测用户1可能喜欢的电影是《The Shawshank Redemption》,《The Godfather》和《Pulp Fiction》。
3.4 基于模型的协同过滤
基于模型的协同过滤是一种利用机器学习模型来预测用户对物品的评分或者进行推荐的方法。与基于用户或基于物品的协同过滤相比,基于模型的方法可以更好地处理数据稀疏性和冷启动问题,并且能够利用更多的特征进行预测。
基于模型的协同过滤的一种常见方法是矩阵分解(Matrix Factorization),它将“用户-物品”评分矩阵分解为两个低维矩阵的乘积,从而捕捉用户和物品之间的潜在特征。具体而言,矩阵分解将用户和物品表示为向量形式,并通过学习这些向量来预测用户对未知物品的评分。
3.4.1 矩阵分解模型
矩阵分解(Matrix Factorization)是一种基于模型的协同过滤方法,用于预测用户对未知物品的评分或进行推荐。该方法将“用户-物品”评分矩阵分解为两个低维矩阵的乘积,从而捕捉用户和物品之间的潜在特征。在矩阵分解模型中,评分矩阵R的维度为m×n,其中m表示用户数量,n表示物品数量。该矩阵中的每个元素R[i][j]表示用户i对物品j的评分。我们的目标是学习两个低维矩阵P和Q,使得它们的乘积逼近原始评分矩阵R。
具体而言,矩阵P的维度为m×k,每行表示一个用户的特征向量,维度为k。矩阵Q的维度为n×k,每行表示一个物品的特征向量,维度也为k。特征向量中的每个元素表示了用户或物品在隐含特征空间中的位置。通过学习这些特征向量,我们可以预测用户对未知物品的评分。
在训练过程中,我们使用梯度下降等优化算法来最小化预测评分与实际评分之间的误差。通过迭代更新P和Q的值,我们可以不断提高模型的准确性。通常,训练过程会设置一些超参数,如学习率、正则化参数等,以控制模型的复杂度和训练的速度。
在训练完成后,可以使用学习到的特征向量来进行预测。给定一个用户和一个物品,我们可以通过计算对应的特征向量之间的内积来预测评分。预测评分越高,表示用户可能对该物品的兴趣越大。
例如下面的实例演示了使用矩阵分解模型实现电影推荐的过程。
源码路径:daima/3/ju.py
import pandas as pd
from surprise import Dataset, Reader, SVD
from surprise.model_selection import train_test_split
# 电影评分数据
ratings = {
"User1": {
"Movie1": 4,
"Movie2": 5,
"Movie3": 3,
"Movie4": 4,
"Movie5": 2
},
"User2": {
"Movie1": 3,
"Movie2": 4,
"Movie3": 4,
"Movie4": 3,
"Movie5": 5
},
"User3": {
"Movie1": 5,
"Movie2": 2,
"Movie3": 4,
"Movie4": 3,
"Movie5": 5
},
# 添加更多用户和电影的评分数据
}
# 将字典转换为DataFrame
df = pd.DataFrame(ratings).stack().reset_index()
df.columns = ["user", "movie", "rating"]
# 构建数据集
reader = Reader(rating_scale=(1, 5))
data = Dataset.load_from_df(df[["user", "movie", "rating"]], reader)
# 划分训练集和测试集
trainset, testset = train_test_split(data, test_size=0.2)
# 训练模型
model = SVD()
model.fit(trainset)
# 预测评分
predictions = model.test(testset)
# 打印用户的Top N推荐电影
user_id = "User1"
top_n = 5
user_ratings = ratings[user_id]
rated_movies = user_ratings.keys()
recommendations = []
for movie_id in model.trainset.ir.keys():
if movie_id not in rated_movies:
predicted_rating = model.predict(user_id, movie_id).est
recommendations.append((movie_id, predicted_rating))
recommendations = sorted(recommendations, key=lambda x: x[1], reverse=True)[:top_n]
print(f"Top {top_n} recommendations for {user_id}:")
for movie_id, _ in recommendations:
print("Movie ID:", movie_id)
对上述代码的具体说明如下:
- 首先,定义了一个包含用户对电影的评分数据的字典ratings,其中键是用户ID,值是另一个字典,表示用户对不同电影的评分。
- 然后,将字典转换为DataFrame,通过pd.DataFrame()将ratings字典转换为DataFrame,其中每一行包含用户、电影和评分。
- 接下来,使用库Surprise构建数据集,通过Reader对象定义评分范围,并使用Dataset.load_from_df()将DataFrame转换为Surprise库中的数据集对象。
- 然后,将数据集划分为训练集和测试集,使用函数train_test_split()按照指定的比例将数据集划分为训练集和测试集。使用SVD算法训练模型,创建SVD对象,并使用训练集调用fit()方法进行模型训练。
- 然后预测评分,使用训练好的模型对测试集进行评分预测,通过调用model.test()方法返回预测结果。
- 接下来,打印输出针对某用户的Top N推荐电影,选择指定的用户ID(例如"User1"),根据模型预测的评分生成未评分电影的推荐列表,并按照评分从高到低进行排序。
- 最后打印输出推荐结果,将生成的Top N推荐电影打印出来,输出格式为"Movie ID: 电影ID"。
总体而言,本实例使用了基于SVD算法的协同过滤推荐方法,在给定的电影评分数据上构建了一个推荐系统,并输出了指定用户的Top N推荐电影。请注意,本实例中的数据集数据是自定义的字典数据,大家可以根据实际情况替换为您自己的电影评分数据。
3.4.2 基于图的模型
基于图的推荐系统模型是一种利用图结构来表示用户和物品之间的关系,并通过图上的算法来进行推荐的方法。通常需要通过如下步骤实现基于图的模型:
(1)构建用户-物品图:将用户和物品作为图的节点,根据用户与物品之间的交互关系构建边。常见的交互关系可以包括用户对物品的评分、购买历史、浏览行为等。
(2)图的表示:将用户-物品图转化为计算机可以处理的数据结构,常用的表示方法包括邻接矩阵和邻接表。邻接矩阵表示节点之间的连接关系,而邻接表则记录每个节点的邻居节点。
(3)图上的算法:利用图上的算法来计算节点之间的相似度或重要性。常见的算法包括基于路径的算法(如最短路径、随机游走)、基于图结构的特征提取算法(如图嵌入)以及基于图聚类的算法。
(4)生成推荐结果:根据用户的历史行为和图上的算法,计算用户与未交互物品之间的关联程度,给用户推荐与之相关性较高的物品。常见的推荐方法包括基于图的随机游走、基于路径的推荐以及基于图嵌入的推荐。
基于图的推荐系统模型具有以下优点:
- 考虑了用户和物品之间的复杂关系:通过建模用户和物品之间的交互关系,能够更好地捕捉到用户的兴趣和物品的特征。
- 考虑了上下文信息:通过分析用户和物品在图上的位置和连接情况,可以获得更多的上下文信息,提高推荐的准确性。
- 能够处理冷启动问题:当新用户或新物品加入系统时,通过图上的算法可以利用已有的交互关系推断其与其他节点的关联程度,从而进行推荐。
然而,基于图的推荐系统模型也存在一些挑战和限制:
- 图的构建和处理需要大量的计算资源:当用户和物品数量庞大时,构建和处理图的复杂度会显著增加,需要高效的算法和计算资源。
- 图的表示和算法的选择需要合理:不同的图表示方法和算法对推荐效果有影响,需要根据具体应用场景选择合适的方法。
- 冷启动问题仍然存在:虽然基于图的模型可以一定程度上处理冷启动问题,但对于完全没有交互信息的新用户和新物品仍然存在挑战。
综上所述,基于图的推荐系统模型可以通过建模用户和物品之间的关系来提供个性化的推荐,但在实际应用中需要仔细选择合适的图表示方法和算法,并考虑资源消耗和冷启动等问题。
当涉及到基于图的推荐系统时,一种常见的方法是使用基于邻域的协同过滤算法。这种算法利用用户和物品之间的交互关系构建一个“用户-物品”图,并通过图上的算法计算物品之间的相似度。例如下面的实例演示了使用基于图的模型实现商品推荐的过程。
源码路径:daima/3/tu.py
import networkx as nx
from itertools import combinations
# 商品交互数据
interactions = {
"User1": ["Item1", "Item2", "Item3"],
"User2": ["Item2", "Item3", "Item4"],
"User3": ["Item1", "Item4", "Item5"],
# 添加更多用户和商品的交互数据
}
# 创建用户-商品图
graph = nx.Graph()
# 添加用户节点和商品节点
users = list(interactions.keys())
items = set(item for item_list in interactions.values() for item in item_list)
graph.add_nodes_from(users, bipartite=0)
graph.add_nodes_from(items, bipartite=1)
# 添加用户和商品之间的边
for user, item_list in interactions.items():
for item in item_list:
graph.add_edge(user, item)
# 计算商品之间的相似度
item_similarity = {}
for item1, item2 in combinations(items, 2):
common_users = list(nx.common_neighbors(graph, item1, item2))
if common_users:
similarity = len(common_users) / (len(set(graph.neighbors(item1))) + len(set(graph.neighbors(item2))))
item_similarity[(item1, item2)] = similarity
item_similarity[(item2, item1)] = similarity
# 根据相似度推荐商品
target_user = "User1"
recommended_items = set()
for item in items:
if item not in interactions[target_user]:
item_score = sum(item_similarity.get((item, interacted_item), 0) for interacted_item in interactions[target_user])
recommended_items.add((item, item_score))
# 按照相似度得分从高到低对推荐商品排序
recommended_items = sorted(recommended_items, key=lambda x: x[1], reverse=True)
print("Recommendations for", target_user)
for item, _ in recommended_items:
print("Item:", item)
对上述代码的具体说明如下:
- 首先,定义了商品之间的交互数据,即每个用户与其交互过的商品。
- 然后,创建了一个空的图对象,添加了用户节点和商品节点到图中,并指定它们的类型为二分图(bipartite)。在图中添加了用户和商品之间的边,表示它们之间的交互关系。
- 接下来,计算了商品之间的相似度。通过遍历商品组合并找到它们之间的共同用户,计算相似度作为共同用户数与两个商品邻居总数的比例。
- 接着,我们选择了一个目标用户,即要为其进行推荐的用户。
- 然后,遍历所有商品,并计算每个商品与目标用户已交互过的商品之间的得分。得分是通过对目标用户已交互过的商品计算商品之间的相似度加权得出的。
- 最后,按照得分从高到低对推荐商品进行排序,并输出推荐结果。
执行后会输出:
Recommendations for User1
Item: Item4
Item: Item5
本实例展示了基于图的商品推荐系统的实现过程,利用商品之间的交互关系和相似度计算来为目标用户生成推荐商品列表。
3.5 混合型协同过滤
混合型协同过滤是一种结合基于用户和基于物品的协同过滤方法的推荐算法,它综合了两种方法的优势,以提高推荐系统的准确性和个性化程度。在混合型协同过滤中,基于用户的协同过滤方法和基于物品的协同过滤方法被同时应用。这种方法首先利用基于用户的协同过滤方法,通过计算用户之间的相似度,找到与目标用户相似的一组用户。然后,基于这组相似用户的评分数据,使用基于物品的协同过滤方法来计算目标用户对未评价物品的喜好程度。
具体来说,混合型协同过滤可以按照以下步骤进行:
(1)根据用户的历史评分数据,计算用户之间的相似度。可以使用基于用户的协同过滤方法,如计算皮尔逊相关系数或余弦相似度。
(2)选择与目标用户最相似的一组用户作为邻居用户集合。
(3)基于邻居用户的评分数据,计算目标用户对未评价物品的喜好程度。可以使用基于物品的协同过滤方法,如计算加权平均评分或基于相似度的加权评分。
(4)综合基于用户和基于物品的评分预测结果,生成最终的推荐列表。可以采用加权融合的方式,将两种方法的预测结果按一定权重进行组合。
混合型协同过滤算法的优点在于综合了基于用户和基于物品的方法,能够克服它们各自的局限性。基于用户的方法更加关注用户的兴趣和行为模式,而基于物品的方法更注重物品的特征和相似度。通过结合两者,混合型协同过滤能够提供更准确和个性化的推荐结果,兼顾了用户和物品两个维度的信息。
在实现混合型协同过滤算法时,可以借助现有的基于用户和基于物品的协同过滤算法,并结合适当的权衡和调整来实现算法的混合。具体的实现方式可以根据具体的推荐系统需求和数据特点进行调整和优化。
例如下面的实例演示了使用混合型协同过滤方法为用户推荐电影的过程。
源码路径:daima/3/hun.py
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
# 读取MovieLens数据集
ratings = pd.read_csv('ratings.csv') # 评分数据集
movies = pd.read_csv('movies.csv') # 电影信息数据集
# 处理数据
df = pd.merge(ratings, movies, on='movieId') # 合并评分数据和电影信息
pivot_table = df.pivot_table(index='userId', columns='title', values='rating') # 构建评分矩阵
# 计算用户之间的相似度
user_similarity = cosine_similarity(pivot_table)
# 计算电影之间的相似度
movie_similarity = cosine_similarity(pivot_table.T)
# 根据用户相似度和评分数据生成基于用户的推荐结果
target_user = 1
recommended_movies_user_based = set()
for movie in pivot_table.columns:
if pd.isnull(pivot_table.loc[target_user, movie]):
movie_score = sum(user_similarity[target_user-1, i] * pivot_table.iloc[i][movie] for i in range(len(pivot_table.index)))
recommended_movies_user_based.add((movie, movie_score))
# 根据电影相似度和评分数据生成基于电影的推荐结果
recommended_movies_item_based = set()
for movieId in pivot_table.columns:
if pd.isnull(pivot_table.loc[target_user, movieId]):
movie_score = sum(movie_similarity[movieId-1, i] * pivot_table.loc[target_user][i] for i in range(len(pivot_table.columns)))
recommended_movies_item_based.add((movieId, movie_score))
# 混合两种推荐结果
recommended_movies = recommended_movies_user_based.union(recommended_movies_item_based)
# 按照得分从高到低对推荐电影排序
recommended_movies = sorted(recommended_movies, key=lambda x: x[1], reverse=True)
print("Recommendations for User", target_user)
for movie, _ in recommended_movies:
print("Movie:", movie)
上述代码实现了基于用户和基于物品的混合型协同过滤推荐算法,下面是对上述代码的解释:
- 导入所需的库和模块:导入了Pandas库用于数据处理和操作,以及sklearn库中的cosine_similarity模块用于计算用户之间和电影之间的相似度。
- 读取MovieLens数据集:通过使用函数pd.read_csv()读取了包含评分数据的ratings.csv文件和包含电影信息的movies.csv文件。
- 数据处理:使用函数pd.merge()将评分数据和电影信息进行合并,基于'movieId'列进行连接。然后使用pivot_table函数构建评分矩阵,其中用户ID为行索引,电影标题为列索引,评分为值。
- 计算用户相似度:使用函数cosine_similarity()计算评分矩阵中用户之间的相似度,生成一个用户相似度矩阵。
- 计算电影相似度:使用函数cosine_similarity()计算评分矩阵的转置矩阵中电影之间的相似度,生成一个电影相似度矩阵。
- 基于用户的推荐:对于目标用户,遍历评分矩阵的每个电影,如果目标用户对该电影没有评分,计算该电影的得分。得分通过目标用户与其他用户之间的相似度乘以其他用户对该电影的评分加权求和得到。将电影及其得分添加到基于用户的推荐集合中。
- 基于物品的推荐:对于目标用户,遍历评分矩阵的每个电影,如果目标用户对该电影没有评分,计算该电影的得分。得分通过目标用户对其他电影的评分与其他电影与该电影之间的相似度乘积加权求和得到。将电影及其得分添加到基于物品的推荐集合中。
- 混合推荐结果:将基于用户的推荐集合和基于物品的推荐集合进行合并。
- 排序推荐结果:根据得分对推荐电影进行排序,得分从高到低。
- 打印推荐结果:输出目标用户的推荐结果,按照电影和得分进行打印。
执行后会输出:
Recommendations for User 1
Movie: Shawshank Redemption, The (1994)
Movie: Godfather, The (1972)
Movie: Pulp Fiction (1994)
Movie: Fight Club (1999)
Movie: Forrest Gump (1994)
这是针对User 1的电影推荐结果,推荐的电影按照得分从高到低进行排序,上述结果展示了推荐给用户1的前5部电影。