我們需要什麼樣的端到端 AI 系統?螞蟻 SQLFlow 的思考與答案

端到端機器學習是一種由輸入端的數據直接得到輸出端結果的AI系統,它可以對業務人員屏蔽複雜技術細節,同時給模型以更多自動調節空間,增加模型整體契合度。近兩年來,端到端機器學習成爲 AI 領域研發熱點,螞蟻集團於2019年5月發佈端到端 AI 系統 SQLFlow 開源項目,受到業界廣泛關注。今天,就讓我們來看看它對端到端 AI 的思考與解答。

SQLFlow 是螞蟻集團開源的使用 SQL 完成 AI 工作流構建的編譯系統。SQLFlow 將多種數據庫系統(MySQL, Hive, MaxCompute)和多種機器學習引擎(Tensorflow, Keras, XGBoost)連接起來,將 SQL 程序編譯成可以分佈式執行的工作流,完成從數據的抽取,預處理,模型訓練,評估,預測,模型解釋,運籌規劃等工作流的構建。

接下來我們會根據以下內容逐步介紹 SQLFlow:

  • 爲什麼要使用 SQL 語言描述端到端 AI 任務;
  • 使用 SQLFlow SQL 語句構建 AI 任務;
  • 使用 SQL 程序構建端到端 AI 工作流;
  • 使用 SQLFlow Model Zoo 沉澱模型;
  • 應用 SQLFlow 的場景案例;

爲什麼要使用 SQL 語言描述端到端 AI 任務

首先,思考一個問題,人工智能和金融有哪些耳熟能詳的結合呢?

  • 在智能徵信風控方向,可以運用大數據進行機器學習,刻畫用戶畫像,抽取個性化典型特徵,推進反欺詐評估、用戶徵信評估。

用到的技術: 聚類 (將有相似特徵的羣體聚類,確定人羣標籤)、 分類 (學習已有分類標籤的用戶特徵,識別新用戶所屬的類型、標籤)、 模型解釋

  • 在智能投資顧問方向,我們以人工智能算法爲基礎,爲客戶提供自動化投資管理解決方案,包括提供投資資訊、構建投資組合、直接投資管理等服務。

用到的技術: 時序模型迴歸運籌規劃

  • 智能營銷方向,上世紀90年代沃爾瑪超市將「啤酒」與「尿布」擺在同一區域的做法,大大增加了商品銷售收入,成爲藉助數據分析實現智能營銷的經典案例。而今天,在人工智能等新技術的加持下,數據分析技術正在不斷進化,千人千面的智能營銷已有廣泛的應用。

用到的技術: 推薦算法RankingCTR運籌規劃

然而,構建傳統的機器學習工作流程,需要經歷非常多的步驟並使用複雜的技術棧:

構建完整的 AI 應用,首先需要獲取用於構建模型的數據,這些數據通常可以從日誌、訂單數據、交易記錄等獲得。之後通過數據抽取,將其中我們需要用到的部分信息,從多個存儲位置抽取出來。抽取數據之後需要進行數據預處理,比如去掉錯誤的數據,填充缺失的數據,整理,排序等。預處理完成之後,我們需要從這部分數據中得到用於訓練模型的特徵,比如提取時間序列的週期性特徵,獲取交叉特徵等,最後將構建的特徵轉換成訓練框架可以接收的數據格式,才能開始訓練。

另外,在開始訓練之前,我們還需要確定使用哪個模型,XGBoost 模型還是深度學習模型,哪個模型更適合當前的場景?模型可以從現有模型庫中獲取並根據需要修改,或者從頭編寫新的模型使用。另外在構建機器學習模型時,我們需要不斷的評估模型的表現如何,以獲得最優的模型,這時就要使用各種評價指標描述訓練好的模型。當模型評估結果驗證達標之後,就需要將模型代碼發佈一個新的版本,部署到線上環境。發佈之前還要通過線下測試,小流量 ABTest,然後推全部署。如果是離線任務則需要更新定時任務使用新的模型代碼。

