特征工程 -类别型特征的预处理

目录

序言

主要介绍:

1 .使用Sklearn的LabelBinarizer来进行one-hot

2 .使用Sklearn的MultilabelBinarizer来进行组合类别特征的One-hot

 3 .对Oridinal序数特征进行编码

4 .对特征字典编码

 5 .填充缺失的分类特征值

6.使用category_encoder包来进行特征转换

总结


序言

在机器学习建模过程中,许多模型例如逻辑回归、支持向量机、K近邻等传统的机器学习模型不能直接将类别型特征用于训练。但是在近年,许多新诞生的模型例如:LightGBM和Catboost等算法开始支持类别型特征直接进行建模。所以,处理类别型特征,是进行机器学习建模前的必不可少的步骤。

 本文将介绍若干种类别特征的处理方案,相信通过这些方法,希望能在今后遇到类别型特征时,能找到一种最合适的解决方法。

主要介绍:

  • 使用sklearn的LabelBinarizer来进行one-hot类别特征
  • 使用sklearn的MultiLabelBinarizer来进行组合类别特征的one-hot
  • 使用sklearn对oridinal序数特征进行编码
  • 对特征字典进行编码
  • 填充缺失的分类值
  • 使用category_encoder包来进行类别特征编码
  1. OridinalEncoder
  2. OnehotEncoder
  3. 目标编码TargetEncoder
  4. M估计量编码MEstimateEncoder
  5. JamesSteinEncoder
  6. WOE编码
  7. Catboost编码

1 .使用Sklearn的LabelBinarizer来进行one-hot

# 导入相关包
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelBinarizer

# 创建特征
feature = np.array([['Texas'],
                    ['Cliforniya'],
                    ['Texas'],
                    ['Delaware'],
                    ['Texas']])

# 实例化编码器
one_hot = LabelBinarizer()

# 查看转换后的结果
display(one_hot.fit_transform(feature))
display(one_hot.classes_)

如上图所示,我们会得到一个类型为<U10的结构化数组,假如我们需要逆转换,我们也可以使用这种方法,将one-hot转换后的分类特征再转回原始的特征。

下面将展示两种方法:

# 使用one-hot编码进行逆转换
one_hot.inverse_transform(one_hot.transform(feature))

# output
array(['Texas', 'Cliforniya', 'Texas', 'Delaware', 'Texas'], dtype='<U10')
# 使用pandas中的pd.get_dummies()来进行转换
pd.get_dummies(pd.DataFrame(feature,columns=['feature name']))


2 .使用Sklearn的MultilabelBinarizer来进行组合类别特征的One-hot

from sklearn.preprocessing import MultiLabelBinarizer
''' multiclass_features = [('Texas','Florida'),
                       ('Californiya','Alabama'),
                       ('Texas','Florida'),
                       ('Delware','Florida'),
                       ('Texas','Alabama')]
'''
multiclass_features =  np.array([['Texas'],
                    ['Cliforniya'],
                    ['Texas'],
                    ['Delaware'],
                    ['Texas']])

one_hot_multiclass = MultiLabelBinarizer()

display(one_hot_multiclass.fit_transform(multiclass_features))
display(one_hot_multiclass.classes_)

 

就会得到相同的结果,这里需要注意的是:得到类型为字节。

 3 .对Oridinal序数特征进行编码

可以使用字典来对相应的特征进行映射。

df = pd.DataFrame({"Score":['Low','Low','Medium','Medium','High']})
display(df)

scale_mapper = {"Low":1,'Medium':2,'High':3}
display(df.replace(scale_mapper))

                                                                                                                   

 

 对于某种天然的顺序,例如李克特量表(Likert scale),值与值之间的间隔可能不是数字所反映出来的大小关系,我们应该主动去更改数字大小。

4 .对特征字典编码

# 加载库
from sklearn.feature_extraction import DictVectorizer
# 创建字典
data_dict = [{"Red":2,"Blue":4},
             {"Red":4,"Blue":3},
             {"Red":1,"Yellow":2},
             {"Red":2,"Yellow":2}]

# 创建字典向量化器(指定非稀疏矩阵)
dictvectorizer = DictVectorizer(sparse=False)
display(dictvectorizer.fit_transform(data_dict))

# 获取特征的名字,使用get_feature_names()
feature_names = dictvectorizer.get_feature_names()
display(feature_names)

# 创建DataFrame
pd.DataFrame(dictvectorizer.fit_transform(data_dict),columns=feature_names)

 5 .填充缺失的分类特征值

