最詳盡翻譯:Rules of Machine Learning: Best Practices for ML Engineering

原文地址:https://developers.google.com/machine-learning/rules-of-ml/
作者:Martin Zinkevich

##前言

Google大佬Martin Zinkevic近期寫了一篇機器學習(ML)學習經驗的文檔,乾貨多多,特翻譯過來分享給大家。

Martin Zinkevich:本文檔旨在幫助具有機器學習基本知識的人員瞭解Google在機器學習方面的最佳實踐。本文提供了機器學習的學習指南,類似於Google C ++風格指南和其他實用編程的流行指南。如果你學過機器學習課程或者有實踐經驗,那麼你已經擁有了機器學習的背景知識。

##術語:

在開始分享整個工作之前,先來闡述一些術語:

Instance:實例。需要預測的事物稱爲實例。例如,該實例可能是您要分類爲“關於貓”或“不關於貓”的一個網頁,或者其他類別。
Label:標籤。待預測任務的真實結果稱爲標籤。無論是機器學習系統預測的結果,還是訓練數據的結果,都稱爲標籤。例如,將網頁標記爲“關於貓的”,“關於貓的”就是標籤。
Feature:特徵。預測任務中使用的實例的屬性。例如,一個網頁可能有一個功能“包含單詞’貓’”。
Feature Column: 特徵集合。比如用戶可能居住的國家,Feature Column包含實例的一個或者多個特徵,它是Google制定的的術語,在其他系統中類似命名空間。
Example:instance+label
Model:模型。預測任務的統計表示。使用實例訓練模型,然後使用該模型進行預測。
Metric:度量指標。評價指標,有的可以直接優化有的不行。
Objective:工程中希望去優化的一個Metric。
Pipeline:圍繞機器學習算法的基礎步驟或流程。包括數據收集,製作成訓練數據,模型訓練以及最後的模型預測。
Click-through Rate:點擊率,比如訪問者點擊網頁中廣告的比例。

##概述

要想做好一個機器學習產品,只需要做到:

以一個偉大的機器學習工程師,和機器學習專家的心態去做機器學習

實際上,你將面臨的大部分問題都是工程問題。對於工程來說,特徵(Features)爲王,越好的結果更依賴於好的特徵,而不是一個偉大的機器學習算法。所以,機器學習的基本的方法是:

  1. 確保你的pipeline是端對端穩定的
  2. 確定一個合理的objective
  3. 以簡單的方式增加尋常意義的特徵-features。
  4. 確保你的pipeline仍然穩定

在學習前期,這個方法可以陪伴你很久。只有使用更多的tricks無法更近一步時,纔會從這種方法中分化出來,在此基礎上增加複雜度,但是方法越複雜, 所耗費的時間精力越多。
當所有簡單的trick用完後,就可以開始一些尖端的機器學習技術了。
本文包括四個部分:

  1. 第一部分應該幫助您瞭解遇到的情況是否適合建立機器學習技術解決。
  2. 第二部分是關於部署你的pipeline
  3. 第三部分是向pipeline中增加特徵,評估模型和訓練偏差,不斷迭代這個過程。
  4. 最後一部分是遇到瓶頸時該怎麼做。

之後,有一份相關工作清單和一份附錄

##序言:寫在正文開始之前

####法則1

rule #1:Don’t be afraid to launch a product without machine learning.
不要擔心發佈的產品沒有用到機器學習技術

機器學習很酷,但它需要數據。理論上,您可以從不同的問題中獲取數據,然後調整新產品的模型,但這可能會比基本啓發式算法差。如果你認爲機器學習會給你100%的提升,那麼啓發式會讓你獲得50%的機會。

例如,如果您在應用市場中對應用進行排名,則可以使用安裝率或安裝次數作爲啓發式。如果您檢測到垃圾郵件,請過濾出之前發送過垃圾郵件的發佈商。不要害怕使用人工編輯。如果您需要對聯繫人進行排名,請排列最近使用的最高(甚至按字母順序排列)。如果您的產品不是絕對需要機器學習,那麼在您有數據之前不要使用它。
####法則2

rule #2:First, design and implement metrics.
首先,針對問題設計和完善評價體系

在開始設計機器學習系統之前,有足夠的理由去當前系統的歷史信息和問題,比如:

  1. 早期更容易獲得系統用戶的權限許可,收集數據更容易。
  2. 如果你覺得某個問題以後會受到關注,最好是從現狀開始就蒐集歷史數據。
  3. 如果在設計機器學習系統的時候時刻考慮到你的度量指標,那麼事情變得更容易,未來也可以避免很多麻煩的事情。
  4. 必須要注意到系統中的變化量和保持不變的量,比如,假設想要直接優化每天的活躍用戶數,如果使用早起的系統可能發現,用戶體驗度的改變並沒有明顯的改變用戶活躍度。

Google Plus團隊衡量指標可擴展每次閱讀,每次閱讀的閱讀次數,每次閱讀的閱讀量,評論/閱讀,每位用戶的評論數,每位用戶的轉化率等等,這些數據用於計算服務時間的帖子的好壞程度。另外,請注意,一個實驗框架非常重要,您可以在其中將用戶分組並通過實驗彙總統計信息。見規則#12
通過更加自由地收集指標可以幫助設計者更全面地瞭解機器學習系統。如果注意到一個問題?添加一個指標-metric來跟蹤它!對上一版本的一些量化變化感興趣?添加一個指標來跟蹤它!
####法則3

Rule #3: Choose machine learning over a complex heuristic.
在複雜的啓發式方法和機器學習技術之間,優先選擇機器學習技術。

