為了讓模型迭代過程更加可操作,并能夠提供更多的信息,Uber 開發了一個用于機器學習性能診斷和模型調試的可視化工具——Manifold。
機器學習在 Uber 平臺上得到了廣泛的應用,以支持智能決策制定和特征預測(如 ETA 預測 及 欺詐檢測)。為了獲得最佳結果,我們在開發精準預測機器學習模型上投入了大量資源。事實上,對從業者來說,他們通常把 20% 的精力放在構建初始的工作模型上,而把 80% 的精力用來提高模型性能,這就是所謂的機器學習模型開發 20/80 分配法則。
傳統上,數據科學家在開發模型時會使用匯總分數,如 對數損失、曲線下面積(area under curve,簡稱 AUC) 和 平均絕對誤差(mean absolute error,簡稱 MAE) 來評估每個候選模型。盡管這些指標提供了有關模型執行情況的見解,但是,它們沒有傳達很多關于模型為什么表現不佳以及如何提高其性能的信息。因而,模型構建者傾向于依賴反復試驗和誤差來決定如何改善模型。
為了讓模型迭代過程更加可操作,并能夠提供更多的信息,我們開發了 Manifold(https://arxiv.org/pdf/1808.00196.pdf)。它是一個用于機器學習性能診斷和模型調試的可視化工具。Manifold 利用可視化分析技術讓機器學習從業者能夠超越總體指標檢測模型沒能精準預測的數據子集。Manifold 還通過揭示性能表現較好和較差數據子集之間的特征分布差異來說明模型性能表現不佳的潛在原因。此外,它還可以揭示對于每一個數據子集,一些候選模型將有怎樣的預測準確性差異,從而為一些高級處理(如模型集成)提供根據。
在本文中,我們將介紹 Manifold 的算法和可視化設計,以及 Uber 是如何利用這工具來獲得模型見解以及提高模型的性能。
Manifold 背后的動機
鑒于其復雜性,機器學習模型本質上是不透明的。隨著機器學習越來越成為 Uber 業務不可分割的部分,我們需要為用戶提供工具,使模型更透明且易于理解。只有這樣,他們才能自信自如地使用機器學習生成的預測,而新興的機器學習可視化可以解決這個問題。
以前的機器學習可視化方法通常包括直接可視化內部結構或模型參數和受底層算法約束的設計(導致無法擴展到可以處理公司范圍內的通用用例)。
為了應對 Uber 面臨的這個挑戰,我們構建了 Manifold 來提供機器學習模型服務,并從分類和回歸模型開始。Manifold 通過揭示數據子集之間的特征分布差異為機器學習模型開發黑盒提供了更高的透明度。
借助 Manifold 的設計,我們顛覆了傳統機器學習模型的可視化。我們不檢查模型,而是通過以下方式檢查各個數據點:
識別影響模型性能的數據段,以及這些數據如何影響模型的性能;
評估這些數據段的聚合特征,以便識別某些模型行為背后的原因。
這個方法有助于實現模型無關性,這是在識別模型集成機會時特別有用的功能。
可視化和工作流設計
除了在《Manifold: A Model-Agnostic Framework for Interpretation and Diagnosis of Machine Learning Models》一文中所描述的研究原型之外,我們專注于揭示大量高維 ML 數據集中的重要信號和模式。在以下部分中,我們將討論 Manifold 的界面和用戶工作流,深入介紹我們的設計考慮事項,并解釋支持此類可視化分析的算法。
Manifold 的界面由兩個可視化部分組成:
- 性能比較視圖,由小提琴編碼的多路圖組成,用于比較模型和數據段之間的性能。
- 特征屬性視圖,由兩套特征分布直方圖構成,用于比較兩個選定數據段的特征。
Manifold 通過以下三個步驟幫助用戶發現模型需要改進的區域:
- 比較:首先,給定一個具有一個或多個機器學習模型輸出的數據集,Manifold 比較并突出顯示模型或數據子集之間的性能差異(圖 3a)。
- 切片:該步驟允許用戶根據模型性能選擇感興趣的數據子集以便進行進一步的檢查(圖 3b)。
- 屬性:然后,Manifold 突出顯示所選數據子集之間的特征分布差異,幫助用戶找到性能結果背后的原因(圖 3c)。
我們使用 Manifold 比較模型在不同數據點(也即特征值)上的表現。作為設計替代方案,該可視化的直接實現如下圖(圖 4)所示:
在圖 4 中,圖中的每個點代表模型 x 在數據點 y 上的性能。盡管在理論上這個概念是成立的,但實際上,該方法存在 3 個主要挑戰:
因為有太多的點,無法清楚地識別模式;需要通過抽離或減少點來揭示模式。
難以確定哪些特征對于 y 軸最有價值,以便識別出相關模式。
隨著模型數量的增加,不同模型之間的比較變得更難。
為了提前解決這些問題,我們實現了一些聚合 / 簡化操作。我們不單獨表示每個數據點,而是把它們組成子集。我們沒有使用 y 軸來編碼特定特征的值,而是使用了表示不同數據子集的分類軸。該方法演變成我們最終的性能圖表,帶來了以下兩個好處:
基本相似的數據點不會重復出現在圖表上,只突出顯示最主要的高層差異。
因為減少了圖表中各種形狀的數量,可以在同一圖表中繪制不同的模型,以更好地加以比較。
在該工具的性能比較視圖中揭示模式的關鍵在于把測試數據集分成子集。在 Manifold 中,數據子集是基于一個或多個性能列的聚類算法自動生成的。這樣,對于每個模型,具有相似性能的數據被分到同一個組中(因為該算法確保模型 X 的性能對于子集 Y 中不同的數據點是一致的)。圖 5 和圖 6 說明了這個過程:
Manifold 的架構
由于生成 Manifold 可視化涉及一些密集的數值計算(聚類、KL 發散),計算性能不足會拖慢用戶界面的渲染,影響到整個用戶體驗。因此,我們開始使用 Python,利用 Python 的 DataFrame 處理和機器學習庫(如 Pandas 和 Scikit-Learn)實現所有重量級的計算。
但是,不得不依賴 Python 后端降低了 Manifold 的靈活性,難以進行組件化,在將 Manifold 和 Uber 的機器學習生態系統(比如我們的機器學習平臺 Michelangelo)集成時,這成了一個缺點。因此,除了 Python 計算外,我們用 GPU 加速器添加了第 2 個用戶工作流,該 GPU 加速器完全是用更加靈活的 JavaScript 編寫的。
圖 7 描述了這兩個工作流是如何和 Manifold 集成的。
對用戶來說,Manifold 的使用方式有 2 種:通過 Python 包或 npm 包(通過網頁)。由于代碼可重用性和模塊化對兩個工作流的共存至關重要,因此,Python 和 JavaScript 代碼庫被組織成 3 個不同的功能模塊:
數據轉換器,一種將來自其他內部服務(如 Michelangelo)的數據格式轉換為 Manifold 內部數據表示格式的功能;
計算引擎,一種負責運行聚類和其他數據密集計算的功能;
前端組件,Manifold 可視化分析系統(其 Python 包使用了 JavaScript 前端組件的內置版本)的用戶界面。
與 Python 不同,處理數據密集計算對我們的 JavaScript 計算引擎來說是個挑戰。為了讓用戶看到有意義的模式,需要大約計算 1 萬個數據記錄(“行”)。除了其他操作,KL 發散的聚類和計算需要在前端進行,可能會造成速度瓶頸,嚴重影響用戶體驗。事實上,根據我們的經驗,每次用戶更新性能比較視圖中的簇數量時,使用純 JavaScript 實現的計算可能需要 10 多秒時間。
相反,我們把 TensorFlow.js 作為線性代數實用庫來實現我們的 k 均值聚類和 KL 發散計算。因為這種類型的計算可以被矢量化,因而可以利用 WebGL 加速,所以更新同樣數量的簇的任務可以在不到 1 秒的時間里完成,超過原來性能的 100 倍。
通過組件化并將其包含在 npm 包中,Manifold 具有更好的靈活性,既可以用作獨立服務,也可以集成到公司的其他機器學習系統(如 Michelangelo)中。因為大多數用于機器學習的可視化工具需要額外的計算處理,超過了模型訓練后端具備的計算處理能力,所以,把它們與企業機器學習系統集成在一起可能很麻煩,而且不可擴展。Manifold 針對這種情況提出了解決方案,通過在可視化分析系統中分開處理訓練模型所需的計算,可以進行更快的迭代,并得到了更干凈的數據接口。
Manifold 在 Uber 的使用情況
在 Uber,各個專注于機器學習的團隊利用 Manifold 來處理所有事情,從 ETA 預測 到更好地理解駕駛員安全模型。下面,我們介紹最常見的兩個用例:識別機器學習模型的有用特征和消除模型結果中的假陰性。在這些示例中,Manifold 讓數據科學家能夠發現引導他們完成模型迭代過程的見解。
識別有用的特征
Uber Eats 團隊使用 Manifold 來評估 訂單交付時間 預測 模型 的效果。在模型迭代過程中,他們集成了一組附加的特征,他們認為這些特征具有提高現有模型性能的潛力。但是,在他們集成了這些特征之后,模型的整體性能幾乎沒有改變。為什么這些新特征沒有幫助?他們是否應該放棄使用這些特征的想法,還是這個低于標準的性能可以歸咎于其他因素?
為了回答這些問題,他們使用了圖 8 所示的模型,其中初始模型(綠色)和用附加特征訓練過的模型(橙色)作為 Manifold 的輸入。這兩個模型的所有其他方面是相同的。
圖 8 描述了通過 Manifold 數據可視化來表示的分析結果。如圖所示,該測試數據集根據數據點中的性能相似性自動分為 4 個簇。對于簇 0、1 和 2,具有附加特征的模型沒有提高性能。但是,在簇 3 中,新模型(具有附加特征的那個)的性能稍微好了一點,因為對數損失向左移動了一點。
由于最初的模型對簇 3 數據段的預測效果很糟糕,(對數損失比其他 3 個簇更高),我們認為對他們的模型來說,這些特征是有價值的,因為它們似乎解決了一些最難的個案。
消除假陰性
在另一個例子中,Uber 的安全團隊利用 Manifold 提高了一個 二元分類 模型的性能,該模型可以識別可能發生安全事故的行程。具體地說,他們希望消除模型生成的假陰性的數量(應該預測為具有陽性標簽的實例,但是模型未能捕捉到)。為此,他們需要確定在這些情形下,模型將陽性實例預測為陰性的原因。
為了實現這個目的,他們在測試數據集中過濾掉所有標記為陰性的實例,然后與標記為陽性的實例之間進行對比。他們把性能比較圖表中的 x 軸度量設置為“實際預測得分”,增加了簇數量,并比較那些值低于或高于決策閾值的子集,如圖 9 所示:
結果,我們注意到有幾個特征(A、B、C、D、E)顯示了真陽性組(灰色)和假陰性組(粉色)之間的分布差異,如圖 10 所示。換句話說,如果數據點在特征 A、B、C 或 D 上的值比較低,且其真實的標簽是陽性,那么該模型往往不能正確地預測 E 的值。
為了進一步深入研究這些假陰性形成的根本原因,我們直接比較了陽性組和陰性組的特征分布,如圖 11 所示:
我們注意到大多數真陰性實例在特征 A、B、C 或 D 上也往往具有較低的值。因此,如果實例在這些特征上具有較低的值,那么該模型傾向于將它們預測為陰性(有時這是錯的!)。在用 Manifold 進行了分析后,他們意識到該模型對這些特征索引過度。為了提高性能,他們要么找到更多能夠有助于區分假陰性和真陰性的特征,要么為低于某個閾值的數據分區單獨訓練模型。
接下來的工作
自從 2018 年 8 月推出 Manifold 以來,該工具已經成為 Uber 機器學習開發過程的不可或缺的組成部分。Manifold 有 3 個主要優勢:
模型無關性;
模型性能評估的可視化分析,超越了模型性能匯總統計,以此來提高準確性;
將可視化分析系統和標準模型訓練計算分開的能力,幫助更快和更靈活進行模型開發。
目前,Manifold 是一個獨立的 Web 工具和 Python 包。為了增加 Manifold 的功能,我們計劃把 Manifold 工具集成到 Uber 眾多的數據科學平臺上,進一步將該工具作為數據科學工作流的關鍵部分。通過這樣做,我們將能夠真正發揮 Manifold 數據無關性的潛力,以此來解決公司的各種數據科學使用場景問題。自此,我們打算根據這些應用程序進行設計改進,從而為這些用例提供更強大的支持。
英文原文:https://eng.uber.com/manifold/