机器学习之特征编码
程序员文章站
2022-07-14 19:26:24
...
为什么特征编码
通常工业数据都是比较脏的,特征变量除了数值外可能还会包括字符等特征值,但一般的机器学习模型一般都是处理数值型的特征值,因此需要将一些非数值的特殊特征值转为为数值,这就要用到特征编码。
编码方式
我们通常会使用两种方式来实现,分别是:自然数编码:label-encoding和独热编码: one-hot encoding。一般如果特征是定类数据,模型对数值大小次序敏感则选择onehot,如果特征是定序数据,模型对数值大小不敏感一般选择label,onehot容易造成维度灾难。
以下我们基于Kaggle的Titanic数据对实现编码
import numpy as np
import pandas as pd
import os
print(os.listdir())
data_train=pd.read_csv('train.csv')
data_train.head(5)
数据如下:
- label-encoding
- 优点
解决了分类编码的问题,可以*定义量化数字。但其实也是缺点,因为数值本身没有任何含义,只是排序。如大中小编码为123,也可以编码为321,即数值没有意义。 - 缺点
可解释性比较差。比如有[dog,cat,dog,mouse,cat],我们把其转换为[1,2,1,3,2],这里就产生了一个奇怪的现象:dog和mouse的平均值是cat。因此,Label encoding编码其实并没有很宽的应用场景。
#先对sibsp和parch创建有序编码family_size_c,family_size_c是值为‘single’,'small','large'的特征变量
def family_size_category(family_size):
if family_size<=1:
return 'single'
elif family_size<=3:
return 'small'
else:
return 'large'
data_train['family_size']=data_train['SibSp']+data_train['Parch']+1
data_train['family_size_c']=data_train['family_size'].map(family_size_category)
#由于family_size_c特征是定序数据类型,也是分类类型,但比定类更高级,因为有排序,因此对family_size_c进行label encoding
from sklearn.preprocessing import LabelEncoder
le=LabelEncoder()
#对要的编码类别进行fit,fit内必须为一个行数组1-D的array(可重复,会自动辨别)
le.fit(np.array(['single','small','large']))
data_train['family_size_c']=le.transform(data_train['family_size_c'])
print(le.classes_)#查看标签类别
print(le.inverse_transform([2,1,0]))#查看数字对应的标签
打印结果如下:
[‘large’ ‘single’ ‘small’]
[‘small’ ‘single’ ‘large’]#[2,1,0]对用的原特征值
- one-hot encoding
- 优点
解决了分类器不好处理分类数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。 - 缺点
当类别的数量很多时,特征空间会变得非常大,容易造成维度灾难。
one-hot编码可以由sklearn.preprocessing import OneHotEncoder和pandas里的get_dummies实现,OneHotEncoder只能处理数值型而get_dummies可以对其他特殊字符进行编码
#用pandas里的get_dummies可以对字符特征变量Sex','Embarked'处理
oh_Sex_Embarked=pd.get_dummies(data_train[['Sex','Embarked']],drop_first=True)
#借助concat函数把编码变量合并到原来数据
data_train_new=pd.concat([data_train.drop(['Sex','Embarked'],axis=1),oh_Sex_Embarked],axis=1)
data_train_new
数据如下
上一篇: numpy向量化函数
下一篇: 将dataframe 转化成图片保存