search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

【超級乾貨】谷歌機器學習全解析 43條黃金法則

術語

以下是對文中反覆出現的術語的解釋。

實例( Instance):做預測的對象。比如說,實例可以是一個網頁,你想要把它分類為「關於貓」或者「與貓不相關」。

標記(Label):預測任務的答案。它既可以是機器學習系統生成的答案,也可以是訓練數據中提供的正確答案(雷鋒網()註:比如監督學習中的人工標記)。舉例來說,一個網頁的標記可以是「關於貓」。

特徵(Feature):預測任務中實例的屬性。比如說,某網頁可能有「包含關鍵詞『貓』」的特徵

特徵欄 (Feature Column):這是谷歌自創的術語,意為關聯特徵的集合。比如說,用戶的所有可能居住國家的集合。一個樣例的特徵欄可以有一個或多個特徵。特徵欄可被看作是VW系統(微軟、雅虎所用)中的命名空間,或者場( field)。

樣例(Example):有標記的實例(具備特徵)。

模型(Model):對預測任務的統計表達。你用樣例訓練模型,然後用模型做預測。

指標(Metric):你在意的數字。可被直接優化過,也可沒有。

目標(Objective):你的演算法試圖優化的指標。

流水線(Pipeline):機器學習演算法的基礎設施;包括從前端收集數據,把它放入訓練數據文檔,訓練一個或多個模型,以及把模型輸出、產品化。

概覽:

為了開發出好產品:

做機器學習這一行首先要擺正心態,你是一名(優秀的)工程師,不要拿專家的標準來要求自己。

事實上,你將要面對的大多數難題是工程問題(engineering problems)。即便是一個傑出的ML專家,坐擁該級別才有的資源,其大多數收穫也來自於特徵而不是 ML 演算法。所以,ML 開發的基本路線是:

保證可靠的端到端流水線

從制定合理的目標著手

用簡單的方式,加入符合常識的特徵

確保流水線始終可靠

該方法能幫你賺錢養家,並且讓很多人滿意。只有當無路可走、簡單的技巧無法再起作用時,你才需要偏離該路線。但注意,提高複雜度會拖慢將來的產品發布。另外,當你窮盡了簡單技巧,或許就到了登堂入室、探索 ML 最前沿技術的時候了。具體請看本文機器學習第三階。

本文分為四個部分:

第一部分「1.0做機器學習之前」,會幫你搞清楚,你創建機器學習系統的時機是否已經成熟。

第二部分「2.0機器學習第一階」是關於設置你的第一個流水線。

第三部分「3.0機器學習第二階」,關乎啟動和重複,同時向流水線加入新特徵。

最後一部分「4.0機器學習第三階」是關於達到瓶頸后怎麼辦。

43條黃金法則列表:

對發布一個不含 ML 技術的產品,不要有顧慮

首先要設計和貫徹指標

在機器學習和複雜啟發演算法之間,選擇前者

第一個模型要簡單,把基礎設施弄好

測試基礎設施要與 ML 測試分開

複製流水線時當心數據遺落

把啟髮式(heuristics)變為特徵,不然就對它們做外部處理

了解系統的時效性

在輸出模型之前發現問題

於無聲處聽驚雷:注意沒表現出來的故障

注意特徵欄的維護者和文件

選擇直接優化哪個目標時,不需要想太多

選擇一個簡單、可觀察並且可歸屬(attributable)的指標來作為第一個目標

用可解釋的模型開頭,修補漏洞會更簡單

用 policy layer(規則層)把垃圾信息過濾和質量排序分來

做好模型被推倒和重建的準備

直接以觀察到的或報告的特徵開始訓練,而不是經過學習的特徵

從不同的上下文環境中提取特徵

盡量選擇更具體的特徵

以合理的方式組合、修改現有特徵

通過線性模型學到的特徵權重的數目,大致與數據量成正比

清理不需要的特徵

你並不是一個典型的用戶

版本之間存在對等差分(symmetric difference)

選擇模型時,性能勝過預測能力

從誤差中查找新模式、創建新特徵

嘗試量化觀察到的異常行為

注意短期行為和長期行為的差別

確保訓練和服務一樣好的最直接辦法是:保存服務時使用的特徵,然後將這些特徵導入日誌,以便在訓練中使用。

重視採樣數據

注意表格中的數據可能改變

盡量在訓練和服務流水線中復用代碼

訓練和測試的數據不能相同

在二進位分類過濾的應用場景中(例如垃圾郵件檢測),不要為了純凈的數據做太大的性能犧牲

注意排序問題的固有偏差

避免具有位置特徵的反饋迴路

測量訓練/服務偏差

如果目標之間不搭,並成為問題,就不要在新特徵上浪費時間

模型發布決策是長期產品目標的代理

保證集成模型(ensemble)的簡潔

當性能達到瓶頸,相比精鍊現存信號,不如尋找新性質的信息源

不要期望多樣性、個性化、相關性和受歡迎程度之間有緊密聯繫

不同產品中,你的朋友總是那一個,你的興趣不會如此

1.0做機器學習之前

1. 對發布一個不含 ML 技術的產品,不要有顧慮

機器學習很酷,但要有數據。理論上,你可以把另一個相近課題的數據拿來用,調整下模型變成一個新產品。但這麼做的實際效果,通常比簡單的啟髮式演算法(heuristics)還差。如果你認為機器學習能完成任務的100%。那麼啟髮式演算法能幫你完成50%。

比如說,若你為應用商店進行 app 排名,不妨直接利用下載率和裝機量寫個簡單演算法;若你在檢測垃圾郵件,可以先把發送過垃圾郵件的地址過濾掉。也不要在人工編輯上有顧慮。如果機器學習對於你的產品不是必需的,那麼在獲得數據之前不要用它。

2. 首先要設計和貫徹指標

在定義你的 ML 系統要做什麼之前,要儘可能多得追蹤你當前的系統。這出於以下原因:

