【BI学习作业13-淘宝定向广告演化与天猫用户复购预测】


写在前面的话

1.思考题

1.1电商定向广告和搜索广告有怎样的区别,算法模型是否有差别

1.1.1电商定向广告

现代社会,我们的生产力在不断提高,各种商品都在不断推陈出新,早已经过了“酒香不怕巷子深”的时代,商家如果不推广,只有死路一条。说到淘宝推广,大家听得最多的应该就是淘宝定向推广,它到底是什么含义呢?

淘宝直通车定向推广是继搜索推广之后的又一精准推广方式。利用淘宝网庞大的数据库,通过创新的多维度人群定向技术,锁定您的目标客户,并将您的推广信息展现在目标客户浏览的网页上。除了淘宝网站内的热门页面外,淘宝直通车还整合了多家外部优质网站,帮助您的推广宝贝覆盖到更多目标客户。展现逻辑是根据潜在买家的浏览和购买习惯、网页内容,由淘宝直通车系统自动匹配出相关度较高的宝贝,并结合出价进行展现,更精准的迎合买家需求。

宝贝定向推广都有哪些

其实我们最常见的定向推广其实大家都有用到,最基础的定向推广三大项就是我们宝贝推广计划中的投放平台、时间、地域的推广,一般掌柜都会根据自己的经验去选择平台、地域和时间的针对性推广。
在这里插入图片描述

另外相对来讲一些掌柜对于宝贝定向推广这个字眼并不陌生,因为在直通车宝贝计划页面有定向推广的专栏。
在这里插入图片描述

一般在调整关键词的时候都会看到这个部分,虽然后台设置中,搜索人群不没有归类在定向推广中,但是严格来讲搜索人权的设置,就是基于关键词基础上的针对特定人群的一种选择性投放,换句话说也是符合我们所说的定向推广的概念的,不过看到是一回事,用起来又是一回事,很多掌柜常常觉得关键词是直通车的重中之重,只要关键词优化的好,转化一定没问题,但是有句话说的好“存在即是合理”,所以可想而知,定向推广放在这里绝对是对宝贝推广有着很大的作用的,另外还有一个很容易忽略的地方,就是关键词推广中的搜索人群部分。
在这里插入图片描述
这一部分可以让掌柜自由的针对访客人群进行定义,有针对性的进行溢价,特别是一些性别或者季节性、温度选择性比较强的产品来说,对于人群的针对性溢价就尤为主要,这个区域可以针对人群的性别,年龄以及天气的好坏,温度的高低进行一系列的针对性溢价,让我们的流量更加精准有针对性,例如在对于一些取暖设施的定向中我们就会侧重于对雨雪天气,并且温度寒冷的地区进行侧重投放。

另外在定向推广部分可以对投放人群以及展示位置进行选择性设置。
在这里插入图片描述
在这里插入图片描述

对于访客以及购物意图、展示位置的选择,可以在更多方面满足掌柜在宝贝推送和展现方面的要求。

淘宝定向推广是针对淘宝千人千面政策而产生的一种推广方式,它可以将我们的商品广告展示给有这方面需求的客户,带来精准流量,从而提升商品的转化率。

1.1.2搜索广告

我们早上醒来会查下天气,出门会查下交通,路上刷微博看到不认识的热搜词条会自己再去进行搜索。工作中更不用说,我们遇到不清楚的内容,除了去问可能了解的前辈、同事,就是百度了!下班后听音乐会在音乐APP里搜索自己喜欢的歌单,去网上买东西也会在搜索栏中搜索。我们其实一直离搜索很近。

不管上述搜索的有多复杂、不同,我们每个用户抱有目的地在各个平台上进行搜索。

各个平台也会整理平台内部的信息以用于展现在用户的搜索结果中。平台发展壮大,用户越来越多,除了自身提供相关服务或商品外,总会希望平台可以带来收益。

对于品牌商家来说,品牌相关的信息或公司介绍、产品说明,或商品特色、货物价格等等,都希望能在搜索结果页面里,以更靠前的位置展示给消费者、经销商等。

搜索广告是不是这么来的,我不清楚,但搜索广告所涉及到的三部分人群的目的大概就是上面这些。

在这里插入图片描述

总结两点:
1、淘宝定向推广是针对淘宝千人千面政策而产生的一种推广方式,它可以将商品广告展示给有这方面需求的客户,带来精准流量,从而提升商品的转化率。
2、搜索广告仅仅是因为你用浏览器搜索词条,给你显示词条相关的广告,不是精准投放。