當模型的時效性比較強的時候,我們還需要不斷的使用新的數據更新模型,就是“增量訓練“,這樣每次增量訓練就不得不再次從頭走一次完整的流程。

要完成這一整套流程,需要用到複雜的技術棧。

我們需要的數據可能存儲在磁盤,或者像 HDFS 這樣的分佈式文件系統,或者可以從結構化的數據庫系統中獲得,或者是 NoSQL 引擎(比如 mongodb)存儲的數據;在預處理階段,有可能需要編寫 MapReduce Job 來處理 HDFS 上的大量的數據,或者使用 Hive 編寫 SQL 語句完成處理,亦或直接編寫 Python 代碼處理數據;在特徵工程階段,又需要使用類似 statsmodels, tsfresh 或者編寫 Python 程序使用諸如 Pandas 之類的庫完成預處理;在模型訓練階段,算法工程師首先需要掌握各種建模的能力,算法原理和基礎知識,也需要熟練使用各種機器學習引擎如 sklearn, XGBoost, Tensorflow, Pytorch 等;最後在上線部署階段,還需要了解模型如何接入 Serving 系統,怎麼樣做 ABTest,怎麼編寫 CI/CD 任務保證模型上線不影響線上業務。

構建 AI 應用,不僅需要冗長的鏈路和複雜的技術,從業務需求到 AI 系統上線也需要特別長的溝通鏈路。

比如業務同學和產品同學在構建產品思路的時候,在他的腦海中的 AI 系統需要完成的任務,傳達給開發同學之後,有可能傳達不到位,需要反覆的溝通。有時甚至做了一半還需要重做。

另外從需求到上線,爲了保證線上服務和數據產出的穩定,也需要通過許多的步驟。比如業務同學說:「活動要上線了,時間點很關鍵,明天必鬚髮布!」開發同學接到需求,加班加點,開發驗證完成之後,模型準確率提升10個點,準備發佈模型。SRE 同學則會把控上線之前的各項準備,包括預發測試是否通過,壓力測試是否通過,CPU 負載是否有提升,硬件資源是否能承載新的模型,模型預測延遲是否提升了等……完成流程也需要很長時間。然而如果沒有 SRE 的把關,線上的服務很難保證穩定性。

使用 SQL 作爲描述和構建 AI 任務的語言,可以降低構建 AI 應用的門檻,提升效率。

首先需要區分編程語言主要的兩種描述方法:描述意圖和描述過程。簡而言之,描述意圖是在描述「做什麼」,描述過程是描述「怎麼做」。比如,夏天大家有空喜歡喫點燒烤喝點啤酒,描述意圖的方式,說「我想去擼串」這一句就夠了。而描述過程,就需要說「我今天晚上下班後,叫上老王小李,去公司樓下的燒烤店,點100個串和10個啤酒,最後用支付寶掃碼付款」。可以看到描述意圖可以非常簡潔,而具體的執行方案,可以根據意圖中構建得出。這點也是 SQL 不同於其他語言的關鍵點。

在描述模型訓練任務時,使用 SQLFlow SQL 只需要編寫 SELECT * FROM iris.train TO TRAIN DNNClassifier LABEL class INTO my_dnn_model; 即可,如果使用 Python 完成相同的任務則需要編寫如下圖這樣的較長的代碼。

SQL 語言除了有非常簡潔的優勢之外,在數據科學領域,SQL 語言的已有用戶量大,並且在不斷的增加。這裏也有兩個統計圖,統計了數據科學類任務所使用的工具的流行程度和增長趨勢。SQL 語言流行程度排名第三,增量排在第四名。數據科學領域正在更多的使用 SQL 是我們希望使用 SQL 語言描述 AI 任務的原因。除了在表達能力上 SQL 語言有非常簡潔的優勢之外,在螞蟻內 MaxCompute 被廣泛使用也是我們選擇 SQL 的一個原因。

