建立機器學習實戰系統的十大經驗教訓

banq發表於2014-12-28
這是來自Netflix機器學習系統的構建經驗,Netflix是機器學習應用實戰的先驅之一,曾經設立百萬獎金用於獎勵影片推薦系統演算法。最近他們又公佈了在機器學習系統的十大經驗教訓,下面大意翻譯一下:

有很多很好的介紹機器學習的教科書和課程,,甚至可以學習一些最複雜的特定的方法或演算法,理解這些理論是一個非常重要的基礎和起點。還有很多構建真實系統的實際問題,你可能聞所未聞。這篇文章將分享一些Netflix多年來構建大型系統放的最重要的教訓,Netflix是跨許多國家支援數以百萬計的使用者規模。(Netflix是線上影片網站,每晚影片流量佔據全美網際網路流量近1/3,是亞馬遜雲端計算的大使用者。)

1.更多資料 對戰 更好的模型

有很多文章已經指出獲得更好的結果的關鍵是改善你的演算法,或將更多資料用於訓練你的模型。

儘管很多團隊試圖為模型新增額外功能以提高結果,但是沒有什麼進展,時隔一年以後,他們發現增加一些後設資料能提高微調得很好的演算法的預測精確性,有許多增加更多資料的途徑,Netflix是透過增加特徵的數量和型別,這樣能夠提高問題空間的維度,以完全不同的方式增加資料填滿空間維度,然後簡單地再扔給更多樣本訓練即可。

谷歌也曾經說:Google並沒有更好的演算法,只是有更多資料而已。

確實,更多資料能夠形成更多訓練樣本,這真的行嗎?其實不一定是真的,帶有巨量特徵的複雜模型會導致"high variance",但是在大多數情況下這還是有用的,在真實的Netflix應用場景中,增加超過2百萬的訓練樣本幾乎沒有什麼效果。

這就形成了我們的第一個教訓,其實不是關於更多資料對決更好演算法,這樣的二分法是錯誤的,有時,你需要更多資料,有時你並不,也需要提高你的演算法,有時兩種沒有什麼區別,專注於一個則另外一個會離最佳化越遠。

2.你並不需要所有的大資料

這個教訓其實前面配套,但是值得在這裡明確一下,今天,每個人似乎都需要他們的所有大資料,大資料被大量宣傳,好像如果你不使用巨量資料你就做錯了,事實是有許多問題你只要是少得多的資料會得到類似的結果。

想想Netflix Prize,你有0.5M使用者資料集,這個資料集可以用於計算50因素的矩陣,如果使用50M而不是0.5M結果會發生很大不同嗎?可能不會。

一個重要問題是如何決定你使用的資料子集?一個好的初始目標是隨機從原始資料中取樣,滿足模型訓練,以Netflix Prize為案例,使用者是非常不同,表現非同質化,新使用者,並沒有多少等級,在資料集增加得比較稀少,而另外一個方面,他們也許有不多於老使用者的行為,我們要讓我們的模型捕獲它,解決方式使用 stratified sampling某種形式,設定一個好的stratified sampling的Schema並不容易,因為它需要我們定義不同的strata,決定什麼是樣本用於訓練模型的好的組合,一個定義良好的stratified取樣子集也許比使用原始完整資料集更好。

Netflix認為更多資料好於更好的模型,一些學生透過新增來自IMDB後設資料改進了Netflix的推薦結果。

當然不是說有很多資料是壞事,你有更多資料,你就有更多選擇如何使用它們.

3.更多複雜模型雖然無濟於事但不代表你一個也不需要

假設你有一個線性模型,有時你得選擇和最佳化這個模型的特徵,一天你決定用同樣的特徵實驗一個更復雜的模型,大部分情況你沒有看到任何提高。

失敗以後,你改變策略,再反過來試驗,使用老的模型,但是增加更具豐富的特徵,試圖捕獲更復雜的互動,大部分情況下結果相同你沒看到任何提高。

到底是怎麼回事?其實一個更復雜的特徵需要更復雜的模型,反之亦然,一個更復雜的模型需要更復雜的特徵。

教訓是:你必須並行提高你的模型和特徵集合,某個時間只做其中一個可能會導致錯誤的結論。

4.想想你是怎麼定義和訓練你的資料集

如果你訓練一個二進位制分類器,首要任務是定義正負樣本,為樣本定義正負標籤也許不是普通任務,聯絡場景考慮,比如你需要一個分類器區分顯示看過的使用者(正)和沒有看過的(負),在這個上下文場景中,下面哪些是正負?

1.使用者看了一部影片,投票一個顆星
2.使用者又看了同樣的電影(也許因為他沒其他可看)
3.使用者在5分鐘或15分鐘或1小時後退出影片
4.使用者在兩個片段或10片段或一季後退出TV show
5.使用者增加一些東西到他的列表,但是從來沒有看過。

正如你看到,決定一個案例的正負並不容易。

除了關注正負定義以外,還有很多事情在你訓練資料集時必須確保正確的,一個情況是Time Traveling,Time Traveling被作為特徵定義使用,這是起源於你試圖預測的事件。(見原文...)


5.學會處理介面展現層的偏差( presentation bias)

使用者在介面上點按,會啟用你的演算法已經決定展示給他們的結果,當然你的演算法決定的結果是符合使用者的預測,讓我們假設一個新使用者進來,我們決定展示給這個使用者僅僅是流行的商品,一個星期後,使用者也許消費了某個流行的商品,但是不意味著該使用者喜歡它,只是這個商品是他唯一選擇消費的機會。

