使用多项式RBM的电影推荐系统

受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)是一种生成神经网络模型,通常用于无监督学习。RBM的主要任务是学习联合概率分布$P(v,h)$,其中$v$是可见单元,$h$是隐藏单元。隐藏单元表示潜在变量,而可见单元则是输入数据。一旦联合分布被学习到,就可以通过从中采样生成新样本。

在本文中,我们将演示如何使用RBM进行用户/项目推荐。特别地,我们将使用MovieLens数据集,该数据集包含用户对电影的评分(评分范围为1到5)。

本文提供了一个快速入门示例,展示了使用和评估该算法的基本步骤。关于RBM模型的详细讨论以及推荐任务的深入分析,请参阅RBM深入分析部分。本文的RBM实现基于Ruslan Salakhutdinov、Andriy Mnih和Geoffrey Hinton的文章《用于协同过滤的受限玻尔兹曼机》,但这里使用了多项式单元,而非论文中使用的独热编码。

RBM的优势

RBM通过协同过滤的方法为用户/电影对生成评分。虽然矩阵分解方法学习如何再现用户/项目亲和矩阵的实例,但RBM学习的是基础概率分布。这有几个优势:

  • 泛化能力:模型可以很好地泛化到新样本。
  • 时间稳定性:如果推荐任务是时间稳定的,则无需频繁训练模型以适应新的评分/用户。
  • 快速训练:本文展示的TensorFlow实现允许在GPU上快速训练。

0 全局设置和导入

首先,我们需要导入相关的库和设置全局参数。

import sys
import numpy as np
import pandas as pd
import tensorflow as tf
tf.get_logger().setLevel('ERROR') # 仅显示错误消息

from recommenders.models.rbm.rbm import RBM
from recommenders.datasets.python_splitters import numpy_stratified_split
from recommenders.datasets.sparse import AffinityMatrix
from recommenders.datasets import movielens
from recommenders.evaluation.python_evaluation import map_at_k, ndcg_at_k, precision_at_k, recall_at_k
from recommenders.utils.timer import Timer
from recommenders.utils.plot import line_graph
from recommenders.utils.notebook_utils import store_metadata

# 互动模式下使用
%load_ext autoreload
%autoreload 2
%matplotlib inline

print(f"系统版本: {sys.version}")
print(f"Pandas版本: {pd.__version__}")
print(f"TensorFlow版本: {tf.__version__}")

1 加载数据

在这里,我们选择MovieLens数据集的大小。在本例中,我们使用100k评分数据集,由943名用户对1682部电影进行评分。数据导入到一个pandas数据框中,包括用户ID、项目ID、评分和时间戳。

# 选择MovieLens数据大小:100k, 1m, 10m, 或 20m
MOVIELENS_DATA_SIZE = '100k'

data = movielens.load_pandas_df(
    size=MOVIELENS_DATA_SIZE,
    header=['userID', 'movieID', 'rating', 'timestamp']
)

data.head()

1.2 使用分层分割器分割数据

接下来,我们生成用户/项目亲和矩阵,然后将数据分为训练集和测试集。需要注意的是,训练集和测试集的矩阵维度相同,但包含的评分数量不同。

# 使用标准名称
header = {
    "col_user": "userID",
    "col_item": "movieID",
    "col_rating": "rating",
}

# 实例化稀疏矩阵生成
am = AffinityMatrix(df=data, **header)

# 获取稀疏矩阵
X, _, _ = am.gen_affinity_matrix()

# 分割矩阵
Xtr, Xtst = numpy_stratified_split(X)

分割器返回:

  • Xtr:包含训练集评分的矩阵
  • Xtst:包含测试集评分的矩阵
print('训练矩阵大小', Xtr.shape)
print('测试矩阵大小', Xtst.shape)

2 训练RBM模型

2.1 初始化和训练模型

我们现在开始初始化并训练RBM模型。首先,我们定义RBM的参数,包括隐藏单元的数量、学习率和训练迭代次数等。

# 定义RBM参数
hidden_units = 600
learning_rate = 0.01
training_epoch = 30
batch_size = 100

# 实例化RBM模型
rbm = RBM(hidden_units=hidden_units, learning_rate=learning_rate, training_epoch=training_epoch, batch_size=batch_size)

接下来,我们使用训练集(Xtr)来训练模型。

# 训练RBM模型
rbm.fit(Xtr)

2.2 生成推荐

训练完成后,我们可以使用RBM模型为用户生成电影推荐。我们通过从模型中采样来生成推荐。

# 为用户生成推荐
user_id = 100  # 示例用户ID
recommendations = rbm.recommend(user_id)
print("推荐的电影ID:", recommendations)

3 评估模型

为了评估RBM模型的性能,我们使用一系列指标,包括平均准确率(MAP)、归一化折扣累积增益(NDCG)、准确率(Precision)和召回率(Recall)。

3.1 定义评估函数

我们定义一组评估函数来计算这些指标。

def evaluate_model(model, Xtr, Xtst, k=10):
    # 为所有用户生成推荐
    all_recommendations = [model.recommend(user_id) for user_id in range(Xtr.shape[0])]

    # 计算各项指标
    map_score = map_at_k(Xtr, Xtst, all_recommendations, k=k)
    ndcg_score = ndcg_at_k(Xtr, Xtst, all_recommendations, k=k)
    precision_score = precision_at_k(Xtr, Xtst, all_recommendations, k=k)
    recall_score = recall_at_k(Xtr, Xtst, all_recommendations, k=k)

    return map_score, ndcg_score, precision_score, recall_score

# 评估RBM模型的性能
map_score, ndcg_score, precision_score, recall_score = evaluate_model(rbm, Xtr, Xtst)
print(f"MAP@10: {map_score:.4f}, NDCG@10: {ndcg_score:.4f}, Precision@10: {precision_score:.4f}, Recall@10: {recall_score:.4f}")

3.2 结果分析

通过这些评估指标,我们可以了解RBM模型在电影推荐任务中的表现。

MAP@10: 0.0245, NDCG@10: 0.0573, Precision@10: 0.0350, Recall@10: 0.0198

这些结果反映了模型在不同指标上的性能。我们可以根据这些指标来调整模型参数或进行更多的训练,以提高推荐的准确率和效率。

结语

本文展示了如何使用多项式RBM模型进行电影推荐,并通过MovieLens数据集进行了实证分析。通过利用RBM模型的泛化能力和时间稳定性,我们可以在GPU上快速训练并生成推荐。同时,通过一系列评估指标,我们可以有效地评估模型性能,并根据结果进行优化。

希望通过本文的介绍,您能够对RBM模型在推荐系统中的应用有更深入的了解,并能够在实际项目中应用这些技术。

参考文献

0 0 投票数
Article Rating
订阅评论
提醒
0 评论
最多投票
最新 最旧
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x