网上收集的使用OneHotEncoder一些要点

1、获取编码后的特征名称
https://blog.csdn.net/cjm083121/article/details/94064950
将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。

from sklearn.preprocessing import OneHotEncode
enc = OneHotEncoder()
1
在新版本中,初始化参数有5个,分别是categories、drop、sparse、dtype、handle_unknown。本人目前是初学者,读了官方文档后,认为前四个参数不用理会,默认即可,而**handle_unknown是一个比较有用的参数,默认是"error",但我认为指定为"ignore”更好,**这个参数的目的是数据在转化为one-hot编码时,如果遇到一个属性值没有事先指定,程序应该怎么办?如果是error的话,程序就报错停止了,其实不方便处理数据,反而是ignore更好,程序可以继续执行,下面举个例子说明。

enc.fit([[“男”, 0, 3], [“男”, 1, 0], [“女”, 2, 1], [“女”, 0, 2]])
1
首先训练一下数据集,提取每一列的属性种类,得到结果如下

print(enc.categories_)
[array([‘女’, ‘男’], dtype=object), array([0, 1, 2], dtype=object), array([0, 1, 2, 3], dtype=object)]
1
2
意思是第一个特征有两个取值,分别为男和女,以此类推
如果handle_unknown默认的话,执行下面的语句就会报错:

print((enc.transform([[“男”, 0, 3], [“中性”, 1, 0], [“女”, 2, 1], [“女”, 0, 2]]).toarray()))
1
因为“中性”没有训练过,所以碰到这个不知道怎么办了,就报错停止了
但是如果指定handle_unknown为ignore,就不会出报错,某种程度上,这样更好

enc = OneHotEncoder(handle_unknown=‘ignore’)
1
这样我们就可以看到最后的one-hot编码:

[[0. 1. 1. 0. 0. 0. 0. 0. 1.]
[0. 0. 0. 1. 0. 1. 0. 0. 0.]
[1. 0. 0. 0. 1. 0. 1. 0. 0.]
[1. 0. 1. 0. 0. 0. 0. 1. 0.]]
1
2
3
4
可以注意到第二行,中性因为没有事先指定,所以显示0,0,而没有报错
如何查看独热编码每一列代表的意义呢?可以使用get_feature_names()方法

print(enc.get_feature_names())
1
最后可以看到特征名如下所示,对应上面的矩阵:

[‘x0_女’ ‘x0_男’ ‘x1_0’ ‘x1_1’ ‘x1_2’ ‘x2_0’ ‘x2_1’ ‘x2_2’ ‘x2_3’]
————————————————
版权声明:本文为CSDN博主「azago」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cjm083121/article/details/94064950

2、onehot适用的算法
https://blog.csdn.net/weixin_39750084/article/details/81432619?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
Sklearn之One-hot编码(编码方式、作用、适用场景)
一、为什么要用做One-hot编码?
在建模过程中,我们通常会碰到各种类型的属性,如果是标称型属性,也就是不具备序列性、不能比较大小的属性,通常我们不能用简单的数值来粗暴替换。因为属性的数值大小会影响到权重矩阵的计算,不存在大小关系的属性,其权重也不应该发生相应的变化,那么我们就需要用到One-hot编码(也有人称独热编码)这种特殊的编码方式了。

二、One-hot编码是什么?
来看一个简单的例子:假设我们有一个特征是自有房和无自有房,样本情况如下:

data = [[‘自有房’,40,50000],
[‘无自有房’,22,13000],
[‘自有房’,30,30000]]
1
2
3
编码后的样本矩阵变为:

data = [[1,0,40,50000],
[0,1,22,13000],
[1,0,30,30000]]
1
2
3
也就是说,一个属性如果有N个可取值,它就可以扩充为N个属性,每个样本的这N个属性中,只能有一个为1,表示该样本的该属性属于这个类别,其余扩展属性都为0。

三、Sklearn实现One-hot编码
one-hot编码属于变量预处理,所以需要在sklearn.preprocessing包中先引入。

from sklearn.preprocessing import OneHotEncoder
import pandas as pd

#原始数据集
data = [[‘自有房’,40,50000],
[‘无自有房’,22,13000],
[‘自有房’,30,30000]]
data = pd.DataFrame(data,columns=[‘house’,‘age’,‘income’])
print(data)