1.2定向广告都有哪些常见的使用模型,包括Attention机制模型

随着技术更新与发展,推荐系统经历了几次变革,主要分为三个大阶段:1.线性模型;2.非线性模型;3.深度学习。

在这里插入图片描述

LR模型阶段用LR模型 + 人工特征的方式处理数据,LR模型不能处理非线性特征,所以需要特征工程去加入非线性特征。

MLR(Mixed Logistic Regression)模型阶段,混合逻辑回归,采用分而治之的策略,用分段线性+级联,拟合高维空间的非线性分类面,相比于人工来说提升了效率和精度。

DNN模型阶段,计算机和硬件运算速度提升,使用GPU,处理复杂模型和大数据量。存在的问题是需要用定长embedding表达用户多种多样的兴趣。
在这里插入图片描述
DIN模型阶段,加入兴趣捕捉,对用户历史行为洞察。Diversity,多样性,一个用户可以对多种品类的东西感兴趣;Local Activation,局部激活,只有部分历史行为对目前的点击预测有帮助。
在这里插入图片描述

DIEN模型阶段,兴趣演化,综合序列随机跳转多,没有规律,噪音大;具体到某个兴趣,存在随时间逐渐演化的趋势。
在这里插入图片描述
在这里插入图片描述

DSIN模型阶段,将用户行为序列看成多个会话;会话内相近,会话与会话之间差别大。
在这里插入图片描述

在这里插入图片描述

1.3DIN中的Attention机制思想和原理是怎样的

在对用户行为的embedding计算上引入了attention network (也称为Activation Unit) 。

把用户历史行为特征进行embedding操作,视为对用户兴趣的表示,之后通过Attention Unit,对每个兴趣表示赋予不同的权值。

Attention Weight是由用户历史行为和候选广告进行匹配计算得到的,对应着洞察(用户兴趣的Diversity,以及Local Activation)。
在这里插入图片描述

Attention思想:在pooling的时候,与 candidate Ad 相关的商品权重大一些,与candidate Ad 不相关的商品权重小一些。

Attention分数,将candidate Ad与历史行为的每个商品发生交互来计算。

Activation Unit输出Activation Weight,输入包括用户行为embedding和候选广告embedding以外,还考虑了他们两个的外积。对于不同的candidate ad,得到的用户行为表示向量也不同。
在这里插入图片描述

不对点击序列的Attention分数做归一化,直接将分数与对应商品的embedding向量做加权和,目的在于保留用户的兴趣强度。

比如,用户的点击序列中90%是衣服,10%是电子产品,有两个候选ad(T恤和手机),T恤的候选ad 激活属于衣服和衣服的大部分历史行为会比手机获得更大的兴趣强度。

用SoftMax不能体现用户的行为强度,比如90%时间看衣服,10%看电子产品。

1.4DIEN相比于DIN有哪些创新

  • DIEN和DIN最底层都有Embedding Layer,User profile, target AD和context feature,处理方式一样
  • Interest Extractor Layer从embedding数据中提取出interest。但用户在某一时间的interest不仅与当前的behavior有关,也与之前的behavior相关,所以使用GRU单元来提取interest
  • Interest Extractor Layer,通过辅助loss,提升兴趣表达的准确性
  • Interest Evolution Layer,更准确的表达用户兴趣的动态变化性,在GRU基础上增加Attention机制,找到与target AD相关的interest
  • DIN中简单的使用外积完成的activation unit => 使用attention-based GRU网络,更好的挖掘序列数据中的兴趣及演化

1.5DSIN关于Session的洞察是怎样的,如何对Session兴趣进行表达

  • 将用户的点击行为按照时间排序,前后的时间间隔大于30min,就进行切分
  • 将用户的行为序列S切分成多个会话序列Q
  • 第k个会话
    T是会话的长度,bi是会话中第i个行为(d_model维embedding向量)Qk是T * d维,会话序列Q是K * T * d维

在这里插入图片描述

1.6如果你来设计淘宝定向广告,会有哪些future work(即下一个阶段的idea)

2.编程题

2.1天猫用户复购预测

数据集地址:https://tianchi.aliyun.com/competition/entrance/231576/introduction

目标:

使用传统机器学习完成预测
使用Attention机制的DNN模型完成预测

