loading

Resources

23Mar 2018

利用 Cloudera 建立生產建議系統

2018 年02 月20 日
作者:Seth Hendrickson
原文:Cloudrea
 
 

什麼是建議系統?

我喜歡看電影,但是我很怕決定要看什麼電影。您還記得從前我們要看電影時,必須先花30 至60 分鐘在影音出租店逐一查找,按圖索驥並靠偶然的機緣選擇電影嗎?如今,我們只需要登入喜歡的串流服務,它就會直接推薦我們想看的電影。
這些電影推薦的基礎就是建議系統,通常由機器學習予以支援,會推薦我們最可能喜歡的一部份電影。建議系統並不只會挑選電影。我們不斷與系統互動,包括閱讀新聞、線上購買、搜尋網際網路,基本上是某人或某些事情需要從許多項目中找到數個相關項目的任何時候。聽起來有些籠統,因為它的確如此:有非常多的資料問題與建議問題相似。
提供良好建議一直是Netflix、Amazon、LinkedIn 和其他公司的重要差異化因素。因此,建議系統是非常活躍的研究領域,而且想要利用機器學習爭取競爭優勢的各大企業均表示高度興趣。

Cloudera Fast Forward Labs 最新研究成果

Cloudera Fast Forward Labs 是Cloudera 內部的應用機器學習研究部門,最近發佈一份報告指出建議系統的最新進展,特別強調運用深度學習將非結構性的資料與建議結合。報告指出,運用非結構性的、語義的內容可以用來超越僅運用較高層級的結構性資料的傳統方法。
 
深度學習對於電腦的願景和自然語言處理的影響,同樣發生在建議系統身上,令人極為期待。但是,您必須能夠建立和部署一個可擴充的建議系統並使進行生產,然後才能運用這些新的技巧。這就是Cloudera 開始參與的地方。
Cloudera 開放原始碼版本的Apache Hadoop 及其共生體系將為企業組織提供一套包羅萬象的工具,協助他們建立這些系統。在本文中,我們先瞭解Cloudera 如何利用協作式建議過濾來協助您建立一個傳統建議系統,再來討論如何整合尖端的深度學習技術打造更加個人化的建議。

系統概述

建議系統,如同任何生產性機器學習系統一樣,並不是花俏的演算法而已,相反的,這是一組整合式元件,會移動、儲存和處理資料以滿足特定的延遲、安全性和擴充要求。雖然精確的建議架構會因為應用的性質而有極大差異,但是大部份建議系統均遵照下列一般結構。
Generic flow diagram for recommendation systems
建議系統的通用流程圖
 
我們會就一般情況探討每個元件的用途和要求,但是也會提供具體的參考架構,讓討論更加確實。Cloudera 提供的Oryx 專案是Hadoop 上Lambda 架構的參考實作,是可用於生產的建議系統之實用範例,其中包含上述每個元件。
 
Oryx project architectureOryx 專案架構
 

機器學習

機器學習元件必須提供可以訓練演算法的方式,讓演算法從過去的資料學習並生產出一個模型,這個模型經過部署可為使用者提出智慧的建議。這個演算法非常重要,因為它的輸出類型會影響其他元件(如部署和儲存) 的設計。隨著使用者與這些項目互動而產生新資料,我們也必須不斷更新模型。
在理想的狀態下,每次新資料進來時,該模型會立即自行改進至最佳狀態,但在實務上卻甚難實現。相反,在實務上運作良好的常見解決方案是利用Lambda 架構。
與其僅使用線上學習或離線學習,Lambda 架構會個別管理兩種學習的程序。線上學習是取其近似結果,從個別資料樣本產生更新,但是具有近即時回饋的優點,而離線學習可以從所有歷史資料學習,因為它較不常執行。
 

離線學習

離線學習是機器學習建議演算法的主要學習機制。這個程序通常包含傳統資料科學的做法,即利用訓練集來訓練模型、進行交叉驗證來選擇最佳的超參數,以及把該模型匯出成某種格式以便由服務層使用。
訓練和選擇最佳模型應採自動化執行,且執行頻率須符合應用之需求,不過通常需要數個小時。它可能使用工作排程服務來執行,或甚至作為更新時間間隔極長的串流工作。在 Oryx 的個案中,會把離線學習當作新使用者/項目互動資料的 Spark DStream 上的一項操作來實作。在最近的批次時間間隔內進來的新資料 Hadoop 檔案系統 (HDFS) 的歷史資料結合並用作 Spark ML 交替最小二乘 (alternating least squares) (ALS) 演算法的訓練資料。
Spark ML ALS
交替最小二乘法是一種矩陣分解演算法,會為每位使用者和每個項目找到數字表示。使用者和項目有效率地嵌入到k 維度的空間中,在該空間中他們各自的距離便是他們對彼此之「偏好」的代表。因此,嵌入項目若接近特定嵌入使用者,則很可能是符合該使用者喜好的良好結果。ALS 模型的輸出是每位使用者和每個項目的k 維度向量,通常儲存成兩個矩陣,一個是使用者向量,另一是項目向量。
 
