协同过滤算法是一种常用的推荐算法,它基于用户行为数据(如浏览记录、评分记录等)来推荐用户可能感兴趣的物品。
在实现电影推荐的协同过滤算法中,可以采用两种常用的方式:基于用户的协同过滤算法和基于物品的协同过滤算法。
下面是使用Python实现基于用户的协同过滤算法的示例代码:
import numpy as np
# 创建用户-电影评分矩阵
ratings = np.array([
[5, 1, 2, 0, 0],
[1, 4, 0, 4, 0],
[0, 0, 3, 5, 0],
[4, 0, 0, 2, 1],
[0, 2, 1, 0, 4]
])
# 计算用户之间的相似度(余弦相似度)
def similarity(user1, user2):
numerator = np.sum(user1 * user2)
denominator = np.sqrt(np.sum(user1 ** 2)) * np.sqrt(np.sum(user2 ** 2))
return numerator / denominator
# 根据用户相似度计算推荐电影
def recommend(user_id):
user_ratings = ratings[user_id]
similarities = []
for i in range(len(ratings)):
if i != user_id:
similarities.append(similarity(user_ratings, ratings[i]))
similarities = np.array(similarities)
sorted_indices = np.argsort(similarities)[::-1]
recommendations = []
for i in range(len(ratings[user_id])):
if user_ratings[i] == 0:
recommendations.append((i, np.mean(ratings[:, i]) * similarities[i]))
sorted_recommendations = sorted(recommendations, key=lambda x: x[1], reverse=True)
return sorted_recommendations
# 示例:用户0的推荐电影
recommendations = recommend(0)
for rec in recommendations:
print(f"电影{rec[0]}:{rec[1]}")
上述代码中,创建了一个用户-电影评分矩阵(ratings
),其中每行表示一个用户的电影评分记录,每列表示一个电影的评分记录。
similarity
函数用于计算用户之间的相似度,这里采用余弦相似度计算。
recommend
函数用于根据用户相似度计算推荐电影。首先计算出用户与其他用户的相似度,然后根据相似度和其他用户对电影的评分计算出推荐电影,并按照推荐电影的评分进行排序。
在Python中实现基于协同过滤算法的电影推荐系统通常涉及以下步骤:
-
数据准备:加载并预处理电影评分数据,通常这些数据会存储在CSV文件中,包含用户ID、电影ID和评分等信息。
-
计算相似度:使用相似度度量(如余弦相似度、皮尔逊相关系数或调整后的余弦相似度)来计算用户或电影之间的相似度。
-
生成推荐:基于相似用户或相似电影的评分来为目标用户生成推荐列表。
以下是一个简化的基于用户的协同过滤算法的电影推荐系统实现:
python复制代码
import pandas as pd | |
import numpy as np | |
from sklearn.metrics.pairwise import cosine_similarity | |
# 假设我们有一个电影评分数据集 | |
# 数据集包含三列:UserID, MovieID, Rating | |
ratings_df = pd.DataFrame({ | |
'UserID': [1, 1, 1, 2, 2, 3, 3, 4, 4, 4], | |
'MovieID': [101, 102, 103, 101, 104, 102, 105, 103, 104, 106], | |
'Rating': [5, 3, 4, 4, 2, 5, 3, 4, 5, 1] | |
}) | |
# 创建用户-电影评分矩阵 | |
user_movie_matrix = ratings_df.pivot(index='UserID', columns='MovieID', values='Rating').fillna(0) | |
# 计算用户之间的相似度(余弦相似度) | |
user_similarity = cosine_similarity(user_movie_matrix) | |
user_similarity_df = pd.DataFrame(user_similarity, index=user_movie_matrix.index, columns=user_movie_matrix.index) | |
# 为指定用户推荐电影(例如,用户ID为1) | |
def recommend_movies(user_id, num_recommendations=2): | |
# 获取指定用户的相似用户(排除自己) | |
similar_users = user_similarity_df[user_id] | |
similar_users[user_id] = 0 # 排除自己 | |
similar_user_indices = similar_users.sort_values(ascending=False).index[:-1] # 获取最相似的用户索引(降序,排除自己) | |
# 初始化推荐分数数组(对应所有电影) | |
movie_scores = np.zeros(user_movie_matrix.shape[1]) | |
# 根据相似用户的评分来计算推荐分数 | |
for similar_user_index in similar_user_indices: | |
similar_user_ratings = user_movie_matrix.loc[similar_user_index] | |
# 只考虑用户未评分的电影 | |
unrated_movies = similar_user_ratings[user_movie_matrix.loc[user_id] == 0] | |
if not unrated_movies.empty: | |
movie_scores[unrated_movies.index] += similar_user_ratings[unrated_movies.index] * user_similarity_df.loc[user_id, similar_user_index] | |
# 归一化推荐分数(使分数在0到5之间,可选) | |
movie_scores /= np.linalg.norm(movie_scores) | |
movie_scores = movie_scores * 5 # 假设评分范围是1到5 | |
# 获取推荐电影索引(按分数降序) | |
recommended_movie_indices = np.argsort(-movie_scores) | |
# 返回推荐电影ID和对应的分数(前num_recommendations个) | |
recommended_movies = user_movie_matrix.columns[recommended_movie_indices[:num_recommendations]] | |
scores = movie_scores[recommended_movie_indices[:num_recommendations]] | |
return recommended_movies, scores | |
# 为用户ID为1的用户推荐电影 | |
recommended_movies, scores = recommend_movies(1) | |
print("为用户1推荐的电影ID:", recommended_movies) | |
print("推荐分数:", scores) |
请注意,这个实现有几个重要的假设和简化:
- 它假设评分数据是完整的(即没有缺失值,除了用户未评分的电影,这些被填充为0)。在实际应用中,你可能需要处理更多的缺失值。
- 它使用余弦相似度来计算用户之间的相似度。虽然余弦相似度在许多情况下都表现良好,但其他相似度度量(如皮尔逊相关系数或调整后的余弦相似度)可能更适合于评分数据。
- 它没有考虑评分的偏差(即用户的平均评分或电影的平均评分),这可能会影响推荐的准确性。调整后的余弦相似度考虑了这些偏差。
- 它没有实现任何形式的优化或并行处理,因此在大规模数据集上可能会很慢。在实际应用中,你可能需要使用更高效的数据结构和算法。
-
最后,调用
recommend
函数可以得到用户0的推荐电影列表。 -
需要注意的是,上述代码仅是一个简单的示例,实际应用中可能需要考虑更多的因素,如用户对电影的喜好程度、时间衰减等。