import numpy as np
from sklearn.neighbors import KNeighborsClassifier

# 用分类特征创建特征矩阵
X = np.array([[0,2.10,1.45],
             [1,1.18,1.33],
             [0,1.22,1.27],
             [1,-0.21,-1.19]])

# 创建带缺失值的特征矩阵
X_with_nan = np.array([[np.nan,0.87,1.31],
                       [np.nan,-0.67,-0.22]])

# 训练分类器
clf = KNeighborsClassifier(3,weights='distance')
trained_model = clf.fit(X[:,1:],X[:,0])

# 预测缺失值的分类
imputed_values = trained_model.predict(X_with_nan[:,1:])

# 将所预测的分类和它们的其他特征链接起来
X_with_imputed = np.hstack((imputed_values.reshape(-1,1),X_with_nan[:,1:]))

# 连接两个特征矩阵
np.vstack((X_with_imputed,X))



#用特征中出现次数最多的值来填充缺失值。

from sklearn.impute import SimpleImputer
# 链接两个特征矩阵
X_complete = np.vstack((X_with_nan,X))

imputer = SimpleImputer(strategy='most_frequent',)
imputer.fit_transform(X_complete)

6.使用category_encoder包来进行特征转换

6.1 使用OrdinalEncoder进行序数转换

缺点:这个编码的缺点在于它随机的给特征排序了,会给这个特征增加不存在的顺序关系,也就是增加了噪声,与编码后特征的顺序不存在相关性。

# 首先安装category_encoder包
# !pip install category_encoder
# 导入序数编码器
from category_encoders import OrdinalEncoder

# 随机生成一些训练集
train_set = pd.DataFrame(np.array([['male',10],['female',20],['male',10],
                                  ['female',20],['female',15]]),columns=['Sex','Type'])
train_y = np.array([False,True,True,False,False])

# 随机生成一些测试集,并有意让其包含未在训练集出现过的类别值与缺失值
test_set = pd.DataFrame(np.array([['female',20],['male',20],['others',15],
                                   ['male',20],['female',40],['male',25]]),columns=['Sex','Type'])
test_set.loc[4,'Type'] = np.nan

display(train_set)
display(test_set)

 

6.2 进行one-hot编码

缺点:但是在离散特征的特征值过多的时候不宜使用,因为会导致生成特征的数量太多且过于稀疏。

# 首先安装category_encoder包
# !pip install category_encoder
# 导入序数编码器
from category_encoders import OrdinalEncoder

# 随机生成一些训练集
train_set = pd.DataFrame(np.array([['male',10],['female',20],['male',10],
                                  ['female',20],['female',15]]),columns=['Sex','Type'])
train_y = np.array([False,True,True,False,False])

# 随机生成一些测试集,并有意让其包含未在训练集出现过的类别值与缺失值
test_set = pd.DataFrame(np.array([['female',20],['male',20],['others',15],
                                   ['male',20],['female',40],['male',25]]),columns=['Sex','Type'])
test_set.loc[4,'Type'] = np.nan

display(train_set)
display(test_set)



from category_encoders import OneHotEncoder

encoder = OneHotEncoder(cols=['Sex','Type'], 
                        handle_unknown='indicator', 
                        handle_missing='indicator', 
                        use_cat_names=True).fit(train_set,train_y) # 在训练集上训练
encoded_train = encoder.transform(train_set) # 转换训练集
encoded_test = encoder.transform(test_set) # 转换测试集
# 将 handle_unknown设为‘indicator’,即会新增一列指示未知特征值
# 将 handle_missing设为‘indicator’,即会新增一列指示缺失值
# 其他的handle_unknown/handle_missing 的选择为:
# ‘error’:即报错; ‘return_nan’:即未知值/缺失之被标记为nan; ‘value’:即未知值/缺失之被标记为0

6.3 使用TargetEncoder目标编码

由名字目标编码就可以猜到,目标编码是一种不仅基于特征值本身,还基于相应因变量的类别变量编码方法。
对于分类问题:将类别特征替换为给定某一特定类别值的因变量后验概率与所有训练数据上因变量的先验概率的组合。
对于连续目标:将类别特征替换为给定某一特定类别值的因变量目标期望值与所有训练数据上因变量的目标期望值的组合。
该方法严重依赖于因变量(target)的分布,但这大大减少了生成编码后特征的数量。
参考文献: Micci-Barreca, D. (2001). A preprocessing scheme for high-cardinality categorical attributes in classification and prediction problems. ACM SIGKDD Explorations Newsletter, 3(1), 27-32.

