利用已有的大數(shù)據(jù)技術(shù),如何構(gòu)建機器學習平臺
機器如何學習?
人腦具備不斷積累經(jīng)驗的能力,依賴經(jīng)驗我們便具備了分析處理的能力,比如我們要去菜場挑一個西瓜,別人或者自己的經(jīng)驗告訴我們色澤青綠、根蒂蜷縮、紋路清晰、敲聲渾響的西瓜比較好吃。
我們具備這樣的能力,那么機器呢?機器不是只接收指令,處理指令嗎?和人腦類似,可以喂給機器歷史數(shù)據(jù),機器依賴建模算法生成模型,根據(jù)模型便可以處新的數(shù)據(jù)得到未知屬性。以下便是機器學習與人腦歸納經(jīng)驗的類別圖:
平臺設(shè)想
在同程內(nèi)部,我們對應(yīng)用機器學習的一些團隊做了了解,發(fā)現(xiàn)他們普遍的處理步驟如下:
這個過程中存在一些痛點:
- 線上數(shù)據(jù)到線下搬運耗時
- 訓(xùn)練數(shù)據(jù)量難均衡,如果訓(xùn)練數(shù)據(jù)量較大,用 R 或者 Python 做單機訓(xùn)練將會非常耗時。如果訓(xùn)練數(shù)據(jù)量較小,訓(xùn)練出來的模型容易過擬合。
- 對分析和挖掘人員的編碼能力有一定的要求。
因此我們覺得可以構(gòu)建一套平臺化的產(chǎn)品直接對線上數(shù)據(jù)進行建模實驗,節(jié)省機器學習的開發(fā)成本,降低機器學習的應(yīng)用門檻。
平臺構(gòu)建
設(shè)計目標
- 支持大數(shù)據(jù)量的建模實驗,通過并行計算縮短耗時
- 抽象出最小執(zhí)行單元,配置簡單。通過拖拽以及連線的形式構(gòu)建建模流程
- 支持常用的機器學習學習算法處理回歸、分類、聚類等問題支持常用的特征工程組件,如標準化、歸一化、缺失值處理等
- 支持算法評估結(jié)果可視化
算法庫
在算法庫方面,我們選擇了 Spark,相比于 R 或者 Python,Spark 具備分布式計算的能力,更高效。
ml 和 mllib 都是 Spark 中的機器學習庫,目前常用的機器學習功能兩個個庫都能滿足需求。ml 主要操作的是 DataFrame,相比于 mllib 在 RDD 提供的基礎(chǔ)操作,ml 在 DataFrame 上的抽象級別更高,數(shù)據(jù)和操作耦合度更低。
ml 提供 pipeline,和 Python 的 sklearn 一樣,可以把很多操作 (算法 / 特征提取 / 特征轉(zhuǎn)換) 以管道的形式串起來,對于任務(wù)組合非常便利,如 StringToIndexer、IndexerToString、VectorAssembler 等。
組件化設(shè)計
從架構(gòu)設(shè)計上來說,不管是算法單元、特征工程單元、評估單元或者其他工具單元,我們認為都可以以組件的形式來設(shè)計。借助通用的接口行為以及不同的實現(xiàn)可以達到松耦合、易擴展的目的。
上圖是整個設(shè)計類圖的一部分,實際上我們做了較多層次的抽象以及公用代碼。下面看看核心類 BaseTask:
run 方法的實現(xiàn)是一套模板,步驟如下:
每個組件只要實現(xiàn)自己的核心邏輯 execute 方法就可以了。
平臺迭代
v1.0(平臺核心架構(gòu))
基于上述的設(shè)計目標,機器學習平臺***個版本的架構(gòu)如下:
用戶通過界面拖拽組件構(gòu)建建模流程,并將組件配置以及依賴關(guān)系保存到 DB 中
- 用戶可以在界面上觸發(fā)建模試驗的運行,實際上通過 spark-submit 提交一個 spark 任務(wù)
- Ml Engine 負責這個任務(wù)的執(zhí)行,在 Driver 端會從 DB 中獲取當前試驗的依賴組件以及流程關(guān)系。這些組件將依次運行,涉及 RDD 相關(guān)的操作時會提交到 Spark Executor 進行并行計算
流程 & 評估視圖
***個版本我們并沒有提供太多的算法組件,只有線性回歸和邏輯回歸,但是基于組件化的思想,我們非常有信心在后期快速迭代。
除了算法較少外,結(jié)合業(yè)務(wù)反饋與自身思考。我們覺得機器學習平臺可以做更多的事:
- 平臺定位不僅僅是實驗控制臺,增加預(yù)測結(jié)果落地的功能(離線計算)
- 訓(xùn)練模型隨著歷史數(shù)據(jù)的不斷擴充在大部分情況下都應(yīng)該是個周期性的事情。我們希望在平臺層面能夠幫助用戶托管這個過程。
v2.0(擴充組件 & 離線計算 & 周期性調(diào)度)
第二個版本中,我們首先基于原有的設(shè)計框架擴充完善了相關(guān)實用組件:
同時在第二個版本中,我們在細節(jié)上又做了一些完善:
- 建模實驗運行狀態(tài)流程展示,用戶可以觀察到每個組件的運行時間,狀態(tài),日志等
- 依賴完整的組件可以進行局部運行,在一個較復(fù)雜的建模實驗中,完全可以先進行局部驗證以及參數(shù)調(diào)整
- 建模實驗支持克隆
離線計算
我們提供了‘字段落地’的工具組件,可以將預(yù)測結(jié)果以 csv 的格式落入 hdfs 中:
周期性調(diào)度 & 宏變量支持
我們的另一款產(chǎn)品:大數(shù)據(jù)開發(fā)套件(BDK),函蓋周期性調(diào)度的功能,機器學習平臺的建模實驗可以以子任務(wù)的形式嵌入其中,結(jié)合宏變量(某種規(guī)則的語法替換,例如’/%Y/%m/%d’可以表示為當前天等等)用戶可以在我們的平臺中托管他們的建模試驗,從而達到周期性離線計算的目的。
架構(gòu)
綜上,豐富組件及完善功能、離線計算結(jié)果落地、結(jié)合 BDK 進行周期性離線計算是我們平臺第二個版本主要關(guān)注的,具體架構(gòu)有了以下演進:
實時預(yù)測
在我們的平臺中可以通過建模實驗訓(xùn)練模型,模型可以通過 PMML 這樣的標準導(dǎo)出,同樣也可以通過我們的模型導(dǎo)出功能將模型以 parquet 格式保存在 Hdfs 相應(yīng)的目錄上。用戶可以得到這些模型標準,自己去實現(xiàn)一些功能。但是我們覺得實時預(yù)測的功能在我們平臺上也可以抽象出來。于是 3.0 的架構(gòu)中我們開發(fā)了提供實時預(yù)測服務(wù)的 tcscoring 系統(tǒng):
tcscoring 系統(tǒng)的依賴介質(zhì)就是模型的 PMML 文件,用戶可以在機器學習平臺上直接部署訓(xùn)練完成了的模型對應(yīng)的 PMML 文件,或者通過其他路徑生成的 PMML 文件。部署成功后會返回用于預(yù)測的 rest 接口供業(yè)務(wù)使用:
當然,PMML 的部署也可以結(jié)合 BDK 設(shè)置成周期性調(diào)度,這些結(jié)合模型的周期性訓(xùn)練,整個訓(xùn)練 + 預(yù)測的過程都可以交給機器學習平臺 +BDK 實現(xiàn)托管。
交叉驗證
在機器學習平臺的第三個版本中,我們還有個關(guān)注點就是交叉驗證,之前的版本中用戶一次只能實驗一組超參數(shù),有了交叉驗證,用戶便可以在一次實驗中配置多組超參數(shù),在訓(xùn)練集中在按比例進行循環(huán)拆分,一部分訓(xùn)練,一部分驗證,從而得到***模型:
平臺展望
個性化
迭代完 3 個版本后,機器學習平臺抽象出了很多通用的東西,但是還有一些個性化的東西沒有辦法很好地變現(xiàn)。我們的想法是對于用戶來說,***的個性化途徑就是讓用戶自己寫代碼,我們會嘗試開放接口自定義插件,同時利用動態(tài)編譯技術(shù)加載這些個性化的組件,融合進建模流程中。
融合其他算法包
我們目前也在嘗試融合 spark ml 之外的算法包,如使用度較廣的 xgboost 等。另一方面目前的算法還是基于傳統(tǒng)的機器學習算法,對于深度學習,不管是嵌入 tensorflow 還是使用一些第三方的深度學習庫,如 Deeplearning4j 等。我們接下來會嘗試融合這些 spark ml 之外的算法包。