dataset.md 8.0 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 6
<li><a href="#orgb9b1ee8">1. 数据集介绍</a></li>
<li><a href="#orgeaf74d5">2. 特征提取</a>
S
Superjom 已提交
7
<ul>
S
Superjom 已提交
8 9 10
<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>
S
Superjom 已提交
11 12
</ul>
</li>
S
Superjom 已提交
13
<li><a href="#org6ef4cab">3. 特征处理</a>
S
Superjom 已提交
14
<ul>
S
Superjom 已提交
15 16 17 18
<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>
S
Superjom 已提交
19
<ul>
S
Superjom 已提交
20 21
<li><a href="#org223ebf2">3.4.1. Deep submodel(DNN)特征</a></li>
<li><a href="#orgb062f1d">3.4.2. Wide submodel(LR)特征</a></li>
S
Superjom 已提交
22 23 24 25
</ul>
</li>
</ul>
</li>
S
Superjom 已提交
26
<li><a href="#org6b9de13">4. 输入到 PaddlePaddle 中</a></li>
S
Superjom 已提交
27 28 29 30 31
</ul>
</div>
</div>


S
Superjom 已提交
32
<a id="orgb9b1ee8"></a>
S
Superjom 已提交
33 34 35

# 数据集介绍

S
Superjom 已提交
36
数据集使用 `csv` 格式存储,其中各个字段内容如下:
S
Superjom 已提交
37

S
Superjom 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
-   `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_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` &#x2013; anonymized categorical variables


S
Superjom 已提交
57
<a id="orgeaf74d5"></a>
S
Superjom 已提交
58 59 60

# 特征提取

S
Superjom 已提交
61
下面我们会简单演示几种特征的提取方式。
S
Superjom 已提交
62 63 64 65

原始数据中的特征可以分为以下几类:

1.  ID 类特征(稀疏,数量多)
S
Superjom 已提交
66
```python
S
wrap ~  
Superjom 已提交
67
-   `id`
S
Superjom 已提交
68 69 70
-   `site_id`
-   `app_id`
-   `device_id`
S
Superjom 已提交
71 72

```
S
Superjom 已提交
73 74

2.  类别类特征(稀疏,但数量有限)
S
Superjom 已提交
75
```python
S
wrap ~  
Superjom 已提交
76
-   `C1`
S
Superjom 已提交
77 78 79
-   `site_category`
-   `device_type`
-   `C14-C21`
S
Superjom 已提交
80 81

```
S
Superjom 已提交
82 83

3.  数值型特征转化为类别型特征
S
Superjom 已提交
84
```python
S
Superjom 已提交
85 86
-   hour (可以转化成数值也可以按小时为单位转化为类别

S
Superjom 已提交
87

S
Superjom 已提交
88
```
S
Superjom 已提交
89

S
Superjom 已提交
90
<a id="org876ed90"></a>
S
Superjom 已提交
91 92 93 94 95 96 97 98 99

## 类别类特征

类别类特征的提取方法有以下两种:

1.  One-hot 表示作为特征
2.  类似词向量,用一个 Embedding Table 将每个类别映射到对应的向量


S
Superjom 已提交
100
<a id="org33838ae"></a>
S
Superjom 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114

## ID 类特征

ID 类特征的特点是稀疏数据,但量比较大,直接使用 One-hot 表示时维度过大。

一般会作如下处理:

1.  确定表示的最大维度 N
2.  newid = id % N
3.  用 newid 作为类别类特征使用

上面的方法尽管存在一定的碰撞概率,但能够处理任意数量的 ID 特征,并保留一定的效果[2]。


S
Superjom 已提交
115
<a id="org96be68a"></a>
S
Superjom 已提交
116 117 118 119 120 121 122 123 124

## 数值型特征

一般会做如下处理:

-   归一化,直接作为特征输入模型
-   用区间分割处理成类别类特征,稀疏化表示,模糊细微上的差别


S
Superjom 已提交
125
<a id="org6ef4cab"></a>
S
Superjom 已提交
126 127 128 129

# 特征处理


S
Superjom 已提交
130
<a id="org967be87"></a>
S
Superjom 已提交
131 132 133 134 135 136 137

## 类别型特征

类别型特征有有限多种值,在模型中,我们一般使用 embedding table 将每种值映射为连续值的向量。

这种特征在输入到模型时,一般使用 One-hot 表示,相关处理方法如下:

S
Superjom 已提交
138
```python
S
Superjom 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
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.
S
Superjom 已提交
154
        '''
S
Superjom 已提交
155 156 157
        if key not in self.dic:
            self.dic[key] = self.counter
            self.counter += 1
S
Superjom 已提交
158

S
Superjom 已提交
159 160 161 162 163 164
    def size(self):
        return len(self.dic)

    def gen(self, key):
        '''
        Generate one-hot representation for a record.
S
Superjom 已提交
165
        '''
S
Superjom 已提交
166 167 168 169 170 171 172 173
        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)
S
Superjom 已提交
174

S
Superjom 已提交
175
```
S
Superjom 已提交
176 177 178 179

本任务中,类别类特征会输入到 DNN 中使用。


S
Superjom 已提交
180
<a id="org516125b"></a>
S
Superjom 已提交
181 182 183 184 185 186

## ID 类特征