如何使用 SQLFlow SQL 語句構建 AI 任務

SQLFlow 是一個開源項目,您可以在任意環境部署 SQLFlow。SQLFlow 提供了兩種用戶界面:基於 Jupyter Notebook 的 Web 圖形界面和命令行工具。在 Jupyter Notebook 中,輸入的 SQL 語句會發送到 SQLFlow server 完成編譯和執行。

對於模型訓練任務,SQLFlow 拓展了標準 SQL 語法,增加了 TO TRAIN 從句來描述模型訓練。我們以 iris(鳶尾花)數據集爲例,訓練數據格式如下圖:

訓練的 SQL 語句是:

SELECT * FROM iris.train
TO TRAIN DNNClassifier
WITH model.n_classes = 3, model.hidden_units = [10, 20]
LABEL class
INTO my_dnn_model;

其中 SELECT * FROM iris.train 部分使用一個標準的 SQL 語句,獲取模型訓練的數據,這個 SQL 語句可以是任意的 SELECT 語句,比如包含嵌套、JOIN 等操作也是支持的。第二行 TO TRAIN DNNClassifier 指定訓練的模型是 DNNClassifier,DNN 分類器。第三行 WITH 語句指定了模型訓練需要的一些參數。LABEL class 指定使用數據庫中的 class 列作爲訓練標籤,INTO my_dnn_model 指定訓練好的模型保存的名字。運行這條 SQL 語句,SQLFlow 會開始模型的訓練,並保存一個叫做 my_dnn_model 的模型用於預測,評估、解釋等。

然後我們可以使用下面的這段 SQL 進行模型評估:

SELECT * FROM iris.test
TO EVALUATE my_dnn_model
WITH validation.metrics="Accuracy"
LABEL class
INTO iris.evaluate_result;

其中, SELECT * FROM iris.test 指定使用另一個表 iris.test 作爲驗證集,TO EVALUATE my_dnn_model 指定要評估的模型是我們剛纔訓練的 my_dnn_model,LABEL class 指定評估數據集中的標籤列爲 class,INTO iris.evaluate_result 指定評估指標的輸出表。模型評估任務執行完成之後,就會輸出如下圖這樣的評估指標的表。您也可以在 SQL 語句中使用 WITH 指定要輸出的指標,就會作爲結果表的一列數據輸出。

在模型訓練完成之後,我們可以使用下面的 SQL 語句進行預測:

SELECT * FROM iris.pred
TO PREDICT iris.pred_result.class
USING my_dnn_model;

我們使用的預測表 iris.pred 的 class 列是空的,是希望輸出的結果。SQL 語句中 TO PREDICT iris.pred_result.class 指定預測結果輸出到表 iris.pred_result 的 class 列。USING my_dnn_model 指定使用之前訓練的 my_dnn_model 這個模型來預測新的數據,這樣 SQLFlow 將預測的結果輸出到表:iris.pred_result 的 class 列。

有時,我們希望進一步地瞭解模型,模型究竟是怎麼通過輸入得到輸出,就需要「解釋」訓練好的模型,看到底哪些輸入會如何影響模型的輸出。SQLFlow 深度集成了 SHAP 和 Tensorflow 的模型解釋功能,只需要編寫如下的 SQL 語句:

SELECT * FROM iris.test TO EXPLAIN my_dnn_model;

在使用 Jupyter Notebook 的情況下可以輸出下面的模型解釋結果的圖。從圖中可以看到,輸入數據中的特徵 petal_length 對模型判斷鳶尾花的類別起到至關重要的幫助。