#把带中文的标称属性转换为数值型,因为one-hot编码也需要先转换成数值型,用简单整数代替即可
listUniq = data.ix[:,‘house’].unique()
for j in range(len(listUniq)):
data.ix[:,‘house’] = data.ix[:,‘house’].apply(lambda x:j if x==listUniq[j] else x)
print(data)

#进行one-hot编码
tempdata = data[[‘house’]]
print(tempdata)
enc = OneHotEncoder()
enc.fit(tempdata)

#one-hot编码的结果是比较奇怪的,最好是先转换成二维数组
tempdata = enc.transform(tempdata).toarray()
print(tempdata)
print(‘取值范围整数个数:’,enc.n_values_)

#再将二维数组转换为DataFrame,记得这里会变成多列
tempdata = pd.DataFrame(tempdata,columns=[‘house’]*len(tempdata[0]))
print(tempdata)

#每一步都输出结果看一看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
四、One-hot编码适用算法
据我现在的经验,one-hot用在GBDT、XGBoost这些模型里面都挺好的,但是用在逻辑回归里不行。因为逻辑回归要求变量间相互独立,如果你只有一个属性需要做one-hot编码还好,如果你有多个属性需要做one-ont编码,那么当某个样本的多个one-hot属性同时为1时,这两个属性就完全相关了,必然会导致singular error,也就是非奇异矩阵不能求解唯一解,得不出唯一的模型,但是你又不可能把同一个属性的某一个one-hot延伸变量删除。

如果在逻辑回归中入模标称属性,可以直接替换成数值,然后做woe变换,用每个类别的woe值来代替原来的数值,这样既能够避免生成相关性强的变量,又能避开类别间大小无法比较的问题。
————————————————
版权声明:本文为CSDN博主「小白白白又白cdllp」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39750084/article/details/81432619

3、one hot encoding+PCA这种组合在实际中也非常有用
https://blog.csdn.net/qq_32793161/article/details/93408802
在学习one-hot编码前,我们首先要知道,连续值的离散化为什么会提升模型的非线性能力?

简单的说,使用连续变量的LR模型,模型表示为公式(1),而使用了one-hot或哑变量编码后的模型表示为公式(2)

式中表示连续型特征,、、分别是离散化后在使用one-hot或哑变量编码后的若干个特征表示。这时我们发现使用连续值的LR模型用一个权值去管理该特征,而one-hot后有三个权值管理了这个特征,这样使得参数管理的更加精细,所以这样拓展了LR模型的非线性能力。

这样做除了增强了模型的非线性能力外,还有什么好处呢?这样做了我们至少不用再去对变量进行归一化,也可以加速参数的更新速度;再者使得一个很大权值管理一个特征,拆分成了许多小的权值管理这个特征多个表示,这样做降低了特征值扰动对模型为稳定性影响,也降低了异常数据对模型的影响,进而使得模型具有更好的鲁棒性。

1.为什么要使用one-hot编码(独热编码)?
one-hot独热编码(或哑变量 dummy variable 后面会具体提到两者区别)是因为大部分算法是基于向量空间中的度量来进行计算的,为了使非偏序关系的变量取值不具有偏序性,并且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1。

    为什么特征向量要映射到欧式空间?

    将离散特征通过one-hot编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。

