08.27 HyperparameterHunter 3.0:一文教你學會自動化特徵工程

選自TowardsDataScience

作者:Hunter McGushion

機器之心編譯參與:Nurhachu Null、一鳴

本文介紹了一個 GitHub 開源項目——HyperparameterHunter 3.0。開發者可以使用這一工具自動化地進行特徵工程。

歡迎使用 HyperparameterHunter 3.0。

Github地址:https://github.com/HunterMcGushion/hyperparameter_hunter

這一工具可以自動保存和優化特徵工程步驟以及超參數,讓優化更加智能,並保證不浪費任何實驗。

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

把特徵工程適應到超參數優化的 Pre-HyperparameterHunter demo

漫長的等待已經結束。HyperparameterHunter 3.0 (Artemis) 來了,它增加了對特徵工程的支持,以下是一些新的特性。

  • 使特徵工程的語法清晰化、可定製的函數列表。
  • 構建特徵工程工作流的一致性框架,流程自動記錄。
  • 特徵工程步驟優化,包括對過去實驗的檢測,以進行快速啟動優化。
  • 別再跟蹤特徵工程步驟的列表,以及它們與其他超參數一起工作的方式

背景

什麼是特徵工程?

很多人對特徵工程和預處理都有不同的定義,那麼 HyperparameterHunter 是如何定義它的呢?

「特徵工程」是在模型訓練之前對數據所做的任何修改——無論是在實驗開始的時候所做的一次修改,還是在在每一輪交叉驗證時所做的重複修改。從技術上講,HyperparameterHunter 可以讓用戶自定義「特徵工程」的細節。下面是「特徵工程」定義下的一些可能的方法:

  • 手動特徵創建
  • 縮放/歸一化/標準化
  • 重採樣 (參考我們的 imblearn 的例子)
  • 目標數據轉換
  • 特徵選擇/消除
  • 編碼(one-hot,標籤等等)
  • 填補
  • 二值化/合併/離散化

還有其他相關的數據操作。

為什麼應該關心特徵工程?

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

特徵工程很少成為超參數優化中的一個話題。所以為什麼要關係它呢?

首先,特徵工程是很重要的。

你幾乎總是需要預處理你的數據。這是一個必須的步驟。

其次,特徵工程和超參數調參是一樣的,只不過超參數可以手動調整。

在數據建模前,我們會遇到很多特徵工程上的問題,比如說,應該使用 StandardScaler 還是 Normalizer?我們只能對這兩者進行測試,嘗試記住哪種對算法是最好的。相似的問題還有:應該使用 one-hot 來編碼每週的日期嗎?或者還是使用「是否是週末」的二值編碼?需要考慮月份嗎?年份呢?應該將十二個月轉換成四季嗎?閏年該怎麼辦?

但是歸根接地,開發者所用的眾多特徵工程中實際上只是另一種需要優化的超參數而已——但是並沒有工具去優化這些「超參數』,為什麼呢?

這裡有一個很好的理由:特徵工程很難。它並不是在 0.1 到 0.7 之間挑一個數字,或者是選擇使用 sigmoid 還是 ReLU 作為神經網絡層的激活函數。這裡討論的是將數據處理的方式參數化,並優化一系列功能。這需要我們知道每個特徵代表著什麼,以及參數化後返回了什麼結果——所有的這一切都是在轉換寶貴的數據。

現在的特徵過程可能是這樣的:拼湊一個腳本文件去進行所有的特徵工程,然後將這個腳本拖拽到其他項目中去。對於每個不同的項目粗暴地刪除或者修改需要的部分。如果這樣做的話,在項目結束的時候不可能重新創建所有的實驗,因為實驗中應用的特徵工程沒有清晰的、自動的記錄。

此外,忽略特徵工程會導致超參數優化結果不可信。確定地說,必須要有一個更好的方法,而現在,有了!

HyperparameterHunter 的方法

在介紹 HyperparameterHunter 如何自動化特徵工程之前。我們首先看一下數據,然後提煉出特徵工程的步驟。數據集是 SKLearn 的波士頓房價迴歸數據集。這個數據集具有可管理的 506 個樣本,除了目標之外還有 13 個特徵。

數據集地址:https://scikit-learn.org/stable/datasets/index.html#boston-house-prices-dataset

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

基線模型

特徵工程的目的是產生更好的模型,首先建立一個基線 CVExperiment,然後通過特徵工程的方式逐漸提升模型的效果。和往常一樣,首先設置環境來定義任務,以及評價結果的方法。

基線CVExperiment地址:https://hyperparameter-hunter.readthedocs.io/en/latest/api_essentials.html#experiment-execution

我們對 5 份數據做 K 重的交叉驗證,只關注在絕對誤差的中間值上。

