机器学习项目 - ctr 电商点击率预估

第一章

腾讯移动App广告转化率预估

机器学习项目 - ctr 电商点击率预估

题目描述

计算广告是互联网最重要的商业模式之一,广告投放效果通常通过曝光、点击和转化各环节来衡量,大多数广告系统受广告效果数据回流的限制只能通过曝光或点击作为投放效果的衡量标准开展优化。

腾讯社交广告(http://ads.tencent.com)发挥特有的用户识别和转化跟踪数据能力,帮助广告主跟踪广告投放后的转化效果,基于广告转化数据训练转化率预估模型(pCVR,Predicted Conversion Rate),在广告排序中引入pCVR因子优化广告投放效果,提升ROI。

本题目以移动App广告为研究对象,预测App广告点击后被激活的概率:pCVR=P(conversion=1 | Ad,User,Context),即给定广告、用户和上下文情况下广告被点击后发生激活的概率。

训练数据

从腾讯社交广告系统中某一连续两周的日志中按照推广中的App和用户维度随机采样。

每一条训练样本即为一条广告点击日志(点击时间用clickTime表示),样本label取值0或1,其中0表示点击后没有发生转化,1表示点击后有发生转化,如果label为1,还会提供转化回流时间(conversionTime,定义详见“FAQ”)。给定特征集如下:

机器学习项目 - ctr 电商点击率预估机器学习项目 - ctr 电商点击率预估机器学习项目 - ctr 电商点击率预估

特别的,出于数据安全的考虑,对于userID,appID,特征,以及时间字段,我们不提供原始数据,按照如下方式加密处理:

机器学习项目 - ctr 电商点击率预估

训练数据文件(train.csv)

每行代表一个训练样本,各字段之间由逗号分隔,顺序依次为:“label,clickTime,conversionTime,creativeID,userID,positionID,connectionType,telecomsOperator”。

当label=0时,conversionTime字段为空字符串。特别的,训练数据时间范围为第17天0点到第31天0点(定义详见下面的“补充说明”)。为了节省存储空间,用户、App、广告和广告位相关信息以独立文件提供(训练数据和测试数据共用),具体如下:

机器学习项目 - ctr 电商点击率预估

注:若字段取值为0或空字符串均代表未知。(站点集合ID(sitesetID)为0并不表示未知,而是一个特定的站点集合。)

测试数据

从训练数据时段随后1天(即第31天)的广告日志中按照与训练数据同样的采样方式抽取得到,测试数据文件(test.csv)每行代表一个测试样本,各字段之间由逗号分隔,顺序依次为:“instanceID,-1,clickTime,creativeID,userID,positionID,connectionType,telecomsOperator”。其中,instanceID唯一标识一个样本,-1代表label占位使用,表示待预测。

评估方式

通过Logarithmic Loss评估(越小越好),公式如下:

机器学习项目 - ctr 电商点击率预估其中,N是测试样本总数,yi是二值变量,取值0或1,表示第i个样本的label,pi为模型预测第i个样本 label为1的概率。

示例代码如下(Python语言):

import scipy as sp
def logloss(act, pred):
  epsilon = 1e-15
  pred = sp.maximum(epsilon, pred)
  pred = sp.minimum(1-epsilon, pred)
  ll = sum(act*sp.log(pred) + sp.subtract(1,act)*sp.log(sp.subtract(1,pred)))
  ll = ll * -1.0/len(act)
  return ll

提交格式

模型预估结果以zip压缩文件方式提交,内部文件名是submission.csv。每行代表一个测试样本,第一行为header,可以记录本文件相关关键信息,评测时会忽略,从第二行开始各字段之间由逗号分隔,顺序依次为:“instanceID, prob”,其中,instanceID唯一标识一个测试样本,必须升序排列,prob为模型预估的广告转化概率。示例如下:

机器学习项目 - ctr 电商点击率预估

 

第二章

CVR预估基线版本

2.1 基于AD统计的版本


# -*- coding: utf-8 -*-
"""
baseline 1: history pCVR of creativeID/adID/camgaignID/advertiserID/appID/appPlatform
"""

import zipfile
import numpy as np
import pandas as pd
"""
pandas中关于DataFrame 去除省略号
#显示所有列
pd.set_option('display.max_columns', None)
#显示所有行
pd.set_option('display.max_rows', None)
#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
"""
pd.set_option('display.max_columns', None)

# 载入数据
dfTrain = pd.read_csv('data/train.csv')
dfTest = pd.read_csv('data/test.csv')
dfAd = pd.read_csv('data/ad.csv')

# 处理数据
"""merger() 函数相当于数据库的左右连接,按照creativeID 相同的数据来凝结为一行"""
dfTrain = pd.merge(dfTrain, dfAd, on='creativeID')
dfTest = pd.merge(dfTest, dfAd,on='creativeID')
y_train = dfTrain['label'].values       # [0 0 0 ... 0 0 0]

# 创建模型
key = 'appID'

"""
groupby(): 将数据进行排列分组,数据按照appid,
"""

dfCvr = dfTrain.groupby(key).apply(lambda df: np.mean(df['label'])).reset_index()

dfCvr.columns = [key, 'avg_cvr']
dfTest = pd.merge(dfTest, dfCvr, how='left', on=key)
dfTest['avg_cvr'].fillna(np.mean(dfTrain['label']), inplace=True)
proba_test = dfTest['avg_cvr'].values

# submission
df = pd.DataFrame({"instanceID": dfTest['instanceID'].values, "proba": proba_test})
df.sort_values("instanceID", inplace=True)
print(df.head(10))
# df.to_csv("submission.csv", index=False)
# with zipfile.ZipFile('submission.zip', 'w') as fout:
#     fout.write('submission.csv', compress_type=zipfile.ZIP_DEFLATED)

得分

Submission 描述 初赛A 初赛B 决赛A 决赛B
baseline 2.1 ad 统计 0.10988 - - -

2.2 AD+LR版本

# -*- coding: utf-8 -*-
"""
baseline 2: ad.csv (creativeID/adID/camgaignID/advertiserID/appID/appPlatform) + lr
"""

import zipfile
import pandas as pd
from scipy import sparse
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression

pd.set_option('display.max_columns', None)

# 载入数据
dfTrain = pd.read_csv('data/train.csv')
dfTest = pd.read_csv('data/test.csv')
dfAd = pd.read_csv('data/ad.csv')

# 处理数据
"""merger() 函数相当于数据库的左右连接,按照creativeID 相同的数据来凝结为一行"""
dfTrain = pd.merge(dfTrain, dfAd, on='creativeID')
dfTest = pd.merge(dfTest, dfAd,on='creativeID')
y_train = dfTrain['label'].values

# feature engineering/encoding
enc = OneHotEncoder()
feats = ["creativeID", "adID", "camgaignID", "advertiserID", "appID", "appPlatform"]
for i, feat in enumerate(feats):
    x_train = enc.fit_transform(dfTrain[feat].values.reshape(-1, 1))    # (0, 2966)	1.0
    x_test = enc.transform(dfTest[feat].values.reshape(-1,1))
    if i == 0:
        X_train, X_test = x_train, x_test
    else:
        X_train, X_test = sparse.hstack((X_train, x_train)), sparse.hstack((X_test, x_test))

# 模型训练
lr = LogisticRegression()
lr.fit(X_train, y_train)
proba_test = lr.predict_proba(X_test)[:, 1]

# submission
df = pd.DataFrame({"instanceID": dfTest["instanceID"].values, "proba": proba_test})
df.sort_values("instanceID", inplace=True)
df.to_csv('submission.csv', index=False)
with zipfile.ZipFile('submission.zip', 'w') as fout:
    fout.write('submission.csv', compress_type=zipfile.ZIP_DEFLATED)

得分

Submission 描述 初赛A 初赛B 决赛A 决赛B
baseline 2.2 ad + lr 0.10743 - - -
上一篇:广告CTR预估中用户行为学习和记忆建模


下一篇:深度时空网络、记忆网络与特征表达学习在 CTR 预估中的应用