Task4_天池新闻推荐特征工程

前言

本文针对天池有关推荐系统的赛题进行特征工程部分大致梳理

一、监督学习问题数据的梳理:

我们知道监督学习的主要特点是有标签,所以我觉得这次推荐赛题的难点之一就是如何把用户有关点击新闻的历史行为数据处理为带标签的监督学习问题。
Datawhale组队学习新闻推荐的特征工程部分捋了一下现有的特征等数据

1.文章的自身特征, category_id表示这文章的类型, created_at_ts表示文章建立的时间, 这个关系着文章的时效性, words_count是文章的字数, 一般字数太长我们不太喜欢点击, 也不排除有人就喜欢读长文。
2.文章的内容embedding特征, 这个召回的时候用过, 这里可以选择使用, 也可以选择不用, 也可以尝试其他类型的embedding特征, 比如W2V等
3.用户的设备特征信息

构造监督数据集的思路: 根据召回结果, 得到一个{user_id: [可能点击的文章列表]}形式的字典。用户user1得到召回列表{user1: [item1, item2, item3]},那么就可以得到三行数据(user1, item1), (user1, item2), (user1, item3)的形式, 这就是监督测试集时候的前两列特征。

构造特征的思路:每个用户的点击文章是与其历史点击的文章信息是有很大关联,所以特征构造这块很重要的一系列特征一结合用户的历史点击文章信息。上面构造数据集已经得到了每个用户及点击候选文章的两列的一个数据集, 而目的是要预测最后一次点击的文章, 比较自然的一个思路就是和其最后几次点击的文章产生关系, 这样既考虑了其历史点击文章信息, 又得离最后一次点击较近,因为新闻很大的一个特点就是注重时效性。 往往用户的最后一次点击会和其最后几次点击有很大的关联。 所以我们就可以对于每个候选文章, 做出与最后几次点击相关的特征如下:

1.候选item与最后几次点击的相似性特征(embedding内积) --- 这个直接关联用户历史行为
2.候选item与最后几次点击的相似性特征的统计特征 --- 统计特征可以减少一些波动和异常
3.候选item与最后几次点击文章的字数差的特征 --- 可以通过字数看用户偏好
4.候选item与最后几次点击的文章建立的时间差特征 --- 时间差特征可以看出该用户对于文章的实时性的偏好
5. 如果使用了youtube召回的话, 还可以制作用户与候选item的相似特征

在下面实现中,通过对这些的考虑定义权重

二、监督学习问题数据的制作:

1.导包
导入需要用到的包,不再赘述
2.数据读取与划分
基本和前几篇的数据读取差不多,为了在线下验证模型参数的好坏,为了完全模拟测试集,为了分解制作排序特征时的压力,这里在训练集中抽取部分用户的所有信息来作为验证集
(1)获取训练集并进行训练和验证集的划分
(2)获取历史点击和最后一次点击
(3)读取训练、验证及测试集
(4)读取召回列表
(5)读取各种Embedding
(6)读取文章信息
(7)对训练数据做负采样
(8)将召回数据转换成字典
(9)读取文章信息
3.特征工程
(1)制作与用户历史行为相关特征