(1)Why do we binarize categorical features?
We binarize the categorical input so that they can be thought of as a vector from the Euclidean space (we call this as embedding the vector in the Euclidean space).使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。
(2)Why do we embed the feature vectors in the Euclidean space?
Because many algorithms for classification/regression/clustering etc. requires computing distances between features or similarities between features. And many definitions of distances and similarities are defined over features in Euclidean space. So, we would like our features to lie in the Euclidean space as well.将离散特征通过one-hot编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。
(3)Why does embedding the feature vector in Euclidean space require us to binarize categorical features?
Let us take an example of a dataset with just one feature (say job_type as per your example) and let us say it takes three values 1,2,3.
Now, let us take three feature vectors x_1 = (1), x_2 = (2), x_3 = (3). What is the euclidean distance between x_1 and x_2, x_2 and x_3 & x_1 and x_3? d(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2. This shows that distance between job type 1 and job type 2 is smaller than job type 1 and job type 3. Does this make sense? Can we even rationally define a proper distance between different job types? In many cases of categorical features, we can properly define distance between different values that the categorical feature takes. In such cases, isn’t it fair to assume that all categorical features are equally far away from each other?
Now, let us see what happens when we binary the same feature vectors. Then, x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1). Now, what are the distances between them? They are sqrt(2). So, essentially, when we binarize the input, we implicitly state that all values of the categorical features are equally away from each other.
将离散型特征使用one-hot编码,确实会让特征之间的距离计算更加合理。比如,有一个离散型特征,代表工作类型,该离散型特征,共有三个取值,不使用one-hot编码,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。两个工作之间的距离是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之间就越不相似吗?显然这样的表示,计算出来的特征的距离是不合理。那如果使用one-hot编码,则得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么两个工作之间的距离就都是sqrt(2).即每两个工作之间的距离是一样的,显得更合理。
(4)About the original question?
Note that our reason for why binarize the categorical features is independent of the number of the values the categorical features take, so yes, even if the categorical feature takes 1000 values, we still would prefer to do binarization.
对离散型特征进行one-hot编码是为了让距离的计算显得更加合理。
(5)Are there cases when we can avoid doing binarization?
Yes. As we figured out earlier, the reason we binarize is because we want some meaningful distance relationship between the different values. As long as there is some meaningful distance relationship, we can avoid binarizing the categorical feature. For example, if you are building a classifier to classify a webpage as important entity page (a page important to a particular entity) or not and let us say that you have the rank of the webpage in the search result for that entity as a feature, then 1] note that the rank feature is categorical, 2] rank 1 and rank 2 are clearly closer to each other than rank 1 and rank 3, so the rank feature defines a meaningful distance relationship and so, in this case, we don’t have to binarize the categorical rank feature.
More generally, if you can cluster the categorical values into disjoint subsets such that the subsets have meaningful distance relationship amongst them, then you don’t have binarize fully, instead you can split them only over these clusters. For example, if there is a categorical feature with 1000 values, but you can split these 1000 values into 2 groups of 400 and 600 (say) and within each group, the values have meaningful distance relationship, then instead of fully binarizing, you can just add 2 features, one for each cluster and that should be fine.
将离散型特征进行one-hot编码的作用,是为了让距离计算更合理,但如果特征是离散的,并且不用one-hot编码就可以很合理的计算出距离,那么就没必要进行one-hot编码,比如,该离散特征共有1000个取值,我们分成两组,分别是400和600,两个小组之间的距离有合适的定义,组内的距离也有合适的定义,那就没必要用one-hot 编码

离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1

2.什么情况下使用one-hot编码(独热编码)?
在很多学习任务中,特征并不总是连续值,而有可能是分类值。

离散特征的编码分为两种情况:

1、离散特征的取值之间没有大小的意义,比如color:[red,blue],那么就使用one-hot编码

2、离散特征的取值有大小的意义,比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}

3.什么是one-hot编码(独热编码)?
这里举个简单的例子来说明。

例如,考虑以下的三个特征:

[“male”, “female”]

[“from Europe”, “from US”, “from Asia”]

[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]

如果将上述特征用数字表示,效率会高很多。例如:

[“male”, “from US”, “uses Internet Explorer”] 表示为[0, 1, 3]

[“female”, “from Asia”, “uses Chrome”]表示为[1, 2, 1]

但是,即使转化为数字表示后,上述数据也不能直接用在我们的分类器中。因为,分类器往往默认数据数据是连续的,并且是有序的。但是,按照我们上述的表示,数字并不是有序的,而是随机分配的。

为了解决上述问题,其中一种可能的解决方法是采用独热编码(One-Hot Encoding)。

独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。

例如:

自然状态码为:000,001,010,011,100,101(6种状态)

独热编码为:000001,000010,000100,001000,010000,100000(6位二元特征值)

可以这样理解,对于每一个特征,如果它有m个可能值,那么经过独热编码后,就变成了m个二元特征。并且,这些特征互斥,每次只有一个激活。因此,数据会变成稀疏的。

这样做的优点:

