机器学习-特征工程-Missing value和Category encoding

好了,你们如今进入到机器学习中的一块核心部分了,那就是特征工程,洋文叫作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。那下面就这三种方法分别来进行代码的演示和结果的展现api

  1. 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。机器学习

  2. 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。学习

  3. 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。spa

  • Categorical Data encoding

上面一节主要讲的是Missing value的一些简单的处理方式,在实际的数据处理中,我们大部分时间遇到的数据并非numerical data,相反,我们大部分时间遇到的都是categorical data,但是在我们的计算机处理数据的时候,处理的都是numerical data,因此我们得想办法将这些categorical data转成numerical才行。实际中我们常用的策略就是下面的五种方式,下面我们来一个个讲解一下,这一块也是我们的重点内容。翻译

  1. 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的数据。设计

  2. 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。code

  3.  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的代码实现吧orm

    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的状况。对象

  4. 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。

  5. 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

      2. Imputation

      3. Extension to Imputation

而后category data的处理主要是下面的5中方式,这里你们必定要理解

      1. Dropping

      2. Label encoding

      3. one hot encoding (最经常使用)

      4. Count encoding

      5. Target encoding (risk of data leakage)

相关文章
相关标签/搜索