Chapter 5~Chapter 12 詳細讨論了設定開發集(development sets)和測試集(test sets)
Chapter 5、Your development and test sets (您的開發和測試集)
讓我們回到前面的例子:貓的圖檔問題,其實可以看成一個二分類的問題,當圖檔是貓時,這是正樣本(positive examples),當圖檔不是貓時,這些樣本是負樣本(negative examples)。在機器學習中一般按照比例70%/30%來切分成訓練集(traindata set)/測試集(testdata set)。
當我們按照這種方式訓練了一個模型時(分類器),這個模型在訓練集和測試集都表現的很好,但是當你把這個模型部署到移動APP時,你發現效果很糟糕!
出現這種情況的原因是什麼呢?
我們發現使用者上傳的圖檔與您建構訓練集的網站圖檔有所不同:使用者上傳的照片使用手機拍攝,這些照片往往分辨率較低,比較模糊,并且采光不好。 由于您的訓練集/測試集是由網站圖檔建構的,您的算法沒有很好的兼顧到你所關心的智能手機圖檔的實際分布。這也就是說我們的訓練集的分布(上面例子中的網站圖檔)不同于你最終關心的分布(手機圖檔),這就是問題所在。
我們通常定義:
- 訓練集(Training set) - 學習算法通過訓練集調整參數。
- 開發集(development set) - 用于調整參數,選擇特征,以及對學習算法做出其他決定。 有時也稱為留出交叉驗證集(hold-out cross validation set)。
- 測試集(Test set) - 用于評估算法的性能,但不能用這個部分資料集去學習算法參數。
你定義一個開發集和測試集,你的團隊會嘗試很多想法,如不同的學習算法參數,看看什麼是最好的。 開發集和測試集能夠使你的團隊快速看到你的算法做得有多好。換句話說,開發和測試集的目的是指導你的團隊對機器學習系統進行最重要的更改。
當我們出現未來資料(移動app圖檔)在性質上與您的訓練集(網站圖像)不同時,就應該調整測試集和開發集資料,而不是僅僅用那切分出來的30%,這樣訓練出來的模型部署之後效果肯定會糟糕,因為訓練集和測試集的資料分布不一樣。
Chapter 6、Your dev and test sets should come from the same distribution (您的開發集和測試集應該來自相同的分布)
一旦确定了開發集和測試集,那麼我們就會專注于提高開發集的性能,是以開發集應該反映我們想提高任務資料的真實分布。
假設我們開發的模型在開發集上性能不錯但是在測試集上性能表現不佳。這個時候如果我們的開發集和測試集有相同的分布,那麼我們可以明确問題所在:模型在開發集上過拟合了。這樣的話我們就可以對症下藥:比如增加開發集的資料。可是如果開發集和測試集有不同的分布,那麼出現這種情況的原因就不好确定了,這個時候可能:
- 開發集過拟合
- 測試集比開發集更難。是以你的算法可能做的和預期一樣好,是以沒有進一步的重大改進的可能了。
- 測試集不一定更難,但隻是和開發集不同。是以在開發集上表現很好但并不能在測試集上表現一樣好。這種情況下,之前很多提高開發集性能的努力可能都白費了。
如果開發集和測試集不比對,那麼很難确定哪些做法是可以的,哪些做法是不好的,是以很難确定後續優化的idea。開發學習算法的一個重要研究問題是在一個分布上進行訓練,并很好地推廣到另一個分布。 但是,如果您的目标是在特定的機器學習應用程式上取得進展而不是進行研究,那麼建議嘗試從相同的分布中選擇開發集和測試集。這會讓你的團隊更有效率。
Chapter 7、How large do the dev/test sets need to be? (開發集/測試集需要多大?)
開發集應該足夠大,以檢測您嘗試的算法之間的差異。
例如,如果分類器A具有90.0%的準确度,分類器B具有90.1%的準确度,那麼100個樣本規模的開發集将不能檢測出這0.1%的差異。常見的開發集的大小在1,000到10,000個樣本之間。有10,000個樣本,你将有可能檢測到這0.1%的提升。
對于一些成熟的應用,例如廣告,網絡搜尋和商品推薦 – 有很多團隊,甚至為提升0.01%積極努力,因為它對公司的利潤有直接影響。在這種情況下,開發集可以遠大于10,000,以便檢測出這種細微的提升。
測試集的大小應該多大?它應該足夠大,使得對系統的整體性能有一個高的置信度。一個比較常見的啟發式方法是将30%的資料用于測試集。當你有适量的樣本,比如100到10,000的樣本,它會工作的很好。但在大資料的時代,我們遇到很多機器學習問題有時會超過十億個樣本,這種情況下配置設定給開發集/測試集的比例一直在縮小,即使開發集 /測試集中的樣本絕對數量一直在增長。除了需要評估算法的性能之外,沒有必要提供過大的開發集/測試集。
Chapter 8、Establish a single-number evaluation metric for your team to optimize(為你的團隊進行算法優化建立一個單一數字的評估名額)
當我們面對大量的分類器中進行選擇時,使用單一數字的評估名額可以加快你做出決策的能力。所有這些都給出了明确的性能排名,進而給出一個清晰的前進方向。
分類準确率(Accuracy)是一種單一的評價名額,比如我們說分類器A有97%準确率,分類器B有90%準确率,那麼我們說分類器A優于分類器B。
而查準率(Precision)和查全率(Recall)就不是一個單一數字的評估名額:它給出了兩個數字來評估分類器。擁有多個數字的評估名額使得比較算法更加困難。假設你的算法表現如下:

