使用Python实现一个简单的推荐系统

今天 3阅读

推荐系统是现代互联网应用中不可或缺的一部分,广泛应用于电商平台、社交媒体、视频网站等领域。本文将介绍如何使用Python构建一个简单的基于协同过滤的推荐系统,并提供完整的代码示例。

我们将使用电影评分数据集来构建推荐系统,通过分析用户对电影的评分来为用户推荐他们可能感兴趣的电影。

1. 推荐系统简介

推荐系统主要分为以下几类:

基于内容的推荐:根据物品的特征或用户的兴趣进行推荐。协同过滤推荐基于用户的协同过滤(User-based):找出与目标用户兴趣相似的其他用户,推荐这些用户喜欢但目标用户未接触过的物品。基于物品的协同过滤(Item-based):找出与目标物品相似的其他物品,推荐给喜欢该物品的用户。混合推荐系统:结合多种推荐方法。

本文将实现的是基于用户的协同过滤推荐系统


2. 数据准备

我们使用经典的 MovieLens 小型数据集,包含以下文件:

movies.csv:包含电影ID和标题。ratings.csv:包含用户ID、电影ID、评分和时间戳。

你可以从 MovieLens 官网 下载最新版本的数据集,或者使用小型数据集如 ml-latest-small.zip

安装依赖库

pip install pandas numpy scikit-learn

3. 实现步骤

步骤一:导入必要的库并加载数据

import pandas as pdimport numpy as npfrom sklearn.metrics.pairwise import cosine_similarityfrom sklearn.preprocessing import MinMaxScaler# 加载数据movies = pd.read_csv('movies.csv')ratings = pd.read_csv('ratings.csv')# 合并数据data = pd.merge(ratings, movies, on='movieId')print(data.head())

输出结果:

userIdmovieIdratingtimestamptitle
1312.51260759144Dangerous Minds (1995)
110293.01260759179Dances with Wolves (1990)
...............

步骤二:构建用户-物品评分矩阵

# 构建用户-电影评分矩阵user_movie_matrix = data.pivot_table(index='userId', columns='title', values='rating')print(user_movie_matrix.head())

输出示例:

title$1,000,000 Duck (1971)'Til There Was You (1997)...
userId
1NaNNaN...
23.0NaN...
............

步骤三:计算用户之间的相似度

我们使用余弦相似度(cosine similarity)来衡量用户之间的相似性。

# 填充NaN值为0user_movie_matrix_filled = user_movie_matrix.fillna(0)# 计算用户之间的相似度user_similarity = cosine_similarity(user_movie_matrix_filled)print("用户相似度矩阵:")print(user_similarity)

输出结果是一个 N×N 的矩阵,表示每个用户与其他用户的相似度。


步骤四:预测用户对未观看电影的评分

我们可以使用加权平均法来预测某个用户对某部电影的评分:

