python onehot编码_[Hulu百面机器学习]python实战系列(1.2)——(单一)类别型特征

6b1a851439c51a9acf764c8ae62201c0.png

上一期我们实战了归一化的两种方法:线性函数归一化(Min-Max Scaling)和零均值归一化(z-score Normalization)。这一期我们从实数型型特征转到类别性特征去回应如下问题:

Q: 在进行数据预处理时,应该怎么处理类别性特征?(难度:2⭐)

我们常用三种方法处理类别型特征:

  • 序号编码(Ordinal Encoding)

是将n种类别从0到n-1或1到n的整数排序,主要是可以保留不同等级(例如空气质量等级1到6级,分别对应"优"到"重污染")。

  • 独热编码(Ordinal Encoding)

将一个类别变量中多种类按照每个种类的有(1)无(0)去分类。输出是:

需要注意如下问题:

(1)使用稀疏向量来节省空间。​因此可以利用向量的稀疏表示有效地节省空间,并且目前大部分的算法均接受稀疏向量形式的输入。

(2)配合特征选择采降低维度。高维度特征会带来几方面的问题​:

一是在K 近邻算法中,高维空间下两点之间的距离很难得到高效的衡量;

二是在逻幅回归模型中,参数的数量会随着维度的增高而增加,易引

起过拟合问题;

三是通常只有高部分维度是对台类、预测有帮助,因此可以考虑配合特征选择来降低维度。

  • 二进制编码(Binary Encoding)

序号编码的二进制数版本​。好处是比独热编码更省空间,空间复杂度是​

其中N是单个类别变量中类别个数,M为​样本长度。

接下来咱们进入实战吧!

同样,我们需要的是葡萄酒数据​(以下代码块均用python3)。这次追加一个包是为后面的对数运算做准备:

import urllib.request
import numpy as np

url = "http://archive.ics.uci.edu//ml//machine-learning-databases//wine//wine.data"
raw_data = urllib.request.urlopen(url)
data0 = np.loadtxt(raw_data, delimiter=",")

用numpy硬干模式:

# arr 的 独特函数,输入一维数组,双指针算法时间复杂度为O(n)
def unique(arr):
    arrs = arr.copy()
    j = 0
    for i in range(len(arrs)):
        if (not i) or (arrs[i] not in arrs[0 : j]):
            arrs[j] = arrs[i]
            j += 1
    return arrs[0 : j]
    # a[0] ~ a[j - 1] 所有a中不重复的数

# 标签编码
def label(arr,a):
    arrs = np.zeros_like(arr)
    for i in range(len(arr)):
        arrs[i] = list(a).index(arr[i])
    return arrs

# 独热编码
def onehot(arr,a):
    arrs = np.zeros((len(arr),len(a)))
    for i in range(len(arr)):
        arrs[i,list(a).index(arr[i])] = 1
    return arrs

# 二进制编码
def binary(arr,a):
    arrs = np.zeros((len(arr),int(math.log(len(a)-1,2))+1),dtype = int)
    for i in range(len(arr)):
        q = list(a).index(arr[i])
        cnt = -1
        if q == 0:
            continue
        while q > 0:
            q,m = q // 2, q % 2
            arrs[i,cnt] = m
            cnt -= 1
    return arrs

# 总函数
encoders_func = {'label': label, 'onehot': onehot, 'binary': binary}
def categotical_encoders(arr, encode_type):
    a = unique(arr)
    return encoders_func[encode_type](arr,a)

# 注意输入数组是一维的,不是n*1的二维
data1 = categotical_encoders(data0[:,0], 'label')
data2 = categotical_encoders(data0[:,0], 'onehot')
data2 = categotical_encoders(data0[:,0], 'binary')

优雅的​sklearn模式:​

from sklearn import preprocessing
from sklearn.preprocessing import OneHotEncoder
le = preprocessing.LabelEncoder()
ohe = OneHotEncoder(handle_unknown='ignore')

# 求unique 函数
le.fit(data0[:,0])
data1 = le.transform(data0[:,0])
ohe.fit(data0[:,0:1])
data2 = ohe.transform(data0[:,0:1])

227a272d7c5743b114776234eed23d4b.png

二进制编码省空间但是耗时,是因为他的时间复杂度为

,高于其他两种方法的
,显然可以接受,毕竟是新开了一个二维数组,对每个数据点进行多次k进制商和余数的计算,去求二进制数。

上一期代码耗时也是按重复1000次来计算的。

各位敬请期待下一期:

[Hulu百面机器学习]python实战系列(1.3-1.4)——(高维)组合特征

最后欢迎大家关注我们的微信公众号哦(科罗娜气候狂热者):

http://weixin.qq.com/r/AS4RCXPEli7prTdq93sT (二维码自动识别)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值