你可能過於高估了機器學習演算法能力,帶你解讀鮮為人知的資料洩露問題

王偉同學發表於2019-02-24

本文是《機器學習寶典》第 6 篇,讀完本文你能夠掌握機器學習中資料洩露問題。


讀完分類與迴歸演算法的評估指標排序演算法的評估指標以及機器學習模型的離線評估方法之後,你已經知道了在機器學習中的該使用什麼指標來評估模型以及使用什麼方法來評估模型,但是在現實生活中評估模型時經常會遇到一個問題:資料洩露(data leakage),這裡我們來對資料洩露做一個解讀。

什麼是資料洩露

先舉個貼近生活的例子,你作為一名優秀的演算法工程師,你的志向是去通過機器學習演算法解決生活中的很多實際問題。在解決一個二分類問題時,你為了充分使用資料集,使用交叉驗證的方法,訓練了一個模型,發現它在測試集上的AUC指標 0.99,這時你心裡美滋滋地想著:開發出了這麼牛逼的模型,今年的年終獎應該能拿到手軟了吧。緊接著系統工程師將這個模型進行工程化,部署到生產環境中,開始真正解決實際的業務問題。當你正在給同事吹噓模型多麼牛逼,多麼吊炸天的時候,模型在生產環境中的效果表現資料出來了,你看完後,頓時雙腿一軟,要不是同事扶著你,你直接癱倒在地。

出現上面這種模型在離線評估時效果好,線上效果不好的原因有很多種,其中有一個經常會碰到的原因是:資料洩露(data leakage),有時也叫做洩露、穿越等。它說的是用於訓練機器學習演算法的資料集中包含了一些將要預測的事務的東西(when the data you are using to train a machine learning algorithm happens to have the information you are trying to predict),也就是說測試資料中的一些資訊洩露到了訓練集中。這裡說的資訊是指關於目標標籤或者在訓練資料中可用但在真實世界中卻不可用、不合法的資料。

資料洩露一般以非常微妙和難以察覺的方式發生。當資料洩露發生時,會導致模型離線的評估結果“虛高”。“虛高”的意思是說你在離線階段評估模型的時候,在測試集上表現很好,但是等真正部署到生產環境解決實際業務問題的時候,效果表現會非常的差。也就是說,離線評估時高估了模型的能力。

關於資料洩露的一些具體例項

上面雖然說了資料洩露的定義,但是太抽象了,這裡舉幾個例項來說明下資料洩露。比較容易理解的的一個洩露例項:如果訓練資料中包含了測試資料,這樣會導致模型過擬合。還有一個比較容易理解的洩露例項:如果將預測目標作為模型的特徵,這樣模型的結論基本上就類似於“蘋果是蘋果”。意思是說如果一個物品被貼上了蘋果的標籤,那麼模型預測它是蘋果。我們再來看一些在KDD比賽中更加微妙的洩露的例子。

預測潛在顧客是否會銀行開戶

在預測潛在顧客是否會在銀行開賬戶的時候,使用的一個特徵叫做:account number,也就是賬號。很明顯,只有開過戶的顧客這個欄位才會有值。在訓練時沒有任何問題,但是在實際進行預測時,對所有顧客來說,這個特徵都是空的,因為在預測之前你是不知道顧客的賬戶是多少,如果說在預測之前你已經知道了顧客的賬戶,那預測模型還有什麼用呢?

預測使用者是否會離開網站

在零售網站中,預測使用者瀏覽當前頁面之後接下來是離開網站或是瀏覽另一個新頁面時,有一個涉及資料洩露的特徵叫做:session length,也就是使用者在訪問網站時瀏覽的頁面總數。這個特徵包含了未來的資訊,即使用者將進行多少次訪問。有一種解決辦法是將 session length 替換為 page number in session,即session中截止到目前為止頁面瀏覽總數。

預測使用者是否會購買商品

在電商網站中,經常會預測給使用者曝光商品後,是否會購買的問題。很明顯,在這個問題中,商品的好評率是非常重要的因素,一般訓練時都是使用過去的資料來生成模型,比如使用過去一週的資料,在為訓練資料生成商品的好評率時,如果使用該商品當前時間的好評率,這會造成這個特徵包含了未來的資訊,所以應該使用在曝光時該商品的好評率。舉例來說,在2018年10月10日22分30秒給使用者u曝光了一件商品i,終端使用者u購買了該商品,在曝光時該商品的好評率是99%,一週後,也就是2018年10月17日22分30秒,該商品的好評率是86%,這時候在使用前面的資料構建訓練樣本時,其中商品好評率這個特徵的取值應該是曝光時的99%,而不是現在的86%。