基於簡單的啓發式方法的產品完全可以可靠的運行。但是複雜的啓發式的方法是不可維護的。一旦你有了新的數據或者實現新的想法,你會希望不斷更新您的方法,不管它是啓發式還是機器學習模型,最終會發現機器學習模型更易於更新和維護(請參閱規則16)。

##建立第一個機器學習pipeline

開始設計機器學習工程系統的時候,一定要確保設計的pipeline的可靠性。

Rule #4: Keep the first model simple and get the infrastructure right.
設計第一個模型的時候不需要設計的很複雜,但是一定要可靠

第一個模型爲最終的產品提供了基礎支持,所以它不需要花哨。但是,你會遇到比你期望的更多的基本問題。在任何人都可以使用你的新機器學習系統之前,你必須確定以下三點:

  1. 如何爲機器學習系統收集學習樣本(examples)
  2. 要確定你的系統對於“好”和“壞”意味着什麼。
  3. 如何將您的模型整合到應用中。你可以應用實時模型,也可以預先計算脫機示例中的模型,並將結果存儲在表格中。例如,您可能希望對網頁進行預分類並將結果存儲在本地,但你也可能想要對聊天消息進行實時分類。

選擇簡單的特徵能更容易確保:

  1. 特徵正確應用到算法中
  2. 模型能夠學習到合理的權重
  3. 特徵正確應用到模型中

一旦構建成功了滿足上面三個條件的模型,大部分工作其實已經完成了。初始的模型可以提供baseline的metric,在此基礎上設計更復雜的算法完善模型,結果與baseline相比較,可以比較算法優劣。

Rule #5: Test the infrastructure independently from the machine learning.
獨立的測試機器學習系統的各模塊

