赛题理解
题目思考:
任何一道题目,都会有一个大的背景,这道题目的背景就是新闻推荐APP预测用户下一次点击情况。其次,任何一道题目都可以抽象出一个关键的问题,对于这道题来说就是:基于时间序列数据的预测。也就是要通过找出前面已经有的时间序列的数据规律,来得到最终那一次的预测。
Note:关键就是要抽象出一个监督学习的问题,分别找到相应的特征和标签,然后才可以进行建模预测。
理解数据:
Note:数据的关键是了解任务相关的数据字段和数据字段的类型, 数据之间的内在关联等,大体梳理一下哪些数据会对我们解决问题非常有用,方便后面我们的数据分析和特征工程。
数据总共有四个文件,其中有一个是测试数据集。他们分别是:
-
articles.csv
:新闻文章信息数据表Field Description article_id 文章id,与click_article_id相对应 category_id 文章类型id created_at_ts 文章创建时间戳 words_count 文章字数 -
articles_emb.csv
:新闻文章embedding向量表示Field Description emb_1,emb_2,…,emb_249 文章embedding向量表示 -
train_click_log.csv
:训练集用户点击日志Field Description user_id 用户id click_article_id 点击文章id click_timestamp 点击时间戳 click_environment 点击环境 click_deviceGroup 点击设备组 click_os 点击操作系统 click_country 点击城市 click_region 点击地区 click_referrer_type 点击来源类型 -
testA_click_log.csv
:测试集用户点击日志(数据字段与3相同)
Note:数据中包含30万用户,36万多篇不同新闻文章。训练集用20万用户的点击日志做训练,5万用户日志作为测试集A,5万用户日志作为测试集B。
结果提交:
官网给出了比赛提交样例:sample_submit.csv
训练集真值(预测的真值)只有一篇新闻,但比赛要求提交的结果是每个用户推荐5篇。
理解评估指标:
Note:在比赛中构建一个合理的本地的验证集和验证的评价指标是很关键的步骤,能有效的节省很多时间。(因为比赛能够测试的次数很少)
MRR(Mean Reciprocal Rank):首先对选手提交的表格中的每个用户计算用户得分
score
(
u
s
e
r
)
=
∑
k
=
1
5
s
(
u
s
e
r
,
k
)
k
\text {score}(u s e r)=\sum_{k=1}^{5} \frac{s(u s e r, k)}{k}
score(user)=k=1∑5ks(user,k)
其中,s函数的定义是是否在这个位置预测出用户的那条真值
公式可以直观的看出,如果没有预测出来那条真值,则得分直接归零;如果预测出来了那个真值,则越靠前分数越高,靠后则会有相应的系数降低得分。
基础思路:
由于模型是要最终从36万多篇文章中找到5篇文章,那么其实可以想到直接通过一个softmax得到每篇文章的概率,最后取前五篇就好了。
由于数据的庞大,还要考虑减小问题的规模。
Baseline学习
由于这次是学习赛,所以我将公开的Baseline一格一格地拷贝到天池的云计算notebook上,这样每一个都可以阅读一下,理解思路以及实现方式。
精彩代码片段
# 根据点击时间获取用户的点击文章序列 {user1: [(item1, time1), (item2, time2)..]...}
def get_user_item_time(click_df):
"""
这一部分代码写的十分精妙
dict(zip(a["alpha"],a["beta"]))和dict(zip(a["alpha"],a["beta"]))区别
"""
click_df = click_df.sort_values('click_timestamp')
def make_item_time_pair(df):
"""
这里将 文章id 和 点击时间戳 ,按照顺序合并在一起,最终合并的外套是list
变成这样:[(item1, time1), (item2, time2)..]
"""
return list(zip(df['click_article_id'], df['click_timestamp']))
user_item_time_df = click_df.groupby('user_id')['click_article_id', 'click_timestamp'].apply(lambda x: make_item_time_pair(x))\
.reset_index().rename(columns={0: 'item_time_list'})
# 这里将 用户id 和生成的 物品-时间 表,按顺序合并在一起,最终外套是dict
user_item_time_dict = dict(zip(user_item_time_df['user_id'], user_item_time_df['item_time_list']))
return user_item_time_dict
未完待续
在自己机器上跑了baseline,因为之前没接触过过推荐,需要了解一下其他模型是什么样的~