在早期,獲得系統用戶的許可相對容易。

如果你認為有些東西在將來需要考慮,最好從現在起就收集歷史數據。

如果你設計系統時考慮了指標的工具化( metric instrumentation),會省下將來的許多力氣。你絕對不想為了指標而查找日誌字元串。

有些東西會改變,有些不會。比如說,假設你想要直接優化每日活躍用戶。但是,在你對系統的早期操作中,你也許會發現用戶體驗的大幅變化並不會顯著改變這個指標。

Google+ 團隊會衡量每次閱讀的擴展數(expands per read)、分享、點贊、評論,以及每用戶評論數、分享等等。然後他們利用這些數據計算髮布消息的質量。另外要注意,能通過試驗把用戶分組並整合數據的試驗框架非常重要,參考第12 條。

通過更靈活地收集指標,你能用更大的視角觀察系統。發現一個問題?添加一個指標來追蹤它!對上一個發布版本的量化變動很興奮?添加指標來追蹤!

3. 在機器學習和複雜啟發演算法之間,選擇前者

一個簡單的啟發演算法能幫助產品走向市場,而複雜啟發演算法難以維護。一旦你有了數據以及需要實現的目標的藍圖,就可以轉去開發 ML。在大多數軟體工程任務中,開發者需要不停更新開發方式,不管是啟髮式演算法還是 ML 模型。你會發現後者更加容易更新維護(參考第16 條)。

2.0 機器學習第一階

2.1 你的第一條流水線

對於第一條流水線,關注你的系統基礎設施。雖然,設想你將要做的種種 ML 應用很有趣;但如果你無法信任自己的流水線,你會很難搞清楚狀況。

4. 第一個模型要簡單,把基礎設施弄好

第一個模型為你的產品提供了最大的助力,所以它不需要花哨。而且你會遇到許多想象之外的基礎設施問題。在你的新 ML 系統誕生之前,你需要決定:

如何獲取學習演算法的樣例

對於你的系統,「好」、「壞」的定義是什麼

如何把模型整合入應用。你可以實時應用模型,也可以在線下預計算模型,並把結果保存好。比如對網頁預分類,然後在表格里保存結果。但有的任務可能需要對實時聊天信息進行分類。

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

這些特徵正確應用於學習演算法

模型學會合理的權重。

這些特徵正確應用於伺服器模型。

當你有了能可靠做到上述三點的系統,大部分的工作就已完成。簡單模型提供給你基礎的指標和行為,然後你可以用它們來測試更複雜的模型。有些團隊把目標定為「中性」的首發——故意在首次發布不那麼重視機器學習成果,以避免分心。

5. 測試基礎設施要與 ML 測試分開

要確保基礎設施可測試,而且系統的學習部分都被包含在內,使得你能夠測試所有相關物。特別是:

測試把數據導入演算法。檢查可填充的特徵欄是不是空的。若條件允許,手工檢查訓練演算法的輸入。若可能,把流水線數據與其他地方作比較,比如 RASTA。

測試把數據導出訓練演算法。確保訓練環境的模型與服務環境(serving environment)的模型產生同樣的得分(詳見第37 條)。

ML 有不可預測的因素。所以一定要對生成訓練、服務樣例的代碼進行測試;這樣你可以在服務中載入、使用固定模型。另外,理解你的數據也十分重要。

6. 複製流水線時當心數據遺落

我們經常複製現成的流水線來創建新流水線(例如 cargo cult 編程),但有時舊流水線遺落了新流水線需要的數據。舉個例子, Google Plus What』s Hot(雷鋒網按:社交軟體 Google+ 的熱門新聞版塊) 的流水線會遺落舊帖子(因為它試圖為新帖子排名)。我們複製該流水線,用於 Google Plus Stream(Google+ 流)。對於後者,舊帖子仍然有意義,但新流水線仍然會丟掉數據。

另一個常見的模式是只記錄用戶看過的數據。因此,當你需要對為什麼用戶沒有看到某個信息進行建模,該數據完全沒用——因為所有反例已經被丟掉了。Google Play 發生過一個類似的問題:當我們開發 Google Play 應用商城主頁時,創建出的新流水線包含另外兩個登錄頁面(Play Games Home and Play Home Home,遊戲主頁和家庭主頁)的樣例。但是,並沒有能夠對「樣例來自於哪個主頁」加以區分的特徵。

7. 把啟髮式(heuristics)變為特徵,不然就對它們做外部處理

通常來講,ML 試圖解決的問題並不是什麼新問題——一般有現成的排名、分類等各種系統。這意味著有一大堆規則和啟髮式演算法可用。這些啟髮式能在你調整 ML 時起到幫助。你應該壓榨出啟髮式演算法的所有信息,這有兩個原因:1. 到 ML 系統的過渡會更順暢。2. 這些規則通常包含一大堆關於系統的直覺信息,你絕對不想把它們扔掉。有四種利用現成啟髮式演算法的途徑:

使用啟髮式演算法預處理。如果該特徵非常棒,那麼這就是一個選擇。舉個垃圾郵件過濾器的例子,若發件人已經被加入黑名單,不要試圖重新學習「加入黑名單」是啥意思。直接攔截該信息。該方法最適用於二分類任務。

創建特徵。直接用啟髮式創建特徵相當棒。比如說,如果你用啟髮式計算一個問題結果的相關度分值,你可以把該得分作為特徵值。之後,你或許想用 ML 技術來操作數值(比如把數值轉化為有限個獨立值集合,或與其他特徵合併),但卻拿啟髮式生成的原始數值來開頭。

挖掘啟髮式的原始輸入。如果有面向 APP 的啟髮式把裝機量、文字中字母數目和日期組合到一起,就得考慮把它們分開——把這些輸入分開來學習。有些應用於整體的技巧可用在這裡(詳見第 40 條)。