ID 类特征代稀疏值,且值的空间很大的情况,一般用模操作规约到一个有限空间,
之后可以当成类别类特征使用,这里我们会将 ID 类特征输入到 LR 模型中使用。

S
Superjom 已提交
187
```python
S
Superjom 已提交
188 189 190 191 192 193 194 195 196 197 198 199 200
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]
S
Superjom 已提交
201

S
Superjom 已提交
202 203
    def size(self):
        return self.max_dim
S
Superjom 已提交
204

S
Superjom 已提交
205

S
Superjom 已提交
206
```
S
Superjom 已提交
207

S
Superjom 已提交
208
<a id="org8a0cce6"></a>
S
Superjom 已提交
209 210 211

## 交叉类特征

S
Superjom 已提交
212
LR 模型作为 Wide & Deep model 的 `wide` 部分,可以输入很 wide 的数据(特征空间的维度很大),
S
Superjom 已提交
213 214
为了充分利用这个优势,我们将演示交叉组合特征构建成更大维度特征的情况,之后塞入到模型中训练。

S
Superjom 已提交
215
这里我们依旧使用模操作来约束最终组合出的特征空间的大小,具体实现是直接在 `IDfeatureGenerator` 中添加一个 `gen_cross_feature` 的方法:
S
Superjom 已提交
216

S
Superjom 已提交
217
```python
S
Superjom 已提交
218 219 220 221 222
def gen_cross_fea(self, fea1, fea2):
    key = str(fea1) + str(fea2)
    return self.gen(key)

```
S
Superjom 已提交
223

S
Superjom 已提交
224
比如,我们觉得原始数据中, `device_id``site_id` 有一些关联(比如某个 device 倾向于浏览特定 site),
S
Superjom 已提交
225 226 227
我们通过组合出两者组合来捕捉这类信息。


S
Superjom 已提交
228
<a id="org6655b66"></a>
S
Superjom 已提交
229 230 231 232

## 特征维度


S
Superjom 已提交
233
<a id="org223ebf2"></a>
S
Superjom 已提交
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253

### 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>
S
Superjom 已提交
254
<td class="org-left">`app_category`</td>
S
Superjom 已提交
255 256 257 258 259
<td class="org-right">21</td>
</tr>


<tr>
S
Superjom 已提交
260
<td class="org-left">`site_category`</td>
S
Superjom 已提交
261 262 263 264 265
<td class="org-right">22</td>
</tr>


<tr>
S
Superjom 已提交
266
<td class="org-left">`device_conn_type`</td>
S
Superjom 已提交
267 268 269 270 271
<td class="org-right">5</td>
</tr>


<tr>
S
wrap ~  
Superjom 已提交
272
<td class="org-left">`hour`</td>
S
Superjom 已提交
273 274 275 276 277
<td class="org-right">24</td>
</tr>


<tr>
S
Superjom 已提交
278
<td class="org-left">`banner_pos`</td>
S
Superjom 已提交
279 280 281 282 283 284 285 286 287 288 289 290 291
<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>


S
Superjom 已提交
292
<a id="orgb062f1d"></a>
S
Superjom 已提交
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

### 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>
S
wrap ~  
Superjom 已提交
313
<td class="org-left">`id`</td>
S
Superjom 已提交
314
<td class="org-right">100000</td>
S
Superjom 已提交
315 316 317 318
</tr>


<tr>
S
Superjom 已提交
319 320
<td class="org-left">`site_id`</td>
<td class="org-right">100000</td>
S
Superjom 已提交
321 322 323 324
</tr>


<tr>
S
Superjom 已提交
325 326
<td class="org-left">`app_id`</td>
<td class="org-right">100000</td>
S
Superjom 已提交
327 328 329 330
</tr>


<tr>
S
Superjom 已提交
331 332
<td class="org-left">`device_id`</td>
<td class="org-right">100000</td>
S
Superjom 已提交
333 334 335 336
</tr>


<tr>
S
Superjom 已提交
337 338
<td class="org-left">`device_id` X `site_id`</td>
<td class="org-right">10000000</td>
S
Superjom 已提交
339 340 341 342 343 344
</tr>
</tbody>

<tbody>
<tr>
<td class="org-left">Total</td>
S
Superjom 已提交
345
<td class="org-right">10,400,000</td>
S
Superjom 已提交
346 347 348 349 350
</tr>
</tbody>
</table>


S
Superjom 已提交
351
<a id="org6b9de13"></a>
S
Superjom 已提交
352

S
Superjom 已提交
353
# 输入到 PaddlePaddle 中
S
Superjom 已提交
354

S
Superjom 已提交
355
Deep 和 Wide 两部分均以 `sparse_binary_vector` 的格式[1]输入,输入前需要将相关特征拼合,模型最终只接受 3 个 input,
S
Superjom 已提交
356 357
分别是

S
wrap ~  
Superjom 已提交
358 359 360
1.  `dnn input` ,DNN 的输入
2.  `lr input` , LR 的输入
3.  `click`  , 标签
S
Superjom 已提交
361 362 363

拼合特征的方法:

S
Superjom 已提交
364
```python
S
Superjom 已提交
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
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

```
S
Superjom 已提交
384 385 386

[1] <https://github.com/PaddlePaddle/Paddle/blob/develop/doc/api/v1/data_provider/pydataprovider2_en.rst>