提交 d718d1e6 编写于 作者: S Superjom

style code

上级 25c0570d
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orgc299c2a">1. 背景介绍</a>
<ul>
<li><a href="#org5cc253b">1.1. LR vs DNN</a></li>
</ul>
</li>
<li><a href="#orgab346e7">2. 数据和任务抽象</a></li>
<li><a href="#org07ef211">3. Wide &amp; Deep Learning Model</a>
<ul>
<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>
</ul>
</li>
<li><a href="#org8f6a6fa">4. 引用</a></li>
</ul>
</div>
</div>
<a id="orgc299c2a"></a>
# 背景介绍
# CTR预估
## 背景介绍
CTR(Click-through rate) 是用来表示用户点击一个特定链接的概率,
通常被用来衡量一个在线广告系统的有效性。
......@@ -40,7 +14,7 @@ CTR(Click-through rate) 是用来表示用户点击一个特定链接的概率
4. 展出广告
可以看到,CTR 在最终排序中起到了很重要的作用。
### 发展阶段
在业内,CTR 模型经历了如下的发展阶段:
- Logistic Regression(LR) / GBDT + 特征工程
......@@ -51,9 +25,7 @@ CTR(Click-through rate) 是用来表示用户点击一个特定链接的概率
逐渐地接过 CTR 预估任务的大旗。
<a id="org5cc253b"></a>
## LR vs DNN
### LR vs DNN
下图展示了 LR 和一个 \(3x2\) 的 NN 模型的结构:
......@@ -73,9 +45,7 @@ LR 对于 NN 模型的优势是对大规模稀疏特征的容纳能力,包括
本文后面的章节会演示如何使用 PaddlePaddle 编写一个结合两者优点的模型。
<a id="orgab346e7"></a>
# 数据和任务抽象
## 数据和任务抽象
我们可以将 `click` 作为学习目标,具体任务可以有以下几种方案:
......@@ -90,16 +60,12 @@ LR 对于 NN 模型的优势是对大规模稀疏特征的容纳能力,包括
具体的特征处理方法参看 [data process](./dataset.md)
<a id="org07ef211"></a>
# Wide & Deep Learning Model
## Wide & Deep Learning Model
谷歌在 16 年提出了 Wide & Deep Learning 的模型框架,用于融合适合学习抽象特征的 DNN 和 适用于大规模稀疏特征的 LR 两种模型的优点。
<a id="orgeae9b2d"></a>
## 模型简介
### 模型简介
Wide & Deep Learning Model 可以作为一种相对成熟的模型框架使用,
在 CTR 预估的任务中工业界也有一定的应用,因此本文将演示使用此模型来完成 CTR 预估的任务。
......@@ -112,9 +78,7 @@ Wide & Deep Learning Model 可以作为一种相对成熟的模型框架使用
而模型右边的 Deep 部分,能够学习特征间的隐含关系,在相同数量的特征下有更好的学习和推导能力。
<a id="org19637b5"></a>
## 编写模型输入
### 编写模型输入
模型只接受 3 个输入,分别是
......@@ -132,13 +96,9 @@ lr_merged_input = layer.data(
type=paddle.data_type.sparse_binary_vector(data_meta_info['lr_input']))
click = paddle.layer.data(name='click', type=dtype.dense_vector(1))
```
<a id="orgd2cbfbd"></a>
## 编写 Wide 部分
### 编写 Wide 部分
Wide 部分直接使用了 LR 模型,但激活函数改成了 `RELU` 来加速
......@@ -147,13 +107,9 @@ def build_lr_submodel():
fc = layer.fc(
input=lr_merged_input, size=1, name='lr', act=paddle.activation.Relu())
return fc
```
<a id="orgd78c9ff"></a>
## 编写 Deep 部分
### 编写 Deep 部分
Deep 部分使用了标准的多层前向传导的 NN 模型
......@@ -169,13 +125,9 @@ def build_dnn_submodel(dnn_layer_dims):
name='dnn-fc-%d' % no)
_input_layer = fc
return _input_layer
```
<a id="org92e3541"></a>
## 两者融合
### 两者融合
两个 submodel 的最上层输出加权求和得到整个模型的输出,输出部分使用 `sigmoid` 作为激活函数,得到区间\((0,1)\) 的预测值,
来逼近训练数据中二元类别的分布,最终作为 CTR 预估的值使用。
......@@ -191,13 +143,9 @@ def combine_submodels(dnn, lr):
# use sigmoid function to approximate ctr rate, a float value between 0 and 1.
act=paddle.activation.Sigmoid())
return fc
```
<a id="orgb4020a9"></a>
## 训练任务的定义
### 训练任务的定义
```python
dnn = build_dnn_submodel(dnn_layer_dims)
......@@ -240,16 +188,10 @@ trainer.train(
feeding=field_index,
event_handler=event_handler,
num_passes=100)
```
<a id="org8f6a6fa"></a>
# 引用
- [1] <https://en.wikipedia.org/wiki/Click-through_rate>
- [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.
## 引用
1. <https://en.wikipedia.org/wiki/Click-through_rate>
2. Mikolov T, Deoras A, Povey D, et al. Strategies for training large scale neural network language models[C]//Automatic Speech Recognition and Understanding (ASRU), 2011 IEEE Workshop on. IEEE, 2011: 196-201.
3. <https://www.kaggle.com/c/avazu-ctr-prediction/data>
4. Cheng H T, Koc L, Harmsen J, et al. Wide & deep learning for recommender systems[C]//Proceedings of the 1st Workshop on Deep Learning for Recommender Systems. ACM, 2016: 7-10.
......@@ -150,8 +150,8 @@ for key in id_features:
fields[key] = IDfeatureGenerator(10000)
# used as feed_dict in PaddlePaddle
field_index = dict(
(key, id) for id, key in enumerate(['dnn_input', 'lr_input', 'click']))
field_index = dict((key, id)
for id, key in enumerate(['dnn_input', 'lr_input', 'click']))
def detect_dataset(path, topn, id_fea_space=10000):
......@@ -175,7 +175,7 @@ def detect_dataset(path, topn, id_fea_space=10000):
feature_dims[key] = item.size()
#for key in id_features:
#feature_dims[key] = id_fea_space
#feature_dims[key] = id_fea_space
feature_dims['hour'] = 24
feature_dims['click'] = 1
......@@ -222,8 +222,7 @@ class AvazuDataset(object):
def train(self):
self.mode = self.TRAIN_MODE
return self._parse(
self.train_path, skip_n_lines=self.n_records_as_test)
return self._parse(self.train_path, skip_n_lines=self.n_records_as_test)
def test(self):
self.mode = self.TEST_MODE
......@@ -257,7 +256,8 @@ class AvazuDataset(object):
else:
fea0 = fields[key].cross_fea0
fea1 = fields[key].cross_fea1
record.append(fields[key].gen_cross_fea(row[fea0], row[fea1]))
record.append(
fields[key].gen_cross_fea(row[fea0], row[fea1]))
sparse_input = concat_sparse_vectors(record, id_dims)
......
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orgb9b1ee8">1. 数据集介绍</a></li>
<li><a href="#orgeaf74d5">2. 特征提取</a>
<ul>
<li><a href="#org876ed90">2.1. 类别类特征</a></li>
<li><a href="#org33838ae">2.2. ID 类特征</a></li>
<li><a href="#org96be68a">2.3. 数值型特征</a></li>
</ul>
</li>
<li><a href="#org6ef4cab">3. 特征处理</a>
<ul>
<li><a href="#org967be87">3.1. 类别型特征</a></li>
<li><a href="#org516125b">3.2. ID 类特征</a></li>
<li><a href="#org8a0cce6">3.3. 交叉类特征</a></li>
<li><a href="#org6655b66">3.4. 特征维度</a>
<ul>
<li><a href="#org223ebf2">3.4.1. Deep submodel(DNN)特征</a></li>
<li><a href="#orgb062f1d">3.4.2. Wide submodel(LR)特征</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#org6b9de13">4. 输入到 PaddlePaddle 中</a></li>
</ul>
</div>
</div>
<a id="orgb9b1ee8"></a>
# 数据集介绍
# 数据及处理
## 数据集介绍
数据集使用 `csv` 格式存储,其中各个字段内容如下:
- `id` : ad identifier
- `click` : 0/1 for non-click/click
- `hour` : format is YYMMDDHH, so 14091123 means 23:00 on Sept. 11, 2014 UTC.
- `C1` &#x2013; anonymized categorical variable
- `C1` : anonymized categorical variable
- `banner_pos`
- `site_id`
- `site_domain`
......@@ -51,45 +19,33 @@
- `device_model`
- `device_type`
- `device_conn_type`
- `C14-C21` &#x2013; anonymized categorical variables
- `C14-C21` : anonymized categorical variables
<a id="orgeaf74d5"></a>
# 特征提取
## 特征提取
下面我们会简单演示几种特征的提取方式。
原始数据中的特征可以分为以下几类:
1. ID 类特征(稀疏,数量多)
```python
- `id`
- `site_id`
- `app_id`
- `device_id`
```
2. 类别类特征(稀疏,但数量有限)
```python
- `C1`
- `site_category`
- `device_type`
- `C14-C21`
```
3. 数值型特征转化为类别型特征
```python
- hour (可以转化成数值也可以按小时为单位转化为类别
```
<a id="org876ed90"></a>
- hour (可以转化成数值,也可以按小时为单位转化为类别)
## 类别类特征
### 类别类特征
类别类特征的提取方法有以下两种:
......@@ -97,9 +53,7 @@
2. 类似词向量,用一个 Embedding Table 将每个类别映射到对应的向量
<a id="org33838ae"></a>
## ID 类特征
### ID 类特征
ID 类特征的特点是稀疏数据,但量比较大,直接使用 One-hot 表示时维度过大。
......@@ -111,25 +65,17 @@ ID 类特征的特点是稀疏数据,但量比较大,直接使用 One-hot
上面的方法尽管存在一定的碰撞概率,但能够处理任意数量的 ID 特征,并保留一定的效果[2]。
<a id="org96be68a"></a>
## 数值型特征
### 数值型特征
一般会做如下处理:
- 归一化,直接作为特征输入模型
- 用区间分割处理成类别类特征,稀疏化表示,模糊细微上的差别
## 特征处理
<a id="org6ef4cab"></a>
# 特征处理
<a id="org967be87"></a>
## 类别型特征
### 类别型特征
类别型特征有有限多种值,在模型中,我们一般使用 embedding table 将每种值映射为连续值的向量。
......@@ -171,15 +117,11 @@ class CategoryFeatureGenerator(object):
def __repr__(self):
return '<CategoryFeatureGenerator %d>' % len(self.dic)
```
本任务中,类别类特征会输入到 DNN 中使用。
<a id="org516125b"></a>
## ID 类特征
### ID 类特征
ID 类特征代稀疏值,且值的空间很大的情况,一般用模操作规约到一个有限空间,
之后可以当成类别类特征使用,这里我们会将 ID 类特征输入到 LR 模型中使用。
......@@ -201,13 +143,9 @@ class IDfeatureGenerator(object):
def size(self):
return self.max_dim
```
<a id="org8a0cce6"></a>
## 交叉类特征
### 交叉类特征
LR 模型作为 Wide & Deep model 的 `wide` 部分,可以输入很 wide 的数据(特征空间的维度很大),
为了充分利用这个优势,我们将演示交叉组合特征构建成更大维度特征的情况,之后塞入到模型中训练。
......@@ -218,139 +156,33 @@ LR 模型作为 Wide & Deep model 的 `wide` 部分,可以输入很 wide 的
def gen_cross_fea(self, fea1, fea2):
key = str(fea1) + str(fea2)
return self.gen(key)
```
比如,我们觉得原始数据中, `device_id``site_id` 有一些关联(比如某个 device 倾向于浏览特定 site),
我们通过组合出两者组合来捕捉这类信息。
<a id="org6655b66"></a>
## 特征维度
<a id="org223ebf2"></a>
### Deep submodel(DNN)特征
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">feature</th>
<th scope="col" class="org-right">dimention</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">`app_category`</td>
<td class="org-right">21</td>
</tr>
<tr>
<td class="org-left">`site_category`</td>
<td class="org-right">22</td>
</tr>
<tr>
<td class="org-left">`device_conn_type`</td>
<td class="org-right">5</td>
</tr>
<tr>
<td class="org-left">`hour`</td>
<td class="org-right">24</td>
</tr>
<tr>
<td class="org-left">`banner_pos`</td>
<td class="org-right">7</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Total</td>
<td class="org-right">79</td>
</tr>
</tbody>
</table>
<a id="orgb062f1d"></a>
### Wide submodel(LR)特征
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Feature</th>
<th scope="col" class="org-right">Dimention</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">`id`</td>
<td class="org-right">100000</td>
</tr>
<tr>
<td class="org-left">`site_id`</td>
<td class="org-right">100000</td>
</tr>
<tr>
<td class="org-left">`app_id`</td>
<td class="org-right">100000</td>
</tr>
<tr>
<td class="org-left">`device_id`</td>
<td class="org-right">100000</td>
</tr>
<tr>
<td class="org-left">`device_id` X `site_id`</td>
<td class="org-right">10000000</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Total</td>
<td class="org-right">10,400,000</td>
</tr>
</tbody>
</table>
<a id="org6b9de13"></a>
# 输入到 PaddlePaddle 中
### 特征维度
#### Deep submodel(DNN)特征
| feature | dimention |
|------------------+-----------|
| app_category | 21 |
| site_category | 22 |
| device_conn_type | 5 |
| hour | 24 |
| banner_pos | 7 |
| **Total** | 79 |
#### Wide submodel(LR)特征
| Feature | Dimention |
|---------------------+-----------|
| id | 10000 |
| site_id | 10000 |
| app_id | 10000 |
| device_id | 10000 |
| device_id X site_id | 1000000 |
| **Total** | 1,040,000 |
## 输入到 PaddlePaddle 中
Deep 和 Wide 两部分均以 `sparse_binary_vector` 的格式[1]输入,输入前需要将相关特征拼合,模型最终只接受 3 个 input,
分别是
......@@ -379,8 +211,6 @@ def concat_sparse_vectors(inputs, dims):
res.append(v + start)
start += dims[no]
return res
```
[1] <https://github.com/PaddlePaddle/Paddle/blob/develop/doc/api/v1/data_provider/pydataprovider2_en.rst>
1. <https://github.com/PaddlePaddle/Paddle/blob/develop/doc/api/v1/data_provider/pydataprovider2_en.rst>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册