import gc
import pandas as pd
# 用户行为,使用format1进行加载
# 加载全量样本
"""
user_log = pd.read_csv('./data_format1/user_log_format1.csv', dtype={'time_stamp':'str'})
user_info = pd.read_csv('./data_format1/user_info_format1.csv')
train_data1 = pd.read_csv('./data_format1/train_format1.csv')
submission = pd.read_csv('./data_format1/test_format1.csv')
"""
# 加载小样本
user_log = pd.read_csv('./data_format1_small/sample_user_log.csv', dtype={'time_stamp':'str'})
user_info = pd.read_csv('./data_format1_small/sample_user_info.csv')
train_data1 = pd.read_csv('./data_format1_small/train.csv')
submission = pd.read_csv('./data_format1_small/test.csv')
train_data = pd.read_csv('./data_format2/train_format2.csv')

train_data1['origin'] = 'train'
submission['origin'] = 'test'
matrix = pd.concat([train_data1, submission], ignore_index=True, sort=False)
#print(matrix)

matrix.drop(['prob'], axis=1, inplace=True)
# 连接user_info表,通过user_id关联
matrix = matrix.merge(user_info, on='user_id', how='left')
# 使用merchant_id(原列名seller_id)
user_log.rename(columns={'seller_id':'merchant_id'}, inplace=True)
# 格式化
user_log['user_id'] = user_log['user_id'].astype('int32')
user_log['merchant_id'] = user_log['merchant_id'].astype('int32')
user_log['item_id'] = user_log['item_id'].astype('int32')
user_log['cat_id'] = user_log['cat_id'].astype('int32')
user_log['brand_id'].fillna(0, inplace=True)
user_log['brand_id'] = user_log['brand_id'].astype('int32')
user_log['time_stamp'] = pd.to_datetime(user_log['time_stamp'], format='%H%M')
# 1 for <18; 2 for [18,24]; 3 for [25,29]; 4 for [30,34]; 5 for [35,39]; 6 for [40,49]; 7 and 8 for >= 50; 0 and NULL for unknown
matrix['age_range'].fillna(0, inplace=True)
# 0:female, 1:male, 2:unknown
matrix['gender'].fillna(2, inplace=True)
matrix['age_range'] = matrix['age_range'].astype('int8')
matrix['gender'] = matrix['gender'].astype('int8')
matrix['label'] = matrix['label'].astype('str')
matrix['user_id'] = matrix['user_id'].astype('int32')
matrix['merchant_id'] = matrix['merchant_id'].astype('int32')
del user_info, train_data1
gc.collect()
print(matrix)

# User特征处理
groups = user_log.groupby(['user_id'])
# 用户交互行为数量 u1
temp = groups.size().reset_index().rename(columns={0:'u1'})
matrix = matrix.merge(temp, on='user_id', how='left')
# 使用agg 基于列的聚合操作,统计唯一值的个数 item_id, cat_id, merchant_id, brand_id
#temp = groups['item_id', 'cat_id', 'merchant_id', 'brand_id'].nunique().reset_index().rename(columns={'item_id':'u2', 'cat_id':'u3', 'merchant_id':'u4', 'brand_id':'u5'})
# 对于每个user_id 不重复的item_id的数量 => u2
temp = groups['item_id'].agg([('u2', 'nunique')]).reset_index()
matrix = matrix.merge(temp, on='user_id', how='left')
# 对于每个user_id 不重复的cat_id的数量 => u3
temp = groups['cat_id'].agg([('u3', 'nunique')]).reset_index()
matrix = matrix.merge(temp, on='user_id', how='left')
temp = groups['merchant_id'].agg([('u4', 'nunique')]).reset_index()
matrix = matrix.merge(temp, on='user_id', how='left')
temp = groups['brand_id'].agg([('u5', 'nunique')]).reset_index()
matrix = matrix.merge(temp, on='user_id', how='left')

# 时间间隔特征 u6 按照小时
# 对于每个user_id 计算time_stamp的最小时间 => F_time, 最大时间max => L_time
temp = groups['time_stamp'].agg([('F_time', 'min'), ('L_time', 'max')]).reset_index()
temp['u6'] = (temp['L_time'] - temp['F_time']).dt.seconds/3600
matrix = matrix.merge(temp[['user_id', 'u6']], on='user_id', how='left')
# 统计操作类型为0,1,2,3的个数
temp = groups['action_type'].value_counts().unstack().reset_index().rename(columns={0:'u7', 1:'u8', 2:'u9', 3:'u10'})
matrix = matrix.merge(temp, on='user_id', how='left')
#print(matrix)

