警惕 特徵工程 中的陷阱

2021-10-23 07:43:42 字數 1663 閱讀 7657

特徵工程(feature engineering)是機器學習中的重要環節。在傳統的專案中,百分之七十以上的時間都花在了預處理資料上(data preprocessing),其中特徵工程消耗了很多時間。

一般來說,特徵工程涵蓋的內容非常廣泛,包括從缺失值補全、特徵選擇、維度壓縮,到對輸入資料的範圍進行變換(data scaling)等。舉個簡單的例子,乙個k-近鄰演算法的輸入資料有兩個特徵

以剛才的例子為基礎,我們把所有資料按照70:30的比例分為訓練集和測試集,並打算使用k-近鄰進行訓練。那麼乙個令人困擾的問題是,對訓練集的特徵做歸一化後,測試集的特徵怎麼辦?這是乙個非常關鍵的問題,因為訓練集特徵歸一化後,測試集的特徵範圍可能就不同了,因此模型失效。一般有幾種思路:

其實不難看出,從某種意義上說,三種做法是等價的。在資料量大且充分打亂的前提下,訓練集和驗證集有相同的分布假設,因此用任意一種其實差別不大。然而這樣的假設過於樂觀,且我們在真實情況下應該只有,因此方法2是明顯不行的

於是似乎方法1和方法3都可以。但其實不然,方法1常常被認為是錯誤的操作,原因是在訓練階段引入了測試資料,這屬於未知資料。即使僅僅引入了1個測試資料,如果取值非常極端,依然會導致輸出範圍有較大的波動。其次,如果對於每乙個測試資料都需要用整個訓練集來歸一的話,那麼運算開銷會非常大。

那麼似乎備選的只有方案3,即保留驗證集上的歸一化引數,並運用於測試集。這樣的做法看似可以,但有不少風險:

模型評估階段,如果我們假設擁有大量資料,且充分打亂其順序。那麼在劃分訓練集和測試集前,可以對整體資料進行統一的特徵工程。不難看出,這和統計學的大數定理有異曲同工之妙。這種做法是最為高效的,需要的運算量最小。而將「測試資料」暴露給訓練模型的風險也並不大,因為大資料量使得分布比較穩定,可以忽略。換個角度來看,當資料量非常大的時候,使用其他方法進行特徵工程的開銷會過大,不利於模型評估。因此,在模型評估階段,如果符合以上假設,可以用這種方法(也就是上文的方法1)。但退一步說,如果滿足這個條件,那麼方法3也是等價的。

**階段,每次假設我們只有1個測試點,那麼最佳方案還是儲存訓練集上特徵工程的引數或者模型,並直接用於未知資料的特徵工程(也就是上文的方法3)。

但在**階段,乙個乙個資料的**是非常昂貴的,我們一般會做「批處理」(batch operation)。換句話說,就是攢夠一定量的**資料後統一進行**。在這種情況下,我們:

這篇文章的重點是:「特徵工程雖然重要,但極容易在使用中帶來風險。」比如在訓練時同時誤用了測試資料進行特徵工程,也叫做資料洩露(data leakage)。但資料洩露其實也是個偽命題,當資料量大且分布相同時,使用哪一種方法得到結果應該都近似等價,而更重要的是執行效率。分類討論的話,方法1、2、3都有可能是適合的方法。

但我們依然希望能避免類似的風險,因此盡量避免不必要的特徵工程,有以下建議:

除此之外,特徵工程中還有很多其他風險。比如測試集**現了訓練集中未出現的類別。如果此時做獨熱編碼(one-hot encoding),那麼就會出現bug,除非單獨賦予乙個類別叫做「未知」。同時,儲存訓練集中的特徵工程引數有時候是非常複雜的,有時候甚至會帶來過大儲存壓力,導致模型失效。

因此,特徵工程不是萬能藥,自動的特徵抽取模型更加魯棒和穩定。對特徵進行處理時,必需要有一萬分的小心,不然很容易出現意想不到的「驚喜」或者「驚嚇」。

警惕值型別的陷阱

1 struct mystruct class program 輸出結果 而如果去掉委託,直接setvalue,結果當然就是1了。為什麼加了乙個委託結果就完全不同了呢?我們知道,委託內部有乙個object型別的 target欄位,用來指明委託所呼叫的方法所在的例項型別。在這個例子中,target就是...

在java 5中警惕」 「 陷阱

在有些jvm中,integer型別從 128到127的範圍內會放回用乙個物件,所以用 的時候,同樣大小的ingeter倆個物件會返回true。而超過這個範圍,就可能返回false了。integer i1 300 integer i2 300 if i1 i2 system.out.println i...

警惕!電腦銷售人員的陷阱

說起這件事,我覺得自己很丟臉,不懂得如何保護自己的合法權益也太過輕易相信銷售人員的花言巧語,但為了眾多的電腦需求者購買電腦時,不再上當受騙,我寧願把我這段痛苦的經歷分享給廣大消費者。願大家吸取經驗並引以為戒。對於電腦品牌配置這方面我基本上是一點不了解,所以 2010年11 月11n82j 配置很高,...