機器學習特徵工程經驗總結二

機器學習特徵工程經驗總結一
機器學習特徵工程經驗總結二

--------------------------------------------

如何做特徵處理和構建

特徵處理和構建一般對以下幾種數據類型做處理:

  •     數值型
  •     類別型
  •     時間型
  •     文本型
  •     統計型
  •     組合特徵

一、數值型

1 幅度調整/歸一化:python中會有一些函數比如preprocessing.MinMaxScaler()將幅度調整到 [0,1] 區間。

2.統計值:包括max, min, mean, std等。python中用pandas庫序列化數據後,可以得到數據的統計值。

3.離散化:把連續值轉成非線性數據。例如電商會有各種連續的價格表,從0.03到100元,假如以一元錢的間距分割成99個區間,用99維的向量代表每一個價格所處的區間,1.2元和1.6元的向量都是 [0,1,0,…,0]。pd.cut() 可以直接把數據分成若干段。

4.柱狀分佈:離散化後統計每個區間的個數做柱狀圖。

二、類別型

類別型一般是文本信息,比如顏色是紅色、黃色還是藍色,我們存儲數據的時候就需要先處理數據。處理方法有:
1. one-hot編碼,編碼後得到啞變量。統計這個特徵上有多少類,就設置幾維的向量,pd.get_dummies()可以進行one-hot編碼。
2. 序數編碼
3. Histogram映射:把每一列的特徵拿出來,根據target內容做統計,把target中的每個內容對應的百分比填到對應的向量的位置。優點是把兩個特徵聯繫起來。
上表中,我們來統計“性別與愛好的關係”,性別有“男”、“女”,愛好有三種,表示成向量 [散步、足球、看電視劇],分別計算男性和女性中每個愛好的比例得到:男[1/3, 2/3, 0],女[0, 1/3, 2/3]。即反映了兩個特徵的關係。

三、時間型

時間型特徵的用處特別大,既可以看做連續值(持續時間、間隔時間),也可以看做離散值(星期幾、幾月份)。數據挖掘中經常會用時間作爲重要特徵,比如電商可以分析節假日和購物的關係,一天中用戶喜好的購物時間等。

四、地理位置

對地理位置信息(類別型變量)最簡單的處理方式是獨熱編碼(one-hot encoding), 但是這樣會得到很高維的稀疏特徵,影響模型的學習。所以我們可以在獨熱編碼的基礎上,做了特徵選擇。我們可以將地理位置和目標變量做相關性分析,比如違約中可以挑違約率較高的地方,然後做獨熱編碼 ,如果地理位置變量是城市,那獨熱編碼後會產生很高維的特徵,這時就要用模型(xgboost)進行特徵選擇,選出相關性較高的特徵。

另外,地理位置還可以做城市等級合併,經緯度特徵引入等。

城市等級合併按照城市等級,將類別變量合併,例如一 線城市北京、上海、廣州、深圳合併,賦值爲 1,同樣地,二線城市合併爲 2,三線城市合 併爲 3。

我們另外收集了各個城市的經緯度, 將城市名用經緯度替換,這樣就可以將類別型的變量轉化爲數值型的變量,比如北京市,用 經緯度(39.92,116.46)替換,得到北緯和東經兩個數值型特徵。加入經緯度後,線下的 cross validation 一般都有千分位的提升。

五、文本型

1. 詞袋:文本數據預處理後,去掉停用詞,剩下的詞組成的list,在詞庫中的映射稀疏向量。Python中用CountVectorizer處理詞袋.

2. 把詞袋中的詞擴充到n-gram:n-gram代表n個詞的組合。比如“我喜歡你”、“你喜歡我”這兩句話如果用詞袋錶示的話,分詞後包含相同的三個詞,組成一樣的向量:“我 喜歡 你”。顯然兩句話不是同一個意思,用n-gram可以解決這個問題。如果用2-gram,那麼“我喜歡你”的向量中會加上“我喜歡”和“喜歡你”,“你喜歡我”的向量中會加上“你喜歡”和“喜歡我”。這樣就區分開來了。

3. 使用TF-IDF特徵:TF-IDF是一種統計方法,用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨着它在文件中出現的次數成正比增加,但同時會隨着它在語料庫中出現的頻率成反比下降。TF(t) = (詞t在當前文中出現次數) / (t在全部文檔中出現次數),IDF(t) = ln(總文檔數/ 含t的文檔數),TF-IDF權重 = TF(t) * IDF(t)。自然語言處理中經常會用到。

六、統計型

歷屆的Kaggle/天池比賽, 天貓/京東排序和推薦業務線裏模型用到的特徵。統計的內容包括加減平均、分位線、次序型、比例類等。

比如“天池大數據之移動推薦算法大賽”中,給比賽選手兩張表,介紹用戶和商品信息,要求預測把哪些商品推薦給用戶,用戶最有可能購買。
(1)加減平均:商品價格高於平均價格多少,用戶在某個品類下消費超過平均用戶多少,用戶連續登陸天數超過平均多少
(2)分位線:商品屬於售出商品價格的多少分位線處
(3)次序:排位第幾
(4)比例:超過百分之多少