$$\text{predicted_rating} = \frac{\sum{u' \in U} \text{similarity}(u, u') \times \text{rating}{u'}(i)}{\sum_{u' \in U} |\text{similarity}(u, u')|}$$

其中:

$ u $ 是目标用户;$ i $ 是目标电影;$ u' $ 是其他用户;分母用于归一化。
def predict_ratings(similarity_matrix, ratings_matrix):    # 归一化相似度(避免相似度高的用户主导)    mean_user_rating = ratings_matrix.mean(axis=1)    ratings_diff = (ratings_matrix.subtract(mean_user_rating, axis=0)).fillna(0)    pred_ratings = similarity_matrix.dot(ratings_diff) / np.array([np.abs(similarity_matrix).sum(axis=1)])    pred_ratings += mean_user_rating.values.reshape(-1, 1)    return pred_ratingspredicted_ratings = predict_ratings(user_similarity, user_movie_matrix)

步骤五:为用户推荐电影

现在我们为指定用户推荐评分最高的未看过的电影。

def recommend_movies(user_id, predicted_ratings_matrix, original_ratings_matrix, movie_titles, n_recommendations=10):    user_index = user_id - 1  # 索引从0开始    scores = predicted_ratings_matrix[user_index]    # 找出用户未评分的电影    watched_mask = np.isnan(original_ratings_matrix.iloc[user_index])    scores_unwatched = pd.Series(scores[watched_mask], index=original_ratings_matrix.columns[watched_mask])    top_movies = scores_unwatched.sort_values(ascending=False).head(n_recommendations)    return pd.DataFrame({'title': top_movies.index, 'predicted_score': top_movies.values})# 示例:为用户1推荐10部电影recommendations = recommend_movies(    user_id=1,    predicted_ratings_matrix=predicted_ratings,    original_ratings_matrix=user_movie_matrix,    movie_titles=movies['title'])print("推荐电影列表:")print(recommendations)

输出示例:

titlepredicted_score
The Shawshank Redemption (1994)4.8
The Godfather (1972)4.7
Pulp Fiction (1994)4.6
......

4. 总结与改进方向

以上我们实现了一个基于用户的协同过滤推荐系统,虽然简单,但展示了推荐系统的基本原理和流程:

构建用户-物品评分矩阵;计算用户相似度;预测评分;根据预测评分推荐物品。

改进方向:

引入稀疏矩阵优化:使用 scipy.sparse 来处理大规模稀疏矩阵,提高性能。使用K近邻算法(KNN):只考虑最相似的前K个邻居,减少计算量。加入冷启动策略:对于新用户或新物品,可采用基于内容的推荐作为补充。使用深度学习模型:如AutoEncoder、NeuMF等模型可以提升推荐质量。

5. 完整代码汇总

import pandas as pdimport numpy as npfrom sklearn.metrics.pairwise import cosine_similarity# 加载数据movies = pd.read_csv('movies.csv')ratings = pd.read_csv('ratings.csv')data = pd.merge(ratings, movies, on='movieId')# 用户-电影评分矩阵user_movie_matrix = data.pivot_table(index='userId', columns='title', values='rating')# 填充缺失值user_movie_matrix_filled = user_movie_matrix.fillna(0)# 计算用户相似度user_similarity = cosine_similarity(user_movie_matrix_filled)# 预测评分函数def predict_ratings(similarity_matrix, ratings_matrix):    mean_user_rating = ratings_matrix.mean(axis=1)    ratings_diff = (ratings_matrix.subtract(mean_user_rating, axis=0)).fillna(0)    pred_ratings = similarity_matrix.dot(ratings_diff) / np.array([np.abs(similarity_matrix).sum(axis=1)])    pred_ratings += mean_user_rating.values.reshape(-1, 1)    return pred_ratingspredicted_ratings = predict_ratings(user_similarity, user_movie_matrix)# 推荐电影函数def recommend_movies(user_id, predicted_ratings_matrix, original_ratings_matrix, movie_titles, n_recommendations=10):    user_index = user_id - 1    scores = predicted_ratings_matrix[user_index]    watched_mask = np.isnan(original_ratings_matrix.iloc[user_index])    scores_unwatched = pd.Series(scores[watched_mask], index=original_ratings_matrix.columns[watched_mask])    top_movies = scores_unwatched.sort_values(ascending=False).head(n_recommendations)    return pd.DataFrame({'title': top_movies.index, 'predicted_score': top_movies.values})# 推荐示例recommendations = recommend_movies(    user_id=1,    predicted_ratings_matrix=predicted_ratings,    original_ratings_matrix=user_movie_matrix,    movie_titles=movies['title'])print("推荐电影列表:")print(recommendations)

本篇文章介绍了如何,并给出了完整的技术实现过程和代码。希望读者能够理解协同过滤的核心思想,并在此基础上进一步探索更复杂的推荐算法和工程实践。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第86672名访客 今日有27篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!