SQLFlow 目前提供了充足的常用模型庫,使得我們可以快速使用 SQL 語句實驗、驗證最終構建 AI Pipeline。目前已經支持的模型包括深度學習常用的網絡包括 DNN, RNN, LSTM 的分類、迴歸,基於 XGBoost 的樹模型的分類迴歸以及 Deep Embedding Clustring,kmeans 聚類模型,還有常見的金融行業模型包括評分卡模型,ARIMA, STL 時間序列模型等。

使用 SQL 程序構建端到端 AI 工作流

SQLFlow 不僅可以使用 SQL 語句完成 AI 應用中的模型訓練、評估、預測、解釋等單個任務,還可以將一整個 SQL 程序(包含許多 SQL 語句的一個 SQL 程序)編譯成爲一個完整的工作流任務執行。在之前列出的「構建 AI 應用的常見流程」中,SQLFlow 已經支持和計劃支持的步驟標註在了圖中。

其中綠色標註的是目前 SQLFlow 已經支持的。SQLFlow 可以支持多種 SQL 引擎的方言,包括 MySQL, Hive, MaxCompute,並在逐步擴展。不論 SQLFlow 對接的是哪種數據庫引擎,只要是當前對接的數據庫支持的 SQL 語句,都可以被 SQLFlow 識別併發送至對應引擎執行,以此來支持使用 SQL 語言完成的數據抽取、預處理的工作。SQLFlow 還計劃使用 TO RUN 關鍵字來拓展自定義數據預處理、特徵工程的能力。SQLFlow 在訓練時可以支持可選的 COLUMN 從句,將支持多種常見的數據轉換的操作,比如歸一化、隨機化、Embedding、分桶等。另外,SQLFlow 也計劃支持可以直接將訓練好的模型部署到在線 Serving 的系統。

這樣,我們可以編寫一大段 SQL 語句,完全交給 SQLFlow 編譯和執行。包括使用 JOIN 操作的 SQL 語句,從各個表抽取需要的數據,使用標準 SQL 完成預處理或者使用自定義函數完成預處理,最後開始訓練和預測的 SQL 語句。

對於這樣的一個包含許多語句的 SQL 程序,SQLFlow 會將其解析,編譯成一個可以在 Kubernetes + Argo 集羣上運行的 workflow。workflow 中每一個步驟(step)可以是執行標準的 SQL,也可以是執行分佈式模型訓練或預測任務。這個 Workflow 會被提交到 Kubernetes 集羣上,交由 Argo Workflow Engine 調度執行。這個 workflow 的執行結果會從 Kubernetes 集羣返回到用戶。

通常情況,使用 SQL 語句編寫的一個 SQL 程序,會被編譯成一個順序的 workflow,step by step 地執行。但有些 SQL 語句的 step 不是相互依賴的,可以併發地執行。如果我們使用如 Hive 這樣的引擎,同時提交兩個 SQL 語句,其實是可以生成2個 Map-Reduce 任務併發的在集羣上執行的。SQLFlow 會自動的分析 SQL 程序中的 SQL 語句之間的依賴關係,並儘量的增大 SQL 程序的併發度,生成一個具有依賴關係 workflow 執行,最大限度的利用集羣資源,降低整段 SQL 程序的執行時間。這個功能,省去了很多傳統平臺上,用戶需要手動的構建任務和任務之間依賴關係的工作,因爲所有的任務都可以用 SQL 語言描述,計算的依賴圖自然可以自動生成。

使用 SQLFlow Model Zoo 沉澱模型

在構建 AI 應用時,另一個關鍵的任務就是需要編寫模型定義的代碼。SQLFlow 社區提供了 Model Zoo 框架,方便模型開發的同學不斷的沉澱應用場景爲通用的模型,並貢獻到私有或公有的模型庫,減少業務和開發之間的溝通成本。

