特徵工程之特徵表達

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

1、缺失值處理

          特徵有缺失值是很是常見的,大部分機器學習模型在擬合前須要全部的特徵都有值,不能是空或者NULL。那麼若是有缺失值咱們須要怎麼處理呢?python

     首先咱們會看是該特徵是連續值仍是離散值。若是是連續值,那麼通常有兩種選擇,一是選擇全部有該特徵值的樣本,而後取平均值,來填充缺失值,另外一種是取中位數來填充缺失值。若是是離散值,則通常會選擇全部有該特徵值的樣本中最頻繁出現的類別值,來填充缺失值。在sklearn中,可使用preprocessing.Imputer來選擇這三種不一樣的處理邏輯作預處理。算法

2、特殊的特徵處理

   有些特徵的默認取值比較特殊,通常須要作了處理後才能用於算法。好比日期時間,好比顯示20180519,這樣的值通常沒辦法直接使用。那麼通常須要如何變換呢?微信

        對於時間原始特徵,處理方法有不少,這裏只舉例幾種有表明性的方法。 第一種是使用連續的時間差值法,即計算出全部樣本的時間到某一個將來時間之間的數值差距,這樣這個差距是UTC的時間差,從而將時間特徵轉化爲連續值。第二種方法是根據時間所在的年,月,日,星期幾,小時數,將一個時間特徵轉化爲若干個離散特徵,這種方法在分析具備明顯時間趨勢的問題比較好用。第三種是權重法,即根據時間的新舊獲得一個權重值。好比對於商品,三個月前購買的設置一個較低的權重,最近三天購買的設置一箇中等的權重,在三個月內可是三天前的設置一個較大的權重。固然,還有其餘的設置權重的方法,這個要根據要解決的問題來靈活肯定。app

       對地理特徵,好比「廣州市天河區XX街道XX號」,這樣的特徵咱們應該如何使用呢?處理成離散值和連續值都是能夠的。若是是處理成離散值,則須要轉化爲多個離散特徵,好比城市名特徵,區縣特徵,街道特徵等。可是若是咱們須要判斷用戶分佈區域,則通常處理成連續值會比較好,這時能夠將地址處理成經度和緯度的連續特徵。機器學習

3、離散特徵的連續化處理

    有不少機器學習算法只能處理連續值特徵,不能處理離散值特徵,好比線性迴歸,邏輯迴歸等。那麼想使用邏輯迴歸,線性迴歸時這些值只能丟棄嗎?固然不是。咱們能夠將離散特徵連續化處理。post

   最多見的離散特徵連續化的處理方法是獨熱編碼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將詞轉化爲詞向量,進而能夠進行一些連續值的後繼處理。編碼

4、離散特徵的離散化處理

   離散特徵有時間也不能直接使用,須要先進行轉化。好比最多見的,若是特徵的取值是高,中和低,那麼就算你須要的是離散值,也是無法直接使用的。

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

   第二種方法是虛擬編碼dummy coding,它和獨熱編碼相似,可是它的特色是,若是咱們的特徵有N個取值,它只須要N-1個新的0,1特徵來代替,而獨熱編碼會用N個新特徵代替。好比一個特徵的取值是高,中和低,那麼咱們只須要兩位編碼,好比只編碼中和低,若是是1,0則是中,0,1則是低。0,0則是高了。目前虛擬編碼使用的沒有獨熱編碼廣,所以通常有須要的話仍是使用獨熱編碼比較好。

   此外,有時候咱們能夠對特徵進行研究後作一個更好的處理。好比,咱們研究商品的銷量對應的特徵。裏面有一個原始特徵是季節春夏秋冬。咱們能夠將其轉化爲淡季和旺季這樣的二值特徵,方便建模。固然有時候轉化爲三值特徵或者四值特徵也是能夠的。

   對於分類問題的特徵輸出,咱們通常須要用sklearn的LabelEncoder將其轉化爲0,1,2,...這樣的類別標籤值。

5、連續特徵的離散化處理

   對於連續特徵,有時候咱們也能夠將其作離散化處理。這樣特徵變得高維稀疏,方便一些算法的處理。

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

   固然還有高級一些的方法。好比使用GBDT。在LR+GBDT的經典模型中,就是使用GDBT來先將連續值轉化爲離散值。那麼如何轉化呢?好比咱們用訓練集的全部連續值和標籤輸出來訓練GBDT,最後獲得的GBDT模型有兩顆決策樹,第一顆決策樹有三個葉子節點,第二顆決策樹有4個葉子節點。若是某一個樣本在第一顆決策樹會落在第二個葉子節點,在第二顆決策樹落在第4顆葉子節點,那麼它的編碼就是0,1,0,0,0,0,1,一共七個離散特徵,其中會有兩個取值爲1的位置,分別對應每顆決策樹中樣本落點的位置。在sklearn中,咱們能夠用GradientBoostingClassifier的 apply方法很方便的獲得樣本離散化後的特徵,而後使用獨熱編碼便可。 

         具體的一個示例代碼以下:

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)
X_train_new = one_hot.fit_transform(gbc.apply(X_train)[:, :, 0])
print (X_train_new.todense())

       輸出是:

[[0. 1. 1. 0.]
[1. 0. 0. 1.]
[1. 0. 0. 1.]
[1. 0. 0. 1.]
[0. 1. 1. 0.]]

6、小結

       本文總結了特徵表達的一些具體方法, 可是特徵表達的方法便不止於上文中的方法,畢竟這是工程實踐。可是上文中的方法是比較廣泛的,但願能夠給你們一些幫助和啓發。 下一篇咱們討論特徵預處理和分類類別不平衡的問題處理。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: 微信:nickchen121)

相關文章
相關標籤/搜索