IJCAI 2018 阿里妈妈广告预测算法大赛

背景

本项目是天池的一个比赛,由阿里妈妈和天池大数据众智平台举办的广告预测算法大赛,本次参赛人数5200多个队伍,而我们只取得了731的成绩,最遗憾的是当我们写好CNN预测结果准备上传,队伍却意外解散,哈哈。虽然没-能进入复赛,但是过程还是很有意思,特此记录一下。


目标

本次比赛以阿里电商广告为研究对象,提供了淘宝平台的海量真实交易数据,参赛选手通过人工智能技术构建预测模型预估用户的购买意向,即给定广告点击相关的用户(user)、广告商品(ad)、检索词(query)、上下文内容(context)、商店(shop)等信息的条件下预测广告产生购买行为的概率(pCVR),形式化定义为:pCVR=P(conversion=1/query, user, ad, context, shop)。

结合淘宝平台的业务场景和不同的流量特点,我们定义了以下两类挑战:
- (1)日常的转化率预估
- (2)特殊日期的转化率预估

评估指标, 公式如下:

通过logarithmic loss(记为logloss)评估模型效果(越小越好)
其中N表示测试集样本数量,yi表示测试集中第i个样本的真实标签,pi表示第i个样本的预估转化率。


数据说明

本次比赛为参赛选手提供了5类数据(基础数据、广告商品信息、用户信息、上下文信息和店铺信息)。基础数据表提供了搜索广告最基本的信息,以及“是否交易”的标记。广告商品信息、用户信息、上下文信息和店铺信息等4类数据,提供了对转化率预估可能有帮助的辅助信息。

1 . 基础数据

字段 解释
instance_id 样本编号,Long
is_trade 是否交易的标记位,Int类型;取值是0或者1,其中1 表示这条样本最终产生交易,0 表示没有交易
item_id 广告商品编号,Long类型
user_id 用户的编号,Long类型
context_id 上下文信息的编号,Long类型
shop_id 店铺的编号,Long类型

2. 广告商品信息

字段 解释
item_id 广告商品编号,Long类型
item_category_list 广告商品的的类目列表,String类型;从根类目(最粗略的一级类目)向叶子类目(最精细的类目)依次排列,数据拼接格式为 “category_0;category_1;category_2”,其中 category_1 是 category_0 的子类目,category_2 是 category_1 的子类目
item_property_list 广告商品的属性列表,String类型;数据拼接格式为 “property_0;property_1;property_2”,各个属性没有从属关系
item_brand_id 广告商品的品牌编号,Long类型
item_city_id 广告商品的城市编号,Long类型
item_price_level 广告商品的价格等级,Int类型;取值从0开始,数值越大表示价格越高
item_sales_level 广告商品的销量等级,Int类型;取值从0开始,数值越大表示销量越大
item_collected_level 广告商品被收藏次数的等级,Int类型;取值从0开始,数值越大表示被收藏次数越大
item_pv_level 广告商品被展示次数的等级,Int类型;取值从0开始,数值越大表示被展示次数越大

3. 用户信息

字段 解释
user_id 用户的编号,Long类型
user_gender_id 用户的预测性别编号,Int类型;0表示女性用户,1表示男性用户,2表示家庭用户
user_age_level 用户的预测年龄等级,Int类型;数值越大表示年龄越大
user_occupation_id 用户的预测职业编号,Int类型
user_star_level 用户的星级编号,Int类型;数值越大表示用户的星级越高

4. 上下文信息

字段 解释
context_id 上下文信息的编号,Long类型
context_timestamp 广告商品的展示时间,Long类型;取值是以秒为单位的Unix时间戳,以1天为单位对时间戳进行了偏移
context_page_id 广告商品的展示页面编号,Int类型;取值从1开始,依次增加;在一次搜索的展示结果中第一屏的编号为1,第二屏的编号为2
predict_category_property 根据查询词预测的类目属性列表,String类型;数据拼接格式为 “category_A:property_A_1,property_A_2,property_A_3;category_B:-1;category_C:property_C_1,property_C_2” ,其中 category_A、category_B、category_C 是预测的三个类目;property_B 取值为-1,表示预测的第二个类目 category_B 没有对应的预测属性

5. 店铺信息

字段 解释
shop_id 店铺的编号,Long类型
shop_review_num_level 店铺的评价数量等级,Int类型;取值从0开始,数值越大表示评价数量越多
shop_review_positive_rate 店铺的好评率,Double类型;取值在0到1之间,数值越大表示好评率越高
shop_star_level 店铺的星级编号,Int类型;取值从0开始,数值越大表示店铺的星级越高
shop_score_service 店铺的服务态度评分,Double类型;取值在0到1之间,数值越大表示评分越高
shop_score_delivery 店铺的物流服务评分,Double类型;取值在0到1之间,数值越大表示评分越高
shop_score_description 店铺的描述相符评分,Double类型;取值在0到1之间,数值越大表示评分越高

思路

我们的实验思路如下:

统计分析 -> 数据预处理 -> 特征抽取 -> 特征表示 -> 模型拟合和预测 -> 模型选择

其实从实验思路我们可以明显看出特征工程在这次比赛尤为重要,只有刻画好特征,才能利用模型得到好的预测结果,接下来我将按照实验思路进行总结。


实验