from category_encoders import  TargetEncoder
encoder = TargetEncoder(cols=['Sex','Type'], 
                        handle_unknown='value',  
                        handle_missing='value').fit(train_set,train_y) # 在训练集上训练
encoded_train = encoder.transform(train_set) # 转换训练集
encoded_test = encoder.transform(test_set) # 转换测试集

# handle_unknown 和 handle_missing 被设定为 'value'
# 在目标编码中,handle_unknown 和 handle_missing 仅接受 ‘error’, ‘return_nan’ 及 ‘value’ 设定
# 两者的默认值均为 ‘value’, 即对未知类别或缺失值填充训练集的因变量平均值

总结

处理分类特征是机器学习建模数据预处理时所不可避免的一项环节,相应通过以上若干种方法,以后在遇到分类特征时,可以不一上手就直接进行Onehot,而有了更多的选择,也可以使得训练的模型能够更好的效果,祝愿未来蒸蒸日上。

参考: Category Encoders — Category Encoders 2.5.1.post0 documentation

参考: GitHub - YC-Coder-Chen/feature-engineering-handbook: A practical feature engineering handbook

参考:特征工程.类别型特征的预处理 - 知乎

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: NSD-KDD数据预处理包括数据清洗、数据转换和数据离散化等步骤。数据清洗涉及删除重复数据、缺失值处理、异常值处理等。数据转换包括将数值数据转换为标称数据、将时间数据转换为数值数据等。数据离散化涉及将连续数据转换为离散数据,便于进行分类和聚类分析。 ### 回答2: NSL-KDD数据集是用于入侵检测的标准数据集,它基于原始的KDD Cup 1999数据集,针对其中的一些问题进行了优化和改进。NSL-KDD数据预处理是指对该数据集进行筛选、清洗和转换等操作,以使数据适合用于入侵检测算法的训练和评估。 首先,需要对原始的KDD Cup 1999数据集进行筛选,即从中选择与入侵检测相的数据。原始数据集中包含正常和异常连接的数据,我们需要挑选出异常连接的数据进行进一步分析和处理。 其次,对筛选后的数据进行清洗操作,去除其中的噪声和冗余信息。这包括去除缺失值、异常值和重复数据。通过清洗操作,可以提高数据的质量,减少噪声对入侵检测算法的干扰。 然后,对清洗后的数据进行转换和编码。这包括将非数值特征转换为数值特征,以及对类别特征进行编码。常用的编码方式包括独热编码和标签编码。转换和编码操作可以将数据转化为入侵检测算法所需要的格式。 最后,对转换和编码后的数据进行归一化操作。归一化将各个特征的取值范围映射到统一的区间,避免某些特征对入侵检测算法的影响过大。常用的归一化方法包括最小-最大归一化和Z-score归一化。 通过以上的预处理操作,NSL-KDD数据集可以得到经过筛选、清洗、转换和归一化的数据,为后续的入侵检测算法的训练和评估提供了可靠的数据基础。 ### 回答3: NSL-KDD数据集是一个常用的入侵检测数据集,它是基于KDD Cup 1999数据集的改进版本。NSL-KDD数据集主要用于开发和评估入侵检测系统。在进行NSL-KDD数据集的预处理时,通常需要完成以下步骤: 1. 数据清洗:首先需要对数据集进行清洗,去除错误、缺失或重复的数据,以保证数据的准确性和一致性。 2. 特征选择:由于NSL-KDD数据集的特征维度较高,为了降低计算复杂性和提高模效果,需要对特征进行选择。常用的特征选择方法包括相性分析、信息增益、卡方检验等。 3. 特征缩放:对于NSL-KDD数据集中不同特征的取值范围差异较大的情况,通常需要进行特征缩放。常用的特征缩放方法有归一化和标准化。 4. 标签转换:NSL-KDD数据集中的标签主要有五类,分别是正常(Normal)和四类入侵行为(DoS、Probe、R2L、U2R)。为了便于模训练,通常需要将这五类标签转换为二进制的形式。 5. 数据分割:为了进行模的训练和评估,需要将NSL-KDD数据集划分为训练集和测试集。常用的划分方法有随机划分和交叉验证。 通过对NSL-KDD数据集的预处理,可以减少数据中的噪声和冗余信息,提高模的训练效果。同时,预处理还可以使得数据的分布更加均匀,有助于提高模的泛化能力。对于NSL-KDD数据集的预处理是入侵检测研究的重要一步,可以为后续的特征工程和模训练提供高质量的数据基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zouia Gail(修行中)

你的鼓励是对我创作的最大支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值