修正標記。當你發現啟髮式抓取了標記中未包含的信息時,這是一個選擇。舉個例子,如果你試圖最大化下載量,但卻仍然想要高品質內容,那麼或許最好的方案是把標記與 APP 的平均星星得分相乘。這裡有很大的餘地。請參考「2.3 你的第一個目標」部分。

請注意啟髮式為 ML 系統加入的複雜度。在新 ML 演算法中加入舊啟髮式有助於平滑地過渡,但你需要考慮是否更簡單的實現方式。

2.2 監測

總的來講,養成處理警告(alerts)的好習慣,比如對每個提醒付諸行動,並且建立一個儀錶頁面(dashboard page)。

8. 了解系統的時效性

當你的模型已經開發出來一天、一周、一季度了,它的效果分別會降低多少?該信息能幫助你理解維護任務的優先順序。假設模型一天沒更新,你就要損失 10% 的收入。那麼你或許要考慮雇傭專人每天維護。許多廣告服務系統每天都有需要處理的新廣告,因此必須每日更新。再舉一個例子,如果 Google Play 的搜索 ML 模型停止更新,一個月內就會造成很大的損失。Google+ What』s Hot(雷鋒網註:熱門推薦)的一些模型,並沒有針對發布信息的身份確認機制,所以不需要頻繁導出這些模型。但有身份確認機制的模型就需要非常頻繁地更新。另外需注意,時效性會隨時間而變化,尤其是為模型添加或移除特徵欄的時候。

9. 在輸出模型之前發現問題

許多 ML 系統包含該步驟:輸出模型到服務端。如果輸出的模型有問題,會直接讓用戶們遇上。而這個環節之前的問題只是訓練問題,不會影響用戶體驗。

在導出模型之前一定要檢查,尤其要確保模型在給定數據上有合理的效果。另外,若你對數據有顧慮,不要輸出該模型。許多開發團隊會在模型輸出前檢查 ROC 曲線 (或 AUC) 下的區域。未輸出的模型存在問題,可能只需要一封 email 提醒一下。但用戶端模型出了問題,很可能需要你向上司、同事解釋一整頁。所以最好多花點時間,在影響到用戶之前做到胸有成竹。

10. 於無聲處聽驚雷:注意沒表現出來的故障

這是一個多見於機器學習、而少見於其他系統的問題。設想一個不再更新的特定表格:機器學習系統會調整,其行為仍會有合理表現,但逐漸退化。有時候開發者會發現過期幾個月的表格——這時,一個簡單的更新所提高的性能,比該季度的所有發布新版本都要高。舉個例子,對一個特徵的取捨會因為執行情況的變化而變化:覆蓋 90% 樣例的特徵欄可能突然降低到只覆蓋 60%。Google Play 曾經就有一個過期了六個月的表格,單單更新那個表格就帶來了 2% 的安裝率提升。如果你對統計數據進行跟蹤,並偶爾人工檢查,就能減少這類失誤。

11. 注意特徵欄的維護者和文件

如果系統很大、有許多特徵欄,你需要知道誰創立、維護了每一個特徵欄。如果你發現懂得特徵欄的那個人要跳槽了,一定要確保團隊里有還有人知道這些信息。雖然許多特徵欄有描述名稱,你仍然需要更詳細的解釋,知道它是什麼、從哪裡來、起什麼作用。

2.3 你的第一個目標

你有許多關心的系統指標或度量,但 ML 演算法通常只需要一個目標——演算法試圖優化的某個數字。這裡,我要區別目標(objectives)和指標(metrics):指標是系統報告的任何數字,或許重要,或許不重要。詳見第二條。

12. 選擇直接優化哪個目標時,不需要想太多

你想要賺錢,讓用戶滿意,並且讓地球更美好。有許多你關心的指標,你應該全部都去測量(見第二條)。但在 ML 初期,你會注意到它們全都有提升,即便是那些沒有直接優化的也是如此。舉個例子,假設你關注點擊數、瀏覽時間和每日活躍用戶。如果你優化點擊數,你會看到瀏覽時間也在上升。

所以簡簡單單就好。當你能輕易地提高所有指標,不需要在不同指標之間的平衡上想太多。但也不要誤解這條建議:別把目標與系統最終的健康混為一談(詳見第 39 條)。另外,如果你增加了直接優化的指標,但決定不予發布,或許有必要重新修訂目標。

13. 選擇一個簡單、可觀察並且可歸屬(attributable)的指標來作為第一個目標

很多情況下你不知道真正的目標是什麼——你以為你知道。但當你仔細觀察數據,以及對舊系統和新 ML 系統進行分析,你意識到自己其實想要對原定目標進行修改。團隊不同成員也經常無法在真正的目標上取得一致意見。ML 目標應當易於測量,並可作為「真正」目標的代理。所以最好採用簡單的 ML 目標訓練,然後考慮在這之上設一個 "policy layer"(規則層),允許你加入額外的邏輯(但願是簡單的邏輯)來做最終排名。

最容易建模的是,能被直接觀察到、並且可歸屬於系統中某個行動的用戶行為:

這個排名鏈接被點擊了嗎?

這個排名對象被下載了嗎?

這個排名對象被 轉發/回復/發 email 了嗎?

這個排名對象被打分了嗎?

這個顯示的對象被標記為垃圾郵件/色情信息/侮辱性信息了嗎?

一開始要避免對間接作用建模:

用戶在第二天訪問了嗎?

用戶的訪問時間是多長?

每日活躍用戶都是誰?

其實,間接作用是非常不錯的指標,並且可在 A/B 測試和發布決定中使用。

最後,不要試圖讓 ML 搞懂:

用戶對使用該產品滿意嗎?

用戶對體驗滿意嗎?

產品提升了用戶的福祉了嗎?

這如何影響公司的整體健康?

這些都很重要,但是極度困難。你應該用代理來替代:如果用戶感到開心,他們會在頁面停留更長時間。如果用戶滿意,他明天會再次訪問。目前,當涉及到福祉和公司健康狀態,把 ML 目標與產品本質和商業計劃之間做關聯需要人的判斷。