如果你真的即關心查準率(Precision)又關心查全率(Recall),我推薦使用一種标準方法将它們組合成一個單一的數字。例如,可以取Precision和Recall的平均值,最終得到單個數字。或者,你可以計算“F1度量(F1 score)”,這是一種基于其平均值改善的方法,比簡單地取平均值效果要好:
另一種例子,假如你分别要在四個主要市場((i)美國,(ii)中國,(iii)印度和(iv)其他地區)跟蹤貓分類器的準确率。這裡提供了四個名額。通過對這四個資料進行平均或權重平均,最終得到一個單一數字度量。取平均值或權重平均值是将多個名額合并為一個的最常見的方法之一。
Chapter 9、Optimizing and satisficing metrics(優化名額和滿足名額)
這裡還有一種組合多個評估名額的方法。
假設你同時關心算法的準确率和運作時間。你需要在如下三個分類器中進行選擇:
這種情況下,如果将準确率和運作時間通過如下一個公式得到單個評估名額會看起來不太自然,例如:Accuracy − 0.5∗RunningTime
這個時候我們可以這樣做:首先,定義一個“acceptable”的運作時間。例如任何運作時間在100ms以内的算法都是可接受的。然後,根據滿足運作時間标準的分類器,最大化準确率。這裡,運作時間就是一個“satisficing metric”,你的分類器必須要在這個名額上表現地“good enough”就行,這就意味着它最多為100ms。準确率是一個“optimizing metric”。
這種方法可以推廣到多個情況,如果你正在權衡N個不同的标準,你可以考慮将其中N-1個标準設定為為“satisficing”名額。也就是說你隻需要他們滿足特定的值即可。然後将最後一個定義為“optimizing”名額。
一旦你的團隊按照評估名額進行優化,他們将能夠取得更快的進展。
Chapter 10、Having a dev set and metric speeds up iterations(有一個開發集和評估名額來加速疊代)
對于一個新問題,其實很難事先知道用什麼方法是最合适的。即使經驗豐富的機器學習研究人員通常也會在嘗試過很多想法之後,才能發現令人滿意的東西。在建構機器學習系統時,我經常會:
- 首先有一些如何建構系統的想法(idea)
- 用代碼(code)來實作這些idea
- 進行實驗(experiment),來告訴我的這個idea工作的如何。(通常我的前幾個想法并不能work)基于這些學習,回去進而産生更多的idea,并不斷疊代。
這是一個不斷疊代的過程。你循環得越快,你的進展也就越快。這就是 開發/測試集 和評估名額非常重要的原因:每次嘗試一個idea時,在開發集上衡量idea的表現,将使你快速判斷你是否在朝着正确的方向前進。
相反,如果你沒有特定的開發集和評估名額。那麼每次團隊開發出一個新的貓分類器時,你必須把它移植到你的app中,并體驗幾個小時來感受一下這個新的分類器性能是否有提升。這将非常慢!
此外,如果你的團隊将分類器的準确率從95.0%提升到95.1%,你可能無法通過體驗app來感受到0.1%的提升。而通過不斷積累這些許多個0.1%的改進,你的系統将取得很大的進步。
有一個開發集和評估名額,可以使你很快地檢測出哪些想法給你的系統帶來了小(或大)的提升,是以你可以快速決定哪些想法可以繼續改善,哪些可以舍棄。
Chapter 11、When to change dev/test sets and metrics(什麼時候需要更改開發/測試集和評估名額)
當開始一個新項目時,我會試圖快速選擇開發/測試集 ,因為這樣可以給團隊制定一個明确的目标。
如果你之後發現初始的開發/測試集或評估名額與目标有失偏頗,那麼使用一切手段快速更改它們。例如,如果在你的開發集和評估名額上分類器A比分類器B表現好,但你的團隊認為分類器B在實際産品中表現的更優越,這可能表示你需要更改開發/測試集或評估名額。
造成開發集/評估名額不正确地把分類器A排得更高的原因可能有:
- 實際資料分布和開發/測試集不同。假設你的初始開發/測試集主要是一些成年貓的照片。你檢視貓app,發現使用者上傳了比預期多很多的幼貓的照片。是以,開發/測試集的資料分布并不能代表實際的資料分布。這種情況下,更新你的開發/測試集,使其更具代表性。
- 你已經在開發集上過拟合了。在開發集上反複評估想法的過程導緻算法逐漸對開發集“過拟合”。當完成開發後,你将在測試集上評估你的算法。如果你的算法在開發集上的表現遠好于在測試集上的表現,這意味着你已經過拟合開發集。這種情況下,更新開發集。但不要使用測試集來對算法做任何決定,如果這樣做,你将開始過拟合測試集,并且不能再依靠它來完全無偏見的評估系統的性能(你可能會在發表研究論文或做出重要商業決策是使用這個名額)。
- 評估名額衡量的并不是項目所需要優化的東西。假設對于你的貓app,你的評估名額是分類準确率。目前在該名額下分類器A優于分類器B。但是假設你嘗試了這兩種算法,發現分類器A會偶爾允許色情圖檔通過。那麼即使分類器A準确率更高,偶爾的色情圖檔所帶來的壞影響也意味着其表現是不可接受的。你需要做什麼呢? 這裡,該評估名額不能辨識出對産品而言算法B比算法A更好這一事實。是以,你不能再相信該名額能挑選出最佳算法。是時候改變評估名額了。例如,你可以更改評估名額,嚴厲懲罰色情圖檔分類錯誤。我強烈建議你選擇一個新的評估名額,并用新的标準來為團隊明确定義一個新的目标,而不是在一個不可信的評估名額下處理太長時間,并恢複到手工選擇分類器。
在項目中改變開發/測試集和評估名額是很常見的。擁有一個初始的開發/測試集和評估名額能幫助你快速疊代。如果你發現 開發/測試集和評估名額不再使你的團隊在正确方向上前進,這不是什麼大問題!隻需要改變它們,并確定你的團隊知道新的方向。
Chapter 12、Takeaways: Setting up development and test sets(小結:建立開發集和測試集)
- 從分布中選擇開發集和測試集,該分布反映你期望在未來獲得什麼樣的資料,并希望在上面做得很好。這可能和你訓練資料的分布不一樣。
- 如果可能的話,選擇來自同一分布的開發集和測試集。
- 為你的團隊選擇單一數字的評估名額進行優化。如果你關心多個目标,考慮把它們合并到一個公式中(例如平均多個錯誤名額),或設定滿足名額和優化名額。
- 機器學習是一個高度疊代的過程:在發現你滿意的方法之前你可能需要嘗試很多的idea。
- 開發/測試集和單一數字評估名額可以幫助你快速評估算法,進而疊代的更快。當開始一個全新的應用時,嘗試快速建立開發/測試集和評估名額,最好在一周之内。當然,在成熟應用上花費更長的時間是ok的。
- 當你擁有大量資料時,依據70%:30%的比例劃分訓練/測試集這一經驗性的方法不太适用;開發/測試集可以占遠小于30%的資料量。
- 你的開發集應該足夠大,以檢測出算法準确性有意義的改變,但沒必要更大。你的測試集應該足夠大,大到能對你的系統整體性能有一個确信的評估。
- 如果你的開發集和評估名額不再使你的團隊在正确方向上前進,快速改變它們:
(i)如果你過拟合了開發集,去獲得更多的開發集資料。
(ii)如果你所關心的實際分布和開發/測試集的分布不同,那麼去獲得新的開發/測試集資料。
(iii)如果你的評估名額不再能衡量對你來說最重要的東西,改變評估名額。
參考:
1.http://www.mlyearning.org/
2.https://xiaqunfeng.gitbooks.io/machine-learning-yearning/content/
更多個人筆記請關注:
知乎專欄:https://www.zhihu.com/people/yuquanle/columns
公衆号:StudyForAI(小白人工智能入門學習)