RUCAIBox / RecBole

A unified, comprehensive and efficient recommendation library
https://recbole.io/
MIT License
3.48k stars 615 forks source link

请问如何获得推荐评分? #1253

Closed zengxinran closed 2 years ago

zengxinran commented 2 years ago

你好,我想问一下: 1.我采用uni100模式进行评估,但是我不知道怎样获得推荐排序时的评分(test数据集的) 2.划分数据集时,数据比例不是我所指定的比例 3.如何获得val数据集的NDCG等指标 4.如何获得train,val,test数据集,并将其输出为csv文件

Sherry-XLL commented 2 years ago

@zengxinran 您好!

1). 模型在测试集上计算评分的函数与验证集并无区别,uni100 模式也不会改变模型的评分函数。 对于测试数据集,在 run_recbole 中,test_result 的结果同样是通过 trainerevaluate 函数得到的:

https://github.com/RUCAIBox/RecBole/blob/896155c56fb2f426554d1179dae85dc0a8f4a38e/recbole/quick_start/quick_start.py#L60-L61

trainerevaluate 中,eval_func 返回的 scores 是每一个 batch 中若干个用户的评分。 https://github.com/RUCAIBox/RecBole/blob/896155c56fb2f426554d1179dae85dc0a8f4a38e/recbole/trainer/trainer.py#L474-L478

若想获得测试集中所有用户的评分,可以在循环之前先设置 self.eval_collector.registerTrue,再输出 rec.score 如下。除此之外获取评分还有很多方式,例如在每次循环中记录 scores 然后拼接等等。

setattr(self.eval_collector.register, 'rec.score', True)        # L474 in trainer.py,设置 'rec.score',否则模型只记录 'rec.topk'
for batch_idx, batched_data in enumerate(iter_data):
    interaction, scores, positive_u, positive_i = eval_func(batched_data)  # scores 表示每个 batch 的 interaction 中用户对所有商品的得分
    if self.gpu_available and show_progress:
        iter_data.set_postfix_str(set_color('GPU RAM: ' + get_gpu_usage(self.device), 'yellow'))
    self.eval_collector.eval_batch_collect(scores, interaction, positive_u, positive_i)
self.eval_collector.model_collect(self.model)
print(self.eval_collector.data_struct['rec.score'])        # 输出待评测用户对所有商品的分数,shape: [n_users, n_items]

2). 这个您的描述比较含糊,请给出具体示例方便我们复现您的结果。在 ratio-based 的数据集划分方式下,数据集比例应该与设置的一致。

3). 模型在每轮训练结束后都会输出验证集的指标,即 valid result 后的结果,不太明白您的意思。

Train     0: 100%|████████████████████████| 40/40 [00:00<00:00, 361.17it/s, GPU RAM: 0.01 G/15.90 G]
18 Apr 23:26    INFO  epoch 0 training [time: 0.11s, train loss: 27.7256]
Evaluate   : 100%|██████████████████████| 472/472 [00:00<00:00, 530.29it/s, GPU RAM: 0.01 G/15.90 G]
18 Apr 23:26    INFO  epoch 0 evaluating [time: 0.90s, valid_score: 0.024200]
18 Apr 23:26    INFO  valid result: 
recall@10 : 0.007    mrr@10 : 0.0242    ndcg@10 : 0.0099    hit@10 : 0.0795    precision@10 : 0.0083

4). RecBole 提供了参数用于存储预处理后的数据集和数据加载器,即 save_dataset (bool)save_dataloaders (bool)

如果你想存储划分好的训练、验证与测试数据集,可以在模型运行时设置 save_dataloaders=True,这样得到的 {checkpoint_dir}/{dataset}-for-{model}-dataloader.pth 包含了 train_data, valid_datatest_data 三个 dataloaders,可以通过 pickle.load 的方式进行加载:

with open(dataloaders_save_path, 'rb') as f:
    train_data, valid_data, test_data = pickle.load(f)

这样得到的结果并不是 .csv 文件,RecBole 提供的接口并不支持直接将划分好的数据集存为三个 .csv 文件。 您还需要通过简单的 python 操作将 dataloaderdatasetInteraction 格式的交互数据转换为 pandas.DataFrame 的格式,再分别存入三个文件中,具体细节不再赘述。

zengxinran commented 2 years ago

你好,怎样将 dataloader 中 dataset 里 Interaction 格式的交互数据转换为 pandas.DataFrame呢? 还有就是怎么获得train_sampler数据和train_sampler的推荐排序时的评分?

Sherry-XLL commented 2 years ago

@Sherry-XLL 您好,Interaction 是 RecBole 设计的内部数据结构,本质上是个字典格式,键值是字段名称,而值是 tensor 的格式,您可以先将 tensor 转为 numpy 的格式,再拼接为 pandas.DataFrame

https://github.com/RUCAIBox/RecBole/blob/896155c56fb2f426554d1179dae85dc0a8f4a38e/recbole/data/interaction.py#L43-L44

train_sampler 是训练数据的采样器,主要用于构造 train_data 这个 dataloader,而不是用于推荐排序的评分,具体细节请参考源码内容。