將系統中的各個部分模塊化,獨立的測試各個模塊的性能,具體來說:

  1. 測試數據輸入到算法中是否正確。檢查應該填充的feature column是否正確填充,在隱私許可的情況下,手動檢查您的訓練算法的輸入。如果可能,請檢查pipeline中的統計數據,並與其他地方處理的相同數據的統計數據比較。
  2. 確保模型的魯棒性。確保訓練環境中的模型與實際部署環境中的模型具有相同的分數(請參閱規則#37)

機器學習中很多不可預測的因素,因此請確保你在訓練環境和部署環境中都使用所有的樣本測試過代碼的每一部分,而且確保可以在部署環境中加載和使用訓練好的模型。此外,瞭解您的數據非常重要:Practical Advice for Analysis of Large, Complex Data Sets.

Rule #6: Be careful about dropped data when copying pipelines.
複製舊的pipeline做新的pipeline的時候,當心數據的丟失

通常我們通過複製現有pipeline來創建新的pipeline,舊pipeline會丟棄我們在新pipeline中所需的數據。例如,Google Plus What’s Hot的pipeline會丟棄較舊的帖子(因爲它試圖對新帖進行排序)。這條pipeline被複制用於Google Plus Stream,其中較舊的帖子仍然有意義,但新的pipeline不希望捨棄舊的帖子。

Rule #7: Turn heuristics into features, or handle them externally.

通常機器學習試圖解決的問題並不是全新的。現有的系統可用於排序,分類或任何你試圖解決的問題。這意味着有一堆規則和啓發式方法。這些相同的啓發式技術可以在機器學習時進行調整。由於兩個原因,您的啓發式技術應該針對他們擁有的任何信息進行挖掘。首先,向機器學習系統的過渡將會更順暢。其次,通常這些規則包含了很多你不想扔掉東西。有四種方法可以使用現有的啓發式方法:
用啓發式規則進行預處理。 若特徵相當完美,則可以採用這個方法。舉個例子,在垃圾郵件過濾器中,如果發件人已經被加入黑名單了,則可以不用重新學習“黑名單”的概念。直接阻止該信息就可以!這種方法在二元分類(binary classification)任務中很有用。

創建特徵。 直接從啓發式規則中創建特徵會很便捷。舉個例子,若要用啓發式規則爲某個查詢結果計算相關度,你可以把分數納入特徵的值中。接下來,用機器學習的方法來處理這些值(例如,把這些值轉化爲由一系列離散值組成的有限集,或者也可以與其它特徵相結合),但是要從啓發式方法生成的原始數據入手。

  1. 是用啓發式的方法做預處理。如果一些特徵很awesome,那麼考慮其作爲一個備選項。例如,如果在垃圾郵件過濾器中發件人已被列入黑名單,那對於此人的消息選擇屏蔽即可,而不是重新考慮一下黑名單的意義。這種方法在二分類任務中最有效。
  2. 製作特徵。從先驗方法中直接獲取特徵是很好的。例如,如果你使用啓發式來計算查詢結果的相關性分數,則可以將分數包括爲某個要素的值。稍後,你可能需要使用機器學習技術來處理該值(例如,將該值轉換爲有限的一組離散值中的一個值,或將其與其他特徵組合),但首先使用啓發式生成的原始值。
  3. 挖掘啓發式的原始輸入。如果應用程序具有啓發式功能,它將安裝次數,文本中的字符數以及星期幾組合起來,考慮作爲特徵-features使用。適用於模型集成的一些技巧(參見規則#40)。
  4. 修改標籤。當你發覺啓發式方法捕捉了一些信息,而這些信息沒有包含在標記中,這時可以考慮該選項。舉個例子,如果你想讓下載量達到最大,但同時對內容的質量有要求,那麼可以用 app 的平均評級乘以標記來解決問題。

####監控-Monitoring

一般來說,系統中要包含警報程序,或設計界面使警報得以顯示

Rule #8: Know the freshness requirements of your system.
掌握系統的實時需求

如果你使用的模型是昨天的模型,那麼昨天的模型適應今天的需求嗎?如果用的模型是一週前甚至一個季度前的呢?還可以保證同樣的精度嗎?因此,對系統的監控是必要的,知道何時該刷新系統能幫助你劃分監控的優先級。如果你的模型一天沒有更新,受益便下降 ,因此有必要指派一名工程師時關注它的動態。大多數廣告服務系統每天都會有新的廣告,因此需要實時處理和更新。比如,如果Google Play Search的機器學習模型一個月沒有更新,它將帶來負收益。對於含有post identifier 的模型需要經常更新模型。但是對於GooglePlus 的What’s Hot 中的模型並沒有post identifier,所以他們可以不用頻繁的導出模型。同時也應注意,信息的freshness是實時變化的,尤其是模型的feature columns更新時。

Rule #9: Detect problems before exporting models.
確保模型導出前沒有問題

對於工程來講,機器學習模型最終要上線運行,如果上線後出了問題,面對這個問題的將是用戶。因此在導出模型之前多次檢查模型是很正確的做法,具體來說,一定要保證模型在所持的數據上表現很好,如果對數據保持懷疑態度,那請不要上線運行。許多的團隊會不斷的部署模型檢查ROC曲線下的面積參數。記住:問題出在上線前後的代價是不一樣的,所以在輸送給用戶之前,耐心的確保模型的可靠性。

Rule #10: Watch for silent failures.

機器學習系統很容易出現隱藏的問題。比如系統的某些存放信息的table一直沒有更新,短時間內系統仍能維持較好的性能,但是性能會隨時間衰減。有時可能發現簡單的刷新這些table可以大幅度提升性能,甚至大幅超過新季度的模型。解決此問題的方法是是對關鍵數據的統計信息進行監控,並且週期性對關鍵數據進行人工檢查。

Rule #11: Give feature columns owners and documentation
記錄feature columns的詳細信息和創造者

如果系統的規模比較大,並且特徵欄比較多,那麼必須清楚每個特徵欄的創建者或者維護者。如果某個瞭解該特徵欄的人離開了,一定要確保另外還有人瞭解這部分信息。雖然很多特徵欄的名字非常直觀,但最好還是使用更詳盡的文檔來描述這些特徵的內容、來自哪裏以及它們的作用。

##Objective

metric是系統的評估指標,其重要性與否視情況而定,見rule#2,但是Objective是算法優化的目標

Rule #12: Don’t overthink which objective you choose to directly optimize.
不要糾結應選擇那一個objective去優化

想關心的metrics太多了,就好像你想掙錢,想讓用戶高興,想讓這個世界更好,想…,實際上應該measure所有metrics。然而,在機器學習算法的設計的前期,會發現即使沒有直接優化一些指標,但是他們的metrics同樣會增加。比如,假設你想優化網站的點擊率和網站停留時間,會發現優化其中一個metric,另一個也會相應的增長。
所以,在設計算法的前期,提高所有的metric都不是很難,就沒必要花心思來如何權衡不同的指標。不過過猶不及:不要混淆了你的目標和系統的整體健康度。

Rule #13: Choose a simple, observable and attributable metric for your first objective.
選擇一個簡單、可觀測並且可歸類的metri作爲第一個objective

大多數情況下你並不清楚最合適的objective是哪一個。即使定下一個objective之後,經過對數據和模型的分析,想要調整objective也是正常的。另外,團隊的不同成員對objective可能會有不一樣的選擇。ML的objective應該是容易去測量的,並且確保是true的。但是,有時候可能沒有一個完全true的objective(見Rule#39)
因此,在簡單的機器學習objective上訓練,並創建一個“決策層”-“policy layer” ,以允許你在上面增加額外的邏輯(這些邏輯,越簡單越好)。

最簡單的機器學習建模方法是直接觀察並歸屬到系統操作的用戶行爲:

  1. 經過排序後的鏈接是否被點擊?
  2. 排序後的對象是否被下載?
  3. 對象是被轉發/回覆/通過電子郵件發送的嗎?
  4. 對象是否被評價?
  5. 顯示的對象是否標記爲垃圾信息/色情/侵犯?

一開始避免對間接效應建模,一些間接效應如下:

  1. 用戶第二天是否還會訪問這個鏈接
  2. 用戶瀏覽此鏈接的長短
  3. 每天有多少活躍用戶

間接效應可以做出很好的衡量標準,並且可以在A / B測試和發佈決定期間使用。

最後,避免用機器學習直接解決如下問題:

  1. 用戶是否樂意使用該產品?
  2. 用戶對體驗滿意嗎?
  3. 該產品是否改善了用戶的整體健康狀況?
  4. 這將如何影響公司的整體健康?

不是說這些問題不重要,而是它們很難直接優化。話說回來:如果用戶很高興,他們會留在網站上更長時間。如果用戶滿意,他們將在明天再次訪問,一些指標是相輔相成的。

Rule #14: Starting with an interpretable model makes debugging easier.
選擇可解釋的機器學習模型很利於早期調試

線性迴歸,邏輯迴歸和泊松迴歸直接由概率模型驅動。每個預測都可以解釋爲概率或預期值。這使得它們比試圖直接優化分類準確性或排名性能的使用目標(零失敗,各種鉸鏈損失等)的模型更容易調試。例如,如果訓練中的概率偏離了並行預測的概率或通過檢查生產系統,則這種偏差可能會出現問題。

例如,在線性,邏輯或泊松迴歸中,有數據的子集,其中平均預測期望等於平均label。假設你沒有正則化並且你的算法已經收斂,這是真實的,並且通常情況下它是近似真實的。如果每個示例都具有1或0的特徵,則校準該特徵爲1的3個樣本的集合。另外,如果每個示例都具有1的特徵,則所有示例的集合都將被校準。

使用簡單的模型,處理反饋迴路更容易(見Rule#36)。通常,我們使用這些概率預測來做出決定:例如按降低的期望值排列帖子(即點擊/下載等的可能性)。但是,請記住,何時需要選擇使用哪種模型,決策不僅限於給定模型的數據的可能性(參見規則#27)。

Rule #15: Separate Spam Filtering and Quality Ranking in a Policy Layer.
在策略層將垃圾信息過濾和質量排名分開

對於信息質量的排序是一門藝術,但垃圾信息過濾是一場戰爭。那些使用您的系統的人會變得很明顯會根據你的信息質量排序方法作出相應的對策,並且他們會調整帖子以獲得這些屬性。因此,你的信息排序應該關注排名含金量高的信息。同樣,對於內容“生動”的信息也應與信息質量排序分開處理。
在某種程度上,這兩個系統的輸出將不得不被整合。請記住,在搜索結果中過濾垃圾信息應該比在電子郵件中過濾垃圾郵件受到更多的重視。假設您沒有正則化並且算法已經收斂,這是正確的。一般情況下大致如此。此外,從質量分類器的訓練數據中刪除垃圾信息也是一種標準做法。

##機器學習第二階段:特徵工程-Feature Engineering

在機器學習系統構建的第一階段,重要的問題是將訓練數據放入學習系統,獲取任何感興趣的度量標準,並創建服務基礎架構。在進行了單元和系統測試的端到端系統工作後,即可開始進行機器學習的第二階段-特徵工程

在第二階段,有很多明顯的feature可以被引入到系統中。因此,機器學習的第二階段涉及儘可能多的引入特徵並以直觀的方式將其結合起來。在這個階段,所有的指標在數值上還會繼續增加。

Rule #16: Plan to launch and iterate.
做好 更新模型-發佈-更新模型-發佈-… 過程循環的準備

不要奢望發佈的模型可以作爲最終版本一直work下去。因此,持續更新模型是必須的過程,因此要考慮到你給當前這個模型增加的複雜度會不會減慢後續的發佈。許多團隊每季度推出一個模型。一般以下三種情況會令你希望更新模型:

提出利用新的feature。
希望調整正則化方式,以不同的方式利用原有的feature。
微調了objective

Rule #17: Start with directly observed and reported features as opposed to learned features.
優先使用直接觀測或收集到的特徵,而不是學習出來的特徵(learned features)

這可能是一個有爭議的問題,但它避免了很多陷阱。首先,讓我們描述一個learned features是什麼。learned features是由其他模型或者方法(例如無監督聚類)或由學習者本身(例如通過因子模型或深度學習)產生的features。這兩種方法都很有用,但它們可能有很多問題,所以它們學習到的feature不應該放在現有的模型中。

因爲其他模型或者方法有其自己的objective。此objective或許與現有模型的objective相關性很小甚至衝突。如果你用外部模型或方法更新feature,則其含義可能會改變。

因式模型和深度模型的主要問題是它們是非凸的。因此,不能保證可以近似或找到最優解,並且在每次迭代中找到的局部最小值可以不同。這種變化使得很難判斷變更對機器學習系統的影響是有意義的還是隨機的。通過創建沒有深度特徵的模型,您可以獲得出色的基準性能。達到此基準後,可以嘗試更復雜的方法。

Rule #18: Explore with features of content that generalize across contexts.
嘗試利用具有上下文概括的內容的feature。

通常情況下,機器學習只佔到一個大系統中的很小一部分,因此你必須要試着從不同角度審視一個用戶行爲。比如在What’s Hot中的一個post有許多評論、分享和閱讀量,如果利用這些統計數據對模型展開訓練,然後對一個新post進行優化,就有可能使其成爲熱門post。另一方面,YouTube上自動播放的下一個視頻也有許多選擇,例如可以根據大部分用戶的觀看順序推薦,或者根據用戶評分推薦等。總之,如果你將一個用戶行爲用作模型的標記(label),那麼在不同的上下文條件下審視這一行爲,可能會得到更豐富的特徵(feature),也就更利於模型的訓練。需要注意的是這與個性化不同:個性化是確定用戶是否在特定的上下文環境中喜歡某一內容,並發現哪些用戶喜歡,喜歡的程度如何。

Rule #19: Use very specific features when you can.
儘可能使用針對性的特徵

簡單的feature唾手可得,複雜的feature萬里挑一。由於被檢索的文本標識與規範化的查詢並不會提供太多的歸一化信息,只會調整頭部查詢中的標記排序。因此你不必擔心雖然整體的數據覆蓋率高達90%以上,但針對每個feature group裏的單一feature卻沒有多少訓練數據可用的情況。另外,你也可以嘗試正則化的方法來增加每個feature所對應的樣本數。

Rule #20: Combine and modify existing features to create new features in human­-understandable ways
用可解釋的方式對已有feature進行組合和修改

有很多中方式可以滿足feature的操作和修改。比如深度學習框架Tensorflow,它可以使用transformations的方式對數據做預處理,其中兩個標準的方法就是discretizations和crosses。
Discretization 會根據一個連續的特徵創建許多離散的特徵。假定年齡是一個連續的特徵。我們可以創建如下特徵,當年齡小於 18 時記爲 1,或者當年齡在 18 到35 歲之間時爲 1,以此類推。不用過多考慮如何劃分年齡。

Cross由兩個或多個feature column組成。根據TensorFlow給出的解釋, feature column是一組同類的feature。(如{男,女}、{美國,加拿大,墨西哥}等)。而Cross是一個新的feature column,可以用{男,女}×{美國,加拿大,墨西哥}等來簡單的表示。新的feature column會包含以下feature,如{男,加拿大}。使用TensorFlow時可以讓它幫你創建cross。{男,加拿大}可以在樣本中代表男性加拿大人。注意若模型使用三個以上的feature column組成的cross,則需要大量的數據來訓練模型。

Cross 得方法可以產生很多feature column,有可能導致過擬合現象。舉個例子,假設你要做某種搜索。檢索詞構成一個 feature column,文檔中的詞構成另一個feature column。你可以通過cross 來組合它們,但這樣會出現很多feature(見Rule#21)。處理文本時,有兩個替代性方案。最苛刻的方案是 dot product(點積)。點積僅統計檢索詞和文檔詞中的公共詞彙。得到的feature可以被離散化。另一種方案是取intersection(交集):因此,我們有一個feature來表示當“pony(色情)”這個詞同時出現在文檔和檢索詞中,另一個特徵表示“the”同時出現在文檔和檢索詞中。

Rule #21: The number of feature weights you can learn in a linear model is roughly proportional to the amount of data you have.
線性模型學習的feature參數的數量應大致和樣本數成比例

關於模型的適當複雜程度,統計學習理論可以給出一個很好的結果,即根據數據調整模型的大小。有些人認爲,樣本越多,學習的效果越好,最好的結果是根據數據的多少選擇學習方法,不要僅限於一種方法。

  1. 如果你在開發一個搜索排序系統,並且有數百萬不同的詞彙存在於文檔和檢索詞中,而你僅有 1000 個帶有標記的樣本。那麼你應該使用文檔和檢索詞的點積特徵、 TF-IDF 以及其它六個人工設計的feature。 1000 個樣本,對應 12個左右的feature。
  2. 如果有一百萬個的樣本,那就通過 regularization 或feature selection,取文檔特徵欄和檢索詞feature column的交集。這樣你能得到數百萬個feature,但 regularization會幫你減少些許的feature。一千萬個樣本,對應大約十萬個feature。
  3. 如果有十億個乃至幾千億個樣本,你可以通過 regularization 和feature selection,取文檔feature column和 query token 的叉積。如果有十億個樣本,那麼你會得到一千萬個特徵。統計學習無法給出一個嚴格的數據界限,但是可以提供一個合適的出發點。

可以按照Rule#28選擇feature。

Rule #22: Clean up features you are no longer using.
清除不經常使用的features

不work的feature會給算法帶來阻礙。如果你不常使用這個feature,並且這個feature和其他feature集合在一起也不會帶來精度的提高,那麼就可以拋棄掉這個feature了。相對乾淨feature的模型可以集中在更好的feature的處理上。
但是feature的選擇和丟棄需要注意一點,feature的涵蓋範圍,即此feature和多少數據相關聯。比如一個feature只和8%的用戶相關,那麼這個特徵就相對不是那麼重要,但是也要考慮到feature權重的問題,如果feature關聯的用戶少,但是90%的正樣本包含這個feature,那麼它也是很重要的。

##系統分析

在進入機器學習第三階段前,有一些在機器學習課程上學習不到的內容也非常值得關注:如何檢測一個模型並改進它。這與其說是門科學,還不如說是一門藝術。

Rule #23: You are not a typical end user.
設計者應站在用戶角度看問題

這可能是團隊陷入困境的最簡單方式。儘管fishfooding(在團隊中使用模型原型)和dogfooding(在公司內部使用模型原型)有很多好處,但技術人員應該考慮性能是否正確。性能不好的拒絕使用,新能說的過去的仍需進一步測試。但是應該通過支付外行人在衆包平臺上問題回答或通過對真實用戶進行實時實驗來進一步測試模型。

有兩個原因。首先是你太接近工程。您可能正在尋找帖子的某個特定方面,或者您只是情緒上過度參與(例如確認偏見)。第二是你的時間很寶貴。與其9個工程師花一個小時討論,不如在衆包平臺上找真實的用戶來測試。

如果你真的想獲得用戶反饋,請使用用戶體驗方法。在一個流程的早期創建用戶角色(一個描述在Bill Buxton的Sketching User Experiences中),然後進行可用性測試(一個描述在Steve Krug的“不要讓我想”)。用戶角色涉及創建一個假想用戶。例如,如果你的團隊全部是男性,則可能有助於設計一個35歲的女性用戶角色(具有用戶功能),並查看其生成的結果,而不是25至40歲的10個結果男性。引入實際的人員觀察他們對本地或遠程對網站的反應,可用性測試也可以爲你提供全新的視角。

Rule #24: Measure the delta between models.
測量模型之間的差異

在模型上線之前,最簡單且有時最實用的測量是計算當前模型結果與將投入使用模型的差異。如果差異非常小,那麼你可以不用繼續實驗。如果差異非常大,那麼需要確保差異的性質,是好還是壞。查看對稱差異高的部分可以幫助您定性地瞭解變化是什麼樣,進而進一步確保系統穩定。確保與自身相比較的模型具有較低(理想情況下爲零)的對稱差異。

Rule #25: When choosing models, utilitarian performance trumps predictive power.
模型選擇上,性能比預測能力重要

您的模型可能會嘗試預測點擊率。然而,最終,關鍵問題是你如何處理這個預測。如果您使用它來對文檔排序,那麼最終排序的質量比預測本身更重要。如果你預測文檔是否是垃圾郵件,然後對被阻止的內容進行截取,那麼你的預測精度就會提高。大多數時候,這兩件事應該是一致的:當他們不一致時,它可能會有小幅增益。因此,如果一些改動增加了log loss但是降低了系統的性能,那需要尋找新的feature代替舊的。如果這些事情出現的很頻繁,那麼是時候重新審視一下objective的正確性。

Rule #26: Look for patterns in the measured errors, and create new features.
從測量誤差中尋找問題,創建新的feature解決它

假設模型對訓練樣本給出了錯誤的預測。比如在分類中,存在分錯或者漏分;在排序任務中,這種錯誤是成對存在的。重要的是要另機器學習模型知道這個錯誤並可以解決掉這中錯誤,可以通過創建新的feature幫助模型修復這個問題。

另一方面,如果你基於系統沒有出錯的樣本創建feature,那麼該feature將很可能被系統忽略。例如,假設在 Google Play商店的應用搜索中,有人搜索“免費遊戲”,但其中一個排名靠前的搜索結果卻是一款其他App,所以你爲其他App創建了一個feature。但如果你將其他App的安裝數最大化,即人們在搜索免費遊戲時安裝了其他App,那麼這個其他App的feature就不會產生其應有的效果。

所以,一旦發現模型判斷出錯的樣本,獨立於當前的feature集合外去嘗試解決。例如,如果你的系統降低了內容較長的帖子的排序位置,那就應該普遍增加帖子的長度。而且也不要拘泥於太具體的細節。例如你要增加帖子的長度,就不要猜測長度的具體含義,而應該直接添加幾個相關的特徵,交給模型自行處理,這纔是最簡單有效的方法。

Rule #27: Try to quantify observed undesirable behavior.
量化觀測到異常行爲

你的team中的一些人對損失函數無法優化的系統屬性很煩惱。在這一點上,他們應該盡一切努力把他們的抱怨變成可靠的數據。例如,如果他們認爲Play搜索中顯示了太多“gag apps”,他們可能會讓人類評估者識別gag apps。 (在這種情況下,你可以使用人類標記的數據,因爲相對較小的查詢佔了很大一部分流量。)如果你的問題是可衡量的,那麼你可以開始將它們用作新的feature,objective或metric。一般規則是“先量化,後優化”。

Rule #28: Be aware that identical short-term behavior does not imply identical long-term behavior.
短期表現良好,但是長期運行不一定是這樣

假設你有一個新機器學習系統,它可以查看每個doc-id和exact-query,然後根據每個doc的每次查詢行爲計算其點擊率。你發現它的表現幾乎與當前系統的並行和A/B測試結果相同,而且它非常簡單,於是你發佈了這個機器學習模型。但是新的模型中無法顯示新的APP信息,爲什麼?由於你的系統只基於自己的歷史查詢記錄顯示文檔,所以不知道應該顯示一個新的文檔。
要了解一個系統長期運行的唯一辦法,就是讓它只基於當前的模型數據完成訓練。但是這並不簡單。

##訓練-測試誤差(Training-Serving Skew)
訓練測試誤差是指訓練的精度和測試的精度之間存在誤差,一般由以下幾個原因導致:

  • 訓練測試的數據處理方式不同
  • 訓練和測試的數據不同
  • 模型和算法之間存在反饋

我們在谷歌對機器學習系統做了嚴密的監控,其精度的。最好的解決方案是是對系統和數據的變化進行監控,以便系統和數據的更改不會引起精度的震盪。

Rule #29: The best way to make sure that you train like you serve is to save the set of features used at serving time, and then pipe those features to a log to use them at training time
保存模型上線使用的feature 集合,並記錄到日誌文件中以便訓練使用,這樣可以保證模型訓練和測試不存在誤差。

即使你無法爲每個樣本都做到這一點,只需做一小部分,這樣你就可以驗證訓練和測試之間的一致性(見規則#37)。在谷歌進行這種測量的團隊有時會對結果感到驚訝。 YouTube主頁在服務時間切換到日誌記錄功能,服務質量得到提高,代碼複雜度反而降低。目前有許多團隊都已經在其基礎設施上採用了這種策略。

Rule #30: Importance-weight sampled data, don’t arbitrarily drop it!
對採樣數據按重要性賦權重,不要隨意丟棄它們

如果你有非常多的數據,可能希望只使用其中的一部分完成訓練,但這是錯誤的。那些對用戶不可見的數據是可以被丟棄的,但最好還是給這些數據賦予一定的權重,比如你決定好30%的概率會用到樣本X,那可以給它乘以一個10/3的權重。

Rule #31: Beware that if you join data from a table at training and serving time, the data in the table may change.
從table中組合數據時,要注意訓練和測試table可能會發生變化

假設你想把文檔的id和table中的其他特徵(比如評論或者點擊量)結合起來,在訓練和測試的時候,table中的feature可能會發生變化,模型在訓練和測試的時候對相同的文檔可能會給出不同的預測。避免這種問題最簡單的方法就是記錄所有實際運行時的feature。若table中的數據變化緩慢化,你也可以照一定的頻率對其做出記錄,得到足夠相近的數據。但是這樣不能根治這個問題。

Rule #32: Re-use code between your training pipeline and your serving pipeline whenever possible.
儘量在訓練的pipeline和測試的pipeline中使用相同的代碼

批處理和在線處理是不同的。在線處理必須及時處理每一個請求(比如爲每一個查詢做單獨的查找),批處理中可以合併一些請求做處理。訓練的時候是批處理,上線的時候是在線處理,但是有時候代碼還是可以重用的。比如,你可以創建針對你係統的對象,其中的所有聯結和查詢結果都以可讀的方式存儲,錯誤也可以被簡單地測試。在模型上線或訓練期間收集了所有信息後,你就可以通過一種通用方法在這個特定對象和機器學習系統需要的格式之間形成互通,訓練和服務的偏差也得以消除。因此,儘量不要在訓練時和服務時使用不同的變成語言,畢竟這樣會讓你沒法重用代碼。

Rule #33: If you produce a model based on the data until January 5th, test the model on the data from January 6th and after.
時間上,測試模型的數據要在訓練模型的數據之後

訓練完模型後,使用接下來收集的數據作爲測試樣本可以很好的測量模型的實際表現。如果你的模型是在一月五號訓練完,那麼使用一月六號或者更靠後的數據測試模型。這樣做測試的精度可能比不上訓練的精度,但是也不會差太多。

Rule #34: In binary classification for filtering (such as spam detection or determining interesting emails), make small short-term sacrifices in performance for very clean data.
二分類任務比如垃圾郵件分類中,在非常‘乾淨‘的數據上可以犧牲一些精度換取一些其他提升。

垃圾郵件分類中,被分爲垃圾郵件的郵件不會展示給用戶。假設你的模型可以阻擋75%的垃圾郵件,但是不能總是從展示給用戶的郵件數據中學習,比如用戶把模型分爲正樣本的郵件標記爲了垃圾郵件,這時,你的模型應該從中學習並改進自己。
但是這個方法引入了樣本偏差,你可以從抽出1%的垃圾郵件作爲‘示例‘(hold out),用戶可以看到這些樣本,這顯然影響了最終的過濾效果,但是用戶會重新標記這些郵件是否是垃圾郵件,這樣做,你的模型就可以從中繼續學習。

Rule #35: Beware of the inherent skew in ranking problems.
注意排序問題中的固有偏差

當你調整你的排序算法後,算法的結果之間肯定存在差異。此時應該圍繞這些差異設計你的模型,以下有一些方法可以幫助你優化:

  1. 對涵蓋範圍廣而不是窄的feature做正則化,這種方式使得模型更偏好那些針對個別查詢的feature,而不是那些能夠泛化到被經常查詢的feature,同時也阻止一些經常被查詢的結果被分到不經常查詢中,請注意,這個方法與傳統的方法是相反的。
  2. 僅允許feature有正的權重,這樣好的feature比其他未知的feature要更突出
  3. 不能僅僅有document-only的feature,這是一種極端情況。例如,你也不會想讓最受歡迎的app到處出現而不管真正的查詢是什麼,肯定也希望其他的app可以被下載。例如,有人搜索‘bird watching app‘,展示給他們的是"angry birds",最終"angry birds"下載量會增加,但是用戶顯然不是很滿意。

Rule #36: Avoid feedback loops with positional features.
使用位置feature避免模型的反饋

我們都知道,鏈接展示的位置影響着瀏覽它的用戶量,排名更靠前的app更容易被點擊、下載,你也很確信他會被瀏覽。因此增加位置feature可以很好的表達具體信息,如果沒有位置feature,這個因素造成的影響可能會算爲其他feature的貢獻,這顯然不合理。注意,在訓練的時候提供位置feature,模型上線的時候並不提供位置feature。而且位置feature必須是兩兩獨立的。

Rule #37: Measure Training/Serving Skew.
測量訓練-上線測試的誤差

很多原因會導致這種誤差,但是一般可以分爲以下三種:

  1. 數據不同,訓練數據和holdout數據會有些不同,這種差異經常存在,但並不一定是壞事。
  2. 模型在今天的holdout數據上的精度或許會和明天的數據上精度有所差別,這也是經常存在的,可以調整正則化方式維持精度的穩定,但是另一方面,如果精度相差很大,就需要詳細分析是否是一些feature對時間太敏感了,導致了精度的降低。
  3. 同一個樣本,不同時間模型預測的結果不同,這時可能是代碼有bug。

##機器學習第三階段:步調放慢、精細優化、增加模型複雜度

標題已經在說明即將接近尾聲了,接下來可能沒有之前進步的那樣快了。首先,你需要在metics之間做tradeoff:一些指標精度的提高可能會造成其他指標的下降。機器學習會變得更加複雜。事先聲明:本節給出的規則是開放性的,許多team可以從上兩個階段獲益頗多,但是在第三階段,他們不得不找出適合自己的方法。

Rule #38: Don’t waste time on new features if unaligned objectives have become the issue.
如果你的objective和優化的最終objective有偏差,不要嘗試使用新的feature去解決,而是確保objective一致。

在你的測試平臺上,你的團隊成員可能脫離與當前的機器學習系統的objective範圍之外看待問題。如果產品的目標和算法優化的objective不一致,那麼修改其中的一個調整到一致。比如,你可能優化點擊量,點贊率,下載量,但是最終決策點是用戶的評分,這就是objective不一致的問題。

Rule #39: Launch decisions are a proxy for long-term product goals.
模型能否發佈最能衡量模型的能力

栗子:Alice有一個降低logistics loss的idea,增加了一個新的feature後,Loss確實降低了。當上線測試的時候,發現下載量的確上升了,然而等到模型發佈的時候,被人指出日活躍用戶數量減少了5%,最終模型沒有發佈,Alice很失望,但是也意識到了最終是否發佈由多個指標決定,而且其中很少一部分是可以被機器學習算法直接優化的。

事實是,現實世界不是龍與地下城:沒有“生命點”來確定你的產品的健康狀況。該團隊必須使用收集的統計數據來有效預測未來系統的良好狀態。他們需要關心參與度,1天活躍用戶(DAU),30 DAU,收入和廣告商的投資回報。這些在A / B測試中可衡量的指標本身僅代表更長期的目標:滿足用戶,增加用戶,滿意合作伙伴和利潤。

所有的metric都在變好(至少沒有變壞)是最好發佈模型的時候。如果一個複雜的機器學習模型和先驗方法取得了同樣好的結果,最好的結果是發佈先驗方法的模型。
然而,所有的metric也沒有一個明確的重要性排序表,對於一些特殊的情況,比如:這裏寫圖片描述
無論當前系統是A還是B,他們肯定都不想更換爲另一種模型,二者有衝突的部分,然而,對指標變化的預測可能會或可能不會出現,因此這兩種變化都有很大的風險。每項指標都涵蓋了團隊所關注的一些風險。
沒有任何一個指標能回答:“五年後我的產品在哪裏”?
每個工程師顯然更喜歡能夠直接優化的objective,這很常見。現在也有一些多目標學習系統在試圖解決這種問題。但仍然有很多objective無法建模,比如用戶爲什麼會來訪問你的網站等等。作者說這是個AI-complete問題,也常被稱爲強AI問題,簡單來說就是不能用某個單一算法解決的問題。

Rule #40: Keep ensembles simple.
模型集成的方法要儘可能簡單

模型集成的方法很容易提升最終的效果。但是請注意:儘可能的使用簡單的模型集成方法,要麼是每個模型以其他模型作爲輸入,要麼是一個basemodel以多種feature作爲輸入,最好不要二者都使用。 也有可能你表現最好的幾個模型放在一起,效果反而變差了。

有時你還希望在這些集成的模型上強制增加屬性。例如,由基本模型生成的分數的增加不應該降低集合的分數。此外,最好傳入的模型在語義上可解釋,這樣基礎模型的更改不會混淆集成模型。此外,單一基礎模型預測概率的增加不會降低集成模型的預測概率。

Rule #41: When performance plateaus, look for qualitatively new sources of information to add rather than refining existing signals.
當性能穩定時,尋找定性的新信息來源來添加而不是對現有的信號做精調

你先是添加了一些用戶的信息,又添加了一些文檔詞彙的信息,接着你又瀏覽了一遍模版,而後又調整了正則化方式,但是最後,關鍵的metirc卻只提升了不到 1%。現在怎麼辦?
那麼是時候使用不同的feature構建基礎架構了,feature可以是此用戶在最後一天,一週或一年中訪問過的文檔的歷史記錄,或者來自不同屬性的數據。使用wikidata實體或公司內部的東西(例如Google的知識圖),或者使用深度學習技術。開始調整您對期望的投資回報的預期,並相應地擴大您的努力。與任何工程項目一樣,你必須權衡添加新feature的好處與增加複雜性的成本。

Rule #42: Don’t expect diversity, personalization, or relevance to be as correlated with popularity as you think they are.
不要指望多樣性,個性化或相關性與你認爲的受歡迎程度有關

一組數據內容中的多樣性可能意味着很多事情,內容來源的多樣性很常見。個性化意味着每個用戶都有自己感興趣的點。相關性意味着特定查詢的結果比任何其他查詢更適合該查詢。因此,這三個屬性的定義和標準都不相同。

問題是越簡單的事情越不容易改變。

請注意,如果你的系統正在測量點擊次數,花費的時間,手錶,+1的次數,轉發等等,說明你正在衡量內容的流行度。團隊有時試圖學習一個多樣化的個性化模型。爲了個性化,他們添加了允許系統個性化(表示用戶興趣的一些特徵)或多樣化的feature(指示該文檔是否與返回的其他文檔(例如作者或內容)具有共同feature的feature),並且發現那些feature得到(或有時是不同的符號)比他們預期的要小的權重。

這並不意味着多樣性,個性化或相關性並不重要。正如前面的規則所指出的那樣,你可以進行後處理以增加多樣性或相關性。如果你看到更長期的objective指標的增加,那麼你可以獨立於受歡迎程度,宣稱多樣性/相關性是有價值的。然後,你可以繼續使用後處理,或者根據多樣性或相關性直接修改objective。

Rule #43: Your friends tend to be the same across different products. Your interests tend not to be.
不同產品上的好友可能很多是相同的,但是並不意味着這些好友對此產品的感興趣點是一樣的。

Google 經常在不同產品上使用同樣的好友關係密切度預測模型,效果都差不多,這證明不同的產品上好友關係是可以遷移的。但他們嘗試將一個產品上的個性化feature使用到另外一個產品上時卻常常得不到好結果。事實上,好友都是一樣的,按理說個性化feature應該也差不多一致啊,事實並非如此。有些特殊的情況下可能會起作用。但是,請牢記,即使知道用戶在其他媒體資源上有歷史記錄,也是可以提供幫助的。例如,同一個用戶同時活躍在兩個不同的產品上,這本身就暗示了一些東西。

##相關工作

  • Machine Learning Crash Course:
  • Machine Learning: A Probabilistic Approach by Kevin Murphy for an understanding of the field of machine learning.
  • Practical Advice for the Analysis of Large, Complex Data Sets: a data science approach to thinking about data sets.
  • Deep Learning by Ian Goodfellow et al for learning nonlinear models.
  • Google paper on technical debt, which has a lot of general advice.
  • Tensorflow Documentation.

####本文同步發佈在微信公衆號–機器學習算法工程師 上,歡迎關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章