解决了分类器不好处理属性数据的问题

在一定程度上也起到了扩充特征的作用(稀疏性)

它的值只有0和1,不同的类型存储在垂直的空间
缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。

4.基于python的实例:
基于Python和Scikit-learn写一个简单的例子:

from sklearn import preprocessing

enc = preprocessing.OneHotEncoder()

enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])

enc.transform([[0, 1, 3]]).toarray()

输出结果:

array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])

5.一些数据(预)处理中常见的问题总结
拿到获取的原始特征,必须对每一特征分别进行归一化。

比如,特征A的取值范围是[-1000,1000],特征B的取值范围是[-1,1].
如果使用logistic回归,w1x1+w2x2,因为x1的取值太大了,所以x2基本起不了作用。
所以,必须进行特征的归一化,每个特征都单独进行归一化。

(1)连续型特征归一化的常用方法:
2.1:Rescale bounded continuous features: All continuous input that are bounded, rescale them to [-1, 1] through x = (2x - max - min)/(max - min).线性缩放到[-1,1]
2.2:Standardize all continuous features: All continuous input should be standardized and by this I mean, for every continuous feature, compute its mean (u) and standard deviation (s) and do x = (x - u)/s.放缩到均值为0,方差为1
(2)离散型特征的处理方法:

a) Binarize categorical/discrete features: For all categorical features, represent them as multiple boolean features. For example, instead of having one feature called marriage_status, have 3 boolean features - married_status_single, married_status_married, married_status_divorced and appropriately set these features to 1 or -1. As you can see, for every categorical feature, you are adding k binary feature where k is the number of values that the categorical feature takes.对于离散的特征基本就是按照one-hot编码,该离散特征有多少取值,就用多少维来表示该特征。

(3)有些情况不需要进行特征归一化:
It depends on your ML algorithms, some methods requires almost no efforts to normalize features or handle both continuous and discrete features, like tree based methods: c4.5, Cart, random Forrest, bagging or boosting. But most of parametric models (generalized linear models, neural network, SVM,etc) or methods using distance metrics (KNN, kernels, etc) will require careful work to achieve good results. Standard approaches including binary all features, 0 mean unit variance all continuous features, etc。
基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等。基于参数的模型或基于距离的模型,都是要进行特征的归一化。

6.关于one-hot的一些问题
(1)one-hot编码为什么可以解决类别型数据的离散值问题?
首先,one-hot编码是N位状态寄存器为N个状态进行编码的方式
eg:高、中、低不可分,→ 用0 0 0 三位编码之后变得可分了,并且成为互相独立的事件
→ 类似 SVM中,原本线性不可分的特征,经过project之后到高维之后变得可分了
GBDT处理高维稀疏矩阵的时候效果并不好,即使是低维的稀疏矩阵也未必比SVM好
(2)Tree Model不太需要one-hot编码:
对于决策树来说,one-hot的本质是增加树的深度。
tree-model是在动态的过程中生成类似 One-Hot + Feature Crossing 的机制

  1. 一个特征或者多个特征最终转换成一个叶子节点作为编码 ,one-hot可以理解成三个独立事件
  2. 决策树是没有特征大小的概念的,只有特征处于他分布的哪一部分的概念

(3)one-hot可以解决线性可分问题 但是比不上label econding

(4)one-hot降维后的缺点:
降维前可以交叉的降维后可能变得不能交叉

树模型的训练过程(关于决策树分类还没有细看,之后会继续补充博文):
从根节点到叶子节点整条路中有多少个节点相当于交叉了多少次,所以树的模型是自行交叉
eg:是否是长的 { 否(是→ 柚子,否 → 苹果) ,是 → 香蕉 } 园 cross 黄 → 形状 (圆,长) 颜色 (黄,红) one-hot度为4的样本
使用树模型的叶子节点作为特征集交叉结果可以减少不必要的特征交叉的操作 或者减少维度和degree候选集
eg 2 degree → 8的特征向量 树 → 3个叶子节点
树模型:Ont-Hot + 高degree笛卡尔积 + lasso 要消耗更少的计算量和计算资源
这就是为什么树模型之后可以stack线性模型
nm的输入样本 → 决策树训练之后可以知道在哪一个叶子节点上 → 输出叶子节点的index → 变成一个n1的矩阵 → one-hot编码 → 可以得到一个n*o的矩阵(o是叶子节点的个数) → 训练一个线性模型
典型的使用: GBDT + RF
优点 : 节省做特征交叉的时间和空间
如果只使用one-hot训练模型,特征之间是独立的

