README.md 8.2 KB
Newer Older
S
Superjom 已提交
1 2 3 4
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
S
Superjom 已提交
5
<li><a href="#orgc299c2a">1. 背景介绍</a>
S
Superjom 已提交
6
<ul>
S
Superjom 已提交
7
<li><a href="#org5cc253b">1.1. LR vs DNN</a></li>
S
Superjom 已提交
8 9
</ul>
</li>
S
Superjom 已提交
10 11
<li><a href="#orgab346e7">2. 数据和任务抽象</a></li>
<li><a href="#org07ef211">3. Wide &amp; Deep Learning Model</a>
S
Superjom 已提交
12
<ul>
S
Superjom 已提交
13 14 15 16 17 18
<li><a href="#orgeae9b2d">3.1. 模型简介</a></li>
<li><a href="#org19637b5">3.2. 编写模型输入</a></li>
<li><a href="#orgd2cbfbd">3.3. 编写 Wide 部分</a></li>
<li><a href="#orgd78c9ff">3.4. 编写 Deep 部分</a></li>
<li><a href="#org92e3541">3.5. 两者融合</a></li>
<li><a href="#orgb4020a9">3.6. 训练任务的定义</a></li>
S
Superjom 已提交
19 20
</ul>
</li>
S
Superjom 已提交
21
<li><a href="#org8f6a6fa">4. 引用</a></li>
S
Superjom 已提交
22 23 24 25
</ul>
</div>
</div>

S
Superjom 已提交
26

S
Superjom 已提交
27
<a id="orgc299c2a"></a>
S
Superjom 已提交
28 29 30

# 背景介绍

S
Superjom 已提交
31
CTR(Click-through rate) 是用来表示用户点击一个特定链接的概率,
S
Superjom 已提交
32 33 34
通常被用来衡量一个在线广告系统的有效性。

当有多个广告位时,CTR 预估一般会作为排序的基准。
S
Superjom 已提交
35
比如在搜索引擎的广告系统里,当用户输入一个带商业价值的搜索词(query)时,系统大体上会执行下列步骤来展示广告:
S
Superjom 已提交
36 37 38 39

1.  召回满足 query 的广告集合
2.  业务规则和相关性过滤
3.  根据拍卖机制和 CTR 排序
S
Superjom 已提交
40
4.  展出广告
S
Superjom 已提交
41 42 43 44 45

可以看到,CTR 在最终排序中起到了很重要的作用。

在业内,CTR 模型经历了如下的发展阶段:

S
Superjom 已提交
46
-   Logistic Regression(LR) / GBDT + 特征工程
S
Superjom 已提交
47 48 49
-   LR + DNN 特征
-   DNN + 特征工程

S
Superjom 已提交
50
在发展早期时 LR 一统天下,但最近 DNN 模型由于其强大的学习能力和逐渐成熟的性能优化,
S
Superjom 已提交
51 52 53
逐渐地接过 CTR 预估任务的大旗。


S
Superjom 已提交
54
<a id="org5cc253b"></a>
S
Superjom 已提交
55 56 57 58 59

## LR vs DNN

下图展示了 LR 和一个 \(3x2\) 的 NN 模型的结构:

S
Superjom 已提交
60
![img](./images/lr-vs-dnn.jpg)
S
Superjom 已提交
61 62

LR 部分和蓝色箭头部分可以直接类比到 NN 中的结构,可以看到 LR 和 NN 有一些共通之处(比如权重累加),
S
Superjom 已提交
63
但前者的模型复杂度在相同输入维度下比后者可能低很多(从某方面讲,模型越复杂,越有潜力学习到更复杂的信息)。
S
Superjom 已提交
64

S
Superjom 已提交
65
如果 LR 要达到匹敌 NN 的学习能力,必须增加输入的维度,也就是增加特征的数量,
S
Superjom 已提交
66 67
这也就是为何 LR 和大规模的特征工程必须绑定在一起的原因。

S
Superjom 已提交
68 69
LR 对于 NN 模型的优势是对大规模稀疏特征的容纳能力,包括内存和计算量等方面,工业界都有非常成熟的优化方法。

S
Superjom 已提交
70 71 72
而 NN 模型具有自己学习新特征的能力,一定程度上能够提升特征使用的效率,
这使得 NN 模型在同样规模特征的情况下,更有可能达到更好的学习效果。

S
Superjom 已提交
73
本文后面的章节会演示如何使用 PaddlePaddle 编写一个结合两者优点的模型。
S
Superjom 已提交
74

S
Superjom 已提交
75

S
Superjom 已提交
76
<a id="orgab346e7"></a>
S
Superjom 已提交
77 78 79

