tonglin0325的个人主页

特征预处理——编码

对于标称型数据,在特征处理的时候,需要对其进行编码

在编码之前,如果训练集和测试集是分开的,则需要对其进行合并,避免标称数据丢失

1
2
3
4
5
# 合并
df = train.append(test).reset_index()
# 列名
original_columns = list(df.columns)

常用的编码方式如下

1.Label编码#

对于一个有m个category的特征,经过label encoding以后,每个category会映射到0到m-1之间的一个数。label encoding适用于ordinal feature (特征存在内在顺序)。

1
2
3
4
5
6
7
8
from sklearn import preprocessing

for col in original_columns:
enc = preprocessing.LabelEncoder()
enc.fit(np.concatenate([train[col], test[col]]))
train[col] = enc.transform(train[col])
test[col] = enc.transform(test[col])

或者

1
2
train_data = train_data.replace({'BsmtQual': {'Ex': 5, 'Gd': 4, 'TA': 3, 'Fa': 2, 'Po': 1, np.NaN: 0}})

2.顺序编码#

类似于Label编码

参考:数据转化

1
2
3
4
5
6
7
8
9
10
from sklearn import preprocessing

enc = preprocessing.OrdinalEncoder()
X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
>> OrdinalEncoder()

enc.transform([['female', 'from US', 'uses Safari']])
>> array([[0., 1., 1.]])

3.one-hot编码#

对于一个有m个category的特征,经过独热编码(OHE)处理后,会变为m个二元特征,每个特征对应于一个category。这m个二元特征互斥,每次只有一个激活。

独热编码解决了原始特征缺少内在顺序的问题,但是缺点是对于high-cardinality categorical feature (category数量很多),编码之后特征空间过大(此处可以考虑PCA降维),而且由于one-hot feature 比较unbalanced,树模型里每次的切分增益较小,树模型通常需要grow very deep才能得到不错的精度。因此OHE一般用于category数量 <4的情况。

参考:机器学习 | 数据缩放与转换方法(1)kaggle编码categorical feature总结

使用sklearn来one-hot编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn import preprocessing

enc = preprocessing.OneHotEncoder()
# enc = preprocessing.OneHotEncoder(handle_unknown='ignore') # 当 handle_unknown='ignore' 被指定而在转换的过程中碰到了未知的枚举特征值,不会产生任何错误,但是该特征的 one-hot 编码列将会被全部置 0

X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
>> OneHotEncoder()

enc.transform([['female', 'from US', 'uses Safari'], ['male', 'from Europe', 'uses Safari']]).toarray()
>> array([[1., 0., 0., 1., 0., 1.], [0., 1., 1., 0., 0., 1.]])

# 查看每个特征的特征值
enc.categories_
>> [array(['female', 'male'], dtype=object), array(['from Europe', 'from US'], dtype=object), array(['uses Firefox', 'uses Safari'], dtype=object)]

使用pandas来one-hot编码

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd

X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
df = pd.DataFrame(X, columns=['sex','country','browser'])
# columns是需要编码的列名
df = pd.get_dummies(df, columns=['sex','country'], dummy_na = True)
print(df)

browser sex_female sex_male sex_nan country_from Europe country_from US country_nan
0 uses Safari 0 1 0 0 1 0
1 uses Firefox 1 0 0 1 0 0

4.target编码#

参考:三种Target Encoding方式总结
 和 kaggle编码categorical feature总结

Target Encoding是任何一种可以从目标中派生出数字替换特征类别的编码方式。这种目标编码有时被称为平均编码。应用于二进制目标时,也被称为bin counting。

target encoding的缺点主要有:

  • 未知类别,会产生过拟合风险;
  • 空值,采用填充的方法不能很好的进行评估;
  • 长尾类别,对长尾类别这种少量数据的编码会导致过拟合;

target encoding的优点主要有:

  • 高维数据特征:具有大量类别的可能很难编码:One-hot会生成太多维度,而替代方案(如标签编码)可能不适合该类型。Target encoding在此处就很好的解决了这个问题;
  • 领域经验特征:根据之前的经验,即使某项数据它在特征度量方面得分很低,你也可能会觉得一个分类特征应该很重要。Target encoding有助于揭示特征的真实信息。

5.模型自动编码#

参考:kaggle编码categorical feature总结