預測病人的患病情況

在開發一個用來診斷特定疾病的模型,現有的患者訓練集中包含了一個病人是否為該疾病做過手術的特徵。很明顯,使用這個特徵可以極大地提高預測的準確性,但是這明視訊記憶體在資料洩露,因為在病人的診斷結果沒有出來之前,這個特徵無法知道。

另外一個與之相關的例子是患者ID,由於患者ID可能根據特定的診斷路徑分配。換句話說,如果是去看專家的結果,ID可能會有所不同,因為最初的醫生認定可能出現疾病。

資料洩露的型別介紹

我們可以將資料洩露分為兩大類:訓練資料洩露特徵洩露。訓練資料洩露通常是測試資料或者未來的資料混合在了訓練資料中,特徵洩露是指特徵中包含了關於真實標籤的資訊。

導致訓練資料洩露可能有以下幾種情況:

  • 在進行某種預處理時是使用整個資料集(訓練集和測試集)來計算的,這樣得到的結果會影響在訓練過程中所看到的內容。這可能包括這樣的場景:計算引數以進行規範化和縮放,或查詢最小和最大特徵值以檢測和刪除異常值,以及使用變數在整個資料集中的分佈來估計訓練集中的缺失值或執行特徵選擇。

  • 在處理時間序列資料時,另一個需要注意的關鍵問題是,未來事件的記錄意外地用於計算特定預測的特性。我們看到的會話長度示例就是其中的一個例項。

導致特徵洩露可能有以下幾種情況:

  • 刪除了一些不合法的特徵,但是忽略刪除了包含相同或類似資訊的特徵(例如前面例子中刪除了病人是否做過手術這個特徵,但是沒有刪除患者ID)

  • 在某些情況下,資料集記錄被有意隨機化,或者某些欄位被匿名化,這些欄位包含關於使用者的特定資訊,比如使用者的名字、位置等等。根據預測任務的不同,取消這種匿名化可以揭示使用者或其他敏感資訊,而這些資訊在實際使用中並不合法。

檢測資料洩露

當我們瞭解了什麼是資料洩露了之後,下一步來看下如何檢測資料洩露。

在構建模型之前,我們可以先對資料進行一些探索分析。例如,尋找與目標標籤或者值高度相關的特徵。比如在醫學診斷的例子中,病人是否為該疾病做過手術這個特徵與最終是否患病的相關性非常高。

當構建模型之後,我們可以檢查下模型中權重極高的特徵是否存在洩漏的情況。或者構建模型之後,發現模型的效果好到不可思議,這時候需要考慮下是否發生了資料洩露。

另一個更可靠的檢查洩漏的方法是,對經過訓練的模型進行有限的實際部署,看看模型的訓練時的效能與真實環境的表現之間是否有很大的差別。但是如果差別比較大的話,也有可能是是過擬合造成的。

修復資料洩露

如果檢測到發生了資料洩露,那麼如何修復呢?

首先,在進行資料預處理時,不應該使用整個資料集來計算,而是應該使用劃分後的訓練集來生成。

如果在處理時間序列問題時,一定要確保關聯特徵時的時間戳與發生時間一致,這樣能避免訓練資料中出現來自未來的資訊。

另外,針對一些與預測目標相關性特別高或者模型中權重特別高的特徵,一定要好好地檢查下是否發生了資料洩露,如果確實是,那麼一定要剔除。

練習題

看完這篇文章,我們來做一道練習題來檢驗下學習成果:

  1. 思考下,當你訓練了一個模型之後,如何快速判斷這個模型是否出現了資料洩露的情況呢?


參考:

[1] Daniel Gutierrez.Ask a Data Scientist: Data Leakage
[2] University of Michigan.Applied Machine Learning in Python-Data Leakage
[3] Leakage in Data Mining: Formulation, Detection, and Avoidance
[4] Data Science in Python:Data Leakage
[5] Data Leakage in Machine Learning
[6] 什麼是特徵穿越?可以舉例子說明嗎?


相關文章