好了, 大家现在进入到机器学习中的一块核心部分了, 那就是特征工程, 洋文叫做 Feature Engineering. 实际在机器学习的应用中, 真正用于算法的结构分析和部署的工作只占很少的一部分, 相反, 用于特征工程的时间基本都占 70% 以上, 因为是实际的工作中, 绝大部分的数据都是非标数据. 因而这一块的内容是非常重要和必要的, 如果想要提高机器学习应用开发的效率, feature engineering 就像一把钥匙, 一个加速器, 能给整个项目带来事半功倍的效果. 另外, feature engineering 做的好不好, 直接关系到后面的模型的质量. 正因为上面的原因, feature engineering 我准备详细的解释, 我准备花三篇随笔说完. 这是第一篇, 主要介绍两部分, 分别是 missing value 的处理和 categorical data 的处理. 其中 missing value 的处理相对简单, 复杂的是 categorical data 的处理, 有很多种处理方式, 我们在这边就直说常用的 5 中方式. 那么好啦, 咱们就直接进入主题内容吧.
Missing value
missing value 顾名思义就是有些实际数据中, 有很多的数值是缺失的, 那么怎么处理这些缺失的数据, 就变成了一个很有必要的事情. 基本上, 咱们处理 missing value 的方法就是三种, 分别是: dropping, Imputation, 和 An extension to imputation. 那下面就这三种方法分别来进行代码的演示和结果的展示
Dropping. 顾名思义, dropping 的意思就是整个删除掉一整行的数据. 这里的意思就是, 如果某一列数据含有空数据 NaN, 那么就直接删除掉这一整行的数据, 它的操作如下所示
- missing_data_cols = [col for col in train_X.columns if train_X[col].isna().any()]
- #drop missing data columns
- reduced_train_X = train_X.drop(missing_data_cols, axis =1)
上面代码的第一句是为了找出所有含有空数据的 column, 第二句代码的意思就是删除掉这些含有空数据的 column, 记住 axis 参数设置成 1 代表着是 column, 如果设置成 0 或者没有设置, 则默认指删除行 row.
Imputation. 这里对于处理 missing value 的第二种方法是指的填充的方法 (不知道翻译的对不对哈), 它是什么意思呢, 其实很简单, 它的意思就是将这个空值的 element, 根据一定的条件填充数据, 这里的条件可以是平均值, 中位数, 出现频率最高的等, 具体采用哪种方式, 还是按照里面的参数 strategy 进行设置的. 具体的代码实现方式, 是通过下面来演示
- from sklearn.impute import SimpleImputer
- my_imputer = SimpleImputer(strategy = "mean")
- my_imputer.fit_transform(train_X)
- imputed_train_X = pd.DataFrame(my_imputer.fit_transform(train_X))
注意这里需要引进一个新的库进行数据处理, 那就是 sklearn, 它是 sci-kit learn 的缩写. 这个库也是一个很牛逼的库, 它和 TensorFlow 的功能一样, 提供了丰富的数据处理方面的接口, 可以极大的方便咱们的数据处理, 也提供了很多常用的模型供咱们选择, 在机器学习领域可以说是经常用到的. 上面第二行代码就是设置通过什么方式来 impute, 这里设置的是平均数. 第三行返回的是一个 numpy array, 第四行咱们将这个 impute 过后的 numpy array 转化成 dataframe.
An Extension to Imputation. 从这个命名咱们可以看出它是对上面 imputation 的一种补充, 是基于 imputation 的. 它实际上是先添加几个 column(有哪些 column 有 missing value, 咱们就添加几个 column), 这些添加的 column 是 boolean 值, 如果某一行对应是 missing value, 这个 Boolean 值就是 True, 如果不是 missing value, 则是 False. 咱们看看下面的代码和图片能够更加深刻的理解.
- X_train_extension = train_X.copy()
- X_val_extension = val_X.copy()
- #making columns with missing data
- for col in missing_data_cols:
- X_train_extension[col + "_was_missing"] = train_X[col].isnull()
- #imputation
- my_imputer = SimpleImputer()
- X_train_extension_impute = pd.DataFrame(my_imputer.fit_transform(X_train_extension))
上面展示了代码还有一小段结果的截图. 大家可以很明显的看出来添加了三个新的 columns. 这里的顺序根据代码也可以看出来, 是先添加新的 columns, 然后再 imputation.
Categorical Data encoding
上面一节主要讲的是 Missing value 的一些简单的处理方式, 在实际的数据处理中, 咱们大部分时间遇到的数据并不是 numerical data, 相反, 咱们大部分时间遇到的都是 categorical data, 可是在咱们的计算机处理数据的时候, 处理的都是 numerical data, 所以咱们得想办法将这些 categorical data 转成 numerical 才行. 实际中咱们经常使用的策略就是下面的五种方式, 下面咱们来一个个讲解一下, 这一块也是咱们的重点内容.
dropping. 和前面的 missing data 一样, 直接 dropping 是最简单粗暴的方法, 虽然这是最简单的方法, 但是实际中, 这种方式却并不常用, 因为她往往不利于咱们的模型. 极端的想一下, 如果咱们的 dataframe 都是 categorical 的数据, 难道咱们直接把他们全部删除????? 哈哈, 那咱们还训练个毛模型. 但是, 咱们还是得了解一下, 毕竟在极少数的情况下, 咱们还是要用到的. 咱们直接看代码演示, 然后解释一下
X_train_result_drop = X_train_result.select_dtypes(exclude=["object"])
看看上面这一句简单的代码, 通过 dataframe 的 select_dtypes 方法, 传递一个 exclude 参数, 因为在 dataframe 中 object 的数据类型就是 categorical data, 所以上面的 API 直接就是删除了所有 categorical data 的数据.
Label encoding. 对于有些 categorical data, 咱们可以给每一个 category 赋值一个数字, 例如 Female=0,Male = 1 等等. 那么哪些 categorical data 适合 label encoding 呢? 就是那些一列数据中 category 的种类不是特别多的数据. 例如一列 categorical data 一共有 20 个 category 或者 50 个 category 都是 OK 的, 如果直接有 1000 多 category, 那么简单的 labeling 的效率就不高了, 结果也可能不理想. 这其实在实际的处理中还是经常会用到的. 下面通过一句简单的代码进行演示. 注意, 这里都是用 sklearn 这个组件来进行的演示的, 并没有用其他的例如 TensorFlow 来演示.
- from sklearn.preprocessing import LabelEncoder
- label_encoder = LabelEncoder()
- X_train_result_label[col] = label_encoder.fit_transform(X_train_result[col])#one column after one column
咱们也可以看出, 咱们得先创建一个 LabelEncoder 实例对象, 然后对每一个 categorical data 的 column 分别应用 encoder, 如果需要对多个 categorical column 进行 lable encoding, 咱们得写一个循环, 分别对每一个 column 进行 label encoding.
one-hot encoding. 这是一个大家可能最常用到的一种 category encoding 的方法, 至少在我学习机器学习的过程中, 这是最常见到的一种方式, 那么到底什么是 one-hot encoding 呢? 这里没有一个官方的定义, 最直接的方法就是先看一下下面的图片, 这是最直接的方式, 也最简单易懂
现在咱们来解释一下, 首先先计算出一个 category column 中一共有多少个 categories, 然后有多少 category 就创建多少个 columns, 每一个 category 对应一个 column, 最后在相对应的位置填充 1, 其他则填充 0. 故而新创建的 dataframe 中, 每一行只有一个 1 其他都是 0. 这也是 one-hot encoding 这个名字的来历. 那咱们来看看 one hot encoding 的代码实现吧
- from sklearn.preprocessing import OneHotEncoder
- one_hot_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
- X_train_result_one_hot = pd.DataFrame(one_hot_encoder.fit_transform(X_train_result[object_cols]))
和之前的 label encoding 一样, 它也需要引用 sklearn 这个库, 但是它是先实例化一个 OneHotEncoder 对象, 然后用这个 encoder 一次性的应用于多个 categorical columns, 而不像 label encoding 那样要一个 column 一个 column 的调用. one hot encoding 是 categorical data encoding 中最常用的技术了, 但是在有些情况下也不是很适用, 例如: 如果一个 categorical column 的 categories 太多的话, 例如 1000 个, 10000 个等等, 那么它就不适用于 one hot encoding 了, 因为有 1000 个 categories, 就会产生 1000 个 columns, 产生的数据就太大了, 而且很容易会产生 overfitting 的情况.
Count encoding
这也是一种简单而且高效的 encoding 方法, 它是先计算一个 categorical column 中的每一个 category 出现的次数, 然后就将这些 category 用次数来代替, 同一个 category 被代替后, 数值是一样的, 有点和 series.values_countt() 有点类似, 大家满满体会一下哈. 这种方式和 label encoding 一样的简单, 而且 Python 也帮助咱们处理好了细节部分, 咱们可以通过下面的方式直接调用它的接口进行计算
- import category_encoders as ce
- count_encoder = ce.CountEncoder()
- categorical_data_ce = count_encoder.fit_transform(ks[categorical_cols])
从上面的代码, 咱们可以看出来, 它也是 encoder 直接作用于多个 categorical columns.
Target encoding Target encoding 是根据 target 来计算 category 的, 然后来替代的. 那么它的具体流程是什么呢? 其实呢它是很简单的, 就是先看每一个 category 对应的 target 值, 然后计算相对应的 target 的平均数, 最后用这个平均数来代替每一个 category. 其实就是这么的 so easy. 老规矩, 咱们先看看如何实现的
- import category_encoders as ce
- target_encoder = ce.TargetEncoder(cols=categorical_cols)
- target_encoder.fit_transform(train[categorical_cols], train.outcome)
从上面咱们可以看出, 整体的步骤和 count encoding 很相似. 但是这种方法也有一个致命的弱点, 那就是这里的 encoding 太过于依赖 target 了, 有很大的可能会有 data leakage 的风险, target encoding 与 target 有很强的 correlation, 就有很强的 data leakage 的风险. 所以大家在选择 target encoding 的时候一定要仔细考虑分析数据后在选择.
总结: 最后国际惯例咱们先来总结一下 feature engineering 的第一部分, 就是 category data 和 missing value 的处理. 上面的一些方法是最简单常用的一些方法了, 大家一定要熟悉理解应用, 这里也设计到一些库的使用, 我会在后面详细叫大家怎么用. missing value 常用的处理方式是: 1. dropping
- Imputation
- Extension to Imputation
然后 category data 的处理主要是下面的 5 中方式, 这里大家一定要理解
- Dropping
- Label encoding
- one hot encoding (最常用)
- Count encoding
- Target encoding (risk of data leakage)
来源: https://www.cnblogs.com/tangxiaobo199181/p/12203808.html