14. 用可解釋的模型開頭,修補漏洞會更簡單

線性回歸、邏輯回歸、泊松回歸(Poisson regression)直接被概率模型驅動,每個預測都可作為概率或期望值解釋。這使得相比使用了目標、直接優化分類精度或排序效果的模型(zero?one 損失、各種 hinge 損失等等),它們修補漏洞更加簡單。如果通過對比或檢查產品系統,發現訓練里的概率偏離了預測概率,就可能存在問題。

比如說,在線性回歸、邏輯回歸、泊松回歸之中,有的數據子集里平均預期和平均標籤相等(1-?moment 校準,或者普通校準 )。對於一個值要麼是 0 要麼是 1 的特徵,三個特徵值為 1 的樣例集就會被校準。同樣地,若某特徵下所有樣例的特徵值都是 1,它們都會被校準。

對於簡單的模型,處理反饋迴路( feedback loops )更加容易。我們經常用這些概率預期來做決定:比如以期望值(點擊概率/下載量等)為標準對發布消息進行降序排列。但要記住,當決定採用那個模型的時候,你的決定比給定模型數據的可能性( the likelihood of the data given the model )更加重要(參考第 21 條)。

15. 用 policy layer(規則層)把垃圾信息過濾和質量排序分來

質量排序是一門高雅的藝術,而垃圾信息過濾是一場戰爭。對於使用你系統的人,你用來判斷高質量消息的信號十分顯而易見。然後,他們會據此調整他們的發布信息來獲得這些屬性。因此,你的質量排序應當專註於有信譽的內容——不應該讓質量排序學習器退化到給垃圾信息高排名。同樣的,重口味內容應當與質量排序分開。而垃圾信息過濾是另一回事了。你需要創建的特徵會不斷變化,對此要有心理準備。通常,你加入系統里的規則有些很顯而易見(比如,若一個發布信息得到超過三個「垃圾信息」票數,不要恢復它)。任何學習到的模型需要至少每天更新。內容生產者的名譽會起到相當大的作用。

在某個層級,這兩個系統的輸出需要整合在一起。需要注意的是,在搜索結果里過濾垃圾信息,比過濾垃圾郵件要更加強力。 為了高質量的分類器而去除訓練數據中的垃圾,已是行業標準。

3.0 機器學習第二階段

3.1 特徵工程

在進行機器學習相關實踐的第一階段,你要關注的主要問題包括以下三個方面:一是將訓練數據導入系統,二是確定系統的重點關注指標,三是保證底層基礎設施的穩定可靠。當這三個問題都確認無誤,即已經搭建了一個端到端的可穩定運行的系統,並且針對系統本身和其中的每個單元都經過了嚴格測試,這時就可以進入第二階段了。

應該說,第二階段將更容易取得成績。這一階段會有許多顯著的特徵(feature)被導入系統,因此,導入並以直觀的方式組合這些特徵,將是本階段涉及的主要任務。另外,本階段也更適合多位工程師協同工作,共同對此前導入的訓練數據進行整合和處理,推動所有的指標(metric)在本階段取得持續性的上升。

16. 做好模型被推倒和重建的準備

不要指望從頭到尾只使用一個模型,也不要指望著某一結點之後就不用重建模型了,模型的推倒和重建是機器學習過程中的必修課。另外,每加入一個新特性都必須考慮是否會拉低模型的運行效率。目前,許多團隊每三個月或一年就會新建一個模型。這裡我們總結了一般情況下引發模型重建的三大原因:

1) 增加新的特徵

2) 打算重組舊的特徵,或對舊模型正則化

3) 修訂建模目標

無論如何,創建模型時多想想並沒有什麼壞處:例如檢查訓練數據是否有更合理的組織形式,考慮當前的建模方式是否便於特徵的修改和重組,當前的機器學習流水線(pipeline)是否便於創建副本並檢驗其正確率,以及是否可以創建兩到三個副本并行運行等等。最後需要指出的是,並不一定非要在一個機器學習流水線中覆蓋所有特徵,在下一個版本中實現也是可行的。

17. 直接以觀察到的或報告的特徵開始訓練,而不是經過學習的特徵

這一點建議或許存在一些爭議,但的確能避免許多潛在的問題。這裡經過學習的特徵(learned feature)是指由外部系統(例如無監督的聚類系統)或模型本身(例如通過深度學習和因子模型)產生的特徵。這兩種情況雖然的確可以使用,但並不適合系統的第一個模型。

首先,在使用外部系統創建特徵時必須要格外小心。因為外部系統的目標可能與當前系統並不相符,而且從外部系統更新當前系統的特徵,其特定的含義也可能改變。

另一方面,因子模型和深度模型的主要問題是它們是非凸的(non-convex),因此它們無法保證可以最終找到或近似找到最優解,它們在每次迭代中產生的局部最小值都可能變化,而且目前無法評估這種變化對系統的影響是有益的還是有害的。通過創建沒有深度特徵的模型,你就可以獲得很好的基準性能。在實現這一基準性能之後,你可以嘗試更高階的方法。

18. 從不同的上下文環境中提取特徵

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

19. 盡量選擇更具體的特徵

在海量數據的支持下,即使學習數百萬個簡單的特徵也比僅僅學習幾個複雜的特徵要容易實現。由於被檢索的文本標識與規範化的查詢並不會提供太多的歸一化信息,只會調整頭部查詢中的標記排序。因此你不必擔心雖然整體的數據覆蓋率高達90%以上,但針對每個特徵組裡的單一特徵卻沒有多少訓練數據可用的情況。另外,你也可以嘗試正則化的方法來增加每個特徵所對應的樣例數。

20. 以合理的方式組合、修改現有的特徵

目前有多種方法組合、修改現有的特徵,由於本文以Google工具為背景,因此在這裡推薦兩種TensorFlow框架已實現好的方法:「離散化」(discretizations)和「交叉」(crosses)。