# 数据和任务抽象

S
Superjom 已提交
80
我们可以将 `click` 作为学习目标,具体任务可以有以下几种方案:
S
Superjom 已提交
81

S
Superjom 已提交
82 83 84
1.  直接学习 click,0,1 作二元分类
2.  Learning to rank, 具体用 pairwise rank(标签 1>0)或者 list rank
3.  统计每个广告的点击率,将同一个 query 下的广告两两组合,点击率高的>点击率低的,做 rank 或者分类
S
Superjom 已提交
85

S
Superjom 已提交
86
我们直接使用第一种方法做分类任务。
S
Superjom 已提交
87

S
Superjom 已提交
88
我们使用 Kaggle 上 `Click-through rate prediction` 任务的数据集[3] 来演示模型。
S
Superjom 已提交
89 90 91

具体的特征处理方法参看 [data process](./dataset.md)

S
Superjom 已提交
92

S
Superjom 已提交
93
<a id="org07ef211"></a>
S
Superjom 已提交
94

S
Superjom 已提交
95
# Wide & Deep Learning Model
S
Superjom 已提交
96

S
Superjom 已提交
97
谷歌在 16 年提出了 Wide & Deep Learning 的模型框架,用于融合适合学习抽象特征的 DNN 和 适用于大规模稀疏特征的 LR 两种模型的优点。
S
Superjom 已提交
98 99


S
Superjom 已提交
100
<a id="orgeae9b2d"></a>
S
Superjom 已提交
101

S
Superjom 已提交
102
## 模型简介
S
Superjom 已提交
103

S
Superjom 已提交
104 105
Wide & Deep Learning Model 可以作为一种相对成熟的模型框架使用,
在 CTR 预估的任务中工业界也有一定的应用,因此本文将演示使用此模型来完成 CTR 预估的任务。
S
Superjom 已提交
106

S
Superjom 已提交
107
模型结构如下:
S
Superjom 已提交
108

S
Superjom 已提交
109
![img](./images/wide-deep.png)
S
Superjom 已提交
110

S
Superjom 已提交
111 112
模型左边的 Wide 部分,可以容纳大规模系数特征,并且对一些特定的信息(比如 ID)有一定的记忆能力;
而模型右边的 Deep 部分,能够学习特征间的隐含关系,在相同数量的特征下有更好的学习和推导能力。
S
Superjom 已提交
113 114


S
Superjom 已提交
115
<a id="org19637b5"></a>
S
Superjom 已提交
116

S
Superjom 已提交
117
## 编写模型输入
S
Superjom 已提交
118

S
Superjom 已提交
119
模型只接受 3 个输入,分别是
S
Superjom 已提交
120

S
Superjom 已提交
121 122 123
-   `dnn_input` ,也就是 Deep 部分的输入
-   `lr_input` ,也就是 Wide 部分的输入
-   `click` , 点击与否,作为二分类模型学习的标签
S
Superjom 已提交
124

S
Superjom 已提交
125
```python
S
Superjom 已提交
126 127 128
dnn_merged_input = layer.data(
    name='dnn_input',
    type=paddle.data_type.sparse_binary_vector(data_meta_info['dnn_input']))
S
Superjom 已提交
129

S
Superjom 已提交
130 131 132
lr_merged_input = layer.data(
    name='lr_input',
    type=paddle.data_type.sparse_binary_vector(data_meta_info['lr_input']))
S
Superjom 已提交
133

S
Superjom 已提交
134
click = paddle.layer.data(name='click', type=dtype.dense_vector(1))
S
Superjom 已提交
135 136


S
Superjom 已提交
137 138
```

S
Superjom 已提交
139
<a id="orgd2cbfbd"></a>
S
Superjom 已提交
140

S
Superjom 已提交
141
## 编写 Wide 部分
S
Superjom 已提交
142

S
Superjom 已提交
143 144 145
Wide 部分直接使用了 LR 模型,但激活函数改成了 `RELU` 来加速

```python
S
Superjom 已提交
146 147 148 149
def build_lr_submodel():
    fc = layer.fc(
        input=lr_merged_input, size=1, name='lr', act=paddle.activation.Relu())
    return fc
S
Superjom 已提交
150 151


S
Superjom 已提交
152 153
```

S
Superjom 已提交
154
<a id="orgd78c9ff"></a>
S
Superjom 已提交
155

S
Superjom 已提交
156
## 编写 Deep 部分
S
Superjom 已提交
157

S
Superjom 已提交
158 159 160
Deep 部分使用了标准的多层前向传导的 NN 模型

