dataset.md 5.7 KB
Newer Older
S
Superjom 已提交
1 2
# 数据及处理
## 数据集介绍
S
Superjom 已提交
3

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

S
Superjom 已提交
6 7 8
-   `id` : ad identifier
-   `click` : 0/1 for non-click/click
-   `hour` : format is YYMMDDHH, so 14091123 means 23:00 on Sept. 11, 2014 UTC.
S
Superjom 已提交
9
-   `C1` : anonymized categorical variable
S
Superjom 已提交
10 11 12 13 14 15 16 17 18 19 20 21
-   `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`
S
Superjom 已提交
22
-   `C14-C21` : anonymized categorical variables
S
Superjom 已提交
23 24


S
Superjom 已提交
25
## 特征提取
S
Superjom 已提交
26

S
Superjom 已提交
27
下面我们会简单演示几种特征的提取方式。
S
Superjom 已提交
28 29 30 31

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

1.  ID 类特征(稀疏,数量多)
S
wrap ~  
Superjom 已提交
32
-   `id`
S
Superjom 已提交
33 34 35
-   `site_id`
-   `app_id`
-   `device_id`
S
Superjom 已提交
36

S
Superjom 已提交
37
2.  类别类特征(稀疏,但数量有限)
S
Superjom 已提交
38

S
wrap ~  
Superjom 已提交
39
-   `C1`
S
Superjom 已提交
40 41 42
-   `site_category`
-   `device_type`
-   `C14-C21`
S
Superjom 已提交
43

S
Superjom 已提交
44 45
3.  数值型特征转化为类别型特征

S
Superjom 已提交
46
-   hour (可以转化成数值,也可以按小时为单位转化为类别)
S
Superjom 已提交
47

S
Superjom 已提交
48
### 类别类特征
S
Superjom 已提交
49 50 51 52 53 54 55

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

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


S
Superjom 已提交
56
### ID 类特征
S
Superjom 已提交
57 58 59 60 61 62 63 64 65 66 67

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

一般会作如下处理:

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

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

S
Superjom 已提交
68
### 数值型特征
S
Superjom 已提交
69 70 71 72 73 74

一般会做如下处理:

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

S
Superjom 已提交
75
## 特征处理
S
Superjom 已提交
76 77


S
Superjom 已提交
78
### 类别型特征
S
Superjom 已提交
79 80 81 82 83

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

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

S
Superjom 已提交
84
```python
S
Superjom 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
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 已提交
100
        '''
S
Superjom 已提交
101 102 103
        if key not in self.dic:
            self.dic[key] = self.counter
            self.counter += 1
S
Superjom 已提交
104

S
Superjom 已提交
105 106 107 108 109 110
    def size(self):
        return len(self.dic)

    def gen(self, key):
        '''
        Generate one-hot representation for a record.
S
Superjom 已提交
111
        '''
S
Superjom 已提交
112 113 114 115 116 117 118 119 120
        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 已提交
121 122 123

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

S
Superjom 已提交
124
### ID 类特征
S
Superjom 已提交
125 126 127 128

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

S
Superjom 已提交
129
```python
S
Superjom 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142
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 已提交
143

S
Superjom 已提交
144 145 146
    def size(self):
        return self.max_dim
```
S
Superjom 已提交
147

S
Superjom 已提交
148
### 交叉类特征
S
Superjom 已提交
149

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

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

S
Superjom 已提交
155
```python
S
Superjom 已提交
156 157 158 159
def gen_cross_fea(self, fea1, fea2):
    key = str(fea1) + str(fea2)
    return self.gen(key)
```
S
Superjom 已提交
160

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

S
Superjom 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
### 特征维度
#### 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 中
S
Superjom 已提交
186

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

S
wrap ~  
Superjom 已提交
190 191 192
1.  `dnn input` ,DNN 的输入
2.  `lr input` , LR 的输入
3.  `click`  , 标签
S
Superjom 已提交
193 194 195

拼合特征的方法:

S
Superjom 已提交
196
```python
S
Superjom 已提交
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
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 已提交
215

S
Superjom 已提交
216
1. <https://github.com/PaddlePaddle/Paddle/blob/develop/doc/api/v1/data_provider/pydataprovider2_en.rst>