特征处理-(离散型特征处理)
完成特征理解和特征清洗之后,我们要进行特征工程中最为重要和复杂的一步了——特征处理
离散型特征处理
离散型特征通常为非连续值或以字符串形式存在的特征,离散型特征通常来讲是不能直接喂入模型中的,例如性别:男/女,绝大部分模型无法对这些变量进行识别,所以,我们需要将离散型特征进行编码数字化,使得模型能够正常识别和学习该数据。
1.Label Encoding
简单来说LabelEncoder就是把n个类别值编码为0~n-1之间的整数,建立起一一对应映射关系,例如:
2.One-Hot Encoding
其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。例如:
为什么要用独热编码?
独热编码(哑变量 dummy variable)是因为大部分算法是基于向量空间中的度量来进行计算的,为了使非偏序关系的变量取值不具有偏序性,并且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1。
独热编码的优缺点:
- 优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
- 缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。
3.二进制编码
使用二进制数对编码进行编写,在原先独热编码的基础上减少了编码后的维度。
# 相关模块加载
import pandas as pd
import category_encoders as ce
# 准备数据
df = pd.DataFrame({'ID':[1,2,3,4,5,6],
'RATING':['G','B','G','B','B','G']})
# 使用binary编码的方式来编码类别变量
encoder = ce.BinaryEncoder(cols=['RATING']).fit(df)
# 转换数据
numeric_dataset = encoder.transform(df)
df # 转换前的数据
4. Target Encoding
目标编码是一种不仅基于特征值本身,还基于相应因变量的类别变量编码方法。对于分类问题:将类别特征替换为给定某一特定类别值的因变量后验概率与所有训练数据上因变量的先验概率的组合。对于连续目标:将类别特征替换为给定某一特定类别值的因变量目标期望值与所有训练数据上因变量的目标期望值的组合。该方法严重依赖于因变量的分布,但这大大减少了生成编码后特征的数量。
5.catboost encoding
这个跟CatBoost一致,是Catboost中的encode方法,这个方法据说效果非常好,而且可以避免过拟合,可能有些复杂
import pandas as pd
import numpy as np
#from unittest import TestCase # or `from unittest import ...` if on Python 3.4+
import category_encoders as encoders
X = pd.DataFrame({'col1': ['A', 'B', 'B', 'C', 'A']})
y = pd.Series([1, 0, 1, 0, 1])
enc = encoders.CatBoostEncoder()
obtained = enc.fit_transform(X, y)
obtained
# For testing set, use statistics calculated on all the training data.
# See: CatBoost: unbiased boosting with categorical features, page 4.
X_t = pd.DataFrame({'col1': ['B', 'B', 'A']})
obtained = enc.transform(X_t)
obtained