SQLFlow 爲快速構建 AI 任務提供了足夠的模型彈藥庫。使用 ModelZoo 框架,算法開發可以將模型貢獻成公開的模型,讓更多的 SQLFlow 用戶享受便利,也可以定向地分享給部分用戶,保證模型的安全使用不泄密。基於模型庫,業務同學可以直接使用 SQL 語句引用模型庫中的模型,探索業務應用,發佈業務應用;算法同學可以更加專注於提升模型效果、開發、更新模型的工作上面。這樣不僅可以減少溝通成本,也可以提升工作成果的複用能力。

另外,Model Zoo 平臺的代碼也是完全開源的。用戶完全可以在公司內部搭建自己的 Model Zoo 並且只在公司內分享模型。同時,用戶可以連接到公開 Model Zoo 獲取或者貢獻新的模型。這樣不便於對外公佈的,和業務場景強綁定的一些模型,就可以在公司內逐步沉澱,構建公司自己的核心算法庫。

應用 SQLFlow 的場景案例

下面,我們結合一些螞蟻的實際場景,解釋 SQLFlow 在實際業務應用中的使用方法。

第一個例子是資金流入流出預測。我們這裏展示的是使用天池的公開數據集,其實螞蟻內部的業務也在使用相同的方法。這個數據集包含了資金的申購,贖回在一段時間內的詳情(脫敏),我們需要預測未來時間內資金申購、贖回的量。

SELECT time, purchase FROM fund.train
TO TRAIN sqlflow_models.ARIMAWithSTLDecomposition
WITH model.order=[7, 0, 2],
model.period=[7, 30],
model.date_format="%[2]s",
model.forecast_start='2014-09-01',
model.forecast_end='2014-09-30'
LABEL purchase
INTO purchase_predict_model;

在示例 SQL 語句中,我們使用了模型 sqlflow_models.ARIMAWithSTLDecomposition 應對此類場景。ARIMAWithSTLDecomposition 模型在金融領域有較爲廣泛的應用,該模型將輸入的時間序列數據自動的提取不同時間窗口的週期性特徵構建模可以獲得比較好的結果。另外,SQLFlow 也提供了基於 LSTM 的深度學習模型用於訓練時間序列模型,可以參考教程:

https://github.com/sql-machine-learning/sqlflow/blob/develop/doc/tutorial/energe_lstmbasedtimeseries.md

WITH 中指定了一些模型的參數配置,這些可以參考模型定義中的參數解釋:

https://github.com/sql-machine-learning/models/blob/develop/sqlflow_models/arima_with_stl_decomposition.py

因爲此數據集數據量不大,這個訓練任務可以在一臺機器上完成訓練。此模型訓練之後可以達到 MAPE 5% 的表現。

