在数据样本中,有些特征不是连续值,而是一些离散值。举个网站访问数据例子:
表1 网站访问数据集
序号 | 性别 | 所属区域 | 使用浏览器 |
1. | Male | Europe | Firefox |
2. | Female | US | Chrome |
3. | Male | Asia | Safari |
4. | Female | Europe | IE |
5. | Female | US | Firefox |
6. | Female | Asia | Chrome |
7. | Male | Europe | Safari |
8. | Male | US | Chrome |
...... | ...... | ...... | ...... |
其中性别、所属区域、使用浏览器都是分类值。这在机器学习算法中不太好处理,所以一般将特征的离散值用数字表示。例如将male编码为0,female编码为1;Europe编码为0,US编码为1,Asia编码为2;Firefox编码为0,Chrome编码为1,Safari编码为2,IE编码为3。
则上表中的8条记录可以表示成:
序号 | 性别 | 所属区域 | 使用浏览器 |
1. | 0 | 0 | 0 |
2. | 1 | 1 | 1 |
3. | 0 | 2 | 2 |
4. | 1 | 0 | 3 |
5. | 1 | 1 | 0 |
6. | 1 | 2 | 1 |
7. | 0 | 0 | 2 |
8. | 0 | 1 | 1 |
...... | ...... | ...... | ...... |
但是,即使转化为数字,上述数据也不能直接用在我们的分类模型中。因为,分类器默认的输入数据是连续的,并且是有序的。
针对这个问题,一种可能的解决方案是采用独热编码(One-Hot Encoding),独热,顾名思义,就是编码中只有一个位是有效的,所以又称为“一位有效编码”。
例如上面的特征“性别”,有2个可能的分类:male,female。那么就可以用2位编码来表示:10,01,每次只有1个位激活。
“所属区域”,有3个可能的分类:即Europe,US,Asia。那么就用3位编码来表示:100,010,001,每次只有1个位激活。
“使用浏览器”,有4个可能的分类:即Firefox,Chrome,Safari,IE。那么就用4位编码来表示:1000,0100,0010,0001,每次只有1个位激活。
那么一条数据记录[‘male’,’Asia’,’Safari’],通过独热编码后就成为:[1,0,0,0,1,0,0,1,0]。
这样,每一条记录都被映射到欧式空间,可以用于计算特征之间的距离与相似度等,能够用于各种机器学习算法了。
将上面的8条记录进行独热编码,则[‘male’,’Asia’,’Safari’]对应的独热编码是:[ 1. 0. 0. 0. 1. 0. 0. 1. 0.],程序如下:
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
enc.fit([[0, 0, 0], [1, 1, 1], [0, 2, 2], [1, 0, 3], [1, 1, 0], [1, 2, 1], [0, 0, 2], [0, 1, 1]])
print enc.transform([[0, 2, 2]]).toarray()
当然,还可以使用pandas中的get_dummies进行one-hot编码。