離散化主要包含提取連續特徵和從連續特徵中創建離散特徵兩個部分。比如對於年齡這一連續的特徵,你就可以創建這樣的離散特徵:當年齡小於18時結果為1,或者當年齡介於18-35之間時為1,等等。另外,不要過分考慮直方圖中基本分位數的問題。

在TensorFlow的術語中,特徵欄是一組相似的特徵,比如{男性,女性},{美國,加拿大,墨西哥}等。這裡的交叉是指將兩個或多個特徵欄合併,例如{男性,女性}×{美國,加拿大,墨西哥}的結果就是一個交叉(a cross),也就構成了一個新的特徵欄。假設你利用TensorFlow框架創建了這樣一個交叉,其中也就包含了{男性,加拿大}的特徵,因此這一特徵也就會出現在男性加拿大人的樣例中。需要注意的是,交叉方法中合併的特徵欄越多,所需要的訓練數據量就越大。

如果通過交叉法生成的特徵欄特別龐大,那麼就可能引起過擬合。例如,假設你正在進行某種搜索,並且在查詢請求和文檔中都具有一個包含關鍵字的特徵欄。那麼假如你選擇用交叉法組合這兩個特徵欄,這樣得到的新特徵欄就會非常龐大,它內部包含了許多特徵。當這種情況發生在文本搜索場景時,有兩種可行的應對方法。最常用的是點乘法(dot produc),點乘法最常見的處理方式就是統計查詢請求和文檔中共同的所有特徵詞,然後對特徵離散化。另一個方法是交集(intersection),比如當且僅當關鍵詞同時出現在文檔和查詢結果中時,我們才能獲取所需的特徵。

21. 通過線性模型學到的特徵權重的數目,大致與數據量成正比

許多人都認為從一千個樣例中並不能得到什麼可靠的訓練結果,或者由於選擇了某種特定的模型,就必須獲取一百萬個樣例,否則就沒法展開模型訓練。這裡需要指出的是,數據量的大小是和需要訓練的特徵數是正相關的:

1) 假如你在處理一個搜索排名問題,文檔和查詢請求中包含了數百萬個不同的關鍵詞,並且有一千個被標記的樣例,那麼你應該用上文提到的點乘法處理這些特徵。這樣就能得到一千個樣例,對應了十幾個特徵。

2) 如你有一百萬個樣例,那麼通過正則化和特徵選擇的方式就可以交叉處理文檔和查詢請求中的特徵欄,這可能會產生數百萬的特徵數,但再次使用正則化可以大大減少冗餘特徵。這樣就可能得到一千萬個樣例,對應了十萬個特徵。

3) 如果你有數十億或數百億個樣例,那同樣可以通過特徵選擇或正則化的方法交叉處理文檔和查詢請求中的特徵欄。這樣就可能得到十億個樣例,對應了一千萬個特徵。

對特徵數和樣例來說,這些統計學上的結論並不能給出一個具體的比例關係,但卻可以從數量級上給出一些指導。另外,這裡推薦用戶依照第28條建議來選擇具體使用哪些特徵。

22. 清理不需要的特徵

如果你發現有些特徵並沒有在使用,而且將其與其他特徵相結合之後也無法使用的話,就應該清理這些特徵。應該保持系統的清潔,這樣才能儘快嘗試那些最有希望出結果的特徵。而且,如果有必要,被刪除的特徵也可以隨時找人加回來。

在考慮增刪一個特徵時,應該仔細排查其覆蓋範圍。例如你有一些個性化的特徵,但只有大約8%的用戶使用了該特徵,那麼刪掉或添加這個特徵就不會有太大影響。

另一方面,增刪特徵時也要考慮其對應的數據量。例如你有一個只覆蓋了1%數據的特徵,但有90%的包含這一特徵的樣例都通過了訓練,那麼這就是一個很好的特徵,應該添加。

3.2 對系統的人工分析

在進入機器學習實踐的第三階段之前,關注一些課堂上不曾教授的問題也同樣至關重要,比如如何檢查一個模型並改進它。要說這一點是一門科學,反而不如說它是一種藝術,這裡我們介紹幾點反面模式(anti-patterns)。

23. 你並不是一個典型的用戶

這可能是讓一個團隊陷入困境的最簡單的方法。雖然fishfooding(只在團隊內部使用原型)和dogfooding(只在公司內部使用原型)都有許多優點,但無論哪一種,開發者都應該首先確認這種方式是否符合性能要求。另一方面,應該盡量避免不好的變化,但任何看起來合理的產品策略都應該被進一步驗證,例如通過非專業人士在眾包平台上的問卷調查,或者請目標用戶來實測。

走外部驗證渠道的原因來自兩個方面:一是作為開發者,你太熟悉代碼。例如你可能正在分析數據的某一方面而非全局,或者投入了太多的個人感情色彩,從而引發一些偏見。二是幾位工程師開一個小時的討論會議得到的評估結果,可能遠比不上直接交給眾包平台來得簡單和有效。

如果你真的想要獲取用戶反饋,那麼應該採用用戶體驗法(user experience methodologies)。 在流程早期創建用戶角色(詳情見Bill Buxton的《Designing User ExperienCES》一書),然後進行可用性測試(詳情見Steve Krug的《Do not Make Me Think》一書)。這裡的用戶角色涉及創建假想用戶。例如,假設你的團隊成員都是男性,現在要針對35歲女性用戶研發一款產品,那麼基於目標群體創建一個假想角色,肯定比幾位25-40歲的男性開發者閉門造車的效果要好。當然,讓用戶實測產品並觀察他們的反應也是很不錯的方法。

24. 版本之間存在對等差分(symmetric difference)

