机器学习首先需要进行数据处理,特征通常不是连续的而是离散的。例如,人类可以有如下离散的属性[‘male’, ‘female’],["from Europe", "from US", "from Asia"], ["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"],这些特征需要被编码为整数类型,从而方便算法处理。
OrdinalEncoder是一个类(class),功能是将分类特征编码为整数数组。它的输入应该是整数或字符串的类数组,也可以理解为矩阵,每一列表示一个特征,每一个特征中的数字或者是字符串表示一类特征,也就是分类(离散)特征所接受的值。特征按顺序转换为有序整数。结果就是每个特征对应一个整数列,取值范围0到n_categories - 1。
例如输入X = [['Male', 1], ['Female', 3], ['Female', 2]],这里输入数据中含有两列,说明有两类特征,第一列取值范围为:[ 'Female','Male'],按照顺序编码为[0,1],第二列取值范围为:[1,2,3],编码结果为[0,1,2]。按照这个思路,['Female', 3], ['Male', 1]的顺序编码分别为[0,2]和[1,0]。scikit-learn中可以使用如下代码:
>>> from sklearn.preprocessing import OrdinalEncoder
>>> enc = OrdinalEncoder()
>>> X = [['Male', 1], ['Female', 3], ['Female', 2]]
>>> enc.fit(X)
OrdinalEncoder()
>>> enc.categories_ # 查看从输入的数据中自动获取的属性
[array(['Female', 'Male'], dtype=object),
array([1, 2, 3], dtype=object)]
>>> enc.transform([['Female', 3], ['Male', 1]])
array([[0., 2.],
[1., 0.]])
还有如下示例:
>>> enc = OrdinalEncoder()
>>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
>>> enc.fit(X)
OrdinalEncoder()
>>> enc.categories_
[array(['female', 'male'], dtype=object),
array(['from Europe', 'from US'], dtype=object),
array(['uses Firefox', 'uses Safari'], dtype=object)]
>>> enc.transform([['female', 'from US', 'uses Safari']])
array([[0., 1., 1.]])
顺序编码的整数表示不能直接用于所有的scikit-learn估计器,因为这些估计器(estimators)会认为输入的整数是有顺序含义的,自动将这个类别解释为有顺序,然而大多数整数数据中,数字的大小都是没有顺序含义的,例如1仅仅表类别1,2仅仅表示类别2。一种可用的、将分类特征转换为可以和scikit-learn估计器一起使用的特征的编码方法称为one-hot编码也叫dummy编码。通俗点说,就是一位有效编码,下面通俗地解释一下这种编码的思路。
Dummy一词意为仿照,说的是one-hot编码仿照芯片中状态寄存器的工作原理来进行编码。将某类特征可能出现的N种特征值看做状态寄存器中可能出现的N种状态,每次只可能有一种状态有效,而其余状态无效。举个简单的例子,对于性别特征:[‘男’,‘女’],有2个值,所以N=2,当性别为男时,编码为[1,0],当性别为女时,编码为[0,1],一个简单代码示例如下:
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
>>> enc.fit(X)
OneHotEncoder()
>>> enc.transform([['female', 'from US', 'uses Safari'],
... ['male', 'from Europe', 'uses Safari']]).toarray()
array([[1., 0., 0., 1., 0., 1.],
[0., 1., 1., 0., 0., 1.]])