学习sklearn和kagggle时遇到的问题,什么是独热编码?为何要用独热编码?什么状况下能够用独热编码?以及和其余几种编码方式的区别。html
首先了解机器学习中的特征类别:连续型特征和离散型特征 算法
拿到获取的原始特征,必须对每一特征分别进行归一化,好比,特征A的取值范围是[-1000,1000],特征B的取值范围是[-1,1].若是使用logistic回归,w1*x1+w2*x2,由于x1的取值太大了,因此x2基本起不了做用。因此,必须进行特征的归一化,每一个特征都单独进行归一化。框架
对于连续性特征:机器学习
对于离散性特征:函数
一. 什么是独热编码?post
独热码,在英文文献中称作 one-hot code, 直观来讲就是有多少个状态就有多少比特,并且只有一个比特为1,其余全为0的一种码制。举例以下:学习
假若有三种颜色特征:红、黄、蓝。 在利用机器学习的算法时通常须要进行向量化或者数字化。那么你可能想令 红=1,黄=2,蓝=3. 那么这样其实实现了标签编码,即给不一样类别以标签。然而这意味着机器可能会学习到“红<黄<蓝”,但这并非咱们的让机器学习的本意,只是想让机器区分它们,并没有大小比较之意。因此这时标签编码是不够的,须要进一步转换。由于有三种颜色状态,因此就有3个比特。即红色:1 0 0 ,黄色: 0 1 0,蓝色:0 0 1 。如此一来每两个向量之间的距离都是根号2,在向量空间距离都相等,因此这样不会出现偏序性,基本不会影响基于向量空间度量算法的效果。ui
天然状态码为:000,001,010,011,100,101this
独热编码为:000001,000010,000100,001000,010000,100000编码
来一个sklearn的例子:
from sklearn import preprocessing enc = preprocessing.OneHotEncoder() enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) # fit来学习编码 enc.transform([[0, 1, 3]]).toarray() # 进行编码
输出:array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
数据矩阵是4*3,即4个数据,3个特征维度。
0 0 3 观察左边的数据矩阵,第一列为第一个特征维度,有两种取值0\1. 因此对应编码方式为10 、01
1 1 0 同理,第二列为第二个特征维度,有三种取值0\1\2,因此对应编码方式为100、0十、001
0 2 1 同理,第三列为第三个特征维度,有四中取值0\1\2\3,因此对应编码方式为1000、0100、00十、0001
1 0 2
再来看要进行编码的参数[0 , 1, 3], 0做为第一个特征编码为10, 1做为第二个特征编码为010, 3做为第三个特征编码为0001. 故此编码结果为 1 0 0 1 0 0 0 0 1
二. 为何要独热编码?
正如上文所言,独热编码(哑变量 dummy variable)是由于大部分算法是基于向量空间中的度量来进行计算的,为了使非偏序关系的变量取值不具备偏序性,而且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征均可以看作是连续的特征。就能够跟对连续型特征的归一化方法同样,对每一维特征进行归一化。好比归一化到[-1,1]或归一化到均值为0,方差为1。
为何特征向量要映射到欧式空间?
将离散特征经过one-hot编码映射到欧式空间,是由于,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或类似度的计算是很是重要的,而咱们经常使用的距离或类似度的计算都是在欧式空间的类似度计算,计算余弦类似性,基于的就是欧式空间。
三 .独热编码优缺点
四. 什么状况下(不)用独热编码?
总的来讲,要是one hot encoding的类别数目不太多,建议优先考虑。
五. 什么状况下(不)须要归一化?
六. 标签编码LabelEncoder
做用: 利用LabelEncoder() 将转换成连续的数值型变量。便是对不连续的数字或者文本进行编号例如:
from sklearn.preprocessing import LabelEncoder le = LabelEncoder() le.fit([1,5,67,100]) le.transform([1,1,100,67,5])
输出: array([0,0,3,2,1])
>>> le = preprocessing.LabelEncoder() >>> le.fit(["paris", "paris", "tokyo", "amsterdam"]) LabelEncoder() >>> list(le.classes_) ['amsterdam', 'paris', 'tokyo'] # 三个类别分别为0 1 2 >>> le.transform(["tokyo", "tokyo", "paris"]) array([2, 2, 1]...) >>> list(le.inverse_transform([2, 2, 1])) # 逆过程 ['tokyo', 'tokyo', 'paris']
限制:上文颜色的例子已经提到标签编码了。Label encoding在某些状况下颇有用,可是场景限制不少。再举一例:好比有[dog,cat,dog,mouse,cat],咱们把其转换为[1,2,1,3,2]。这里就产生了一个奇怪的现象:dog和mouse的平均值是cat。因此目前尚未发现标签编码的普遍使用。
附:基本的机器学习过程
参考:
Quora:What are good ways to handle discrete and continuous inputs together?