1.对于每个用户, 获取最后点击的N个商品的item_id,
2.对于该用户的每个召回商品, 计算与上面最后N次点击商品的相似度的和(最大, 最小,均值), 时间差特征,相似性特征,字数差特征,与该用户的相似性特征
# 下面基于data做历史相关的特征
def create_feature(users_id, recall_list, click_hist_df,  articles_info, articles_emb, user_emb=None, N=1):
    """
    基于用户的历史行为做相关特征
    :param users_id: 用户id
    :param recall_list: 对于每个用户召回的候选文章列表
    :param click_hist_df: 用户的历史点击信息
    :param articles_info: 文章信息
    :param articles_emb: 文章的embedding向量, 这个可以用item_content_emb, item_w2v_emb, item_youtube_emb
    :param user_emb: 用户的embedding向量, 这个是user_youtube_emb, 如果没有也可以不用, 但要注意如果要用的话, articles_emb就要用item_youtube_emb的形式, 这样维度才一样
    :param N: 最近的N次点击  由于testA日志里面很多用户只存在一次历史点击, 所以为了不产生空值,默认是1
    """
    
    # 建立一个二维列表保存结果, 后面要转成DataFrame
    all_user_feas = []
    i = 0
    for user_id in tqdm(users_id):
        # 该用户的最后N次点击
        hist_user_items = click_hist_df[click_hist_df['user_id']==user_id]['click_article_id'][-N:]
        
        # 遍历该用户的召回列表
        for rank, (article_id, score, label) in enumerate(recall_list[user_id]):
            # 该文章建立时间, 字数
            a_create_time = articles_info[articles_info['article_id']==article_id]['created_at_ts'].values[0]
            a_words_count = articles_info[articles_info['article_id']==article_id]['words_count'].values[0]
            single_user_fea = [user_id, article_id]
            # 计算与最后点击的商品的相似度的和, 最大值和最小值, 均值
            sim_fea = []
            time_fea = []
            word_fea = []
            # 遍历用户的最后N次点击文章
            for hist_item in hist_user_items:
                b_create_time = articles_info[articles_info['article_id']==hist_item]['created_at_ts'].values[0]
                b_words_count = articles_info[articles_info['article_id']==hist_item]['words_count'].values[0]
                
                sim_fea.append(np.dot(articles_emb[hist_item], articles_emb[article_id]))
                time_fea.append(abs(a_create_time-b_create_time))
                word_fea.append(abs(a_words_count-b_words_count))
                
            single_user_fea.extend(sim_fea)      # 相似性特征
            single_user_fea.extend(time_fea)    # 时间差特征
            single_user_fea.extend(word_fea)    # 字数差特征
            single_user_fea.extend([max(sim_fea), min(sim_fea), sum(sim_fea), sum(sim_fea) / len(sim_fea)])  # 相似性的统计特征
            
            if user_emb:  # 如果用户向量有的话, 这里计算该召回文章与用户的相似性特征 
                single_user_fea.append(np.dot(user_emb[user_id], articles_emb[article_id]))
                
            single_user_fea.extend([score, rank, label])    
            # 加入到总的表中
            all_user_feas.append(single_user_fea)
    
    # 定义列名
    id_cols = ['user_id', 'click_article_id']
    sim_cols = ['sim' + str(i) for i in range(N)]
    time_cols = ['time_diff' + str(i) for i in range(N)]
    word_cols = ['word_diff' + str(i) for i in range(N)]
    sat_cols = ['sim_max', 'sim_min', 'sim_sum', 'sim_mean']
    user_item_sim_cols = ['user_item_sim'] if user_emb else []
    user_score_rank_label = ['score', 'rank', 'label']
    cols = id_cols + sim_cols + time_cols + word_cols + sat_cols + user_item_sim_cols + user_score_rank_label
            
    # 转成DataFrame
    df = pd.DataFrame( all_user_feas, columns=cols)
    
    return df

(2)用户和文章特征

1.文章自身的特征, 文章字数,文章创建时间, 文章的embedding (articles表中)
2.用户点击环境特征, 那些设备的特征(这个在df中)
3.对于用户和商品还可以构造的特征:
(1)基于用户的点击文章次数和点击时间构造可以表现用户活跃度的特征
(2)基于文章被点击次数和时间构造可以反映文章热度的特征
(3)用户的时间统计特征: 根据其点击的历史文章列表的点击时间和文章的创建时间做统计特征,比如求均值, 这个可以反映用户对于文章时效的偏好
(4)用户的主题爱好特征, 对于用户点击的历史文章主题进行一个统计, 然后对于当前文章看看是否属于用户已经点击过的主题
(5)用户的字数爱好特征, 对于用户点击的历史文章的字数统计, 求一个均值

(3)分析点击时间和点击文章的次数,区分用户活跃度
(4)分析点击时间和被点击文章的次数, 衡量文章热度特征
(5)用户的各种习惯,如设备习惯、时间习惯、主题爱好、
文章字数偏好

上述每一部分的思路我觉得大致理解是可以的,但每一部分其实相当一个功能函数,可以根据自己的理解进行制作再进行验证,接下去在理解的基础上俺再来进行补充,不理解通透我真的是…写不下去了

未完待续…

五、总结

这里我其实还没有很好的理解每一部分,所以暂时先遵着Datawhale提供的特征工程这部分代码把要点汇合了一下,具体每一部分的理解和实现都不是完全剖离的得先搞懂每一块再贯穿一下

六、参考

[1]Datawhale组队学习新闻推荐_特征工程

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TaskFunction_t是一个函数指针类型,它指向一个参数为void指针的函数,函数返回类型为void。\[3\]在任务创建函数中,需要传入一个TaskFunction_t类型的参数,用于指定任务的入口函数。这个入口函数会在任务创建后被调用,并执行任务的具体逻辑。 #### 引用[.reference_title] - *1* [源码分析之任务创建](https://blog.csdn.net/qq_41890114/article/details/121132108)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [02_FreeRTOS内核实现---任务的定义与任务切换](https://blog.csdn.net/qq_70244454/article/details/125823771)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [FreeRTOS任务函数与函数指针](https://blog.csdn.net/ssssadw/article/details/111147256)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值