```python
S
Superjom 已提交
161 162 163 164 165 166 167 168 169 170 171
def build_dnn_submodel(dnn_layer_dims):
    dnn_embedding = layer.fc(input=dnn_merged_input, size=dnn_layer_dims[0])
    _input_layer = dnn_embedding
    for no, dim in enumerate(dnn_layer_dims[1:]):
        fc = layer.fc(
            input=_input_layer,
            size=dim,
            act=paddle.activation.Relu(),
            name='dnn-fc-%d' % no)
        _input_layer = fc
    return _input_layer
S
Superjom 已提交
172 173


S
Superjom 已提交
174 175
```

S
Superjom 已提交
176
<a id="org92e3541"></a>
S
Superjom 已提交
177 178 179

## 两者融合

S
Superjom 已提交
180 181 182 183
两个 submodel 的最上层输出加权求和得到整个模型的输出,输出部分使用 `sigmoid` 作为激活函数,得到区间\((0,1)\) 的预测值,
来逼近训练数据中二元类别的分布,最终作为 CTR 预估的值使用。

```python
S
Superjom 已提交
184 185 186 187 188 189 190 191 192 193
# conbine DNN and LR submodels
def combine_submodels(dnn, lr):
    merge_layer = layer.concat(input=[dnn, lr])
    fc = layer.fc(
        input=merge_layer,
        size=1,
        name='output',
        # use sigmoid function to approximate ctr rate, a float value between 0 and 1.
        act=paddle.activation.Sigmoid())
    return fc
S
Superjom 已提交
194 195


S
Superjom 已提交
196 197
```

S
Superjom 已提交
198
<a id="orgb4020a9"></a>
S
Superjom 已提交
199 200 201

## 训练任务的定义

S
Superjom 已提交
202
```python
S
Superjom 已提交
203 204 205 206 207 208 209 210 211
dnn = build_dnn_submodel(dnn_layer_dims)
lr = build_lr_submodel()
output = combine_submodels(dnn, lr)

# ==============================================================================
#                   cost and train period
# ==============================================================================
classification_cost = paddle.layer.multi_binary_label_cross_entropy_cost(
    input=output, label=click)
S
Superjom 已提交
212

S
Superjom 已提交
213
params = paddle.parameters.create(classification_cost)
S
Superjom 已提交
214

S
Superjom 已提交
215
optimizer = paddle.optimizer.Momentum(momentum=0)
S
Superjom 已提交
216

S
Superjom 已提交
217 218
trainer = paddle.trainer.SGD(
    cost=classification_cost, parameters=params, update_equation=optimizer)
S
Superjom 已提交
219

S
Superjom 已提交
220
dataset = AvazuDataset(train_data_path, n_records_as_test=test_set_size)
S
Superjom 已提交
221

S
Superjom 已提交
222 223 224 225 226
def event_handler(event):
    if isinstance(event, paddle.event.EndIteration):
        if event.batch_id % 100 == 0:
            logging.warning("Pass %d, Samples %d, Cost %f" % (
                event.pass_id, event.batch_id * batch_size, event.cost))
S
Superjom 已提交
227

S
Superjom 已提交
228 229 230 231 232 233
        if event.batch_id % 1000 == 0:
            result = trainer.test(
                reader=paddle.batch(dataset.test, batch_size=1000),
                feeding=field_index)
            logging.warning("Test %d-%d, Cost %f" % (event.pass_id, event.batch_id,
                                           result.cost))
S
Superjom 已提交
234 235


S
Superjom 已提交
236 237 238 239 240 241 242
trainer.train(
    reader=paddle.batch(
        paddle.reader.shuffle(dataset.train, buf_size=500),
        batch_size=batch_size),
    feeding=field_index,
    event_handler=event_handler,
    num_passes=100)
S
Superjom 已提交
243

S
Superjom 已提交
244

S
Superjom 已提交
245
```
S
Superjom 已提交
246

S
Superjom 已提交
247
<a id="org8f6a6fa"></a>
S
Superjom 已提交
248

S
Superjom 已提交
249
# 引用
S
Superjom 已提交
250

S
Superjom 已提交
251
-   [1] <https://en.wikipedia.org/wiki/Click-through_rate>
S
Superjom 已提交
252 253 254
-   [2] Mikolov, Tomáš, et al. "Strategies for training large scale neural network language models." Automatic Speech Recognition and Understanding (ASRU), 2011 IEEE Workshop on. IEEE, 2011.
-   [3] <https://www.kaggle.com/c/avazu-ctr-prediction/data>
-   [4] Cheng, Heng-Tze, et al. "Wide & deep learning for recommender systems." Proceedings of the 1st Workshop on Deep Learning for Recommender Systems. ACM, 2016.
S
Superjom 已提交
255