关注我的公众号YueTan进行交流探讨
欢迎关注数据比赛方案仓库 https://github.com/hongyingyue/Competition-solutions
背景
我们从三个层面定义用户未来价值。
- 用户N日留存分
- 用户N日观看视频次数
- 用户N日观看视频的总时长
以七日作为未来时间窗口:
1.一个用户的7日留存分等于3,代表这个用户未来的7天里,有3天会访问芒果TV。
2.一个用户未来7天观看了20次视频,代表这个用户7日观看视频次数为20。
3.一个用户未来7天一共观看了1000秒,代表这个用户7日观看视频时长为1000。
数据
数量量比较大
用户观看行为序列数据
- did 用户设备id
- vid 视频id
- vts 用户观看vid的播放时长
- timestamp 用户观看vid的时间戳
视频信息表
- vid 视频id
- cid 合集id
- Is_intact 视频类型
- online_time 上线时间
- serialno 集号
- series_id 系列id
- duration 视频时长
- stars 明星
- tags 标签
- img_url 视频封面图片地址
- classify_id 频道id
预测目标
-
active_days
-
watch_nums
-
watch_durations
评价指标
R^2
Baseline
https://github.com/MgtvAi/4nd_mgtv_ijcai/blob/main/mgtv_ijcai_baseline.ipynb
https://mp.weixin.qq.com/s/X_Krkq0t58OUe9Ot274vwQ
- 针对每一个目标分别建立一个LGB模型
utils
def sliding_window (df, end_date, day=7) :
#end_date = df['timestamp'].max()
start_date = end_date - datetime.timedelta(day)
return df[(df['date'] <= end_date) & (df['date'] > start_date)].reset_index(drop=True)
def date_2_timestamp (date_time) :
# 字符类型的时间
# 转为时间数组
timeArray = time.strptime(date_time, "%Y%m%d%H%M%S")
# 转为时间戳
timeStamp = long(time.mktime(timeArray))
return timeStamp # 1381419600
def timestamp_to_date (timestamp) :
# 获得当前时间时间戳
#转换为其他日期格式,如:"%Y-%m-%d %H:%M:%S"
timeArray = time.localtime(int(timestamp))
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
#return pd.to_datetime(otherStyleTime)
return otherStyleTime
标签
def get_label (df_behaviors, end_date, day=7) :
user_behaviors_label_windows = sliding_window (df_behaviors,
end_date,
day=7)
user_history_hebaviors = sliding_window (df_behaviors,
end_date - datetime.timedelta(day),
day=df_behaviors['date_day'].nunique())
agg = {
'date_day' : 'nunique',
'vid' : 'count',
'vts' : 'sum',
}
df_label = user_behaviors_label_windows.groupby(['did']).agg(agg)
df_label.columns = pd.Index([e[0] + e[1].upper() for e in df_label.columns.tolist()])
df_label = df_label.reset_index()
df_label.columns = ['did', 'active_days', 'watch_nums', 'watch_durations']
return df_label, user_history_hebaviors, user_behaviors_label_windows
特征
过去一段时间的活跃天数,观看视频数量,观看时长的统计特征
def make_feats (df, days) :
end_date = df['date'].max()
df_temp = sliding_window(df, end_date, days)
agg = {
'date_day' : 'nunique',
'vid' : 'count',
'vts' : ['mean', 'std', 'min', 'max', 'sum'],
}
df_feats = df_temp.groupby(['did']).agg(agg)
df_feats.columns = pd.Index([e[0] + '_last_' + str(days) + "_" + e[1].upper() for e in df_feats.columns.tolist()])
df_feats = df_feats.reset_index()
return df_feats
def create_sample (user_history_behaviors, df_label) :
#训练集特征窗口
#最近一天
df_feats_1 = make_feats (user_history_behaviors, days=1)
#最近三天
df_feats_2 = make_feats (user_history_behaviors, days=3)
#最近七天
df_feats_3 = make_feats (user_history_behaviors, days=7)
#最近21天
df_feats_4 = make_feats (user_history_behaviors, days=7 * 3)
df_label = df_label.merge(df_feats_1, on='did', how='left')
df_label = df_label.merge(df_feats_2, on='did', how='left')
df_label = df_label.merge(df_feats_3, on='did', how='left')
df_label = df_label.merge(df_feats_4, on='did', how='left')
return df_label
其他可能的点
- 目标是预测did在未来7天行为