將產品交付至用戶之前,有時候最簡單有效的做法就是評估當前版本與交付版本的差異。例如面對排名問題,你可以在兩個版本間利用同一組樣例進行測試,然後對比其結果。如果差異很小,那麼意味著這個版本沒問題。如果差異很大,那麼就需要確認進行了哪些修改,為什麼進行這些修改。通過查看哪些測試樣例造成了這一差異,也有助於定性了解修改具體是怎樣的。總之,目標是確保不同版本的模型之間的對等差分做到最小。

25. 選擇模型時,性能勝過預測能力

你的模型可能會被用來預測點擊率,但更關鍵問題是:這種預測是應用在什麼場景的。如果你用它來排列文檔,那麼最終排名的質量顯然比預測本身更重要。如果你用它來排查垃圾郵件,那麼識別精度顯然更重要。大多數情況下,這兩類功能應該是一致的,如果他們存在不一致,則意味著系統可能存在某種小增益。因此,假如一個改進措施可以解決日誌丟失的問題,但卻造成了系統性能的下降,那就不要採用它。當這種情況頻繁發生時,通常應該重新審視你的建模目標。

26. 從誤差中查找新模式、創建新特徵

假設你的模型在某個樣例中預測錯誤。在分類任務中,這可能是誤報或漏報。在排名任務中,這可能是一個正向判斷弱於逆向判斷的組。但更重要的是,在這個樣例中機器學習系統知道它錯了,需要修正。如果你此時給模型一個允許它修復的特徵,那麼模型將嘗試自行修復這個錯誤。

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

所以,正確的做法是一旦出現樣例錯誤,那麼應該在當前的特徵集之外尋找解決方案。例如,如果你的系統降低了內容較長的帖子的排名,那就應該普遍增加帖子的長度。而且也不要拘泥於太具體的細節。例如你要增加帖子的長度,就不要猜測長度的具體含義,而應該直接添加幾個相關的特徵,交給模型自行處理,這才是最簡單有效的方法。

27. 嘗試量化觀察到的異常行為

有時候團隊成員會對一些沒有被現有的損失函數覆蓋的系統屬性感到無能為力,但這時抱怨是沒用的,而是應該盡一切努力將抱怨轉換成實實在在的數字。例如,當有些開發者認為在谷歌Play商店的搜索結果中顯示了過多的其他App,就可以選擇人工識別的方法剔除這些App(這時是可以選擇人工標記數據的,因為相對較小的App查詢可能佔了很大一部分流量)。首先要確認你的問題是可量化的,然後才可以根據這些問題創建新的特徵(features)、目標(objectives)或者指標(metrics)。總之規則是:先量化,再優化。

28. 注意短期行為和長期行為的差別

假設你有一個新系統,它可以查看每個doc_id和exact_query,然後根據每個文檔的每次查詢行為計算其點擊率。你發現它的行為幾乎與當前系統的并行和A/B測試結果完全相同,而且它很簡單,於是你啟動了這個系統。但卻沒有新的應用顯示,為什麼?由於你的系統只基於自己的歷史查詢記錄顯示文檔,所以不知道應該顯示一個新的文檔。

要了解一個系統在長期行為中如何工作的唯一辦法,就是讓它只基於當前的模型數據展開訓練。這一點非常困難。

3.3 訓練服務的偏差(Training?-Serving Skew)

這裡訓練服務偏差是指系統在訓練時的性能表現和服務中的性能表現出現差別。造成這種差別的原因可能有如下三個方面:

1) 在訓練和服務中的數據處理流水線不同;

2) 在訓練和服務中使用了不同的數據;

3) 模型和演算法間的反饋迴路引起。

我們注意到谷歌的機器學習系統也存在訓練服務偏差,而且會對性能產生負面影響。這裡需要說明的是:最好的解決辦法就是明確地監視它,使系統和數據的改變不至於引發潛在的偏差。

29. 確保訓練和服務一樣好的最直接辦法是:保存服務時使用的特徵,然後將這些特徵導入日誌,以便在訓練中使用

即使你不能對每個樣例都這樣做,做一小部分也比什麼也不做好,這樣你就可以驗證服務和訓練之間的一致性(見規則37)。在谷歌採取了這項措施的團隊有時候會對其效果感到驚訝。比如YouTube主頁在服務時會切換到日誌記錄特徵,這不僅大大提高了服務質量,而且減少了代碼複雜度。目前有許多團隊都已經在其基礎設施上採用了這種策略。

30. 重視採樣數據

當數據太多時,有些團隊可能會選擇丟棄一部分以減輕負擔。這是一個明顯的錯誤:歷史經驗證明在訓練過程中丟棄數據將引發一系列問題(詳見規則6)。當然,有時候的確可以丟棄數據,比如那些從未向用戶顯示過的,但重要性加權卻是更好的選擇。重要性加權意味著,如果你決定以30%的概率對樣例X進行抽樣,則權重應該是3/10。值得一提的是,使用重要性加權並不影響規則14中討論的校準屬性。

31. 注意表格中的數據可能改變

假設你通過包含文件特徵的表格(表格中還可能包含評論或點擊的次數)加入文件的ID信息,那麼需要注意表格中的特徵可能會在訓練和服務的不同時間點發生一些變化,造成模型對同一文檔的預測也跟著改變。避免此類問題的最簡單方法是在服務時記錄特徵(請參閱規則32)。如果表格的變化足夠緩慢的話,你可以每天或每小時都記錄一次表格以獲得非常接近的數據,但需要注意的是,這並不能完全解決問題。

32. 盡量在訓練和服務流水線中復用代碼

首先需要明確的一點是:批處理與在線處理不同。在線處理中,你必須在每個請求到達時及時處理(例如必須為每個查詢單獨查找);而在批處理中,你可以組合任務(例如建立聯結)。類似的,可以將服務視為在線處理過程,而訓練視為批處理過程,而其中有許多代碼是可以復用的。比如說,你可以創建特定於系統的對象,其中的所有聯結和查詢結果都以人類可讀的方式存儲,錯誤也可以被簡單地測試。然後,一旦在服務或訓練期間收集了所有信息,你就可以通過一種通用方法在這個特定對象和機器學習系統需要的格式之間形成互通,訓練和服務的偏差也得以消除。另外,由此推知:最好不要在訓練和服務期間使用不同的編程語言(因為不同的語言間幾乎無法復用)。

