【 推荐系统 | 计算广告 | CTR 】算法竞赛笔记

黄色为笔者的批注

1. 天猫复购预测

赛题链接:

天猫复购预测之挑战Baseline

1.1 数据探索

笔者仅列出数据的字段方便理解,您可以看官方的EDA:

天猫重复购买预测 02 数据探索

1.1.1 用户行为日志

在这里插入图片描述

感觉是把行为日志表和商品表join了一下

1.1.2 用户画像

在这里插入图片描述

只有年龄和性别两个特征

1.1.3 训练数据与测试数据

最后训练与预测,给俩ID预测1标签: u s e r _ i d + m e r c h a n t _ i d → l a b e l user\_id + merchant\_id \rightarrow label user_id+merchant_idlabel

label表示用户是否复购

本质上是3表join,构造用户与商品的交互特征

1.2 特征工程(官方代码)

本节介绍官方代码的特征工程操作

天猫重复购买预测 03 特征工程

1.2.1 根据用户浏览商品的各个属性,构造xx_path的序列特征

这里有个坑,实际文件的字段名和网页塞题信息不符

$ head -n 1 user_log_format1.csv 
user_id,item_id,cat_id,seller_id,brand_id,time_stamp,action_type

卖家在train_format1.csvmerchant_id,在user_log_format1.csvseller_id

group_by用户,按时间顺序形成一个列表

agg_dict = {
    
      # group by user_id
    'item_id': list_join_func,
    'cat_id': list_join_func,
    'seller_id': list_join_func,
    'brand_id': list_join_func,
    'time_stamp': list_join_func,
    'action_type': list_join_func
}

rename_dict = {
    
    
    'item_id': 'item_path',
    'cat_id': 'cat_path',
    'seller_id': 'seller_path',
    'brand_id': 'brand_path',
    'time_stamp': 'time_stamp_path',
    'action_type': 'action_type_path'
}
# 主键是user_id, 表示用户的浏览记录
user_log_path = user_log.groupby('user_id').agg(agg_dict).reset_index().rename(columns=rename_dict)

all_data_path = all_data.merge(user_log_path, on='user_id')

官方代码是用这个path提取统计信息的(虽然完全可以用group by做,咱也不知道,咱也没法问)

这个path在后面会用来构造

  1. 统计特征
  2. TFIDF特征
  3. Embedding特征

1.2.2 统计特征

  • 用户交互了多少个商品
  • 用户交互了多少商家
  • 用户交互了多少类别的商品

⋯ \cdots

  • 用户最早(最晚)有交互记录的时间
  • 用户交易持续时间
  • timestap的分布取方差

⋯ \cdots

  • 用户最喜欢的店铺
  • 用户最喜欢的品牌
  • 用户最常见的动作

批注:

  1. 可以对店铺做Embedding替换掉这个ID选项
  2. 造一个特征,即【用户最喜欢的xx Embedding】- 【被预测的xx Embedding】

⋯ \cdots

  • 用户在最喜欢店铺上花费的行为次数
  • 用户在最喜欢品牌上花费的行为次数

这类特征用助于描述用户是否对某个产品(店铺)“忠诚”,不过最好除以总次数算一个比例出来

因为action_type这个字段很特殊,包含了收藏点击购买等动作,所以需要单独计算每个用户不同类别动作的次数

  • 点击次数
  • 添加到购物车次数
  • 购买次数
  • 收藏次数

其实统计得太少了。仅仅只是 【 select 开窗函数 from user_id 】 ,没考虑商家等因素

1.2.3 TFIDF特征

本质上仍在做序列建模。上文说道,对user_id做group by后,对seller,cat等字段做agg,会得到xx_path的特征。

本质上这就是一组句子,可以用NLP的word2vec提取各个实体的Embedding。

在讨论Embedding之前,我们可以用词袋模型对实体进行建模,然后用TFIDF降低高频常见词的权重,提高低频重要词的权重。

超参:

  1. ngram_range=(1, 1) unigram模型
  2. max_features=100 最大特征数为100(最后只有100列)

其实最后得到的是一个用来描述用户的特征

tfidfVec = TfidfVectorizer(stop_words=ENGLISH_STOP_WORDS, ngram_range=(1, 1), max_features=100)

# 利用countvector,tfidf提取特征

# columns_list = ['seller_path', 'cat_path', 'brand_path', 'action_type_path', 'item_path', 'time_stamp_path']
columns_list = ['seller_path']
for i, col in enumerate(columns_list):
    all_data_test[col] = all_data_test[col].astype(str)
    tfidfVec.fit(all_data_test[col])
    data_ = tfidfVec.transform(all_data_test[col])
    if i == 0:
        data_cat = data_
    else:
        data_cat = sparse.hstack((data_cat, data_))

## 特征重命名 特征合并

df_tfidf = pd.DataFrame(data_cat.toarray())
df_tfidf.columns = ['tfidf_' + str(i) for i in df_tfidf.columns]
all_data_test = pd.concat([all_data_test, df_tfidf], axis=1)

批注:

可以尝试LDA、LSA、pLSA、NFM等主题模型、矩阵分解、降维 等特征提取方法

可以group_by seller_id,agg user_id,这样得到的就是商家的词向量了。总之,group_by 啥,就会得到啥的词向量

1.2.4 计算w2v词向量后对所有词向量取平均

标题其实已经把内容说完了。

对词向量取评价,从本质上来说是一种最基本、最简单文档向量计算方法。

问题转化为文档向量计算,可以顺着这个思路去优化:

什么SIF加权啊,BM25排序啊,很多的,先列下参考文献。

  1. 将句子表示为向量(上):无监督句子表示学习(sentence embedding)
  2. 将句子表示为向量(下):无监督句子表示学习(sentence embedding)
  3. A Simple but Tough-to-Beat Baseline for Sentence Embeddings[Sanjeev Arora and Yingyu Liang and Tengyu Ma, 2017]
  4. 四种计算文本相似度的方法对比[Yves Peirsman]
  5. Improvements to BM25 and Language Models Examined

词向量的优化思路:

  1. GloVe计算词向量

1.2.5 Stacking特征

本质上是类似awslab的AutoGluon的2层stacking

即将模型的预测值concat进训练集中。因为concat的是交叉验证中验证集的预测值,所以并不会标签泄露。

批注:

可以采用AutoGluon的RepeatedKFold增加鲁棒性(具体用法需要看源代码)

猜你喜欢

转载自blog.csdn.net/TQCAI666/article/details/112905911