AI比赛-推荐系统(一)-新闻推荐03:多路召回【用不同策略分别召回部分候选集,然后把候选集混在一起供后续排序模型使用】【①、YoutubeDNN双塔召回;②、基于物品召回;③、基于用户召回】【天池】

所谓的“多路召回”策略,就是指采用不同的策略、特征或简单模型,分别召回一部分候选集,然后把候选集混合在一起供后续排序模型使用,可以明显的看出,“多路召回策略”是在“计算速度”和“召回率”之间进行权衡的结果。其中,各种简单策略保证候选集的快速召回,从不同角度设计的策略保证召回率接近理想的状态,不至于损伤排序效果。如下图是多路召回的一个示意图,在多路召回中,每个策略之间毫不相关,所以一般可以写并发多线程同时进行,这样可以更加高效。

上图只是一个多路召回的例子,也就是说可以使用多种不同的策略来获取用户排序的候选商品集合,而具体使用哪些召回策略其实是与业务强相关的 ,针对不同的任务就会有对于该业务真实场景下需要考虑的召回规则。例如新闻推荐,召回规则可以是“热门新闻”、“作者召回”、“关键词召回”、“主题召回“、”协同过滤召回“等等。

导包

import pandas as pd  
import numpy as np
from tqdm import tqdm  
from collections import defaultdict  
import os, math, warnings, math, pickle
from tqdm import tqdm
import faiss
import collections
import random
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from datetime import datetime
from deepctr.feature_column import SparseFeat, VarLenSparseFeat
import tensorflow as tf
if tf.__version__ >= '2.0.0':
    tf.compat.v1.disable_eager_execution()
from tensorflow.python.keras import backend as K
K.set_learning_phase(True)
from tensorflow.python.keras.models import Model
from tensorflow.python.keras.preprocessing.sequence import pad_sequences    # pip install tensorflow==2.5.0
from deepmatch.models import *
from deepmatch.utils import sampledsoftmaxloss

warnings.filterwarnings('ignore')
# 设置整个开发环境的seed
def seed_everything(seed=1029):
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
seed_everything()
data_path = './data_raw/'
save_path = './temp_results/'

# 做召回评估的一个标志, 如果不进行评估就是直接使用全量数据进行召回
metric_recall = True
# 定义一个多路召回的字典,将各路召回的结果都保存在这个字典当中
user_multi_recall_dict =  {'itemcf_sim_itemcf_recall': {}, 'embedding_sim_item_recall': {}, 'usercf_u2u2i_recall' : {}, 'youtubednn_recall': {}, 'youtubednn_usercf_recall': {}, 'cold_start_recall': {}}   

一、读取数据

在一般的rs比赛中读取数据部分主要分为三种模式, 不同的模式对应的不同的数据集:

  1. debug模式: 这个的目的是帮助我们基于数据先搭建一个简易的baseline并跑通, 保证写的baseline代码没有什么问题。 由于推荐比赛的数据往往非常巨大, 如果一上来直接采用全部的数据进行分析,搭建baseline框架, 往往会带来时间和设备上的损耗, **所以这时候我们往往需要从海量数据的训练集中随机抽取一部分样本来进行调试(train_click_log_sample)**, 先跑通一个baseline。
  2. 线下验证模式: 这个的目的是帮助我们在线下基于已有的训练集数据, 来选择好合适的模型和一些超参数。 **所以我们这一块只需要加载整个训练集(train_click_log)**, 然后把整个训练集再分成训练集和验证集。 训练集是模型的训练数据, 验证集部分帮助我们调整模型的参数和其他的一些超参数。
  3. 线上模式: 我们用debug模式搭建起一个推荐系统比赛的baseline, 用线下验证模式选择好了模型和一些超参数, 这一部分就是真正的对于给定的测试集进行预测, 提交到线上, **所以这一块使用的训练数据集是全量的数据集(train_click_log+test_click_log)**

1、读取用户点击新闻日志数据