七、組合特徵

1.拼接型
簡單的組合特徵。例如挖掘用戶對某種類型的喜愛,對用戶和類型做拼接。正負權重,代表喜歡或不喜歡某種類型。
- user_id&&category: 10001&&女裙 10002&&男士牛仔
- user_id&&style: 10001&&蕾絲 10002&&全棉

2.模型特徵組合
- 用GBDT產出特徵組合路徑
- 組合特徵和原始特徵一起放進LR訓練

3.兩兩特徵相除/相乘/相加/相減
乘法特徵(取對數):log(x*y),選擇出重要度高的特徵,加入到原始特徵體系中,會有千分位提高。這種特徵組合有助於表示非線性關係。

我們可以創建很多不同種類的特徵組合。例如:
[A X B]:將兩個特徵的值相乘形成的特徵組合。
[A x B x C x D x E]:將五個特徵的值相乘形成的特徵組合。
[A x A]:對單個特徵的值求平方形成的多項式特徵組合。(二階,三階等)

爭對第三個的可以生成n次方,A的二次方,三次方等,還可以對多個特徵進行不同的n次方,比如A的2次方乘與B的三次方等,增加非線性。

4.交互特徵:組合獨熱矢量
在實踐中,機器學習模型很少會組合連續特徵。不過,機器學習模型卻經常組合獨熱特徵矢量,將獨熱特徵矢量的特徵組合視爲邏輯連接.例如,假設我們具有以下兩個特徵:國家/地區和語言。對每個特徵進行獨熱編碼會生成具有二元特徵的矢量,這些二元特徵可解讀爲 country=USA, country=France 或language=English,language=Spanish。然後,如果您對這些獨熱編碼進行特徵組合,則會得到可解讀爲邏輯連接的二元特徵。

假設我們的模型需要根據以下兩個特徵來預測狗主人對狗狗的滿意程度:

行爲類型(吠叫、叫、偎依等)
時段

如果我們根據這兩個特徵構建特徵組合。我們最終獲得的預測能力將遠遠超過任一特徵單獨的預測能力。例如,如果狗狗在下午 5 點主人下班回來時(快樂地)叫喊,可能表示對主人滿意度的正面預測結果。如果狗狗在凌晨 3 點主人熟睡時(也許痛苦地)哀叫,可能表示對主人滿意度的強烈負面預測結果。

5.分桶特徵(分箱)

例如,我們可以將 population 分爲以下 3 個分桶:

bucket_0 (< 5000):對應於人口分佈較少的街區
bucket_1 (5000 - 25000):對應於人口分佈適中的街區
bucket_2 (> 25000):對應於人口分佈較多的街區
根據前面的分桶定義,以下 population 矢量:

[[10001], [42004], [2500], [18000]]
將變成以下經過分桶的特徵矢量:

[[1], [2], [0], [1]]
這些特徵值現在是分桶索引。請注意,這些索引被視爲離散特徵。通常情況下,這些特徵將被進一步轉換爲獨熱編碼表示。

6.最大最小特徵
最小最大值一直都是特徵提取的重點,當前值與最大最小值之間的差更是值得嘗試的特徵。

7.還可以用FM模型進行特徵組合和降維

總結:組合兩個(或更多個)特徵是使用線性模型來學習非線性關係的一種聰明做法。在我們的問題中,如果我們只使用 latitude 特徵進行學習,那麼該模型可能會發現特定緯度(或特定緯度範圍內,因爲我們已經將其分桶)的城市街區更可能比其他街區住房成本高昂。longitude 特徵的情況與此類似。但是,如果我們將 longitude 與 latitude 組合,產生的組合特徵則代表一個明確的城市街區。如果模型發現某些城市街區(位於特定緯度和經度範圍內)更可能比其他街區住房成本高昂,那麼這將是比單獨考慮兩個特徵更強烈的信號。

 

如何做特徵選擇

在特徵工程部分,我們構建了一系列位置信息相關的特徵、組合特徵、成交時間特徵、 排序特徵、類別稀疏特徵等,這麼多維特徵一方面可能會導致維數災難,另一方面很容易導致過擬合,需要做降維處理,降維方法常用的有如 PCA,t-SNE 等,這類方法的計算複雜度比較高。並且根據以往工作經驗,PCA 或 t-SNE 效果不是特別好。

除了採用降維算法之外,也可以通過特徵選擇來降低特徵維度。

特徵選擇的方法很多: 最大信息係數(MIC)、皮爾森相關係數(衡量變量間的線性相關性)、正則化方法(L1, L2)、基於模型的特徵排序方法。

用正則化來做特徵選擇,L1,L2,對於特徵維度很大的情況,作L1, 對於特徵維度很小的情況,作L2。

比較高效的是最後一種,即基於學習模型的特徵排序方法, 這種方法有一個好處:模型學習的過程和特徵選擇的過程是同時進行的,因此我們採用這種 方法,基於 xgboost 來做特徵選擇,xgboost 模型訓練完成後可以輸出特徵的重要性,據此我們可以保留 Top N 個特徵,從而達到特徵選擇的目的。