33. 訓練和測試的數據不能相同

一般來說,最好用不同的數據對模型進行訓練和測試,例如你用1月5日之前的數據訓練了一個模型,那麼最好用1月6日之後的數據對模型展開測試。可能模型對新數據的性能表現不如訓練數據,但也不會太糟。由於可能會產生每日效應(daily effects),因此你可能無法預測平均點擊率或轉化率,但曲線下方的面積(表示正面樣例的分數高於反面樣例的可能性)應該是接近的。

34. 在二進位分類過濾的應用場景中(例如垃圾郵件檢測),不要為了純凈的數據做太大的性能犧牲

一般在過濾應用場景中,反面樣例並不會對用戶展示。不過假如你的過濾器在服務過程中阻止了75%的反面樣例,那麼你可能需要從向用戶顯示的實例中提取額外的訓練數據並展開訓練。比如說,用戶將系統認可的郵件標記為垃圾郵件,那麼你可能就需要從中學習。

但這種方法同時也引入了採樣偏差。如果改為在服務期間將所有流量的1%標記為「暫停」,並將所有這樣的樣例發送給用戶,那你就能收集更純凈的數據。現在你的過濾器阻止了至少74%的反面樣例,這些樣例可以成為訓練數據。

需要注意的是,如果你的過濾器阻止了95%或更多的反面樣例,那這種方法可能就不太適用。不過即使如此,如果你想衡量服務的性能,可以選擇做出更細緻的採樣(例如0.1%或0.001%),一萬個例子足以準確地估計性能。

35. 注意排序問題的固有偏差

當你徹底改變排序演算法時,一方面會引起完全不同的排序結果,另一方面也可能在很大程度上改變演算法未來可能要處理的數據。這會引入一些固有偏差,因此你必須事先充分認識到這一點。以下這些方法可以有效幫你優化訓練數據。

1) 對涵蓋更多查詢的特徵進行更高的正則化,而不是那些只覆蓋單一查詢的特徵。這樣,模型將偏好於那些基於一個或幾個特定查詢的特徵,而不是所有的特徵。這種方式可以有效防止那些最常見的查詢結果泄漏到不相關的查詢中。需要注意的是,這與一條更傳統的建議相左:更多地正則化一些具有單一值的特徵欄。

2) 只允許特徵具有正向權重,這樣一來就能保證任何好特徵都會比未知特徵合適。

3) 不要選擇那些只處理文檔數據的特徵。例如,不管搜索請求是什麼,即使一個給定的應用程序是當前的熱門下載,你也不會想在所有地方都顯示它。沒有文檔特徵的話,這一點會很容易做到。

36. 避免具有位置特徵的反饋迴路

內容的位置會顯著影響用戶與它交互的可能性。很明顯,如果你把一個App置頂,那它一定會更頻繁地被點擊。處理這類問題的一個有效方法是加入位置特徵,即關於頁面中的內容的位置特徵。假如你用正向特徵來訓練模型,那模型就會更偏向「1st-position」這類的特徵。因而模型對其他因素的權重就會相應地減小,例如對「1st-position = true」這種樣例。在服務的時候,你可以選擇不提供任何位置特徵的實例,或者為所有位置特徵設置相同的初始值,因為在決定以怎樣的順序顯示它們之前,你具有決策權。

需要注意的是,因為訓練和測試的不對稱性,所以最好在一些位置特徵和模型之間保持一定的分離性,這一點很重要。讓模型成為位置特徵函數和其他特徵函數的和,是理想的狀態。比如說,最好不要交叉任何文檔特徵和位置特徵。

37. 測量訓練/服務偏差

許多情況都會引起偏差,但它們大多可以分為如下三類:

1) 訓練數據和測試數據的性能之間的差異。一般來說,這總是存在的,但並不會太嚴重。

2) 測試數據的性能與「第二天數據」(next-day data)之間的差異。同樣,這也會一直存在。你可以不同程度地正則化以最大限度地提高第二天的性能(next-day performance)。然而,如果在測試數據和第二天數據之間存在很大的性能下降,這有可能意味著某些特徵是時間敏感的,而且整個模型的性能也會跟著下降。

3) 「第二天數據」和實時數據的性能之間的差異。如果你將模型應用於訓練數據的樣例,也應用於相同的服務樣例,則它們應該給出完全相同的結果(詳見規則5)。因此,這裡的差異可能是指工程誤差。

4.0 機器學習第三階

4.1 減慢的增速,精細優化和複雜模型

第二階段將要結束的時候,一定會有些信號。首先,你每月的收益開始降低。你開始要在指標之間做犧牲:一些試驗中有的上升有的下降。從此情況變得更有趣。由於更難產生效益,機器學習不得不變得更複雜。

警告:這部分有許多開放式的實踐法則。我們親眼看著很多團隊走過第一階段和第二階段的幸福期——一旦到達第三階段,開發團隊就不得不找出他們自己的路。

38. 如果目標之間不搭,並成為問題,就不要在新特徵上浪費時間

當達到度量瓶頸,你的團隊開始關注 ML 系統目標範圍之外的問題。如同之前提到的,如果產品目標沒有包括在演算法目標之內,你就得修改其中一個。比如說,你也許優化的是點擊數、點贊或者下載量,但發布決策部分依賴於人類評估者。

39. 模型發布決策是長期產品目標的代理

(雷鋒網註:谷歌工程師在這裡舉了個例子)Alice 有一個關於降低安裝預測的邏輯損失的想法。她加入一個特徵。邏輯損失下降。當她實時測試時,安裝量上升了。但在公司的發布會議上,有人指出每日活躍用戶數降低了 5%。團隊決定不發布該模型。Alice 很失望,但意識到發布決策取決於多個標準,其中只有一部分能夠被 ML 直接優化。

