特徵工程之特徵表達

2021-08-30 15:53:24 字數 2987 閱讀 8433

在特徵工程之特徵選擇中,我們講到了特徵選擇的一些要點。本篇我們繼續討論特徵工程,不過會重點關注於特徵表達部分,即如果對某乙個特徵的具體表現形式做處理。主要包括缺失值處理,特殊的特徵處理比如時間和地理位置處理,離散特徵的連續化和離散化處理,連續特徵的離散化處理幾個方面。

特徵有缺失值是非常常見的,大部分機器學習模型在擬合前需要所有的特徵都有值,不能是空或者null。那麼如果有缺失值我們需要怎麼處理呢?

首先我們會看是該特徵是連續值還是離散值。如果是連續值,那麼一般有兩種選擇,一是選擇所有有該特徵值的樣本,然後取平均值,來填充缺失值,另一種是取中位數來填充缺失值。如果是離散值,則一般會選擇所有有該特徵值的樣本中最頻繁出現的類別值,來填充缺失值。在sklearn中,可以使用preprocessing.imputer來選擇這三種不同的處理邏輯做預處理。

有些特徵的預設取值比較特殊,一般需要做了處理後才能用於演算法。比如日期時間,比如顯示20180519,這樣的值一般沒辦法直接使用。那麼一般需要如何變換呢?

對於時間原始特徵,處理方法有很多,這裡只舉例幾種有代表性的方法。第一種是使用連續的時間差值法,即計算出所有樣本的時間到某乙個未來時間之間的數值差距,這樣這個差距是utc的時間差,從而將時間特徵轉化為連續值。第二種方法是根據時間所在的年,月,日,星期幾,小時數,將乙個時間特徵轉化為若干個離散特徵,這種方法在分析具有明顯時間趨勢的問題比較好用。第三種是權重法,即根據時間的新舊得到乙個權重值。比如對於商品,三個月前購買的設定乙個較低的權重,最近三天購買的設定乙個中等的權重,在三個月內但是三天前的設定乙個較大的權重。當然,還有其他的設定權重的方法,這個要根據要解決的問題來靈活確定。

對地理特徵,比如「廣州市天河區xx街道xx號」,這樣的特徵我們應該如何使用呢?處理成離散值和連續值都是可以的。如果是處理成離散值,則需要轉化為多個離散特徵,比如城市名特徵,區縣特徵,街道特徵等。但是如果我們需要判斷使用者分布區域,則一般處理成連續值會比較好,這時可以將位址處理成經度和緯度的連續特徵。

有很多機器學習演算法只能處理連續值特徵,不能處理離散值特徵,比如線性回歸,邏輯回歸等。那麼想使用邏輯回歸,線性回歸時這些值只能丟棄嗎?當然不是。我們可以將離散特徵連續化處理。

最常見的離散特徵連續化的處理方法是獨熱編碼one-hot encoding。處理方法其實比較簡單,比如某特徵的取值是高,中和低,那麼我們就可以建立三個取值為0或者1的特徵,將高編碼為1,0,0這樣三個特徵,中編碼為0,1,0這樣三個特徵,低編碼為0,0,1這樣三個特徵。也就是說,之前的乙個特徵被我們轉化為了三個特徵。sklearn的onehotencoder可以幫我們做這個處理。

第二個方法是特徵嵌入embedding。這個一般用於深度學習中。比如對於使用者的id這個特徵,如果要使用獨熱編碼,則維度會**,如果使用特徵嵌入就維度低很多了。對於每個要嵌入的特徵,我們會有乙個特徵嵌入矩陣,這個矩陣的行很大,對應我們該特徵的數目。比如使用者id,如果有100萬個,那麼嵌入的特徵矩陣的行就是100萬。但是列一般比較小,比如可以取20。這樣每個使用者id就轉化為了乙個20維的特徵向量。進而參與深度學習模型。在tensorflow中,我們可以先隨機初始化乙個特徵嵌入矩陣,對於每個使用者,可以用tf.nn.embedding_lookup找到該使用者的特徵嵌入向量。特徵嵌入矩陣會在反向傳播的迭代中優化。

