数据工程系列精讲(第一讲): Data-centric AI 之特征工程
前言
這兩年我們觀察到越來越多的算法工程師重視數據的特征工程,AI業界大佬吳恩達教授在2021年提出了從model-centric AI切換到data-centric AI的論調,我個人認為data-centric AI的三個核心就是特征工程,樣本工程和數據集質量(本系列文章將圍繞這三個核心來介紹),即使使用深度學習,對結構化數據建模,特征工程仍然是重中之重,而對于結構化數據建模,隨著機器學習平臺的成熟比如亞馬遜云科技的拳頭產品 Amazon SageMaker https://aws.amazon.com/cn/sagemaker/,讓人們從底層基礎設施以及繁雜的訓練和推理的各種環境搭建中解放出來,從而有更多的時間和精力關注數據和特征本身,真正邁入“AI平民化”,只要掌握了data-centric AI三個核心,大家都可以利用成熟的模型來建模。很多場景下,甚至你只要把高質量的數據集準備好以后(比如可以借助Amazon SageMaker Data Wranglerhttps://aws.amazon.com/cn/sagemaker/data-wrangler/來做數據集的準備),就可以利用?SageMaker Canvas https://aws.amazon.com/cn/sagemaker/canvas/來基于UI的code-free建模,不需要關心算法本身的同時還能得到不錯的效果。
為了行文方便,在之后的討論中我不專門提結構化數據建模。對于涉及到非結構化數據的CV,NLP,語音識別這三大領域來說,現在(2022年)主流都是用深度學習來建模而不考慮復雜的人工提取的特征。因此目前來說,我們討論的特征工程針對的就是結構化數據建模。更詳細的data-centric AI相關的內容請參考該github repo https://github.com/yuhuiaws/ML-study/tree/main/Data-centric%20AI。
更多數據工程系列精講內容,敬請期待系列推送
本文大綱
-
什么是特征?
-
連續特征和category特征
-
什么是好的特征?
-
特征工程概覽
-
特征工程詳細步驟
-
特征預處理
-
特征生成
-
特征選擇
-
特征降維
-
總結
什么是特征?
特征這個術語有很多別名,比如字段,屬性,自變量(在今后的內容中可能會混用這些別名)等等。我們看一個例子,下表中Play Cricket是目標變量也就是我們常說的label/ 標注,其他的變量比如Height,Gender等都是特征。
特征的大致類型如下表:
| 類型 | 舉例 |
| 基本特征 | IP地址,性別,年齡,常駐地,手機廠商 |
| 統計特征 | 游戲玩家最近一周內的累積消費金額 |
| 組合特征 | 用戶最近點擊過的10個商品組成的item id序列特征;男性用戶且使用蘋果手機這樣的交叉特征 |
特征有2個統計特點:
一是特征是否發散,如果一個特征的方差接近于0,我們稱這個特征不發散。也就是說所有樣本在這個特征上基本沒有差異,這個特征對于樣本的區分沒有什么用,可以丟棄它(比如1萬條樣本中的“性別”這個特征的取值都是“男性”,這時候我們說“性別”這個特征的方差就是0. ?比如1萬條樣本中的“國家”這個特征的取值有9900都是“中國”,其他國家一共的樣本數才100條,這個時候我們說“國家”這個特征的方差接近于0)
二是特征與目標的相關性,與目標相關性高的特征(包括正相關和負相關),應當優選選擇。(比如預測試用產品的用戶是否在一個月內付費的目標任務,“用戶的累積登錄次數”這樣的特征可能就是與目標相關性高的特征)
連續特征和category特征
在做特征工程的時候,我們要時刻注意每個特征到底是連續特征還是category特征,這個非常重要。Category特征指語義上有枚舉特點的特征,包括字符串類型和數值類型。比如[“北京”,“上海”,“深圳”]這樣的“城市”特征就是字符串類型category特征;而[“中國”,“美國”,“日本”]這樣的特征經過數字編碼為[0,1,2]后得到的“國家”特征就是數值類型的category特征。離散特征是指具有數值類型的Category特征。Category特征的枚舉值數量越多,我們稱它的基數越高(以后為了行文方便,不再區分離散特征和Category特征);連續特征指語義上連續的數值型特征,包括整數類型和浮點類型。需要注意的是,數值型特征不一定就是連續特征。(比如“身高”,“體重”這樣的特征都是連續特征;而如上面提到的用數字編碼過的“國家”這樣的特征就不是連續特征)
對于Category特征來說,我們要判斷它是無序還是有序。有序和無序只是相對于當前的目標任務。比如從小到大排列的“學歷等級”特征[“小學”,“初中”,“高中”,“學士”,“碩士”,“博士”],在預測收入這樣的任務的時候可能是有序特征(有序的含義在這里的體現是:可能學歷越高,收入越高),而在預測身體健康程度這樣的任務的時候可能就是無序特征(無序的含義在這里的體現是:是否健康與學歷高低沒有什么關系)。
特征工程階段不同子步驟的不同方法對category特征的適用性是不同的(比如特征縮放主要是針對連續性特征;比如特征降維的PCA主成分分析算法只是針對連續性特征)。不同的機器學習模型對連續特征和category特征的適用性是不同的(比如GMM高斯混合模型只能使用連續特征,而多項式分布樸素貝葉斯模型只能使用category特征;比如XGBoost https://xgboost.readthedocs.io/en/stable/模型把所有特征都當成連續特征)。
不同的機器學習模型對category特征的無序和有序的適用性也是不同的。(比如邏輯回歸模型LR,如果category特征的基數不是很高(比如小于10的情況),一個可行的做法是把單個category特征變成由多個二值特征組成的One-hot向量(如下圖所示)。
比如LightGBM https://lightgbm.readthedocs.io/en/latest/可以處理category特征并且它不考慮該category特征是有序還是無序,因為LightGBM在做樹的節點分裂的時候,對于category特征的候選分裂點計算過程不涉及排序)
什么是好的特征?
我們的美好愿望是送到模型中的特征是我們“想要”的特征,這樣的特征的特質如下:
| 特質 | 舉例 | 備注 |
| 對當前任務“有用”的特征 | “app版本”這個特征對于預測用戶是否付費的任務就很有用;“用戶是否喜歡購物”這個特征對預測用戶是否會報名馬拉松這樣的任務可能就沒有用。 | 特征的好壞一定要放在具體的上下文中來看。 |
| 好的category特征的枚舉值應在數據集中出現多次 | 比如8次以上 | 某個特征值出現次數太少的話,模型對該特征值就幾乎學習不到什么知識。 |
| 最好具有清晰明確的含義 | “商品最近一天的點擊率”這樣的特征含義就很清晰;而“商品day1點擊率”這樣的特征就有歧義了,是表示第一天的點擊率還是最近一天的點擊率還是當天的點擊率? | 最好能見文識意 |
| 特征的值不應該超出語義范圍或者業務知識范圍 | “季節”特征不應該出現除了春夏秋冬外的其他季節;“天氣氣溫”特征不應該有太離譜的值比如100攝氏度出現。 | 為了更好的模型效果,這個一定要在訓練時和推理時都要檢查并處理的 |
| 與目標變量相關性高的特征(包括正相關和負相關) | “用戶消費等級”特征對于用戶流失預測任務可能就是強特征 | 經常叫這樣的特征是“ 強特征“ |
特征工程概覽
?特征工程本質是一項工程活動,它目的是最大限度地從原始數據中提取并加工特征以供模型或者算法使用。在傳統機器學習領域流傳著這樣一句話:“數據和特征決定了機器學習的上限,而模型和算法只是逼近這個上限而已”,從而可見特征工程的重要性。其實對于結構化數據建模,即使用深度學習模型,特征工程也是比模型本身要重要的。
特征工程目前主要是純手工打造(指的是結構化數據建模),因為特征工程是藝術,幾乎不可能全部自動化。但是特征工程的某個部分可以自動化比如自動生成特征:目前(到2022年5月)特征生成自動化不是主流;第四范式在嘗試一些特征工程自動化,包括:連續特征自動離散化, 時序特征自動提取,特征交叉自動生成。
下面我們來了解特征工程的詳細步驟。
1
步驟一: 特征預處理之字符串特征轉換為數字特征
我們拿到的原始數據中經常會有一些字段是字符串類型的,這個時候我們需要首先根據具體機器學習任務來判定這個字符串特征本質上是category特征還是文本語義特征?比如對于電影推薦場景的CTR點擊率預估任務,電影內容的文本描述特征是形如“這個影片呈現了中國60年代知青下鄉的各種景象”,該特征是對電影內容本身的刻畫,屬于文本語義特征;電影出產地的文本描述特征形如“中國北影”,“美國好萊塢”等這些是具有枚舉特點的,屬于category特征。
如果判定為文本語義特征并且該特征對當前目標任務有用的話,一種做法是用另一個預訓練的語言模型來獲得這個文本特征的sentence embedding向量(embedding向量可以簡單理解為原始特征映射到另一個空間的不可解釋的某種表示),然后和其他特征拼接作為下游模型的特征向量。如果判定為category特征,需要把這個字符串category特征轉為數值型category特征。
參考如下的流程對字符串category特征做轉換:首先結合業務知識考慮是否丟棄對目標任務沒有意義的字符串category特征(比如對于信用卡欺詐檢測任務來說,“姓名”category特征對這個任務沒有什么意義,可以直接丟棄。比如對于音樂歌曲推薦場景來說,“歌曲的演唱者”category特征就不應該丟棄,因為用戶可能就是對演唱者感興趣才播放他唱的歌曲);然后或者把它轉換為具有物理意義的數字(比如類似小區門牌號信息這樣的地址特征轉換為經緯度2個特征);或者將單個字符串特征拆為多個字符串特征并編碼為數字值(比如把通信地址特征或者IP特征可以拆分/轉換為國家,省,市三個特征);或者對某個字符串category特征的訓練集中出現的所有字符串建立一個映射表并索引對應的字符串(為了完整,需要有一個占位索引來表示之后的數據中看到的不在映射表中的字符串)
2
步驟二: 特征預處理之異常值處理
我們拿到的原始數據很可能或多或少都會有一些特征的取值不太合理,也就是說這些特征值可能是異常值。異常點(又叫離群點)產生原因:一種是人為錯誤(人工錄入數據或者人工整理數據出現了問題);一種是自然原因(某些數據樣本本身就和大多數數據樣本不同或者采集數據的設備/服務的問題導致)
對于非異常檢測任務,機器學習模型希望數據集(包括訓練集,測試集,驗證集)都是正常的樣本點。處理的流程如下:首先需要把異常檢測任務作為非異常檢測任務的前置任務來做數據預處理,找到并人工確認異常點。(異常檢測的方法有很多比如基于規則的,基于統計的,基于模型的等等,可以參考我總結的另一個文檔 https://github.com/yuhuiaws/ML-study/blob/main/ML%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%85%A5%E9%97%A8/%E5%BC%82%E5%B8%B8%E6%A3%80%E6%B5%8B%E4%BB%8B%E7%BB%8D.pptx);然后如果異常點的原因能歸結到特征粒度:如果之后要選擇對異常值相對不敏感的模型比如隨機森林或XGBoost,這里可以先跳過異常值處理步驟。然后把異常值當成缺失值來處理;或者用變換方法,比如對異常的連續性特征取自然對數,對異常的連續性特征分箱處理,對異常的連續特征做3-sigma截斷處理,分位數上下限截斷處理或者最大最小值截斷處理(參考Amazon SageMaker Data Wrangler中關于異常值的處理https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html:);否則從數據集中剔除異常樣本,把異常樣本單獨存儲以便之后做異常檢測。
3
步驟三: 特征預處理之缺失值處理
我們拿到的原始數據中一般都會有一些特征有缺失的現象(見下圖)。缺失值的原因有幾下幾種:暫時無法獲取某些特征值;出現人為錯誤;數據采集階段出現的程序/設備故障導致;歷史局限性;有意隱瞞的特征值;有些樣本的特征值根本就是不存在的;從異常值轉換而來;線上預測時從feature store獲取特征超時。
通常用來處理缺失值的方式:在預測時處理缺失值并寫完整的特征向量到日志,訓練時直接用該日志(最建議的方式,能最大程度的保證特征的線上線下一致性);或者讓訓練算法在訓練階段自行處理缺失值(XGBoost和LightGBM都支持自行處理缺失值);或者在訓練開始前處理掉缺失值。(建議:在做缺失值處理的時候,嘗試新增一個特征來標識有缺失值的特征對應的該條樣本這個特征是否做了缺失值處理,可能最后的模型效果更好(相當于給模型更多的的信號)。具體可以參考Amazon SageMaker Data Wrangler缺失值處理中提到的這個indicator https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html:)
對訓練集處理缺失值(有可能多種特征都有缺失值),流程如下(處理過程中為了不發生信息泄露,不要去看驗證集和測試集中的該特征的任何取值):
-
首先逐個檢查每個特征的缺失情況。對于某個特征,如果有太多的訓練樣本有缺失值比如超過1半的樣本量,考慮是否可以從數據集中去除這個特征。如果需要去除的特征有很多個,說明數據集質量太差,最好考慮重新收集數據;
-
然后逐個檢查每個樣本的缺失情況。對于某個樣本,如果缺失的特征數量太多比如超過1半數量的特征都缺失,那么可以考慮是否可以把這個樣本給去除;
-
接著考慮如果之后的模型選擇是能直接處理含缺失值樣本的模型比如XGBoost,那么先跳過缺失值處理步驟;否則進行缺失值補全。
在訓練集做完缺失值處理后,就可以處理測試集和驗證集的缺失值了:如果是連續性特征,用訓練集該特征的平均值或者中位數補全;如果是category特征,用訓練集該特征的眾數(出現頻率最高的那個值)來補全。在預測時處理缺失值常見的方法就是使用預先計算好的連續特征的平均值/中位數,或者category特征的眾數來補全。
針對訓練集,常見的缺失值補全的方法(均值補全和同類均值補全可能是用的最多的方法):
| 方法 | 原理 | 備注 |
| 均值補全 | 如果特征是連續型, 用平均值補全;如果特征是離散型,用眾數補全 | 對于連續特征,除了均值補全,中位數補全也比較常用。 |
| 同類均值補全 | 首先按照目標變量的? label對樣本進行分類,然后以該類中的樣本的均值或者眾數來補全缺失值 | 適合分類問題 |
| 基于聚類的補全 | 把沒有缺失值的特征都抽取出來組成新的數據集進行聚類,然后把每個樣本的缺失值進行同簇均值或者眾數補全 | 這種方法類似同類均值補全,不過它對分類和回歸問題都適用;它還可以做簇間加權均值補全,加權方法用樣本對每個簇的歸屬度。 |
| 矩陣補全 | 從最小化矩陣的秩出發,通過利用數值優化來解出矩陣中的缺失值。 | - |
| 高維映射 | 把單個離散category變量變為one-hot向量。one-hot向量長度為category枚舉值數量+1,缺失值就表示為最后的other特征 | 對于連續特征,高維映射無法直接處理。可以對連續特征離散化之后,再進行高維映射。 |
| 基于預測的補全 | 將含缺失值的特征作為預測目標,并排除掉原來的目標變量,建立模型來預測。 | 這種方法的效果相對較好。 |
對于有缺失值的數據集在經過缺失值處理后如何選型,可以參考如下:數據量很小,用貝葉斯模型;數據量適中或者較大,用XGBoost或者LightGBM這樣的模型;數據量較大,也可以用神經網絡;避免使用距離度量相關的模型,比如SVM,線性回歸,邏輯回歸(可能的原因是,缺失值處理會帶入一定的噪音,而基于距離的模型本身對噪音就比較敏感)
總結
Data-centric AI之特征工程第一講到此結束。本文介紹了特征相關的概念以及連續特征和category特征的特點,歸納了“好的特征”應有的特質。在此基礎上,介紹了特征預處理的三個子步驟即字符串特征轉換為數值特征,異常值處理和缺失值處理。相信大家現在對特征以及特征工程有了更深刻的理解,接下來的第二講我會繼續講特征預處理。再次感謝大家的閱讀。
本篇作者
梁宇輝
亞馬遜云科技機器學習產品技術專家
負責基于亞馬遜云科技的機器學習方案的咨詢與設計,專注于機器學習的推廣與應用,深度參與了很多真實客戶的機器學習項目的構建以及優化。對于深度學習模型分布式訓練,推薦系統和計算廣告等領域具有豐富經驗。
聽說,點完下面4個按鈕
就不會碰到bug了!
總結
以上是生活随笔為你收集整理的数据工程系列精讲(第一讲): Data-centric AI 之特征工程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模数转换器ADS1118 四通道采集电压
- 下一篇: [技术讨论] 交流MOSFET的损耗估算