(5)对于现有模型的通用解释:

通用表达方式:(G(l(张量))) ,其中l(·)为节点的模型 ,G(·)为节点的拓扑方式
神经网络:l(·)取逻辑回归模型 ;G(·)取全连接的方式
决策树: l(·)取LR ;G(·)取树形链接方式
创新点: l(·)取 NB,SVM 单层NN ,等 ;G(·)取怎样的信息传递方式

7.one-hot coding和dummy encoding和label econding(未完待续)
one-hot encoding

关于one-hot编码的具体介绍,可以参考我之前的一篇博客,博客地址:特征提取方法: one-hot 和 IF-IDF。这里,不再详细介绍。one-hot的基本思想:将离散型特征的每一种取值都看成一种状态,若你的这一特征中有N个不相同的取值,那么我们就可以将该特征抽象成N种不同的状态,one-hot编码保证了每一个取值只会使得一种状态处于“激活态”,也就是说这N种状态中只有一个状态位值为1,其他状态位都是0。举个例子,假设我们以学历为例,我们想要研究的类别为小学、中学、大学、硕士、博士五种类别,我们使用one-hot对其编码就会得到:

dummy encoding

哑变量编码直观的解释就是任意的将一个状态位去除。还是拿上面的例子来说,我们用4个状态位就足够反应上述5个类别的信息,也就是我们仅仅使用前四个状态位 [0,0,0,0] 就可以表达博士了。只是因为对于一个我们研究的样本,他已不是小学生、也不是中学生、也不是大学生、又不是研究生,那么我们就可以默认他是博士,是不是。(额,当然他现实生活也可能上幼儿园,但是我们统计的样本中他并不是,-)。所以,我们用哑变量编码可以将上述5类表示成:

one-hot编码和dummy编码:区别与联系

通过上面的例子,我们可以看出它们的“思想路线”是相同的,只是哑变量编码觉得one-hot编码太罗嗦了(一些很明显的事实还说的这么清楚),所以它就很那么很明显的东西省去了。这种简化不能说到底好不好,这要看使用的场景。下面我们以一个例子来说明:

假设我们现在获得了一个模型,这里自变量满足(因为特征是one-hot获得的,所有只有一个状态位为1,其他都为了0,所以它们加和总是等于1),故我们可以用表示第三个特征,将其带入模型中,得到:

这时,我们就惊奇的发现和这两个参数是等价的!那么我们模型的稳定性就成了一个待解决的问题。这个问题这么解决呢?有三种方法:

(1)使用正则化手段,将参数的选择上加一个限制,就是选择参数元素值小的那个作为最终参数,这样我们得到的参数就唯一了,模型也就稳定了。

(2)把偏置项去掉,这时我们发现也可以解决同一个模型参数等价的问题。

因为有了bias项,所以和我们去掉bias项的模型是完全不同的模型,不存在参数等价的问题。

(3)再加上bias项的前提下,使用哑变量编码代替one-hot编码,这时去除了,也就不存在之前一种特征可以用其他特征表示的问题了。

总结:

我们使用one-hot编码时,通常我们的模型不加bias项 或者 加上bias项然后使用正则化手段去约束参数;

当我们使用哑变量编码时,通常我们的模型都会加bias项,因为不加bias项会导致固有属性的丢失。

选择建议:我感觉最好是选择正则化 + one-hot编码;哑变量编码也可以使用,不过最好选择前者。虽然哑变量可以去除one-hot编码的冗余信息,但是因为每个离散型特征各个取值的地位都是对等的,随意取舍未免来的太随意。

参考链接:

https://blog.csdn.net/dulingtingzi/article/details/51374487

https://www.cnblogs.com/lianyingteng/p/7792693.html

https://www.cnblogs.com/zongfa/p/9305657.html
————————————————
版权声明:本文为CSDN博主「nice_evil」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_32793161/article/details/93408802

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值