此外,通過 SKLearn 的 train_test_split 函數可以從 train_dataset 提取出一個 holdout_dataset。

然後使用 AdaBoostRegressor 和它的默認參數運行一個簡單的 CVExperiment 模型,這樣可以看到沒有特徵工程時的結果。

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

定義問題

現在已經建立了 0.51 的基線 MAE 用於 out-of-fold 預測,現在可以看一下用來超越這個基線的一些特徵工程步驟。

A. 創建人工特徵

因為人類是創造性的,我們喜歡使用特徵工程做一些有趣的事情,所以可以把自定義的特徵添加到輸入數據中,首先,可以創建一個特徵,它是由 13 個其他特徵得到的歐幾里得範數,或者我們可以定義ℓ2-norm!本著創新的精神,本文將歐幾里得範數創新性地命名為 euclidean_norm

B. 輸入縮放

接下來要進行一下輸入縮放。認真地講,對數據進行縮放通常是一個好主意。

別忘了對 train_inputs 做一下 fit_transform,但是隻對的 non_train_inputs(validation/holdout data)做一下 transform,這樣做是為了避免數據洩露(https://machinelearningmastery.com/data-leakage-machine-learning/)。

C. 目標轉換

特徵工程的最後一步是使用 SKLearn 的 QuantileTransformer 讓目標輸出均勻地分佈,從而讓最頻繁出現的值分散開,並異常值的影響。與我們的輸入縮放一樣,僅僅對 train_targets 進行 fit_transform,然後只 transform 的 non_train_targets。

上手 HyperparameterHunter

好了,別再拖延。如何在 HyperparameterHunter 中完成這些吧。

但是,Hunter 中定義特徵工程步驟的語法是如此的順暢和合乎邏輯!我從來沒想過 HyperparameterHunter 會以我早在使用的格式期待它們!真是太瘋狂了!但是那又如何呢???—你(也許你會這麼說)

好了,親愛的讀者,秘密的成分就是上面寫到的那些函數,尤其是那些輸入的參數命令。我麼將這些函數叫做 EngineerStep 函數,因為每個函數都是一個工程步驟。一個 FeatureEngineer 在這裡僅僅是一個 EngineerSteps 的列表或者函數。

回到秘密成分上。一個 EngineerStep 函數僅僅是一個普通的函數,你可以在其中做任何你想做的數據處理。只需要在輸入參數中告知想要處理的數據就行。精明的讀者或許已經注意到了上面提到的 EngineerStep 函數的模式,但是為了記住合規的 EngineerStep 函數參數,這裡有一個有效的公式。

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

從第一個集合中拿一個字符串,將第二個集合中的一個字符串連接在它後面,然後你就得到了一個合規的 EngineerStep 函數參數。另一個重要的部分就是函數返回的結果。幸好這個更加容易記住。返回的是函數的新值。你還可以選擇返回變換器來執行逆目標變換,就像我們上面的 quantile_transform 一樣。

還有兩個別名來組合數據以便於處理,我們已在上面的函數中使用過這些別名了。讓我們更新一下這個高度複雜和細緻入微的公式,以添加額外的 EngineerStep 函數參數別名:

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

正如新參數的名稱所暗示的那樣,「all_inputs」/「all_targets」為你提供了所有數據集輸入/目標的大型 DataFrame。「non_train_inputs」和「non_train_targets」類似,只是它們省略了所有訓練數據。每個公式下面的註釋都提醒「test_inputs」沒有目標對應參數,因為我們不按設計跟蹤測試目標。

進一步瞭解

有了對如何創建特徵工程步驟的新認識,現在開始在 CVExperiment 中使用特徵工程吧。

在 CVExperiment 中僅僅需要 feature_engineer kwarg,或者任何 OptPro 的 forge_experiment 方法。feature_engineer 可以是一個 FeatureEngineer 實例,或者是 EngineerSteps/函數的列表,就像我們上面定義過的那些一樣。

hyperparameter_hunter package地址:https://hyperparameter-hunter.readthedocs.io/en/latest/source/hyperparameter_hunter.html#hyperparameter_hunter.EngineerStep

實驗部分

還記得基線在 OOF 數據上達到了中位數為 0.51 的絕對誤差中值嗎。現在可以用一些 FeatureEngineer 增強的 CVExperiments 模型做一些測試,看看會發生什麼...

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

讓我們分析一下發生了什麼。三個不同的 CVExperiment,每個都使用了不同的 FeatureEngineer,實驗 #1 和基線實驗的性能一樣。實驗 #2 稍微好一些。實驗 #3 說明誤差從 0.51 降到 0.46。或許現在可以說 quantile_transform 就是最好的特徵工程步驟,然後就完事了。但是我們如何能夠確定呢?

首先面對的是優化

在 CVExperiment 中使用 FeatureEngineer 是非常棒的。讓 HyperparameterHunter 的 OptPros 來為測試特徵工程步驟的不同組合甚至會有更好的效果。

讀者可能會擔心,增加優化步驟必然會使特徵工程複雜化。但是不必擔心,因為僅僅需要使用 OptPros 的 forge_experiment 方法,這就像在初始化一個 CVExperiment。

為了在不同 EngineerSteps 組成的空間內進行搜索,只需將這些步驟放在 Categorical 內部,像是標準的超參數優化一樣。想嘗試一個特別值得懷疑的 EngineerStep 時,Categorical 也有一個可選擇的 kwarg。如果 optional = True(默認值= False),則搜索空間不僅包括顯式給出的 Categorical,還包括完全省略當前的 EngineerStep。

在做特徵優化之前,需要更多的 EngineerStep 函數來做優化。也許讀者希望嘗試一些 standard_scale 之外的其他的縮放方法。我們可以先來先定義一下 min_max_scale 和 normalize 的相關方法。

請注意,在經典的 HyperparameterHunter 中,我 OptPro 會自動發現上面的 4 個實驗與我們的搜索空間是兼容的,並且將它們作為學習材料來實現快速啟動優化。

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

藍色矩形中添加了通過 OptPro 實現的一些新實驗的分數。

每當 OptPros 發現一個實驗具有比當前最好的結果更高的分數,它就會將這個得分標為粉紅色,將它的超參數標為綠色。通過 16 次實驗,OptPro 只是剛剛預熱,但 quantile_transform 看起來很有希望。此外,似乎嘗試一些不同的縮放器可能會得到更好的結果,畢竟我們新的最佳實驗使用最近添加的 min_max_scale 方法,而不是 standard_scale。

回到源頭

現在,讓我們回到我們的根源。我們希望把我們新的特徵優化技術和一些經典的超參數優化混合起來,因為沒人願意陷在局部最優裡面。

除了增加經典的超參數優化之外,讓我們假裝自信一些——euclidean_norm 是重要的 (儘管它實際上似乎並非如此),通過刪除包含它的 Categorical,讓它變成一個必需的 EngineerStep。請注意,這個變化意味著我們的 OptPro 將會僅僅從 16 個候選實驗中的 8 個已經保存的實驗中學習,因為我們限制了搜索空間。

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

quantile_transform 繼續執行沒有目標的轉換,但是讓我們在 power_transform 中添加一些真正的競爭。

我們還可以通過把 BayesianOptPro 切換成 RandomForestOptPro(或者任何其他的 OptPro)來得到另一種觀點。看一下我們上面的實驗,貌似 normalize 並不是做得十分好,所以我們放棄它吧。實際上,讓我們假設,確定想要的是 standard_scale 或者 min_max_scale,所以我們將會從這種混合中刪除 normalize,並在我們的第二個 EngineerStep 中刪除 optional=True 的部分。

因為我們有些過於熱情的決定 euclidean_norm 很重要的一件事,所以讓我們再次選擇第一個 EngineerStep 吧。當然,我們還需要添加 power_transform 作為我麼最後一個 EngineerStep 的選擇。

總之,下面的 OptPro 將會修改上面的三個 EngineerSteps,作為一種改變,我們將會嘗試 RandomForestOptPro。

HyperparameterHunter 3.0:一文教你學會自動化特徵工程

儘管改變了整個 FeatureEngineer 的空間,甚至需要一個新的 OptPro 來運行整個過程,我們還是能夠從 26 個保存的候選者中識別出 16 個匹配的實驗,這些實驗可以用作跳躍式優化。可以說,這要比開始的時候好很多。

更好的是,我們有一個新的最佳實驗了,它將結果提升到了 0.37 的 MAE,沒有做任何的特徵工程,從基線的 0.51 上降了下來。

現在,你這隻美麗的孔雀,起飛吧!

這些結果的神奇之處就是它們都會保存在你計算機本地,這意味著你可以持續使用好多天、好幾星期、好幾年,甚至好幾代人。好了,也許這不是最後一部分。

關鍵在於當你從這個小問題開始,朝著構建一個需要訓練好多時間的模型開始的時候,你為何要滿足於重新運行相同的模型呢?或者從過去的實驗中攫取有價值的信息,或者手動地追蹤所有這些荒謬的超參數和特徵工程呢?

展開你的翅膀,讓 HyperparameterHunter 來處理這些煩人的瑣事吧,這樣你就可以不再去跟蹤這一切了,可以將你的時間花在機器學習上了。

原文鏈接:https://towardsdatascience.com/hyperparameter-hunter-feature-engineering-958966818b6e


分享到:


相關文章: