精华内容
下载资源
问答
  • 首先了解机器学习中的特征类别:连续型特征和离散型特征 拿到获取的原始特征,必须对每一特征分别进行归一化,比如,特征A的取值范围是[-1000,1000],特征B的取值范围是[-1,1].如果使用logistic回归,w1x1+w2x2,...

    学习sklearn和kagggle时遇到的问题,什么是独热编码?为什么要用独热编码?什么情况下可以用独热编码?以及和其他几种编码方式的区别。

    首先了解机器学习中的特征类别:连续型特征和离散型特征

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

    对于连续性特征:

    • Rescale bounded continuous features: All continuous input that are bounded, rescale them to [-1, 1] through x = (2x - max - min)/(max - min). 线性放缩到[-1,1]
    • 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

    对于离散性特征:

    • Binarize categorical/discrete features: 对于离散的特征基本就是按照one-hot(独热)编码,该离散特征有多少取值,就用多少维来表示该特征。
      独热码,在英文文献中称做 one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。举例如下:

    一. 什么是独热编码?

    独热码,在英文文献中称做 one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。举例如下:

    假如有三种颜色特征:红、黄、蓝。 在利用机器学习的算法时一般需要进行向量化或者数字化。那么你可能想令 红=1,黄=2,蓝=3. 那么这样其实实现了标签编码,即给不同类别以标签。然而这意味着机器可能会学习到“红<黄<蓝”,但这并不是我们的让机器学习的本意,只是想让机器区分它们,并无大小比较之意。所以这时标签编码是不够的,需要进一步转换。因为有三种颜色状态,所以就有3个比特。即红色:1 0 0 ,黄色: 0 1 0,蓝色:0 0 1 。如此一来每两个向量之间的距离都是根号2,在向量空间距离都相等,所以这样不会出现偏序性,基本不会影响基于向量空间度量算法的效果。

    自然状态码为:000,001,010,011,100,101

    独热编码为: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、010、001

    0 2 1 同理,第三列为第三个特征维度,有四中取值0\1\2\3,所以对应编码方式为1000、0100、0010、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编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。

    三 .独热编码优缺点

    • 优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
    • 缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。

    四. 什么情况下(不)用独热编码?

    • 用:独热编码用来解决类别型数据的离散值问题,
    • 不用:将离散型特征进行one-hot编码的作用,是为了让距离计算更合理,但如果特征是离散的,并且不用one-hot编码就可以很合理的计算出距离,那么就没必要进行one-hot编码。 有些基于树的算法在处理变量时,并不是基于向量空间度量,数值只是个类别符号,即没有偏序关系,所以不用进行独热编码。 Tree Model不太需要one-hot编码: 对于决策树来说,one-hot的本质是增加树的深度。
      总的来说,要是one hot encoding的类别数目不太多,建议优先考虑。

    五. 什么情况下(不)需要归一化?

    • 需要: 基于参数的模型或基于距离的模型,都是要进行特征的归一化。
    • 不需要:基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等。

    六. 标签编码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。所以目前还没有发现标签编码的广泛使用。
    在这里插入图片描述
    数据预处理:独热编码(One-Hot Encoding)
    使用sklearn进行数据挖掘
    数据挖掘比赛通用框架
    Label Encoding vs One Hot Encoding
    [scikit-learn] 特征二值化编码函数的一些坑

    展开全文
  • 山鸢尾变色鸢尾维吉尼亚鸢尾001最终向量为0 0 1 表示种类是维吉尼亚鸢尾为什么要使用独热编码,原因如下独热编码可以很好的表示分类数据的,而许多机器学习与深度学习的任务就是实现各种回归模型分类任务,而且独...

    山鸢尾变色鸢尾维吉尼亚鸢尾001

    最终向量为0 0 1 表示种类是维吉尼亚鸢尾

    为什么要使用独热编码,原因如下

    独热编码可以很好的表示分类数据的,而许多机器学习与深度学习的任务就是实现各种回归模型分类任务,而且独热编码非常容易实现,无需复杂计算,只有整数0、1的二进制表达容易被技术与工程人员理解与接受。

    独热编码的代码演示手动版from numpy import argmax

    # define input string

    data = 'hello world'

    print(data)

    # define universe of possible input values

    alphabet = 'abcdefghijklmnopqrstuvwxyz '

    # define a mapping of chars to integers

    char_to_int = dict((c, i) for i, c in enumerate(alphabet))

    int_to_char = dict((i, c) for i, c in enumerate(alphabet))

    # integer encode input data

    integer_encoded = [char_to_int[char] for char in data]

    print(integer_encoded)

    # one hot encode

    onehot_encoded = list()

    for value in integer_encoded:

    letter = [0 for _ in range(len(alphabet))]

    letter[value] = 1

    onehot_encoded.append(letter)

    print(onehot_encoded)

    # invert encoding

    inverted = int_to_char[argmax(onehot_encoded[0])]

    print(inverted)keras版本from numpy import array

    from numpy import argmax

    from keras.utils import to_categorical

    # define example

    data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1]

    data = array(data)

    print(data)

    # one hot encode

    encoded = to_categorical(data)

    print(encoded)

    # invert encoding

    inverted = argmax(encoded[0])

    print(inverted)

    参考引用

    https://machinelearningmastery.com/how-to-one-hot-encode-sequence-data-in-python/

    展开全文
  • 首先了解机器学习中的特征类别:连续型特征和离散型特征 拿到获取的原始特征,必须对每一特征分别进行归一化,比如,特征A的取值范围是[-1000,1000],特征B的取值范围是[-1,1].如果使用logistic回归,w1*x1+w...

    学习sklearn和kagggle时遇到的问题,什么是独热编码?为什么要用独热编码?什么情况下可以用独热编码?以及和其他几种编码方式的区别。

    首先了解机器学习中的特征类别:连续型特征和离散型特征     

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

           对于连续性特征:

    • Rescale bounded continuous features: All continuous input that are bounded, rescale them to [-1, 1] through x = (2x - max - min)/(max - min).    线性放缩到[-1,1]
    • 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

           对于离散性特征:

    • Binarize categorical/discrete features: 对于离散的特征基本就是按照one-hot(独热)编码,该离散特征有多少取值,就用多少维来表示该特征。

    一. 什么是独热编码?

           独热码,在英文文献中称做 one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。举例如下:

           假如有三种颜色特征:红、黄、蓝。 在利用机器学习的算法时一般需要进行向量化或者数字化。那么你可能想令 红=1,黄=2,蓝=3. 那么这样其实实现了标签编码,即给不同类别以标签。然而这意味着机器可能会学习到“红<黄<蓝”,但这并不是我们的让机器学习的本意,只是想让机器区分它们,并无大小比较之意。所以这时标签编码是不够的,需要进一步转换。因为有三种颜色状态,所以就有3个比特。即红色:1 0 0 ,黄色: 0 1 0,蓝色:0 0 1 。如此一来每两个向量之间的距离都是根号2,在向量空间距离都相等,所以这样不会出现偏序性,基本不会影响基于向量空间度量算法的效果。

          自然状态码为:000,001,010,011,100,101

          独热编码为: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、010、001

    0 2 1                                               同理,第三列为第三个特征维度,有四中取值0\1\2\3,所以对应编码方式为1000、0100、0010、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编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。

    三 .独热编码优缺点

    • 优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
    • 缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。

    四. 什么情况下(不)用独热编码?

    • 用:独热编码用来解决类别型数据的离散值问题,
    • 不用:将离散型特征进行one-hot编码的作用,是为了让距离计算更合理,但如果特征是离散的,并且不用one-hot编码就可以很合理的计算出距离,那么就没必要进行one-hot编码。 有些基于树的算法在处理变量时,并不是基于向量空间度量,数值只是个类别符号,即没有偏序关系,所以不用进行独热编码。  Tree Model不太需要one-hot编码: 对于决策树来说,one-hot的本质是增加树的深度。

    总的来说,要是one hot encoding的类别数目不太多,建议优先考虑。 

    五.  什么情况下(不)需要归一化?

    • 需要: 基于参数的模型或基于距离的模型,都是要进行特征的归一化。
    • 不需要:基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等。

    六.  标签编码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。所以目前还没有发现标签编码的广泛使用。

     附:基本的机器学习过程

     

    Label encoding在某些情况下很有用,但是场景限制很多。比如有一列 [dog,cat,dog,mouse,cat],我们把其转换为[1,2,1,3,2]。这里就产生了一个奇怪的现象:dog和mouse的平均值是cat。而且像decision tree,random forest和xgboost这种算法能处理好这种转换,而且相比转换前,所需要的内存空间小一点。

    One-Hot 编码即独热编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。这样做的好处主要有:1. 解决了分类器不好处理属性数据的问题; 2. 在一定程度上也起到了扩充特征的作用。

    将离散型特征进行one-hot编码的作用,是为了让距离计算更合理,但如果特征是离散的,并且不用one-hot编码就可以很合理的计算出距离,那么就没必要进行one-hot编码。离散特征进行one-hot编码,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1。

    基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等。基于参数的模型或基于距离的模型,都是要进行特征的归一化。Tree Model不太需要one-hot编码: 对于决策树来说,one-hot的本质是增加树的深度。

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

    总的来说,要是one hot encoding的类别数目不太多,建议优先考虑。

    七、Sklearn的LabelEncoder和OneHotEncoder实战

    LabelEncoder和OneHotEncoder

    我们也可以通过sklearn的模块实现对离散变量的one-hot编码,其中LabelEncoder是将离散变量替换为数字,

    OneHotEncoder则实现对替换为数字的离散变量进行one-hot编码。

    注:get_dummies()可以直接对字符型变量进行one-hot编码,但OneHotEncoder不能直接对字符型变量编码,因此我们需要先将字符型变量转换为数值型变量。这就是为什么在OneHotEncoder之前需要LabelEncoder的原因。

    如下代码为将一列数据进行one-hot编码后,然后拼接

        all_weekday_cache={}
        for e in allday:
            all_weekday_cache[e]=pd.to_datetime(e).isoweekday()
        traindata['weekday']=traindata['sampleday'].apply(lambda x:all_weekday_cache[x])
    
        if flag=="train":
            Enc_ohe.fit(traindata[['weekday']])
        print(Enc_ohe.categories_) 
        print(list(Enc_ohe.categories_[0]))
    
        DF_dummies2 = pd.DataFrame(Enc_ohe.transform(traindata[['weekday']]).todense(), columns = list(Enc_ohe.categories_[0]))
        print(DF_dummies2.head(3))
        #拼接
        traindata = pd.concat((traindata,DF_dummies2),axis=1) # 1 水平方向拼接

    打印如下:

    [array([1., 2., 3., 4., 5., 6., 7.])]
    [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
       1.0  2.0  3.0  4.0  5.0  6.0  7.0
    0  0.0  1.0  0.0  0.0  0.0  0.0  0.0
    1  0.0  0.0  1.0  0.0  0.0  0.0  0.0
    2  0.0  0.0  0.0  0.0  1.0  0.0  0.0
    

     

    例1
    
    1
    from sklearn.preprocessing import OneHotEncoder
    2
    ohe = OneHotEncoder()
    3
    ohe.fit([[1,1],[2,1],[3,2],[4,5]])
    4
    ohe.transform([[2,1],[3,1],[1,1],[4,5]]).toarray()
    /home/bigdevelp_user/anaconda3/lib/python3.6/site-packages/sklearn/preprocessing/_encoders.py:368: FutureWarning: The handling of integer data will change in version 0.22. Currently, the categories are determined based on the range [0, max(values)], while in the future they will be determined based on the unique values.
    If you want the future behaviour and silence this warning, you can specify "categories='auto'".
    In case you used a LabelEncoder before this OneHotEncoder to convert the categories to integers, then you can now use the OneHotEncoder directly.
      warnings.warn(msg, FutureWarning)
    array([[0., 1., 0., 0., 1., 0., 0.],
           [0., 0., 1., 0., 1., 0., 0.],
           [1., 0., 0., 0., 1., 0., 0.],
           [0., 0., 0., 1., 0., 0., 1.]])
    
    ohe.categories_
    1
    ohe.categories_
    [array([1., 2., 3., 4.]), array([1., 2., 5.])]
    例2
    
    r
    1
    from sklearn.preprocessing import OneHotEncoder
    2
    ohe = OneHotEncoder()
    3
    ohe.fit([[1],[2],[3],[4]])
    4
    ohe.transform([[2],[3],[1],[4]]).toarray()
    /home/bigdevelp_user/anaconda3/lib/python3.6/site-packages/sklearn/preprocessing/_encoders.py:368: FutureWarning: The handling of integer data will change in version 0.22. Currently, the categories are determined based on the range [0, max(values)], while in the future they will be determined based on the unique values.
    If you want the future behaviour and silence this warning, you can specify "categories='auto'".
    In case you used a LabelEncoder before this OneHotEncoder to convert the categories to integers, then you can now use the OneHotEncoder directly.
      warnings.warn(msg, FutureWarning)
    array([[0., 1., 0., 0.],
           [0., 0., 1., 0.],
           [1., 0., 0., 0.],
           [0., 0., 0., 1.]])
    
    1
    ohe.categories_
    [array([1., 2., 3., 4.])]
    例3
    
    1
    from sklearn.preprocessing import LabelEncoder
    2
    le = LabelEncoder()
    3
    le.fit([1,5,67,100])
    4
    le.transform([1,1,100,67,5])
    array([0, 0, 3, 2, 1])
    
    [
    1
    from sklearn.preprocessing import LabelEncoder
    2
    le = LabelEncoder()
    3
    le.fit([[1,5,67,100],[2,3,4,5]])
    4
    le.transform([[1,100,67,5],[2,3,4,5]])
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-15-01b4bc8aa27f> in <module>()
          1 from sklearn.preprocessing import LabelEncoder
          2 le = LabelEncoder()
    ----> 3 le.fit([[1,5,67,100],[2,3,4,5]])
          4 le.transform([[1,100,67,5],[2,3,4,5]])
    
    ~/anaconda3/lib/python3.6/site-packages/sklearn/preprocessing/label.py in fit(self, y)
        217         self : returns an instance of self.
        218         """
    --> 219         y = column_or_1d(y, warn=True)
        220         self.classes_ = _encode(y)
        221         return self
    
    ~/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in column_or_1d(y, warn)
        795         return np.ravel(y)
        796 
    --> 797     raise ValueError("bad input shape {0}".format(shape))
        798 
        799 
    
    ValueError: bad input shape (2, 4)

     

    import pandas as pd
    import numpy as np
    from sklearn.datasets import load_iris
    sns.set()
    
    %matplotlib inline
    
    #Iris Plot
    iris = load_iris()
    n_samples, m_features = iris.data.shape
    
    #Load Data
    X, y = iris.data, iris.target
    D_target_dummy = dict(zip(np.arange(iris.target_names.shape[0]), iris.target_names))
    
    DF_data = pd.DataFrame(X,columns=iris.feature_names)
    DF_data["target"] = pd.Series(y).map(D_target_dummy)
    #sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)  \
    #0                  5.1               3.5                1.4               0.2   
    #1                  4.9               3.0                1.4               0.2   
    #2                  4.7               3.2                1.3               0.2   
    #3                  4.6               3.1                1.5               0.2   
    #4                  5.0               3.6                1.4               0.2   
    #5                  5.4               3.9                1.7               0.4   
    
    DF_dummies = pd.get_dummies(DF_data["target"])
    #setosa  versicolor  virginica
    #0         1           0          0
    #1         1           0          0
    #2         1           0          0
    #3         1           0          0
    #4         1           0          0
    #5         1           0          0
    
    from sklearn.preprocessing import OneHotEncoder, LabelEncoder
    def f1(DF_data):
        Enc_ohe, Enc_label = OneHotEncoder(), LabelEncoder()
        DF_data["Dummies"] = Enc_label.fit_transform(DF_data["target"])
        DF_dummies2 = pd.DataFrame(Enc_ohe.fit_transform(DF_data[["Dummies"]]).todense(), columns = Enc_label.classes_)
        return(DF_dummies2)
    
    %timeit pd.get_dummies(DF_data["target"])
    #1000 loops, best of 3: 777 µs per loop
    
    %timeit f1(DF_data)
    #100 loops, best of 3: 2.91 ms per loop

     

    注:get_dummies返回的为数据框,OneHotEncoder返回的为数组。

    >>> from sklearn.preprocessing import OneHotEncoder
    >>> enc = OneHotEncoder()
    
    >>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
    
    >>> enc.n_values_
    array([2, 3, 4])
    
    >>> enc.feature_indices_
    array([0, 2, 5, 9])
    
    >>> enc.transform([[0, 1, 1]]).toarray()
    array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])

     

     One-Hot 编码即独热编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。这样做的好处主要有:1. 解决了分类器不好处理属性数据的问题; 2. 在一定程度上也起到了扩充特征的作用。

           将离散型特征进行one-hot编码的作用,是为了让距离计算更合理,但如果特征是离散的,并且不用one-hot编码就可以很合理的计算出距离,那么就没必要进行one-hot编码。离散特征进行one-hot编码,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1。

            基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等。基于参数的模型或基于距离的模型,都是要进行特征的归一化。Tree Model不太需要one-hot编码: 对于决策树来说,one-hot的本质是增加树的深度。

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

    # 简单来说 LabelEncoder 是对不连续的数字或者文本进行编号
    # sklearn.preprocessing.LabelEncoder():标准化标签,将标签值统一转换成range(标签值个数-1)范围内
    
    from sklearn.preprocessing import LabelEncoder
    le = LabelEncoder()
    le.fit([1,5,67,100])
    le.transform([1,1,100,67,5])
    out: array([0, 0, 3, 2, 1], dtype=int64)
    
    #OneHotEncoder 用于将表示分类的数据扩维:
    from sklearn.preprocessing import OneHotEncode
    ohe = OneHotEncoder()
    ohe.fit([[1],[2],[3],[4]])
    ohe.transform([[2],[3],[1],[4]]).toarray()
    out:array([[ 0.,  1.,  0.,  0.],
           [ 0.,  0.,  1.,  0.],
           [ 1.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  1.]])

     

     Examples
        --------
        Given a dataset with three features and four samples, we let the encoder
        find the maximum value per feature and transform the data to a binary
        one-hot encoding.
    
        >>> from sklearn.preprocessing import OneHotEncoder
        >>> enc = OneHotEncoder()
        >>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], \
    [1, 0, 2]])  # doctest: +ELLIPSIS
        OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
               handle_unknown='error', n_values='auto', sparse=True)
        >>> enc.n_values_
        array([2, 3, 4])
        >>> enc.feature_indices_
        array([0, 2, 5, 9])
        >>> enc.transform([[0, 1, 1]]).toarray()
        array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])

     

     Examples
        --------
        `LabelEncoder` can be used to normalize labels.
    
        >>> from sklearn import preprocessing
        >>> le = preprocessing.LabelEncoder()
        >>> le.fit([1, 2, 2, 6])
        LabelEncoder()
        >>> le.classes_
        array([1, 2, 6])
        >>> le.transform([1, 1, 2, 6]) #doctest: +ELLIPSIS
        array([0, 0, 1, 2]...)
        >>> le.inverse_transform([0, 0, 1, 2])
        array([1, 1, 2, 6])
    
        It can also be used to transform non-numerical labels (as long as they are
        hashable and comparable) to numerical labels.
    
        >>> le = preprocessing.LabelEncoder()
        >>> le.fit(["paris", "paris", "tokyo", "amsterdam"])
        LabelEncoder()
        >>> list(le.classes_)
        ['amsterdam', 'paris', 'tokyo']
        >>> le.transform(["tokyo", "tokyo", "paris"]) #doctest: +ELLIPSIS
        array([2, 2, 1]...)
        >>> list(le.inverse_transform([2, 2, 1]))
        ['tokyo', 'tokyo', 'paris']

     

    八、pandas的get_dummies

    pd.get_dummies(prefix=)

    pandas的get_dummies()可以直接对变量进行one-hot编码,其中prefix是为one-hot编码后的变量进行命名。

    get_dummies()也可以对某一列数据进行。

    DF_dummies = pd.get_dummies(DF_data["target"])
    #setosa  versicolor  virginica
    #0         1           0          0
    #1         1           0          0
    #2         1           0          0
    #3         1           0          0
    #4         1           0          0
    #5         1           0          0

    相关参考:

    https://www.cnblogs.com/king-lps/p/7846414.html

    https://blog.csdn.net/Mr_HHH/article/details/80006971

    展开全文
  • 什么是整数编码和One-Hot编码,以及为什么它们在机器学习中是必需的。 · 2.如何在Python中手工计算一个整数编码和One-Hot编码。 · 3.如何使用scikit-learn和Keras库来自动对Python中的序列数据进行编码。 本...

    机器学习算法无法直接用于数据分类。数据分类必须转换为数字才能进一步进行。

    在本教程中,你将发现如何将输入或输出的序列数据转换为一种热编码,以便于你在Python中深度学习的序列分类问题中使用。

    看完本教程后,你将会了解:

    ·   1.什么是整数编码和One-Hot编码,以及为什么它们在机器学习中是必需的。

    ·   2.如何在Python中手工计算一个整数编码和One-Hot编码。

    ·   3.如何使用scikit-learn和Keras库来自动对Python中的序列数据进行编码。

    本教程分为4部分:

    1.什么是One-Hot编码?

    2.手动编写One-Hot编码

    3.One-Hot Encode with scikit-learn.

    4.One-Hot Encode with Keras.

    1.什么是One-Hot编码?

    One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。

    One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。然后,每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,它被标记为1。

    2.One-Hot编码的工作示例

    让我们用一个小例子来说明一下到底什么是One-Hot编码。假设我们有一个带有'red'和'green'值的标签序列。我们可以将'red'的整数值分配为0,'green'的整数值为1。只要我们总是将这些数字分配给这些标签,这称为整数编码。一致性是重要的,所以我们可以稍后反转编码,并从整数值获取标签。

    接下来,我们可以创建一个二进制向量来表示每个整数值。对于2个可能的整数值,向量的长度为2。

    编码为0的“红色”标签将用二进制向量[1,0]表示,其中第0个索引被标记为值1。然后,编码为1的“绿色”标签将用一个二进制向量[0,1],其中第一个索引被标记为1。

    如果我们有序列:

    ‘red’,‘red’,‘green’。

    我们可以用整数编码来表示它:

    0,0,1

    而One-Hot编码就为:

    1

    2

    3

    [1, 0]

    [1, 0]

    [0, 1]

    1.为什么要使用One-Hot编码?

    One hot 编码进行数据的分类更准确,许多机器学习算法无法直接用于数据分类。数据的类别必须转换成数字,对于分类的输入和输出变量都是一样的。

    我们可以直接使用整数编码,需要时重新调整。这可能适用于在类别之间存在自然关系的问题,例如温度“冷”(0)和”热“(1)的标签。

    当没有关系时,可能会出现问题,一个例子可能是标签的“狗”和“猫”。

    在这些情况下,我们想让网络更具表现力,为每个可能的标签值提供概率式数字。这有助于进行问题网络建模。当输出变量使用one-hot编码时,它可以提供比单个标签更准确的一组预测。

    2.手动One Hot编码:

    在这个例子中,我们将假设我们有一个字符串的例子,但是示例序列并不涵盖所有可能的例子。

    我们将使用以下字符的输入序列:

    Hello world。

    我们将假设所有可能输入是小写字母和空格的完整字母表。因此,我们将以此展示如何滚动我们自己的one hot编码。

    完整的示例如下所示。

    from numpy import argmax
    # define input string
    data = 'hello world'
    print(data)
    # define universe of possible input values
    alphabet = 'abcdefghijklmnopqrstuvwxyz '
    # define a mapping of chars to integers
    char_to_int = dict((c, i) for i, c in enumerate(alphabet))
    int_to_char = dict((i, c) for i, c in enumerate(alphabet))
    # integer encode input data
    integer_encoded = [char_to_int[char] for char in data]
    print(integer_encoded)
    # one hot encode
    onehot_encoded = list()
    for value in integer_encoded:
           letter = [0 for _ in range(len(alphabet))]
           letter[value] = 1
           onehot_encoded.append(letter)
    print(onehot_encoded)
    # invert encoding
    inverted = int_to_char[argmax(onehot_encoded[0])]
    print(inverted)

     

    运行示例首先打印输入字符串。

    所有可能的输入的映射都是从char值创建为整数值。然后使用该映射对输入字符串进行编码。我们可以看到输入'h'中的第一个字母被编码为7。然后将整数编码转换为one hot编码。一次完成一个整数编码的字符。创建0个值的列表,以便字母表的长度可以表示任何预期的字符的长度。

    接下来,特定字符的索引标记为1。我们可以看到,编码为7的第一个字母“h”整数由二进制向量表示,长度为27,第七个索引标记为1。

    最后,我们反转第一个字母的编码并打印结果。我们通过使用NumPy argmax()函数定位具有最大值的二进制向量中的索引,然后使用字符值的反向查找表中的整数进行整数。

    注意:输出格式化为可读性(我们将空格默认设置为z)。

     

     hello world

     [7, 4, 11, 11, 14, 26, 22, 14, 17, 11, 3]

     [[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

     [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

      h

    现在我们已经看到了如何从头开始自己的one hot编码,我们来看看如何使用scikit学习库来对输入序列自动完全捕获输入值的预期范围的情况。

    3.One-Hot Encode with scikit-learn:

    在这个例子中,我们假设你有一个输出序列如下3个标签:

    Cold,warm,hot

    10个时间序列的示例顺序可以是:

    Cold,cold,warm,cold,hot,hot,warm,cold,warm,hot

    这将首先需要一个整数编码,如1,2,3,然后是整数到one hot编码具有3个值的二进制向量,例如[1,0,0]。

    这个情况下提供序列中每个可能值的至少一个示例。因此,我们可以使用自动方法来定义整数到二进制向量的映射。

    在这个例子中,我们将使用scikit学习库的编码器。具体来说,LabelEncoder创建标签的整数编码,OneHotEncoder用于创建整数编码值的one hot编码。

    
     
    from numpy import array
    from numpy import argmax
    from sklearn.preprocessing import LabelEncoder
    from sklearn.preprocessing import OneHotEncoder
    # define example
    data = ['cold', 'cold', 'warm', 'cold', 'hot', 'hot', 'warm', 'cold', 'warm', 'hot']
    values = array(data)
    print(values)
    # integer encode
    label_encoder = LabelEncoder()
    integer_encoded = label_encoder.fit_transform(values)
    print(integer_encoded)
    # binary encode
    onehot_encoder = OneHotEncoder(sparse=False)
    integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
    onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
    print(onehot_encoded)
    # invert first example
    inverted = label_encoder.inverse_transform([argmax(onehot_encoded[0, :])])
    print(inverted)

     

     

     

     

     

     

    运行示例首先打印标签序列。之后是标签的整数编码,最后是one hot编码。训练数据包含所有可能示例的集合,因此我们可以依靠整数和one hot编码变换来创建标签到编码的完整映射。

    默认情况下,OneHotEncoder类将返回更高效的稀疏编码,这可能不适用于某些应用程序。例如使用Keras深度学习库。在这种情况下,我们通过设置sparse = False这个参数来禁用稀疏返回类型。

    首先,我们可以使用argmax()NumPy函数来找到具有最大值的列的索引。然后可以将其输入到LabelEncoder,以计算反向变换回文本标签。运行结果为:

     

    ['cold' 'cold' 'warm' 'cold' 'hot' 'hot' 'warm' 'cold' 'warm' 'hot'] 

    [0 0 2 0 1 1 2 0 2 1]

    [[ 1.  0.  0.]

     [ 1.  0.  0.]

     [ 0.  0.  1.]

     [ 1.  0.  0.]

     [ 0.  1.  0.]

     [ 0.  1.  0.]

     [ 0.  0.  1.]

     [ 1.  0.  0.]

     [ 0.  0.  1.]

     [ 0.  1.  0.]] 

    ['cold']

    在下一个例子中,我们来看一下如何直接对一个整数值进行one hot编码。

    4.One Hot Encode with Keras:

    您可能有一个已经是整数编码的序列。

    经过处理后,您可以直接使用整数。或者,您可以直接对整数进行one hot 编码。这是非常重要的如果整数没有真正的顺序关系并且只是标签的占位符。

    Keras提供了一个名为to_categorical()的函数,它可以帮助你使用one hot编码整数数据。接下来我们看一个小例子:

    在这个例子中,我们有4个整数值[0,1,2,3],我们有以下10个数字的输入序列:

    Data = [1,3,2,0,3,2,2,1,0,1]

    该序列具有已知了所有值,因此我们可以直接使用to_categorical()函数。以下列出了此功能的完整示例。

    from numpy import array
    from numpy import argmax
    from keras.utils import to_categorical
    # define example
    data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1]
    data = array(data)
    print(data)
    # one hot encode
    encoded = to_categorical(data)
    print(encoded)
    # invert encoding
    inverted = argmax(encoded[0])
    print(inverted)

     

     

     

    运行示例并打印输入序列。

    然后将整数编码为二进制向量并打印。我们可以看到,正如我们预期的那样,第一个整数值1被编码为[0,1,0,0]。

    然后,我们使用NumPy argmax()函数反转编码,该函数返回第一个整数的期望值1的序列中的第一个值。

     

    [1 3 2 0 3 2 2 1 0 1]

    [[ 0.  1.  0.  0.]

     [ 0.  0.  0.  1.]

     [ 0.  0.  1.  0.]

     [ 1.  0.  0.  0.]

     [ 0.  0.  0.  1.]

     [ 0.  0.  1.  0.]

     [ 0.  0.  1.  0.]

     [ 0.  1.  0.  0.]

     [ 1.  0.  0.  0.]

     [ 0.  1.  0.  0.]

    1

    展开全文
  • 数据科学家Rakshith Vasudev简要解释了one hot编码这一机器学习中极为常见的技术。 你可能在有关机器学习的很多文档、文章、论文中接触到“one hot编码”这一术语。本文将科普这一概念,介绍one hot编码到底是...
  • 文章目录一、 Index编码二、 OneHot编码独热编码优缺点什么情况下(不)用独热编码什么情况下(不)需要归一化?三、 Multiple编码如何使用Multiple编码呢?四、 编码比较参考文献 一、 Index编码 用来对离散的类型...
  • 一、为什么要独热编码? 独热编码(是因为大部分算法是基于向量空间的度量来进行计算的,为了使非偏序关系的变量取值不具有偏序性,并且到原点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散...
  • 1. 为什么使用 one-hot 编码? 问题: 在机器学习算法,我们经常会遇到分类特征,例如:人的性别有男女,祖国有中国,美国,法国等。 这些特征值并不是连续的,而是离散的,无序的。 目的: 如果要作为...
  • 1. 为什么使用 one-hot 编码?   问题: 在机器学习算法,我们经常会遇到分类特征,例如:人的性别有男女,祖国有中国,美国,法国等。 这些特征值并不是连续的,而是离散的,无序的。   目的:   ...
  • 为什么要使用独热编码

    千次阅读 2019-08-13 17:13:58
    在很多机器学习任务如ctr预估任务,特征不全是连续值,而有可能是分类值。如下: 分类变量(定量特征)与连续变量(定性特征)。我们训练模型的变量,一般分为两种形式。以广告收入增长率例,如果取值0-1之间...
  • 使用one-hot编码,可以使得离散特征变量扩展到欧式空间,有助于特征空间中的距离计算,而在机器学习,深度学习中,在欧式空间中的距离、相似度的计算是非常重要、常见的。 但如果特征是离散的,并且不用one-hot编码...
  • 1、为什么要独热编码 因为大部分算法是基于向量空间的度量来进行计算的,为了使非偏序关系的变量取值不具有偏序性,并且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值...
  • 在很多机器学习任务如ctr预估任务,特征不全是连续值,而有可能是分类值。如下:  分类变量(定性特征)与连续变量(定量特征)。我们训练模型的变量,一般分为两种形式。以广告收入增长率例,如果取值0-1...
  • 热编码与标签编码

    千次阅读 2018-03-18 14:36:12
    最近在看机器学习,遇到了两种编码形式,OneHotEncoder(独热编码)和LabelEncoder(标签编码),感觉既然都是为了给离散型变量编码,为什么要有两种,既然有两种,那平时该用哪一种。先说结论:OneHotEncoder更常用...
  • OneHotEncoder独热编码和 LabelEncoder标签编码 ...首先了解机器学习中的特征类别:连续型特征和离散型特征 拿到获取的原始特征,必须对每一特征分别进行归一化,比如,特征A的取值范围是[-1000,1000],特...
  • OneHotEncoder独热编码和LabelEncoder标签编码

    千次阅读 多人点赞 2018-09-22 14:51:20
    首先了解机器学习中的特征类别:连续型特征和离散型特征。 拿到获取的原始特征,必须对每一特征分别进行归一化,比如,特征A的取值范围是[-1000,1000],特征B的取值范围是[-1,1].如果使用log...
  • 最近学习Kaggle,对于数据清洗过程中,category类型数据数值化的问题,OneHotEncoder独热编码和 LabelEncoder标签编码区别和用法不清晰,看到一篇文章,写的...首先了解机器学习中的特征类别:连续型特征和离散型...
  • 目录 一OneHotEncoder独热编码 1.1 OneHotEncoder独热编码原理 2.1. 为什么要独热编码OneHotEncoder? 2.3 独热编码优缺点 2.4什么情况下(不)用独热编码? 2.5 什么情况下(不)需要归一...首先了解机器学习中...
  • OneHotEncoder独热编码 问题:学习sklearn和kagggle时遇到的问题,什么是独热编码为什么要用独热编码?什么情况下可以用独热编码?...首先了解机器学习中的特征类别:连续型特征和离散型特征。...
  •  首先了解机器学习中的特征类别:连续型特征和离散型特征。 拿到获取的原始特征,必须对每一特征分别进行归一化,比如,特征A的取值范围是[-1000,1000],特征B的取值范围是[-1,1].如果使用logistic回归,w1*x1+w2*...
  • 2.将离散特征通过one-hot编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
关键字:

机器学习中为什么热编码