Skip to content

Commit 72e6225

Browse files
committed
add ctr.
1 parent db593e5 commit 72e6225

File tree

1 file changed

+300
-0
lines changed

1 file changed

+300
-0
lines changed

ctr/index.html

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
2+
<html>
3+
<head>
4+
<script type="text/x-mathjax-config">
5+
MathJax.Hub.Config({
6+
extensions: ["tex2jax.js", "TeX/AMSsymbols.js", "TeX/AMSmath.js"],
7+
jax: ["input/TeX", "output/HTML-CSS"],
8+
tex2jax: {
9+
inlineMath: [ ['$','$'] ],
10+
displayMath: [ ['$$','$$'] ],
11+
processEscapes: true
12+
},
13+
"HTML-CSS": { availableFonts: ["TeX"] }
14+
});
15+
</script>
16+
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js" async></script>
17+
<script type="text/javascript" src="../.tools/theme/marked.js">
18+
</script>
19+
<link href="http://cdn.bootcss.com/highlight.js/9.9.0/styles/darcula.min.css" rel="stylesheet">
20+
<script src="http://cdn.bootcss.com/highlight.js/9.9.0/highlight.min.js"></script>
21+
<link href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
22+
<link href="https://cdn.jsdelivr.net/perfect-scrollbar/0.6.14/css/perfect-scrollbar.min.css" rel="stylesheet">
23+
<link href="../.tools/theme/github-markdown.css" rel='stylesheet'>
24+
</head>
25+
<style type="text/css" >
26+
.markdown-body {
27+
box-sizing: border-box;
28+
min-width: 200px;
29+
max-width: 980px;
30+
margin: 0 auto;
31+
padding: 45px;
32+
}
33+
</style>
34+
35+
36+
<body>
37+
38+
<div id="context" class="container-fluid markdown-body">
39+
</div>
40+
41+
<!-- This block will be replaced by each markdown file content. Please do not change lines below.-->
42+
<div id="markdown" style='display:none'>
43+
# CTR预估
44+
45+
## 背景介绍
46+
47+
CTR(Click-Through Rate)\[[1](https://en.wikipedia.org/wiki/Click-through_rate)\] 是用来表示用户点击一个特定链接的概率,
48+
通常被用来衡量一个在线广告系统的有效性。
49+
50+
当有多个广告位时,CTR 预估一般会作为排序的基准。
51+
比如在搜索引擎的广告系统里,当用户输入一个带商业价值的搜索词(query)时,系统大体上会执行下列步骤来展示广告:
52+
53+
1. 召回满足 query 的广告集合
54+
2. 业务规则和相关性过滤
55+
3. 根据拍卖机制和 CTR 排序
56+
4. 展出广告
57+
58+
可以看到,CTR 在最终排序中起到了很重要的作用。
59+
60+
### 发展阶段
61+
在业内,CTR 模型经历了如下的发展阶段:
62+
63+
- Logistic Regression(LR) / GBDT + 特征工程
64+
- LR + DNN 特征
65+
- DNN + 特征工程
66+
67+
在发展早期时 LR 一统天下,但最近 DNN 模型由于其强大的学习能力和逐渐成熟的性能优化,
68+
逐渐地接过 CTR 预估任务的大旗。
69+
70+
71+
### LR vs DNN
72+
73+
下图展示了 LR 和一个 \(3x2\) 的 DNN 模型的结构:
74+
75+
<p align="center">
76+
<img src="images/lr_vs_dnn.jpg" width="620" hspace='10'/> <br/>
77+
Figure 1. LR 和 DNN 模型结构对比
78+
</p>
79+
80+
LR 的蓝色箭头部分可以直接类比到 DNN 中对应的结构,可以看到 LR 和 DNN 有一些共通之处(比如权重累加),
81+
但前者的模型复杂度在相同输入维度下比后者可能低很多(从某方面讲,模型越复杂,越有潜力学习到更复杂的信息)。
82+
83+
如果 LR 要达到匹敌 DNN 的学习能力,必须增加输入的维度,也就是增加特征的数量,
84+
这也就是为何 LR 和大规模的特征工程必须绑定在一起的原因。
85+
86+
LR 对于 DNN 模型的优势是对大规模稀疏特征的容纳能力,包括内存和计算量等方面,工业界都有非常成熟的优化方法。
87+
88+
而 DNN 模型具有自己学习新特征的能力,一定程度上能够提升特征使用的效率,
89+
这使得 DNN 模型在同样规模特征的情况下,更有可能达到更好的学习效果。
90+
91+
本文后面的章节会演示如何使用 PaddlePaddle 编写一个结合两者优点的模型。
92+
93+
94+
## 数据和任务抽象
95+
96+
我们可以将 `click` 作为学习目标,任务可以有以下几种方案:
97+
98+
1. 直接学习 click,0,1 作二元分类
99+
2. Learning to rank, 具体用 pairwise rank(标签 1>0)或者 listwise rank
100+
3. 统计每个广告的点击率,将同一个 query 下的广告两两组合,点击率高的>点击率低的,做 rank 或者分类
101+
102+
我们直接使用第一种方法做分类任务。
103+
104+
我们使用 Kaggle 上 `Click-through rate prediction` 任务的数据集\[[2](https://www.kaggle.com/c/avazu-ctr-prediction/data)\] 来演示模型。
105+
106+
具体的特征处理方法参看 [data process](./dataset.md)
107+
108+
109+
## Wide & Deep Learning Model
110+
111+
谷歌在 16 年提出了 Wide & Deep Learning 的模型框架,用于融合适合学习抽象特征的 DNN 和 适用于大规模稀疏特征的 LR 两种模型的优点。
112+
113+
114+
### 模型简介
115+
116+
Wide & Deep Learning Model\[[3](#参考文献)\] 可以作为一种相对成熟的模型框架使用,
117+
在 CTR 预估的任务中工业界也有一定的应用,因此本文将演示使用此模型来完成 CTR 预估的任务。
118+
119+
模型结构如下:
120+
121+
<p align="center">
122+
<img src="images/wide_deep.png" width="820" hspace='10'/> <br/>
123+
Figure 2. Wide & Deep Model
124+
</p>
125+
126+
模型左边的 Wide 部分,可以容纳大规模系数特征,并且对一些特定的信息(比如 ID)有一定的记忆能力;
127+
而模型右边的 Deep 部分,能够学习特征间的隐含关系,在相同数量的特征下有更好的学习和推导能力。
128+
129+
130+
### 编写模型输入
131+
132+
模型只接受 3 个输入,分别是
133+
134+
- `dnn_input` ,也就是 Deep 部分的输入
135+
- `lr_input` ,也就是 Wide 部分的输入
136+
- `click` , 点击与否,作为二分类模型学习的标签
137+
138+
```python
139+
dnn_merged_input = layer.data(
140+
name='dnn_input',
141+
type=paddle.data_type.sparse_binary_vector(data_meta_info['dnn_input']))
142+
143+
lr_merged_input = layer.data(
144+
name='lr_input',
145+
type=paddle.data_type.sparse_binary_vector(data_meta_info['lr_input']))
146+
147+
click = paddle.layer.data(name='click', type=dtype.dense_vector(1))
148+
```
149+
150+
### 编写 Wide 部分
151+
152+
Wide 部分直接使用了 LR 模型,但激活函数改成了 `RELU` 来加速
153+
154+
```python
155+
def build_lr_submodel():
156+
fc = layer.fc(
157+
input=lr_merged_input, size=1, name='lr', act=paddle.activation.Relu())
158+
return fc
159+
```
160+
161+
### 编写 Deep 部分
162+
163+
Deep 部分使用了标准的多层前向传导的 DNN 模型
164+
165+
```python
166+
def build_dnn_submodel(dnn_layer_dims):
167+
dnn_embedding = layer.fc(input=dnn_merged_input, size=dnn_layer_dims[0])
168+
_input_layer = dnn_embedding
169+
for i, dim in enumerate(dnn_layer_dims[1:]):
170+
fc = layer.fc(
171+
input=_input_layer,
172+
size=dim,
173+
act=paddle.activation.Relu(),
174+
name='dnn-fc-%d' % i)
175+
_input_layer = fc
176+
return _input_layer
177+
```
178+
179+
### 两者融合
180+
181+
两个 submodel 的最上层输出加权求和得到整个模型的输出,输出部分使用 `sigmoid` 作为激活函数,得到区间 (0,1) 的预测值,
182+
来逼近训练数据中二元类别的分布,并最终作为 CTR 预估的值使用。
183+
184+
```python
185+
# conbine DNN and LR submodels
186+
def combine_submodels(dnn, lr):
187+
merge_layer = layer.concat(input=[dnn, lr])
188+
fc = layer.fc(
189+
input=merge_layer,
190+
size=1,
191+
name='output',
192+
# use sigmoid function to approximate ctr, wihch is a float value between 0 and 1.
193+
act=paddle.activation.Sigmoid())
194+
return fc
195+
```
196+
197+
### 训练任务的定义
198+
```python
199+
dnn = build_dnn_submodel(dnn_layer_dims)
200+
lr = build_lr_submodel()
201+
output = combine_submodels(dnn, lr)
202+
203+
# ==============================================================================
204+
# cost and train period
205+
# ==============================================================================
206+
classification_cost = paddle.layer.multi_binary_label_cross_entropy_cost(
207+
input=output, label=click)
208+
209+
210+
paddle.init(use_gpu=False, trainer_count=11)
211+
212+
params = paddle.parameters.create(classification_cost)
213+
214+
optimizer = paddle.optimizer.Momentum(momentum=0)
215+
216+
trainer = paddle.trainer.SGD(
217+
cost=classification_cost, parameters=params, update_equation=optimizer)
218+
219+
dataset = AvazuDataset(train_data_path, n_records_as_test=test_set_size)
220+
221+
def event_handler(event):
222+
if isinstance(event, paddle.event.EndIteration):
223+
if event.batch_id % 100 == 0:
224+
logging.warning("Pass %d, Samples %d, Cost %f" % (
225+
event.pass_id, event.batch_id * batch_size, event.cost))
226+
227+
if event.batch_id % 1000 == 0:
228+
result = trainer.test(
229+
reader=paddle.batch(dataset.test, batch_size=1000),
230+
feeding=field_index)
231+
logging.warning("Test %d-%d, Cost %f" % (event.pass_id, event.batch_id,
232+
result.cost))
233+
234+
235+
trainer.train(
236+
reader=paddle.batch(
237+
paddle.reader.shuffle(dataset.train, buf_size=500),
238+
batch_size=batch_size),
239+
feeding=field_index,
240+
event_handler=event_handler,
241+
num_passes=100)
242+
```
243+
## 运行训练和测试
244+
训练模型需要如下步骤:
245+
246+
1. 下载训练数据,可以使用 Kaggle 上 CTR 比赛的数据\[[2](#参考文献)\]
247+
1. 从 [Kaggle CTR](https://www.kaggle.com/c/avazu-ctr-prediction/data) 下载 train.gz
248+
2. 解压 train.gz 得到 train.txt
249+
2. 执行 `python train.py --train_data_path train.txt` ,开始训练
250+
251+
上面第2个步骤可以为 `train.py` 填充命令行参数来定制模型的训练过程,具体的命令行参数及用法如下
252+
253+
```
254+
usage: train.py [-h] --train_data_path TRAIN_DATA_PATH
255+
[--batch_size BATCH_SIZE] [--test_set_size TEST_SET_SIZE]
256+
[--num_passes NUM_PASSES]
257+
[--num_lines_to_detact NUM_LINES_TO_DETACT]
258+
259+
PaddlePaddle CTR example
260+
261+
optional arguments:
262+
-h, --help show this help message and exit
263+
--train_data_path TRAIN_DATA_PATH
264+
path of training dataset
265+
--batch_size BATCH_SIZE
266+
size of mini-batch (default:10000)
267+
--test_set_size TEST_SET_SIZE
268+
size of the validation dataset(default: 10000)
269+
--num_passes NUM_PASSES
270+
number of passes to train
271+
--num_lines_to_detact NUM_LINES_TO_DETACT
272+
number of records to detect dataset's meta info
273+
```
274+
275+
## 参考文献
276+
1. <https://en.wikipedia.org/wiki/Click-through_rate>
277+
2. <https://www.kaggle.com/c/avazu-ctr-prediction/data>
278+
3. Cheng H T, Koc L, Harmsen J, et al. [Wide & deep learning for recommender systems](https://arxiv.org/pdf/1606.07792.pdf)[C]//Proceedings of the 1st Workshop on Deep Learning for Recommender Systems. ACM, 2016: 7-10.
279+
280+
</div>
281+
<!-- You can change the lines below now. -->
282+
283+
<script type="text/javascript">
284+
marked.setOptions({
285+
renderer: new marked.Renderer(),
286+
gfm: true,
287+
breaks: false,
288+
smartypants: true,
289+
highlight: function(code, lang) {
290+
code = code.replace(/&amp;/g, "&")
291+
code = code.replace(/&gt;/g, ">")
292+
code = code.replace(/&lt;/g, "<")
293+
code = code.replace(/&nbsp;/g, " ")
294+
return hljs.highlightAuto(code, [lang]).value;
295+
}
296+
});
297+
document.getElementById("context").innerHTML = marked(
298+
document.getElementById("markdown").innerHTML)
299+
</script>
300+
</body>

0 commit comments

Comments
 (0)