下面就分别对这三种不同的数据读取模式先建立不同的代导入函数, 方便后面针对不同的模式下导入数据。

# 从训练集中读取数据
def get_click_df(data_path, debug=True, sample_nums=10000, offline=True):
    # debug模式: 从训练集中划出一部分数据来调试代码
    if debug:
        """
            训练集中采样一部分数据调试
            data_path: 原数据的存储路径
            sample_nums: 采样数目(这里由于机器的内存限制,可以采样用户做)
        """
        all_click = pd.read_csv(data_path + 'train_click_log.csv')
        all_user_ids = all_click.user_id.unique()
        sample_user_ids = np.random.choice(all_user_ids, size=sample_nums, replace=False) 
        all_click = all_click[all_click['user_id'].isin(sample_user_ids)]
        all_click = all_click.drop_duplicates((['user_id', 'click_article_id', 'click_timestamp'])) # 去重
        
        return all_click
    else:
        # 读取点击数据,这里分成线上和线下,如果是为了获取线上提交结果应该将测试集中的点击数据合并到总的数据中
        # 如果是为了线下验证模型的有效性或者特征的有效性,可以只使用训练集,这里只是用训练集
        """
            data_path: 原数据的存储路径
            sample_nums: 采样数目(这里由于机器的内存限制,可以采样用户做)
        """
        if offline:
            all_click = pd.read_csv(data_path + 'train_click_log.csv')
        else:
            trn_click = pd.read_csv(data_path + 'train_click_log.csv')
            tst_click = pd.read_csv(data_path + 'testA_click_log.csv')
            all_click = trn_click.append(tst_click)
        all_click = all_click.drop_duplicates((['user_id', 'click_article_id', 'click_timestamp'])) # 去重

        return all_click
# 读取用户点击新闻日志数据
all_click_df = get_click_df(data_path=data_path, debug=False, offline=True)
all_click_df = all_click_df.sort_values('click_timestamp')
all_click_df
user_id click_article_id click_timestamp click_environment click_deviceGroup click_os click_country click_region click_referrer_type
3 199998 157770 1507029532200 4 1 17 1 25 5
45 199987 272143 1507029551778 4 1 17 1 24 5
52 199984 70594 1507029553199 4 3 2 1 5 7
32 199990 272143 1507029564434 4 1 17 1 7 5
0 199999 160417 1507029570190 4 1 17 1 13 1
... ... ... ... ... ... ... ... ... ...
705656 121158 224148 1509798422502 4 1 17 1 13 2
925954 70254 207672 1510093882860 4 1 17 1 20 2
925955 70254 96333 1510093912860 4 1 17 1 20 2
1091177 2465 203538 1510603424886 4 1 17 1 2 2
1091178 2465 145309 1510603454886 4 1 17 1 2 2

1112623 rows × 9 columns

2、对用户点击新闻日志数据的时间戳进行归一化,用于在关联规则的时候计算权重

# 对时间戳进行归一化,用于在关联规则的时候计算权重
max_min_scaler = lambda x : (x-np.min(x))/(np.max(x)-np.min(x))
all_click_df['click_timestamp'] = all_click_df[['click_timestamp']].apply(max_min_scaler)
all_click_df
user_id click_article_id click_timestamp click_environment click_deviceGroup click_os click_country click_region click_referrer_type
3 199998 157770 0.000000 4 1 17 1 25 5
45 199987 272143 0.000005 4 1 17 1 24 5
52 199984 70594 0.000006 4 3 2 1 5 7
32 199990 272143 0.000009 4 1 17 1 7 5
0 199999 160417 0.000011 4 1 17 1 13 1
... ... ... ... ... ... ... ... ... ...
705656 121158 224148 0.774748 4 1 17 1 13 2
925954 70254 207672 0.857419 4 1 17 1 20 2
925955 70254 96333 0.857428 4 1 17 1 20 2
1091177 2465 203538 0.999992 4 1 17 1 2 2
1091178 2465 145309 1.000000 4 1 17 1 2 2