還有其他的總結。

特徵選擇,就是從多個特徵中,挑選出一些對結果預測最有用的特徵。因爲原始的特徵中可能會有冗餘和噪聲。

特徵選擇和降維有什麼區別呢?前者只踢掉原本特徵裏和結果預測關係不大的, 後者做特徵的計算組合構成新特徵。

3.1 過濾型
方法: 評估單個特徵和結果值之間的相關程度, 排序留下Top相關的特徵部分。

-評價方式:通過方差選擇法、Pearson相關係數,相關係數法、卡方檢驗法、互信息法來對特徵進行評分,設定閾值或者待選擇的閾值的個數來選擇 。

-缺點:只評估了單個特徵對結果的影響,沒有考慮到特徵之間的關聯作用, 可能把有用的關聯特徵誤踢掉。比如多項式組合特徵,pearson相關係數不是很大,因爲是非線性,所以相關係數也不一定大,但如果用這個方法有可能會被去掉,因此工業界使用比較少。

還有方差計算其實可以放在特徵處理。計算各個特徵的方差,剔除小於設定的閾值的特徵,剔除特徵值 波動較小的特徵,例如一個特徵的所有值都爲1,那這個特徵對於預測目標變量就沒什麼作用;方法很簡單,但實際應用中只有少數變量纔會存在只取某個值的情況,對特徵選擇作用比較小,可以當做數據預處理部分,之後再用其他方法進行特徵選擇。

3.2 包裹型

-方法:把特徵選擇看做一個特徵子集搜索問題, 篩選各種特 徵子集, 用模型評估效果。

-典型算法:“遞歸特徵刪除算法”。

-應用在邏輯迴歸的過程:用全量特徵跑一個模型;根據線性模型的係數(體現相關性),刪掉5-10%的弱特徵,觀察準確率/auc的變化;逐步進行, 直至準確率/auc出現大的下滑停止。

3.3 嵌入型

-方法:根據模型來分析特徵的重要性,最常見的方式爲用正則化方式來做特徵選擇。

-舉例:最早在電商用LR做CTR預估, 在3-5億維的係數特徵上用L1正則化的LR模型。上一篇介紹了L1正則化有截斷作用,剩餘2-3千萬的feature, 意味着其他的feature重要度不夠。

正則化主要包括L1正則化和L2正則化:

L1正則化將係數W的L1範數作爲懲罰項加到損失函數中,L1正則方法具有稀疏解的特性,因此天然具有特徵選擇的特性,但是不代表沒被選到的特徵就不重要,有可能是因爲兩個高度相關的特徵最後只保留了一個;另外L1正則化和非正則化模型一樣是不穩定的,如果特徵集合中具有相關聯的特徵,當數據發生細微變化時也有可能導致很大的模型差異。

L2正則化將係數向量的L2範數添加到損失函數中,由於L2懲罰項中的係數是二次方的,會讓係數的取值變得平均,對於有相關性的變量,會得到相近的係數;L2正則化也較L1穩。L1會令特徵權重變成0,L2會使特徵權重趨向於零。

"""1.過濾型"""
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

iris=load_iris()
X,y=iris.data,iris.target
print X.shape
X_new=SelectKBest(chi2,k=2).fit_transform(X,y)
print X_new.shape

"""輸出:
(150L, 4L)
(150L, 2L)
"""

"""2.包裹型"""
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_boston

boston=load_boston()
X=boston["data"]
Y=boston["target"]
names=boston["feature_names"]

lr=LinearRegression()
rfe=RFE(lr,n_features_to_select=1)#選擇剔除1個
rfe.fit(X,Y)

print "features sorted by their rank:"
print sorted(zip(map(lambda x:round(x,4), rfe.ranking_),names))

"""輸出:按剔除後AUC排名給出
features sorted by their rank:
[(1.0, 'NOX'), (2.0, 'RM'), (3.0, 'CHAS'), (4.0, 'PTRATIO'), (5.0, 'DIS'), (6.0, 'LSTAT'), (7.0, 'RAD'), (8.0, 'CRIM'), (9.0, 'INDUS'), (10.0, 'ZN'), (11.0, 'TAX')
, (12.0, 'B'), (13.0, 'AGE')]"""


"""3.嵌入型 ,老的版本沒有SelectFromModel"""
from sklearn.svm import  LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel

iris=load_iris()
X,y=iris.data,iris.target
print X.shape

lsvc=LinearSVC(C=0.01,penalty='l1',dual=False).fit(X,y)
model=SelectFromModel(lsvc,prefit=True)
X_new=model.transform(X)
print X_new.shape

"""輸出:
(150,4)
(150,3)
"""

還可以用邏輯迴歸。
from sklearn.linear_model import LogisticRegression

LogisticRegression 裏的參數有penalty,可以調用來做特徵選擇

參考:

https://blog.csdn.net/weixin_42736194/article/details/83050297

https://blog.csdn.net/weixin_42736194/article/details/83051487

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章