機器學習-特徵工程-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)

相關文章
相關標籤/搜索