新闻中心
使用协同过滤实现电影推荐
本文以Movielens数据集为例,基于PaddlePaddle2.0用协同过滤算法实现电影推荐。先介绍数据集,含用户、电影ID及评分等文件。接着处理数据,编码用户和电影,划分训练与验证集。然后构建模型,将用户和电影嵌入向量并计算匹配分数。经训练评估后,能为用户推荐预测高分电影。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

使用协同过滤实现电影推荐
一、介绍
此示例演示使用Movielens 数据集基于PaddlePaddle2.0向用户推荐电影的协作过滤算法。MovieLens 评级数据集列出了一组用户对一组电影的评分。我们的目标是能够预测用户尚未观看的电影的收视率。然后,可以向用户推荐预测收视率最高的电影。
模型中的步骤如下:
1.通过嵌入矩阵将用户 ID 映射到"用户向量" 2.通过嵌入矩阵将电影 ID 映射到"电影载体" 3.计算用户矢量和电影矢量之间的点产品,以获得用户和电影之间的匹配分数(预测评级)。 4.使用所有已知的用户电影对通过梯度下降训练嵌入。
引用:
Item-based collaborative filtering recommendation algorithms
Neural Collaborative Filtering
2. 环境设置
PaddlePaddle框架,AI Studio平台已经默认安装最新版2.0。
In [10]import pandas as pdimport numpy as npimport paddleimport paddle.nn as nnfrom paddle.io import Dataset
3. 数据集
这个数据集(ml-latest-small)描述了MovieLens的五星评级和自由文本标记活动。它包含100836个收视率和3683个标签应用程序,涵盖9742部电影。这些数据由610名用户在1996年3月29日至2018年9月24日期间创建。
该数据集于2018年9月26日生成,用户是随机选择的。所有选定的用户都对至少20部电影进行了评分。不包括人口统计信息。每个用户都由一个id表示,不提供其他信息。数据包含在文件中links.csv, movies.csv, ratings.csv以及tags.csv。
用户ID
MovieLens的用户是随机选择的
电影ID
数据集中只包含至少具有一个分级或标记的电影,这些电影id与MovieLens网站上使用的一致.。
分级数据文件结构(ratings.csv)
ECMall 繁体UFT-8
与 ECShop 不同的是,ECMall 是一个允许店铺加盟的多店系统。它不仅可以帮助众多成熟的网络社区实现社区电子商务还可以推进各种地域性、垂直性明显的门户网站的电子商务进程。 ECMall是一个根据融合了电子商务以及网络社区特色的产品,它不仅能使您的电子商务进程变得异常轻松,同时通过和康盛创想相关产品的结合还能进一步提高用户的活跃度以及黏性,从而促进用户的忠诚度。 ECMall 2.3.0 正
0
查看详情
所有评级都包含在文件中ratings.csv. 文件头行后的每一行代表一个用户对一部电影的一个分级,格式如下: userId,movieId,rating,timestamp
标记数据文件结构(tags.csv)
文件中包含所有标记tags.csv. 文件头行后的每一行代表一个用户应用于一部电影的一个标记,格式如下: userId,movieId,tag,timestamp
电影数据文件结构(movies.csv)
格式如下: 电影ID、片名、类型
链接数据文件结构(links.csv)
格式如下: 电影ID,imdbId,tmdbId
In [11]!unzip data/data71839/ml-latest-small.zip
Archive: data/data71839/ml-latest-small.zip creating: ml-latest-small/ inflating: ml-latest-small/links.csv inflating: ml-latest-small/tags.csv inflating: ml-latest-small/ratings.csv inflating: ml-latest-small/README.txt inflating: ml-latest-small/movies.csv
数据处理
执行一些预处理,将用户和电影编码为整数指数
In [12]df = pd.read_csv('ml-latest-small/ratings.csv')
user_ids = df["userId"].unique().tolist()
user2user_encoded = {x: i for i, x in enumerate(user_ids)}
userencoded2user = {i: x for i, x in enumerate(user_ids)}
movie_ids = df["movieId"].unique().tolist()
movie2movie_encoded = {x: i for i, x in enumerate(movie_ids)}
movie_encoded2movie = {i: x for i, x in enumerate(movie_ids)}
df["user"] = df["userId"].map(user2user_encoded)
df["movie"] = df["movieId"].map(movie2movie_encoded)
num_users = len(user2user_encoded)
num_movies = len(movie_encoded2movie)
df["rating"] = df["rating"].values.astype(np.float32)# 最小和最大额定值将在以后用于标准化额定值min_rating = min(df["rating"])
max_rating = max(df["rating"])print( "Number of users: {}, Number of Movies: {}, Min rating: {}, Max rating: {}".format(
num_users, num_movies, min_rating, max_rating
)
)
Number of users: 610, Number of Movies: 9724, Min rating: 0.5, Max rating: 5.0
准备训练和验证数据
In [13]df = df.sample(frac=1, random_state=42)
x = df[["user", "movie"]].values# 规范化0和1之间的目标。使训练更容易。y = df["rating"].apply(lambda x: (x - min_rating) / (max_rating - min_rating)).values# 假设对90%的数据进行训练,对10%的数据进行验证。train_indices = int(0.9 * df.shape[0])
x_train, x_val, y_train, y_val = (
x[:train_indices],
x[train_indices:],
y[:train_indices],
y[train_indices:],
)
y_train = y_train[: ,np.newaxis]
y_val = y_val[: ,np.newaxis]
y_train = y_train.astype(np.float32)
y_val = y_val.astype(np.float32)# 自定义数据集#映射式(map-style)数据集需要继承paddle.io.Datasetclass SelfDefinedDataset(Dataset):
def __init__(self, data_x, data_y, mode = 'train'):
super(SelfDefinedDataset, self).__init__()
self.data_x = data_x
self.data_y = data_y
self.mode = mode def __getitem__(self, idx):
if self.mode == 'predict': return self.data_x[idx] else: return self.data_x[idx], self.data_y[idx] def __len__(self):
return len(self.data_x)
traindataset = SelfDefinedDataset(x_train, y_train)for data, label in traindataset: print(data.shape, label.shape) print(data, label) breaktrain_loader = paddle.io.DataLoader(traindataset, batch_size = 128, shuffle = True)for batch_id, data in enumerate(train_loader()):
x_data = data[0]
y_data = data[1] print(x_data.shape) print(y_data.shape) breaktestdataset = SelfDefinedDataset(x_val, y_val)
test_loader = paddle.io.DataLoader(testdataset, batch_size = 128, shuffle = True)
for batch_id, data in enumerate(test_loader()):
x_data = data[0]
y_data = data[1] print(x_data.shape) print(y_data.shape) break
(2,) (1,) [ 431 4730] [0.8888889] [128, 2] [128, 1] [128, 2] [128, 1]
4. 模型组网
将用户和电影嵌入到 50 维向量中。
该模型计算用户和电影嵌入之间的匹配分数,并添加每部电影和每个用户的偏差。比赛分数通过 sigmoid 缩放到间隔[0, 1]。
In [14]EMBEDDING_SIZE = 50class RecommenderNet(nn.Layer):
def __init__(self, num_users, num_movies, embedding_size):
super(RecommenderNet, self).__init__()
self.num_users = num_users
self.num_movies = num_movies
self.embedding_size = embedding_size
weight_attr_user = paddle.ParamAttr(
regularizer = paddle.regularizer.L2Decay(1e-6),
initializer = nn.initializer.KaimingNormal()
)
self.user_embedding = nn.Embedding(
num_users,
embedding_size,
weight_attr=weight_attr_user
)
self.user_bias = nn.Embedding(num_users, 1)
weight_attr_movie = paddle.ParamAttr(
regularizer = paddle.regularizer.L2Decay(1e-6),
initializer = nn.initializer.KaimingNormal()
)
self.movie_embedding = nn.Embedding(
num_movies,
embedding_size,
weight_attr=weight_attr_movie
)
self.movie_bias = nn.Embedding(num_movies, 1) def forward(self, inputs):
user_vector = self.user_embedding(inputs[:, 0])
user_bias = self.user_bias(inputs[:, 0])
movie_vector = self.movie_embedding(inputs[:, 1])
movie_bias = self.movie_bias(inputs[:, 1])
dot_user_movie = paddle.dot(user_vector, movie_vector)
x = dot_user_movie + user_bias + movie_bias
x = nn.functional.sigmoid(x) return x
5. 模型训练
后台可通过VisualDl观察Loss曲线。
In [15]model = RecommenderNet(num_users, num_movies, EMBEDDING_SIZE)In [16]
model = paddle.Model(model) optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.0003) loss = nn.BCELoss() metric = paddle.metric.Accuracy()# # 设置visualdl路径log_dir = './visualdl'callback = paddle.callbacks.VisualDL(log_dir=log_dir) model.prepare(optimizer, loss, metric) model.fit(train_loader, epochs=5, s*e_dir='./checkpoints', verbose=1, callbacks=callback)
The loss value printed in the log is the current step, and the metric is the *erage value of previous step. Epoch 1/5 step 709/709 [==============================] - loss: 0.6742 - acc: 0.8687 - 3ms/step s*e checkpoint at /home/aistudio/checkpoints/0 Epoch 2/5 step 709/709 [==============================] - loss: 0.6505 - acc: 0.8687 - 3ms/step s*e checkpoint at /home/aistudio/checkpoints/1 Epoch 3/5 step 709/709 [==============================] - loss: 0.6052 - acc: 0.8687 - 3ms/step s*e checkpoint at /home/aistudio/checkpoints/2 Epoch 4/5 step 709/709 [==============================] - loss: 0.5992 - acc: 0.8687 - 3ms/step s*e checkpoint at /home/aistudio/checkpoints/3 Epoch 5/5 step 709/709 [==============================] - loss: 0.5755 - acc: 0.8687 - 3ms/step s*e checkpoint at /home/aistudio/checkpoints/4 s*e checkpoint at /home/aistudio/checkpoints/final
6. 模型评估
In [17]model.evaluate(test_loader, batch_size=64, verbose=1)
Eval begin... The loss value printed in the log is the current batch, and the metric is the *erage value of previous step. step 79/79 [==============================] - loss: 0.6166 - acc: 0.8713 - 2ms/step Eval samples: 10084
{'loss': [0.6166183], 'acc': 0.8712812376041253}
7. 模型预测
In [18]movie_df = pd.read_csv('ml-latest-small/movies.csv')# Let us get a user and see the top recommendations.user_id = df.userId.sample(1).iloc[0]
movies_watched_by_user = df[df.userId == user_id]
movies_not_watched = movie_df[
~movie_df["movieId"].isin(movies_watched_by_user.movieId.values)
]["movieId"]
movies_not_watched = list( set(movies_not_watched).intersection(set(movie2movie_encoded.keys()))
)
movies_not_watched = [[movie2movie_encoded.get(x)] for x in movies_not_watched]
user_encoder = user2user_encoded.get(user_id)
user_movie_array = np.hstack(
([[user_encoder]] * len(movies_not_watched), movies_not_watched)
)
testdataset = SelfDefinedDataset(user_movie_array, user_movie_array, mode = 'predict')
test_loader = paddle.io.DataLoader(testdataset, batch_size = 9703, shuffle = False, return_list=True,)
ratings = model.predict(test_loader)
ratings = np.array(ratings)
ratings = np.squeeze(ratings, 0)
ratings = np.squeeze(ratings, 2)
ratings = np.squeeze(ratings, 0)
top_ratings_indices = ratings.argsort()[::-1][0:10]print(top_ratings_indices)
recommended_movie_ids = [
movie_encoded2movie.get(movies_not_watched[x][0]) for x in top_ratings_indices
]print("Showing recommendations for user: {}".format(user_id))print("====" * 9)print("Movies with high ratings from user")print("----" * 8)
top_movies_user = (
movies_watched_by_user.sort_values(by="rating", ascending=False)
.head(5)
.movieId.values
)
movie_df_rows = movie_df[movie_df["movieId"].isin(top_movies_user)]for row in movie_df_rows.itertuples(): print(row.title, ":", row.genres)print("----" * 8)print("Top 10 movie recommendations")print("----" * 8)
recommended_movies = movie_df[movie_df["movieId"].isin(recommended_movie_ids)]for row in recommended_movies.itertuples(): print(row.title, ":", row.genres)
Predict begin... step 1/1 [==============================] - 17ms/step Predict samples: 9149 [ 427 7916 2135 1725 6763 898 3749 5269 6498 1281] Showing recommendations for user: 91 ==================================== Movies with high ratings from user -------------------------------- Nightmare Before Christmas, The (1993) : Animation|Children|Fantasy|Musical Monty Python and the Holy Grail (1975) : Adventure|Comedy|Fantasy Aliens (1986) : Action|Adventure|Horror|Sci-Fi Shrek (2001) : Adventure|Animation|Children|Comedy|Fantasy|Romance Tremors (1990) : Comedy|Horror|Sci-Fi -------------------------------- Top 10 movie recommendations -------------------------------- Schindler's List (1993) : Drama|War Full Metal Jacket (1987) : Drama|War Big Lebowski, The (1998) : Comedy|Crime American History X (1998) : Crime|Drama American Beauty (1999) : Drama|Romance Amelie (Fabuleux destin d'Amélie Poulain, Le) (2001) : Comedy|Romance Eternal Sunshine of the Spotless Mind (2004) : Drama|Romance|Sci-Fi Departed, The (2006) : Crime|Drama|Thriller Dark Knight, The (2008) : Action|Crime|Drama|IMAX Inception (2010) : Action|Crime|Drama|Mystery|Sci-Fi|Thriller|IMAX
以上就是使用协同过滤实现电影推荐的详细内容,更多请关注其它相关文章!
# 将在
# 福建营销关键词排名优化
# 嘉兴网站购物推广公司
# 网站建设服务项目明细
# 济南seo搜索优化软件
# 邯郸网站建设创意
# 邗江关键词排名
# 乐至网站建设和优化服务
# 滨州网站开发二维码推广
# 宝安优质网站建设哪家快
# 丹阳网站建设企业
# 额定值
# 还能
# python
# 还可以
# 出了
# 的是
# 官网
# 中文网
# 是一个
# 一言
# type
# udio
# red
# ai
相关栏目:
【
行业资讯67740 】
【
技术百科0 】
【
网络运营39195 】
相关推荐:
什么是域名解析 域名解析中采用了什么
点焊机接触器上power是什么意思
折叠屏手机哪个有性价比
typescript 如何解决 null
如何自己加装固态硬盘
抖音GMV是什么_抖音GMV是什么意思
阿里云盘扩容是什么_扩容阿里云盘方法是什么教程
如何更新typescript
苹果16系统有哪些系列
壁挂炉power常亮是什么意思
移动固态硬盘如何使用
税负是什么意思
怎么更新typescript
typescript中文怎么读
热水器没热水显示power是什么意思
课程伴侣电脑怎么登录
选哪个折叠屏手机好用
如何在一串数字前面去掉四位数的命令
春运抢票如何抢连坐的票
萝卜快跑的收费标准是什么
命令不执行如何处理
单片机软件keil怎么运行
如何体验苹果16系统
element ui的好处
一年多少周
命令行如何打开文件
cos150度等于多少
市盈率当中17A 18E是什么意思
苹果16promax有哪些颜色
typescript怎么写游戏
春运抢票哪个城市好抢
折叠屏有哪些手机
怎么看手机是不是双模5g手机
typescript如何使用
固态硬盘质量如何
meet是什么意思
春运抢票要用抢票软件吗
春运抢票准备什么
typescript性能如何
ftp$如何执行宏命令
vi命令如何退出
linux如何打开命令窗口
市盈率估值1stdv是什么意思
固态硬盘装完如何使用
ai文件里无法找到链接文件怎么解决
如何更新固态硬盘固件
哪个品牌有折叠屏手机卖
如何通过命令行聊天
手机全功能type-c接口是什么意思
如何用命令连接mysql


2025-07-23
浏览次数:次
返回列表