你可能过于高估了机器学习算法能力,带你解读鲜为人知的数据泄露问题
本文是《機器學習寶典》第 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] 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] 什么是特征穿越?可以舉例子說明嗎?
總結
以上是生活随笔為你收集整理的你可能过于高估了机器学习算法能力,带你解读鲜为人知的数据泄露问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea常用但容易忘记的快捷键
- 下一篇: 第十三课时:递归组件的使用