此外,在自然語言處理中,我們也可以用word2vec將詞轉化為詞向量,進而可以進行一些連續值的後繼處理。

離散特徵有時間也不能直接使用,需要先進行轉化。比如最常見的,如果特徵的取值是高,中和低,那麼就算你需要的是離散值,也是沒法直接使用的。

對於原始的離散值特徵,最常用的方法也是獨熱編碼,方法在第三節已經講到。

第二種方法是虛擬編碼dummy coding,它和獨熱編碼類似,但是它的特點是,如果我們的特徵有n個取值,它只需要n-1個新的0,1特徵來代替,而獨熱編碼會用n個新特徵代替。比如乙個特徵的取值是高,中和低,那麼我們只需要兩位編碼,比如只編碼中和低,如果是1,0則是中,0,1則是低。0,0則是高了。目前虛擬編碼使用的沒有獨熱編碼廣,因此一般有需要的話還是使用獨熱編碼比較好。

此外,有時候我們可以對特徵進行研究後做乙個更好的處理。比如,我們研究商品的銷量對應的特徵。裡面有乙個原始特徵是季節春夏秋冬。我們可以將其轉化為淡季和旺季這樣的二值特徵,方便建模。當然有時候轉化為三值特徵或者四值特徵也是可以的。

對於分類問題的特徵輸出,我們一般需要用sklearn的labelencoder將其轉化為0,1,2,...這樣的類別標籤值。

對於連續特徵,有時候我們也可以將其做離散化處理。這樣特徵變得高維稀疏,方便一些演算法的處理。

對常用的方法是根據閾值進行分組,比如我們根據連續值特徵的分位數,將該特徵分為高,中和低三個特徵。將分位數從0-0.3的設定為低,0.3-0.7的設定為中,0.7-1的設定為高。

具體的乙個示例**如下:

from sklearn.datasets import make_classification

from sklearn.model_selection import train_test_split

from sklearn.ensemble import gradientboostingclassifier

from sklearn.preprocessing import onehotencoder

x, y = make_classification(n_samples=10)

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.5)

gbc = gradientboostingclassifier(n_estimators=2)

one_hot = onehotencoder()

gbc.fit(x_train, y_train)

print (x_train_new.todense())

[[ 0.  1.  0.  1.]

[ 1.  0.  1.  0.]

[ 1.  0.  1.  0.]

[ 0.  1.  0.  1.]

[ 1.  0.  1.  0.]]

本文**

劉建平pinard

特徵工程之特徵選擇

在前一篇文章中我介紹了一些資料預處理的方法,原始資料在經過預處理之後可以被演算法處理了,但是實際中可能有一些特徵是沒有必要的,比如在中國採集的一些資料,那麼國籍就都是中國,其實也就沒有意義了,反映在統計量上就是方差過小,也就是樣本在這個特徵上變化很小。還有一種情況是特徵和最後的結果相關性很小,也就是...

特徵工程之特徵選擇

特徵選擇其實就是減少屬性個數,為什麼要這麼做呢?直接使用原始資料來訓練模型的話,雖然說在訓練模型上的準確率會非常高,但是在測試樣本上的準確率將會大打折扣,也就是會產生過擬合的現象。所以說需要選擇出最適合的屬性進行訓練。特徵選擇的原因 2 雜訊 部分特徵對 結果又影響 進行特徵選擇的時候有兩種情況 一...

特徵工程之特徵選擇

在做資料分析的時候,特徵的 一般有兩塊,一塊是業務已經整理好各種特徵資料,我們需要去找出適合我們問題需要的特徵 另一塊是我們從業務特徵中自己去尋找高階資料特徵。我們就針對這兩部分來分別討論。2.選擇合適的特徵 我們首先看當業務已經整理好各種特徵資料時,我們如何去找出適合我們問題需要的特徵,此時特徵數...