天池入门赛- 新闻推荐-task4-特征工程

特征工程和数据清洗转换是比赛中至关重要的一块, 因为数据和特征决定了机器学习的上限,而算法和模型只是逼近这个上限而已,所以特征工程的好坏往往决定着最后的结果,特征工程可以一步增强数据的表达能力,通过构造新特征,我们可以挖掘出数据的更多信息,使得数据的表达能力进一步放大。
在新闻推荐系统这个赛事背景下,有以下特征可以直接被利用:
1.文章的自身特征,category_id 表示文章的类型,created_as_ts表示文章建立的时间,关系着文章的时效性,words_counts表示文章的字数。
2.文章的embedding特征。
3.用户的设备特征信息。

如何实现?
1.我们首先获得用户的最后一次点击操作和用户的历史点击, 这个基于我们的日志数据集做。
####### 获取当前数据的历史点击和最后一次点击
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)

# 如果用户只有一个点击,hist为空了,会导致训练的时候这个用户不可见,此时默认泄露一下
def hist_func(user_df):
    if len(user_df) == 1:
        return user_df
    else:
        return user_df[:-1]

click_hist_df = all_click.groupby('user_id').apply(hist_func).reset_index(drop=True)

return click_hist_df, click_last_df

2.基于用户的历史行为制作特征, 这个会用到用户的历史点击表, 最后的召回列表, 文章的信息表和embedding向量。
####### 下面基于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

3.制作标签, 形成最后的监督学习数据集
#######训练验证特征
trn_user_item_feats_df.to_csv(save_path + ‘trn_user_item_feats_df.csv’, index=False)
if val_user_item_feats_df is not None:
val_user_item_feats_df.to_csv(save_path + ‘val_user_item_feats_df.csv’, index=False)
tst_user_item_feats_df.to_csv(save_path + ‘tst_user_item_feats_df.csv’, index=False)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值