# 商家特征处理
groups = user_log.groupby(['merchant_id'])
# 商家被交互行为数量 m1
temp = groups.size().reset_index().rename(columns={0:'m1'})
matrix = matrix.merge(temp, on='merchant_id', how='left')
# 统计商家被交互的user_id, item_id, cat_id, brand_id 唯一值
temp = groups['user_id', 'item_id', 'cat_id', 'brand_id'].nunique().reset_index().rename(columns={'user_id':'m2', 'item_id':'m3', 'cat_id':'m4', 'brand_id':'m5'})
matrix = matrix.merge(temp, on='merchant_id', how='left')
# 统计商家被交互的action_type 唯一值
temp = groups['action_type'].value_counts().unstack().reset_index().rename(columns={0:'m6', 1:'m7', 2:'m8', 3:'m9'})
matrix = matrix.merge(temp, on='merchant_id', how='left')
# 按照merchant_id 统计随机负采样的个数
temp = train_data[train_data['label']==-1].groupby(['merchant_id']).size().reset_index().rename(columns={0:'m10'})
matrix = matrix.merge(temp, on='merchant_id', how='left')
#print(matrix)

# 按照user_id, merchant_id分组
groups = user_log.groupby(['user_id', 'merchant_id'])
temp = groups.size().reset_index().rename(columns={0:'um1'}) #统计行为个数
matrix = matrix.merge(temp, on=['user_id', 'merchant_id'], how='left')
temp = groups['item_id', 'cat_id', 'brand_id'].nunique().reset_index().rename(columns={'item_id':'um2', 'cat_id':'um3', 'brand_id':'um4'}) #统计item_id, cat_id, brand_id唯一个数
matrix = matrix.merge(temp, on=['user_id', 'merchant_id'], how='left')
temp = groups['action_type'].value_counts().unstack().reset_index().rename(columns={0:'um5', 1:'um6', 2:'um7', 3:'um8'})#统计不同action_type唯一个数
matrix = matrix.merge(temp, on=['user_id', 'merchant_id'], how='left')
temp = groups['time_stamp'].agg([('first', 'min'), ('last', 'max')]).reset_index()
temp['um9'] = (temp['last'] - temp['first']).dt.seconds/3600
temp.drop(['first', 'last'], axis=1, inplace=True)
matrix = matrix.merge(temp, on=['user_id', 'merchant_id'], how='left') #统计时间间隔
#print(matrix)

#用户购买点击比
matrix['r1'] = matrix['u9']/matrix['u7'] 
#商家购买点击比
matrix['r2'] = matrix['m8']/matrix['m6'] 
#不同用户不同商家购买点击比
matrix['r3'] = matrix['um7']/matrix['um5']
matrix.fillna(0, inplace=True)
# # 修改age_range字段名称为 age_0, age_1, age_2... age_8
temp = pd.get_dummies(matrix['age_range'], prefix='age')
matrix = pd.concat([matrix, temp], axis=1)
temp = pd.get_dummies(matrix['gender'], prefix='g')
matrix = pd.concat([matrix, temp], axis=1)
matrix.drop(['age_range', 'gender'], axis=1, inplace=True)
print(matrix)

# 分割训练数据和测试数据
train_data = matrix[matrix['origin'] == 'train'].drop(['origin'], axis=1)
test_data = matrix[matrix['origin'] == 'test'].drop(['label', 'origin'], axis=1)
train_X, train_y = train_data.drop(['label'], axis=1), train_data['label']
del temp, matrix
gc.collect()

# 使用机器学习工具
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LinearRegression
from sklearn.metrics import classification_report
import xgboost as xgb
# 将训练集进行切分,20%用于验证
X_train, X_valid, y_train, y_valid = train_test_split(train_X, train_y, test_size=.2)

# 使用XGBoost
model = xgb.XGBClassifier(
    max_depth=8,
    n_estimators=1000,
    min_child_weight=300, 
    colsample_bytree=0.8, 
    subsample=0.8, 
    eta=0.3,    
    seed=42    
)
model.fit(
    X_train, y_train,
    eval_metric='auc', eval_set=[(X_train, y_train), (X_valid, y_valid)],
    verbose=True,
    #早停法,如果auc在10epoch没有进步就stop
    early_stopping_rounds=10 
)


model.fit(X_train, y_train)

prob = model.predict_proba(test_data)
submission['prob'] = pd.Series(prob[:,1])
submission.drop(['origin'], axis=1, inplace=True)
submission.to_csv('prediction.csv', index=False)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水花

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值