第二個例子是較爲複雜的場景,使用 SQLFlow 構建點擊率預估模型。我們以 kaggle 的一個開源數據集 (https://www.kaggle.com/c/criteo-display-ad-challenge/data) 爲例,螞蟻在類似的場景中,也會使用同樣的方法構建模型。這個數據集中,列 l1~l13 是脫敏之後的連續值特徵,c1~c26 列是離散類別特徵,離散類別特徵存儲爲 hash string。

SELECT label,COALESCE(NULLIF(l1, ''),0) AS ll1,COALESCE(NULLIF(l2, ''),0) AS ll2,
            COALESCE(NULLIF(l3, ''),0) AS ll3,COALESCE(NULLIF(l4, ''),0) AS ll4,COALESCE(NULLIF(l5, ''),0) AS ll5,
            COALESCE(NULLIF(l6, ''),0) AS ll6,COALESCE(NULLIF(l7, ''),0) AS ll7,COALESCE(NULLIF(l8, ''),0) AS ll8,
            COALESCE(NULLIF(l9, ''),0) AS ll9,COALESCE(NULLIF(l10, ''),0) AS ll10,COALESCE(NULLIF(l11, ''),0) AS ll11,
            COALESCE(NULLIF(l12, ''),0) AS ll12,COALESCE(NULLIF(l13, ''),0) AS ll13,C* 
FROM alifin_jtest_dev.sqlflow_ctr_train_raw
TO TRAIN DNNLinearCombinedClassifier
WITH model.dnn_hidden_units=[64,32], train.batch_size=32, validation.throttle_secs=300
COLUMN NUMERIC(“^ll[0-9]+$”, 1) FOR linear_feature_columns
COLUMN EMBEDDING(CATEGORY_HASH(“^C[0-9]+$”, 100), 8, "sum") FOR dnn_feature_columns
LABEL 'label'
INTO my_ctr_model;

我們可以使用以上的 SQL 語句描述訓練一個「Deep and Wide」模型,將 l1~l13 列作爲模型的線性部分的輸入,將 c1~c26 特徵作爲模型的 DNN 部分輸入。其中 COLUMN 語句分別可以使用正則表達式指定哪些些列作爲模型哪部分的輸入。我們將離散特徵通過 HASH 分桶,然後增加 embedding 層的方法,將原始字符串特徵輸入傳遞給模型。注意這條 SQL 語句同時也可以包含部分預處理功能,使用 COALESCE 函數填充 l1~l13 列中的缺失值。

在螞蟻點擊率預估實際任務中,我們通常會有很多的預處理 SQL 語句,獲得這張訓練數據表,然後將訓練數據再切分成訓練集和驗證集,再使用 SQLFlow 進行訓練。這些步驟在螞蟻都是使用 MaxCompute 的 SQL 語句編寫的。所以整個點擊率預估應用,從預處理到訓練只需要編寫一段 SQL 語句即可。不同於其他圖形化平臺,SQL 程序也可以存入代碼倉庫,方便 code review。

最後一個例子是 SQLFlow 的重要貢獻者滴滴在去年雲棲大會分享的一個應用:滴滴司機出車偏好分析。探索出不同類別的司機,可以爲後續策略投放和管理提供信息。左側數據表中爲每個司機的每天的出車時長數據,每一列表示10分鐘,一天有144個10分鐘,就是144個數據點,每個點是在這10分鐘內司機出車的時間比例。這樣我們就可以在 JupyterNotebook 使用 matplot 得到如下圖的這樣的可視化展示,這張圖裏明顯看不出來任何規律。

然後我們使用 DeepEmbeddingClusterModel 來進行聚類分析,編寫如下的 SQL:

SELECT * FROM driver_log.train
TO TRAIN sqlflow_models.DeepEmbeddingClusterModel
WITH model.n_clusters=5
INTO cluster_dirver_model;

其中 model.n_clusters=5 指定把數據聚成5類。然後使用下面預測 SQL 語句輸出聚類結果:

SELECT * FROM driver_log.train
TO PREDICT dirver_log.predict.class
USING cluster_driver_model;

然後再次使用 matplot,根據類別繪製司機出車時長,可以得到如下這張圖,比如我們可以這樣解釋這張圖:司機分成了自由職業司機,定時上下班司機,996司機,佛系司機,夜貓子司機5大類。當然我們也可以探索不同數目的聚類結果,可能會發現更多的規律。

總結

SQLFlow 不但將數據庫和 AI 系統連接起來,還提供將一段 SQL 程序自動根據依賴關係編譯成併發執行的工作流,在 Kubernetes 集羣上分佈式地運行。SQLFlow 提供了豐富的內置模型和 Model Zoo,用戶只需要編寫 SQL 就可以完成完整 AI 任務的構建,算法同學可以更加專注於建模工作,大大降低構建 AI 系統的成本和時間。如果您對 SQLFlow 項目感興趣,可以在 SQLFlow Github 社區獲得幫助。也可以使用我們提供的本地 playground 快速試用:

https://github.com/sql-machine-learning/playground/blob/master/dev.md

本文轉載自公衆號金融級分佈式架構(ID:Antfin_SOFA)。

原文鏈接

https://mp.weixin.qq.com/s/LydAst4w5-O2d1rUPVsTWg

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