解決這個問題一個方式是實現一些展現折扣機制。

另外一個方式是使用使用者的瀏覽而不是點選商品作為訓練過程的負向,如果一個使用者查詢,然後在結果頁面上點按第三個商品,那意味著前面兩個商品是壞的,不應該作為負向訓練? 或者不是?前面兩個比第三個好像差一點點,但是不意味著它們一直很差,比如比第四個商品,這些讓你的原始模型決定的選擇是沒有益處的,你需要移除展現偏差。

第一種方式是引入一些隨機性,這會允許收集一些非偏差使用者反饋,以便決定哪個商品是好還是差。

另外一個方式是開發一些使用者的“注意力模型”,這樣點選或沒有點選的商品都會作為權重,只要使用者能夠注意到它們,它們的位置可能是在頁面會讓人注意感興趣的區域。

最後,你還可以透過使用一些explore/exploit方式,比如Thompson Sampling等
...

6. UI是聯絡演算法和最重要的使用者之間唯一通道

從前面案例你已經發現對展現層和使用者介面進行思考在機器學習演算法設計中是多麼重要,一方面,介面產生使用者所有的反饋,可以作為演算法的輸入,另外一個方面,UI是僅有的我們演算法展示的地方,它不關注我們的ML演算法多麼智慧,如果UI隱藏了或沒有讓使用者產生反饋,我們關於模型的所有努力都是徒勞。

在使用者介面的改變也許需要演算法的改變,正如模型和特徵之間的聯絡一樣,在演算法和展現層之間聯絡也同樣需要注意。

7.資料和模型非常棒,但是你知道什麼更重要?正確的演化路徑

這可能是這些教訓中最重要的,所有關於資料 模型 和基礎設施都很重要,如果沒有正確的自我進化的路徑,這些都沒有用,如果你不知道如何衡量和提高,你只能是無休止空轉車輪,其實哪兒也去不了,一些我在實踐中見過最大的收穫確實來自模型被最佳化微調後的結果

那麼什麼是正確的進化途徑,下圖是演示了從起始開始離線/線上不斷創新,不管你的ML演算法最終目標是什麼,你應該是透過兩種不同方式驅動你的創新演進:離線和線上。

[img index=1]

首先,你應該以離線方式遵循傳統ML經驗試驗不同的模型和特徵,訓練你的模型到某個程度,你能最佳化引數到一個有效範圍,最後在測試資料集中評估結果。在Netflix場景中,評估衡量可以是IR衡量,如精確度和recall, ROC curves, 或者排名度量如NDCG, MRR, 或FPC (Concordant Pairs的分形).....

離線經驗是很棒的,因為一旦你有正確的資料和正確的測量,那麼你就容易獲得以很少資源執行很多的經驗,不幸的是,成功的離線經驗也會被用於錯誤的線上測試,很多公司正在投入以發現離線和線上的結果的相關性,這還是一個未解決的問題,需要更多研究。

線上經驗通常是A/B測試(其他 Multiarmed Bandit Testing 或 Interleaved Testing正在逐步流行),A/B測試目標是量化跨同一個集合不同演算法的區別不同的程度。

選擇適當的評估方式很重要,它確保產品中所有決定並不都是資料驅動的。

大多數人民有不同的跟蹤AB測試的度量方式,最重要是搞清楚Overall Evaluation Criteria (OEC)
....


8.分散式演算法?是的,但是在什麼層次?

分散式演算法需要很多資源,主要決定於你在哪個層次分發:

Netflix在三個層次分發:
1.基於整個資料的每個獨立子集
2.混合引數的每個組合
3.每個訓練資料集的所有分割槽


第一層為不同地區 不同語言的使用者定義不同的訓練資料集,訓練能夠無需協調或資料聯絡情況下分佈。

(此處省去幾段介紹如何在三層分佈的細節...)

Netflix是透過亞馬遜AWS雲分佈器人工神經網路,對於第一層,不同AWS區域使用不同機器例項,對於2層,在同樣區域使用不同機器,設立一箇中央點用於協調,使用Condor進行叢集協調(其他選項是StarCluster Mesos甚至Spark),第三層最佳化使用在GPU上定製的CUDA程式碼。

[img index=2]


9.對混合引數Hyperparameters的付出總會有回報

建立你的ML系統最重要是微調混合引數,大部分情況下,演算法總是有一些混合引數需要微調:
矩陣分解(matrix factorization)的學習率,邏輯迴歸(LR:logistic regression)的正則lambda,
神經網路的隱藏層數量,gradient boosted decision trees(GBDT)的損率等等,這些都有引數需要微調到有效資料。

(此處略去詳細微調介紹....)

10. 有些事情你能離線完成,也有不能的,可選擇在離線和線上之間的Nearline.

之前我們討論了資料 模型 UI和度量的重要性,現在應該是聚焦系統和架構,當你的ML模型最終目標是在生產環節有重要影響,你有必要得思考正確的系統架構。

在延時和複雜性之間權衡很重要,一些計算需要實時,儘快響應給使用者反饋,另外複雜的ML模型需要大量資料,需要長時間才能計算好,還有一些近乎線上NearLine,操作不保證實時發生,但是最好儘可能快地執行。

總結:
1.思考你的資料
2.理解資料和模型的依賴
3.選擇正確的度量
4.只最佳化重要的

原文

[該貼被banq於2014-12-30 16:37修改過]

相關文章