Spark ALS 模型只是範例之一,而且可擴充機器學習套件的其他演算法或是自訂演算法實作(如我們在建議報告中探索的) 均可取代它。矩陣分解演算法(比如ALS)是非常好的起點,因為他們簡單、容易實作而且可以普遍適用於幾乎任何建議問題。
 

線上訓練

線上訓練流程包括在新的資料串流進入系統時,更新最新批次模型的副本。我們需要一個地方來儲存模型,方便它立即更新,也需要一個串流工作,以便在資料進來時從中學習新的模型參數。我們也需要可以支援增量更新的演算法。
Oryx 專案使用的ALS 演算法利用遞歸最小二乘法取得近似的結果,並在線上更新使用者和項目的參數。這項更新只是近似結果,因為它不會如同完整演算法所要求一般一直交替演算直至趨同,但是即時整合新資料仍相當實用。目前在運作的使用者和項目矩陣會留存在邊緣節點的記憶體中並透過Spark 串流轉換進行更新,就是把一串新資料對照到一串模型更新。
線上更新模型亦可協助系統克服冷啟動問題。當使用者首次使用服務,我們對於使用者的喜好一無所知,且可能被迫提出粗糙或個人化不足的建議。然後,藉由線上更新,當使用者與他們的首個項目互動時,我們可以立即把這項新資訊納入,藉此改進其預測結果。由於使用者與服務的首次互動是能否留住使用者的關鍵,所以這項功能尤其重要。
前端
Front End
前端一般是某種Web 服務,使用者可與應用程式互動並接收建議。就系統的建議元件而言,前端必須能夠擴充,才能同時為許多使用者提供建議,以及把新使用者/項目的互動資訊轉送到傳輸層。Oryx 專案的前端是一個使用Apache Tomcat實作的簡易型Web 伺服器。該伺服器也包含部署或服務層,而且把新產生的互動資料寫入到Apache Kafka主題。
 
Apache Tomcat
資料傳輸
 
Data Transport
資料會在生產和消費資料的系統的不同組件之間不斷流動,所以該系統需要專用的傳輸層才能確保可靠傳遞資料。當使用者與應用程式互動時,便會持續產生新資料,這些資料必須加以處理並移動到長期儲存空間,並在訓練新模型時納入這些資料。建議模型的更新會傳達到服務層並寫入長期儲存空間。
傳輸層應:
   •   接受來自各種不同來源的多個輸入串流
   •   傳遞資料流給多個下游消費者
   •   可容錯
   •   在極端規模下運作
   •   增加和減少資料生產者和資料消費者且無停機時間
   •   在傳輸中的記錄上執行串流處理
 
Apache Kafka 是不錯的選擇,特別是因為它允許任意數量的資料生產者和消費者。透過Kafka 移動系統中所有資料是比較簡單的做法,因為每個元件只需要從Kafka 讀取或寫入Kafka,而不能與數個不同的來源或消費者整合。不過,Kafka 並不是為串流處理而設計的,所以其他串流元件如Spark Streaming 或Apache Flume可與Kafka 搭配使用。
Oryx 專案的資料傳輸層使用Apache Kafka 和Spark Streaming。新的使用者與項目互動資料透過Apache Tomcat 前端進入系統,之後會經過剖析然後寫入Kafka 輸入主題。即時更新元件以及Spark DStream 都會消費這些資料,而後者接著會用小批次的方式把資料寫入HDFS。也有一個Kafka 主題會從線上和離線訓練元件接收模型更新,並由前端和線上學習元件消費。
 
Kafka and Spark Streaming
使用者可能希望延伸這個架構,把已處理的資料串流發送到即時儀表板或是BI 工具,使用Kafka 可輕鬆完成這工作,因為只要把工具加入作為串流的另一消費者即可。此外,這個架構也可以輕鬆從前端取出資料並依指定管道遞送到某種A/B 測試工具,這是模型評估的重要程序。
 

部署