事實是,現實世界並不是網路遊戲:沒有「攻擊值」和「血量」來衡量產品的健康。團隊需要利用收集的數據,來試圖預測將來系統的表現會怎樣。他們需要操心用戶黏性、每日活躍用戶、每月活躍用戶、收入和廣告主的收益。這些 A/B 測試中的指標,實際上只是長期目標的代理:讓用戶滿意、增加用戶、讓合作方滿意還有利潤;即便這時你還可以考慮高品質、有使用價值的產品的代理,以及五年後一個繁榮的企業的代理。

做出發布決策變得容易的唯一一種情況是:所有指標都變好了(起碼沒有變差的)。如果團隊在複雜 ML 演算法和簡單啟髮式演算法之間有的選擇;如果簡單的啟髮式演算法在這些指標上做得更好;那麼應當選擇後者。另外,所有指標數值並沒有明確的排序。更具體的,考慮以下兩種情形:

如果現有系統是 A ,團隊不會想要轉移到 B。如果現有系統是 B,團隊也不會想要轉到 A。這看起來與理性決策相抵觸:但是,對指標變化的預期情形或許會發生,或許不會。因此任意一種改變都有相當大的風險。每一個指標覆蓋了一些團隊所關注的風險。但沒有指標能覆蓋團隊的首要關切——「我的產品在五年後會怎樣?」

另一方面,個體傾向於選擇能直接優化的目標。大多數 ML 工具喜歡這樣的環境。這樣的環境下,一個能快速創建新特徵的工程師能穩定輸出一系列產品發布。有一種叫「多目標學習」(multi?objective learning)的機器學習開始解決這一問題。比如說,可以制定一個在每個指標上有下限的約束滿意度問題(constraint satisfaction problem),然後優化指標的一些線性組合。但即便那時,也不是所有指標都能輕易表達為 ML 目標:如果一個文件被點擊,或者 APP 被安裝,這是因為有內容被展示出來。但搞清楚用戶為什麼訪問你的頁面就更加難了。如何預測一個頁面在將來是否成功,是一項 AI?-complete 問題(雷鋒網註:意味著完成它的難度相當於解決 AI 問題),與計算機視覺和自然語言處理一樣難。

40. 保證集成模型(ensemble)的簡潔

接收原始特徵、直接對內容排序的統一模型,是最容易理解、最容易修補漏洞的模型。但是,一個集成模型(一個把其他模型得分組合在一起的「模型」)的效果會更好。為保持簡潔,每個模型應該要麼是一個只接收其他模型的輸入的集成模型,要麼是一個有多種特徵的基礎模型,但不能兩者皆是。如果你有單獨訓練、基於其它模型的模型,把它們組合到一起會導致不好的行為。

只用簡單模型來集成:那些只把基礎模型的輸入作為輸出、進行接收的模型。你或許想要為這些集成模型強加上屬性。比如,基礎模型生成得分的提高,不應該降低集成模型的分數。另外,如果連入模型在語義上可解釋(比如校準了的)會更好,這樣其下層模型不會與集成模型混淆。再者,強行讓下層分類器預測的概率升高,不會降低集成模型的預測概率。

41. 當性能達到瓶頸,相比精鍊現存信號,不如尋找新性質(qualitatively)的信息源

你已經加入了一些關於用戶的人口統計信息,還有文件中的詞語。你經歷了模板探索,和正則化(regularization)調參。但連續幾個季度的發布,你都沒有看到核心指標有超過 1% 的提升。現在怎麼辦?

你已經到了為不同尋常(雷鋒網()註:很不一樣)的特徵,創建基礎設施的時候了。比如用戶昨天、上周、去年檢索的文檔,或是另一種屬性的數據。為你的公司使用維基數據(wikidata)實體或者一些內部的東西(比如谷歌的知識圖,Google』s knowledge graph)。你或許需要使用深度學習。開始調整你對投資回報的期望,並作出相應努力。如同所有工程項目,你需要平衡新增加的特徵與提高的複雜度。

42. 不要期望多樣性、個性化、相關性和受歡迎程度之間有緊密聯繫

一系列內容的多樣性能意味著許多東西,內容來源的多樣性最為普遍。個性化意味著每個用戶得到屬於他們自己的結果。相關性意味著一個特定檢索的結果,對應它比對應其他檢索更合適。因此,這三個屬性的定義都有別於「標準」。

但標準更難被打敗。

注意:如果你的系統在統計點擊量、耗費時間、瀏覽數、點贊數、分享數等等,你事實上在衡量內容的受歡迎程度。有團隊試圖學習具備多樣性的個性化模型。為個性化,他們加入允許系統進行個性化的特徵(有的特徵代表用戶興趣),或者加入多樣性(表示該文檔與其它返迴文檔有相同特徵的特徵,比如作者和內容),然後發現這些特徵比他們預想的得到更低的權重(有時是不同的信號)。

這不意味著多樣性、個性化和相關性就不重要。如同上個法則所指出的,你可以通過後處理來提高多樣性或相關性。如果你看到長期目標的進步,那麼你可以宣布在受歡迎程度之外,多樣性和相關性是有價值的。你可以繼續採用后處理,或者直接根據多樣性或相關性修改目標。

43. 不同產品中,你的朋友總是同一個,你的興趣不會如此

谷歌的 ML 團隊 常常把一個預測某產品聯繫緊密程度(the closeness of a connection in one product)的模型,應用在另一個產品上,然後發現效果很好。另一方面,我見過好幾個在產品線的個性化特徵上苦苦掙扎的團隊。是的,之前看起來它應該能奏效。但現在看來它不會了。有時候起作用的是——用某屬性的原始數據來預測另一個屬性的行為。即便知道某用戶存在另一個屬性能湊效的歷史,也要記住這一點。比如說,兩個產品上用戶活動的存在或許就自身說明了問題。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