1. 统计分析

目的: 看清数据分布,了解广告、商品、店铺、用户与购买概率的关系

基础数据的统计分析(饼图、柱状图和折线图结合) ,将数据按照is_trade属性分为两张子表,分别进行对比统计分析

  • 购买的用户分析:
    单变量:性别分布、年龄分布、职业分布、星级分布
    交叉变量:(重点)性别-年龄、性别-星级、年龄-星级、职业-星级,(参考)年龄-职业,性别-职业

  • 购买的商品分布对比
    (重点)标签分布、属性分布、品牌分布、价格分布、销量分布,展示次数(后四项需考虑粒度的粗细)
    (参考)城市分布、收藏次数分布

  • 上下文信息对比
    (重点)时间戳分布
    (参考)页面分布(看能否精确到类别)、预测类目的准确度(?)

  • 购买的店铺分布对比
    (重点)评论数分布,好评率分布、星级分布
    (参考)服务评分、物流评分、描述评分

实施:利用R对数据分布进行了统计

结果如下

以在不同属性上is_trade=0/1为例, 简要分析


  • 1.转化分布

从上图可以明显看出在给定情景下转化率很低,也就是说,我们的训练数据存在了极度平衡的现象,甚至是可以把购买理解成异常值,我们的算法要能够极好的检测出异常实例。


  • 2.年龄,性别,星级 分布

从图1可以明显看出,年龄越大,转化率先增加后减少(-1表示未知年龄),这个结果与我们常识一致,中间年龄段更具有消费能力, 性别转化分布没有贴出来,结果跟我们常识也是一致的,女性转化率高于男性。从图2中可以看出,星级越高购买率相对要更高一些,但是差距不太明显。


  • 3.价格,收藏,展示 分布

图1,可以看出价格越高转化率先增加后降低,这与我们对电商平台的认知有关,价格太低必然会让人觉得物品质量不佳,但是随着价格增加,购买会带来更高的风险,转化率自然会降低。图2收藏次数越高,购买的可能性越大,收藏在电商市场的本质,就是商品入选了用户的购买集,对相关商品综合排序后,收藏的商品更有可能转化。图3,总体趋势是展示次数(广告效应)越多,购买率越高


  • 4.商店星级,评论数量 分布

图1.商店星级差异不明显。图2.评论数量居中的购买率更高

  • 5 城市 | 商品标签 分布


这两幅图是仅仅选择了高频的城市和商标分布,可以看出城市和商品图,都有集中表现类,而商品更为明显


总结: 数据统计分析的目的是分析变量之间的关系,观察具体特征对转化率的影响,从而用于模型中初始化权重


2. 数据预处理
  1. 处理缺失值
    主要处理缺失值,以及属性值为-1的值,因为后期特征表示时,我们调用的sklearn借口进行one-hot表征,而接口要求输入数据不包括负数

  2. 特征映射
    由于城市和商品的值字段太长,在表征时会出现错误,因此将他们分别映射,并更新原始数据,代码如下:


def map_field(train_data, test_data, path):
    train_data = set(train_data.unique())
    test_data = set(test_data.unique())
    all_property = list(train_data.union(test_data))
    print(len(all_property))
    map_data = {}
    for i in range(len(all_property)):
        map_data[str(all_property[i])] = i
    with open(path, "w", encoding="utf-8") as dump:
        json.dump(map_data, dump)
    return map_data


def update_data(raw_data, field_1, field_2, path_1, path_2):
    with open(path_1, "r", encoding="utf-8") as dump:
        update_field_1 = json.load(dump)
    with open(path_2, "r", encoding="utf-8") as dump:
        update_field_2 = json.load(dump)
    raw_data[field_1] = raw_data[field_1].apply(lambda x: update_field_1[str(x)])
    raw_data[field_2] = raw_data[field_2].apply(lambda x: update_field_2[str(x)])
    return raw_data
3. 特征抽取

本小节主要涉及对特征的转化和抽取,比如在上下文中的时间轴数据,考虑到节假日流量问题(比赛提出的挑战解决方法),我节假日和周末前后时间戳进行映射, 代码见下:


        def convert_interval_time(hour, size=3):
        """
        方法:把一天24小时按照力粒度为size大小进行分割
        :param hour:
        :param size:
        :return:
        """
        interval_time = [list(range(i, i + size)) for i in range(0, 24, size)]
        interval_time_factor = {}
        for i in range(len(interval_time)):
            interval_time_factor[i] = interval_time[i]
        for factor, h in interval_time_factor.items():
            if hour in h:
                return factor
            else:
                pass

    def time_to_factor(self):
        """
        方法:将时间戳转为区间因子
        tips: add two features, is_weekend and is_holiday
        :param data: 输入带时间戳的数据,
        :param size:将原始时间戳转化为粒度为size个小时一个因子,默认为size=3
        :return: 对于时间戳转为化为区间因子
        """
        data_time = self.raw_data[self.modify_features["time"]]
        data_time["format_time"] = data_time["context_timestamp"].apply(lambda x: time.localtime(x))
        convert_data_time = pd.DataFrame(columns=["interval_time", "is_weekends", "is_holidays"])
        convert_data_time["is_weekends"] = \
            data_time["format_time"].apply(lambda x: 1 if x[6] in self.weekends else 0)
        conv
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值