模型的部署方式,定義了在使用者瀏覽服務時給他們提供一系列建議的程序。這方面通常大部份取決於已訓練模型的輸出。例如,它可能是一個分類模型中較小份的參數清單,或可能是矩陣分解演算法的兩個大型矩陣。另一個要關注的,就是在進行預測時要如何產生或擷取模型的特徵。有些模型可能不需要額外的特徵,而其他模型則可從低延遲資料儲存庫擷取已儲存的特徵或是在執行時間進行運算。
 
很遺憾地,模型部份並不一定有常見或明顯的解決方案。您的選擇大部份取決於該應用程式對延遲和擴充的要求。Oryx 架構部署模型時採用自訂的實作方式,會把ALS 矩陣儲存在記憶體並使用空間敏感散列(LSH) 的專用變體以及近似最鄰近搜尋,以利加速預測。透過讀取模型更新的Kafka 主題,然後更新儲存在快取記憶體模型,即可結合線上訓練程序的模型更新。
Serving LSH+KNN
自訂解決方案需要極大的工程開銷,但這是滿足低延遲預測的要求所必需。若是可以接受與網路請求相關的延遲,則有其他選項,例如使用自訂計分服務,按請求提供建議。
 

部署深度模型

幾乎許多任何種類的建議應用程式,預計您都得探索各種不同的學習演算法,才能做出最佳的建議。當然,每次在系統中新增建模方式或轉換建模方式,都會有額外的工作量。然而,若兩種不同的學習方法產生類型相同或相似的模型,您便已經擁有必要基礎架構的最重要部份,所以在轉換過程中花費開銷會較少。
 
幸好許多建議演算法均採用通用樣式,只是實作細節有所不同:使用過去的資料來學習使用者和項目的向量空間表示(嵌入),以及利用嵌入空間中這些使用者和項目之間的距離來衡量其相似性然後得出其喜好結果。Oryx 專案使用的交替最小二乘演算法的輸出,事實上是每位使用者的向量表示(使用者矩陣) 以及每個項目的向量表示(項目矩陣)。Cloudera Fast Forward Labs 報告原型所使用的深度學習模型的輸出也是使用者與項目嵌入項目。使用ALS 演算法來設計系統的第一次迭代有一個極大的優點,就是未來要增加更進階的深度學習技術時會簡單很多。
 
要在Oryx 架構中進行此一變更,我們只需要注意切換離線訓練元件,並有選擇地切換線上訓練元件。部署層可以保持完全相同,因為我們只需要把ALS 嵌入切換成新深度學習模型的嵌入!
 
至於離線元件,我們可以排定一項工作,把訓練資料分成小批次從HDFS 串流到一個邊緣節點,最好是具備一個以上GPU,而且使用Keras 搭配Tensorflow 進行批次訓練。或者,我們可以使用以Spark 為基礎的深度學習框架,如deeplearning4jIntel BigDL,並且離線訓練元件會繼續作為在叢集上啟動的Spark 工作。因為神經網路依預設使用梯度下降法進行遞增訓練,取代線上元件也同樣輕鬆。在每個時間間隔抵達的新資料可以視作小批次的訓練資料,而模型可藉由前向傳播和反向傳播經過模型來進行更新。這個部份不需要GPU,因為每個新批次只需要傳播經過網路一次。
Spark Streaming Keras+Tensorflow
建立生產建議引擎時,一般建議從比較簡單的模型開始,例如矩陣分解,然後,如果簡單的模型之效能不足,可再考慮轉往更加複雜的技術。在大多數情況下,我們並不會一開始就取代矩陣分解,而且增加深度學習模型作為額外的模型,可與協作式過濾方法結合運用。
 

結論

有效的建議系統不但需要一個可以提出良好建議的機制,也需要一個完整的基礎架構,以便在必要時提供建議給使用者而且可以隨時間不斷調整。就算是簡易型實作如Oryx 架構,要完成正確的設置也相當有難度,而且必須面對各種取捨。精密或尖端的學習演算法若無法有效投入生產,則毫無用處。
與其依賴複雜的建模技巧,不如先著手採用比較簡單的建議演算法並投入生產,然後在周邊再建構可擴展的基礎架構。系統需求必定會隨時間變化,所以基礎架構應支援擴展與修改既有元件和建模技巧。如果基礎架構的設計良好,在需要更加個人化的建議時,我們可以轉換新的深度學習模型。
Back to list.
Prev
解釋 Hadoop Delegation Token 下篇
解釋 Hadoop Delegation Token 下篇