提交 b3e717be 编写于 作者: S Superjom

finish first version

上级 1ba7d6ab
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org2665a87">1. 数据集介绍</a></li>
<li><a href="#org6179fca">2. 特征提取</a>
<ul>
<li><a href="#org42da1c1">2.1. 类别类特征</a></li>
<li><a href="#org53b2fea">2.2. ID 类特征</a></li>
<li><a href="#orgc5d512d">2.3. 数值型特征</a></li>
<li><a href="#org38ba127">2.4. 特征处理方法</a></li>
</ul>
</li>
<li><a href="#orgbef0a6e">3. 特征处理</a>
<ul>
<li><a href="#org72e16f2">3.1. 类别型特征</a></li>
<li><a href="#org3473ce8">3.2. ID 类特征</a></li>
<li><a href="#org53745e6">3.3. 交叉类特征</a></li>
<li><a href="#org60b0048">3.4. 特征维度</a>
<ul>
<li><a href="#orgac20756">3.4.1. Deep submodel(DNN)特征</a></li>
<li><a href="#orgbccc155">3.4.2. Wide submodel(LR)特征</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#org758adb3">4. 输入到 Paddle 中</a></li>
</ul>
</div>
</div>
<a id="org2665a87"></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
- banner<sub>pos</sub>
- site<sub>id</sub>
- site<sub>domain</sub>
- site<sub>category</sub>
- app<sub>id</sub>
- app<sub>domain</sub>
- app<sub>category</sub>
- device<sub>id</sub>
- device<sub>ip</sub>
- device<sub>model</sub>
- device<sub>type</sub>
- device<sub>conn</sub><sub>type</sub>
- C14-C21 &#x2013; anonymized categorical variables
<a id="org6179fca"></a>
# 特征提取
下面我们会简单演示几种特征的提取方式。
原始数据中的特征可以分为以下几类:
1. ID 类特征(稀疏,数量多)
- id
- site<sub>id</sub>
- app<sub>id</sub>
- device<sub>id</sub>
2. 类别类特征(稀疏,但数量有限)
- C1
- site<sub>category</sub>
- device<sub>type</sub>
- C14-C21
3. 数值型特征转化为类别型特征
- hour (可以转化成数值,也可以按小时为单位转化为类别)
<a id="org42da1c1"></a>
## 类别类特征
类别类特征的提取方法有以下两种:
1. One-hot 表示作为特征
2. 类似词向量,用一个 Embedding Table 将每个类别映射到对应的向量
<a id="org53b2fea"></a>
## ID 类特征
ID 类特征的特点是稀疏数据,但量比较大,直接使用 One-hot 表示时维度过大。
一般会作如下处理:
1. 确定表示的最大维度 N
2. newid = id % N
3. 用 newid 作为类别类特征使用
上面的方法尽管存在一定的碰撞概率,但能够处理任意数量的 ID 特征,并保留一定的效果[2]。
<a id="orgc5d512d"></a>
## 数值型特征
一般会做如下处理:
- 归一化,直接作为特征输入模型
- 用区间分割处理成类别类特征,稀疏化表示,模糊细微上的差别
<a id="org38ba127"></a>
## 特征处理方法
具体特征处理方法参看 [data process](./dataset.md)
<a id="orgbef0a6e"></a>
# 特征处理
<a id="org72e16f2"></a>
## 类别型特征
类别型特征有有限多种值,在模型中,我们一般使用 embedding table 将每种值映射为连续值的向量。
这种特征在输入到模型时,一般使用 One-hot 表示,相关处理方法如下:
class CategoryFeatureGenerator(object):
'''
Generator category features.
Register all records by calling `register` first, then call `gen` to generate
one-hot representation for a record.
'''
def __init__(self):
self.dic = {'unk': 0}
self.counter = 1
def register(self, key):
'''
Register record.
'''
if key not in self.dic:
self.dic[key] = self.counter
self.counter += 1
def size(self):
return len(self.dic)
def gen(self, key):
'''
Generate one-hot representation for a record.
'''
if key not in self.dic:
res = self.dic['unk']
else:
res = self.dic[key]
return [res]
def __repr__(self):
return '<CategoryFeatureGenerator %d>' % len(self.dic)
本任务中,类别类特征会输入到 DNN 中使用。
<a id="org3473ce8"></a>
## ID 类特征
ID 类特征代稀疏值,且值的空间很大的情况,一般用模操作规约到一个有限空间,
之后可以当成类别类特征使用,这里我们会将 ID 类特征输入到 LR 模型中使用。
class IDfeatureGenerator(object):
def __init__(self, max_dim):
'''
@max_dim: int
Size of the id elements' space
'''
self.max_dim = max_dim
def gen(self, key):
'''
Generate one-hot representation for records
'''
return [hash(key) % self.max_dim]
def size(self):
return self.max_dim
<a id="org53745e6"></a>
## 交叉类特征
LR 模型作为 Wide & Deep model 的 \`wide\` 部分,可以输入很 wide 的数据(特征空间的维度很大),
为了充分利用这个优势,我们将演示交叉组合特征构建成更大维度特征的情况,之后塞入到模型中训练。
这里我们依旧使用模操作来约束最终组合出的特征空间的大小,具体实现是直接在 \`IDfeatureGenerator\` 中添加一个\`gen<sub>cross</sub><sub>feature</sub>\` 的方法:
def gen_cross_fea(self, fea1, fea2):
key = str(fea1) + str(fea2)
return self.gen(key)
比如,我们觉得原始数据中,\`device<sub>id</sub>\`\`site<sub>id</sub>\` 有一些关联(比如某个 device 倾向于浏览特定 site),
我们通过组合出两者组合来捕捉这类信息。
<a id="org60b0048"></a>
## 特征维度
<a id="orgac20756"></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<sub>category</sub></td>
<td class="org-right">21</td>
</tr>
<tr>
<td class="org-left">site<sub>category</sub></td>
<td class="org-right">22</td>
</tr>
<tr>
<td class="org-left">device<sub>conn</sub><sub>type</sub></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<sub>pos</sub></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="orgbccc155"></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">10000</td>
</tr>
<tr>
<td class="org-left">site<sub>id</sub></td>
<td class="org-right">10000</td>
</tr>
<tr>
<td class="org-left">app<sub>id</sub></td>
<td class="org-right">10000</td>
</tr>
<tr>
<td class="org-left">device<sub>id</sub></td>
<td class="org-right">10000</td>
</tr>
<tr>
<td class="org-left">device<sub>id</sub> X site<sub>id</sub></td>
<td class="org-right">1000000</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Total</td>
<td class="org-right">1,040,000</td>
</tr>
</tbody>
</table>
<a id="org758adb3"></a>
# 输入到 Paddle 中
Deep 和 Wide 两部分均以 \`sparse<sub>binary</sub><sub>vector</sub>\` 的格式[1]输入,输入前需要将相关特征拼合,模型最终只接受 3 个 input,
分别是
1. \`dnn input\`,DNN 的输入
2. \`lr input\`, LR 的输入
3. \`click\`, 标签
拼合特征的方法:
def concat_sparse_vectors(inputs, dims):
'''
concaterate sparse vectors into one
@inputs: list
list of sparse vector
@dims: list of int
dimention of each sparse vector
'''
res = []
assert len(inputs) == len(dims)
start = 0
for no, vec in enumerate(inputs):
for v in vec:
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>
#+title: 数据处理
* 数据集介绍
数据集使用 `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 -- anonymized categorical variable
- banner_pos
- site_id
- site_domain
- site_category
- app_id
- app_domain
- app_category
- device_id
- device_ip
- device_model
- device_type
- device_conn_type
- C14-C21 -- anonymized categorical variables
* 特征提取
下面我们会简单演示几种特征的提取方式。
原始数据中的特征可以分为以下几类:
1. ID 类特征(稀疏,数量多)
- id
- site_id
- app_id
- device_id
2. 类别类特征(稀疏,但数量有限)
- C1
- site_category
- device_type
- C14-C21
3. 数值型特征转化为类别型特征
- hour (可以转化成数值,也可以按小时为单位转化为类别)
** 类别类特征
类别类特征的提取方法有以下两种:
1. One-hot 表示作为特征
2. 类似词向量,用一个 Embedding Table 将每个类别映射到对应的向量
** ID 类特征
ID 类特征的特点是稀疏数据,但量比较大,直接使用 One-hot 表示时维度过大。
一般会作如下处理:
1. 确定表示的最大维度 N
2. newid = id % N
3. 用 newid 作为类别类特征使用
上面的方法尽管存在一定的碰撞概率,但能够处理任意数量的 ID 特征,并保留一定的效果[2]。
** 数值型特征
一般会做如下处理:
- 归一化,直接作为特征输入模型
- 用区间分割处理成类别类特征,稀疏化表示,模糊细微上的差别
** 特征处理方法
具体特征处理方法参看 [[./dataset.md][data process]]
* 特征处理
** 类别型特征
类别型特征有有限多种值,在模型中,我们一般使用 embedding table 将每种值映射为连续值的向量。
这种特征在输入到模型时,一般使用 One-hot 表示,相关处理方法如下:
#+BEGIN_SRC python
class CategoryFeatureGenerator(object):
'''
Generator category features.
Register all records by calling `register` first, then call `gen` to generate
one-hot representation for a record.
'''
def __init__(self):
self.dic = {'unk': 0}
self.counter = 1
def register(self, key):
'''
Register record.
'''
if key not in self.dic:
self.dic[key] = self.counter
self.counter += 1
def size(self):
return len(self.dic)
def gen(self, key):
'''
Generate one-hot representation for a record.
'''
if key not in self.dic:
res = self.dic['unk']
else:
res = self.dic[key]
return [res]
def __repr__(self):
return '<CategoryFeatureGenerator %d>' % len(self.dic)
#+END_SRC
本任务中,类别类特征会输入到 DNN 中使用。
** ID 类特征
ID 类特征代稀疏值,且值的空间很大的情况,一般用模操作规约到一个有限空间,
之后可以当成类别类特征使用,这里我们会将 ID 类特征输入到 LR 模型中使用。
#+BEGIN_SRC python
class IDfeatureGenerator(object):
def __init__(self, max_dim):
'''
@max_dim: int
Size of the id elements' space
'''
self.max_dim = max_dim
def gen(self, key):
'''
Generate one-hot representation for records
'''
return [hash(key) % self.max_dim]
def size(self):
return self.max_dim
#+END_SRC
** 交叉类特征
LR 模型作为 Wide & Deep model 的 `wide` 部分,可以输入很 wide 的数据(特征空间的维度很大),
为了充分利用这个优势,我们将演示交叉组合特征构建成更大维度特征的情况,之后塞入到模型中训练。
这里我们依旧使用模操作来约束最终组合出的特征空间的大小,具体实现是直接在 `IDfeatureGenerator` 中添加一个`gen_cross_feature` 的方法:
#+BEGIN_SRC python
def gen_cross_fea(self, fea1, fea2):
key = str(fea1) + str(fea2)
return self.gen(key)
#+END_SRC
比如,我们觉得原始数据中,`device_id` 和 `site_id` 有一些关联(比如某个 device 倾向于浏览特定 site),
我们通过组合出两者组合来捕捉这类信息。
** 特征维度
*** 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 |
|---------------------+-----------|
* 输入到 Paddle 中
Deep 和 Wide 两部分均以 `sparse_binary_vector` 的格式[1]输入,输入前需要将相关特征拼合,模型最终只接受 3 个 input,
分别是
1. `dnn input`,DNN 的输入
2. `lr input`, LR 的输入
3. `click`, 标签
拼合特征的方法:
#+BEGIN_SRC python
def concat_sparse_vectors(inputs, dims):
'''
concaterate sparse vectors into one
@inputs: list
list of sparse vector
@dims: list of int
dimention of each sparse vector
'''
res = []
assert len(inputs) == len(dims)
start = 0
for no, vec in enumerate(inputs):
for v in vec:
res.append(v + start)
start += dims[no]
return res
#+END_SRC
[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.
先完成此消息的编辑!
想要评论请 注册