1112623 rows × 9 columns

3、获取历史和最后一次点击

这个在评估召回结果, 特征工程和制作标签转成监督学习测试集的时候回用到

# 获取当前数据的历史点击和最后一次点击
def get_hist_and_last_click(all_click):
    all_click = all_click.sort_values(by=['user_id', 'click_timestamp'])
    click_last_df = all_click.groupby('user_id').tail(1)    # 最后一个点击
    # 如果用户只有一个点击,history为空了,会导致训练的时候这个用户不可见,此时默认泄露一下
    def history_func(user_df):
        if len(user_df) == 1:
            return user_df
        else:
            return user_df[:-1]
    click_history_df = all_click.groupby('user_id').apply(history_func).reset_index(drop=True)

    return click_history_df, click_last_df
# 使用召回评估函数验证当前召回方式的效果
# 这里是为了召回评估,所以提取最后一次点击作为召回评估,如果不需要做召回评估直接使用全量的训练集进行召回(线下验证模型)【如果不是召回评估,直接使用全量数据进行召回,不用将最后一次提取出来】
if metric_recall:
    trn_hist_click_df, trn_last_click_df = get_hist_and_last_click(all_click_df) # 这里是为了召回评估,所以提取最后一次点击  406431, 90000
else:
    trn_hist_click_df = all_click_df
trn_hist_click_df
user_id click_article_id click_timestamp click_environment click_deviceGroup click_os click_country click_region click_referrer_type
0 0 30760 0.330768 4 1 17 1 25 2
1 1 289197 0.330669 4 1 17 1 25 6
2 2 36162 0.330703 4 3 20 1 25 2
3 3 50644 0.330681 4 3 2 1 25 2
4 4 42567 0.330755 4 1 12 1 16 1
... ... ... ... ... ... ... ... ... ...
912618 199999 161191 0.177905 4 1 17 1 13 1
912619 199999 42223 0.177913
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为AI助手,我可以提一个大概的设计思路,但是我无法编写代码。以下是新闻推荐系统的页面设计的详细解析: 1. 首页设计 新闻推荐系统的首页应该是用户进入网站时的第一个界面。因此,在设计首页时,需要考虑到用户的体验和导航。 新闻推荐系统的首页应该有以下几个部分: (1)顶部导航栏 顶部导航栏应包括网站的标志、网站的名称、搜索框和分类导航。在分类导航中,可以将新闻按照不同的栏目分类,以便用户快速找到自己感兴趣的新闻。 (2)中部推荐内容区域 在首页的中部,可以采用卡片式的设计将推荐新闻展示出来。每一条新闻应该带有标题、作者、发表时间和摘要。此外,还应该设置一个“更多”的按钮,让用户可以点击进入更多推荐新闻的页面。 (3)底部的服务栏 底部的服务栏应该包括网站的联系方式、版权声明、友情链接、最新动态等相关信息。 2. 推荐新闻页面设计 推荐新闻页面是新闻推荐系统中最重要的页面之一。它展示了根据用户的兴趣推荐新闻,因此,在页面设计中需要考虑到如何显示新闻内容,以便用户更好地浏览。 (1)左侧分类栏 左侧的分类栏应该包括不同新闻分类,以及热门新闻推荐新闻等选项,让用户可以根据自己的兴趣选择阅读。用户也可以通过搜索框快速找到自己感兴趣的新闻。 (2)中间的新闻展示区域 中间的新闻展示区域是推荐新闻页面的重点。推荐新闻应该以卡片形式呈现,每一张卡片上应该包括标题、摘要、图片、作者、发表时间等信息。可以采用瀑布流式布局展示新闻,提高用户的阅读体验。 (3)右侧推荐栏 为了提高阅读体验和吸引用户的注意力,可以将右侧的推荐栏设置为滚动推荐,每次滚动展示一定数量的相关新闻或关注点。 以上是新闻推荐系统的页面设计和部分设计思路。具体的实现过程和代码需要根据具体的需求和技术架构来定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值