天天看點

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

背景

本文示範如何使用 OpenMLDB 和 Byzer-lang 聯合完成一個完整的機器學習應用。Byzer-lang 作為面向大資料和 AI 的一門語言,通過 Byzer-Notebook 和使用者進行互動,使用者可以輕松完成資料的抽取、ETL、特征/模型訓練、儲存、部署到最後預測等整個端到端的機器學習流程。

OpenMLDB 在本例中接收 Byzer 發送的指令和資料,完成資料的實時特征計算,并經特征工程處理後的資料集傳回 Byzer,供其進行後續的機器學習訓練和預測。

準備

心理準備:因為作業系統環境的千差萬别,安裝部署常常是最繁瑣的和消耗時間的部分。請大家耐心準備,在遇到問題時及時尋求兩個社群的幫助。

使用者需要找一台 Linux 機器(虛拟機也行),然後部署如下幾個應用(都很簡單,基本都是下載下傳、解壓、運作即可):

  1. Byzer-lang: Byzer-lang 部署
  2. Byzer-Notebook:Byzer-Notebook 部署
  3. OpenMLDB 0.5.2:OpenMLDB 部署,注意是叢集版的部署模式,并且 zk 路徑要配置成 /openmldb
值得注意的是,如果沒有使用對象存儲這種共享存儲,那麼 Byzer-lang, OpenMLDB 需要部署在一台伺服器,這樣才能互相通路雙方産出的檔案。

部署時需要注意的幾個小問題:

  1. 部署好 JDK8
  2. 請確定一些基礎的指令,諸如有 curl、ipconfig 等指令。一般部署腳本裡會用到,如果沒有,按報錯提示安裝即可。
  3. 最好使用 bash 執行腳本而不是預設的 sh

對于最後确認是不是安裝完成,可以按如下方式進行檢查。

首先是檢查 OpenMLDB, 使用者可以在 OpenMLDB 安裝目錄裡執行如下指令:

./bin/openmldb --zk_cluster=192.168.3.14:7181 --zk_root_path=/openmldb --role=sql_client      

順利連接配接上後說明是可行的,此時需要初始化一個資料庫和表:

> CREATE DATABASE demo_db;
> USE demo_db;
> CREATE TABLE t1(id string, vendor_id int, pickup_datetime timestamp, dropoff_datetime timestamp, passenger_count int, pickup_longitude double, pickup_latitude double, dropoff_longitude double, dropoff_latitude double, store_and_fwd_flag string, trip_duration int);      

執行完成後大概這個樣子:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

其次是檢查 Byzer ,可以通路伺服器的 9002 端口,如果你順利進入 Byzer-Notebook 顯示如下界面,則證明是可行的:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

資料準備

首先,從 New York City Taxi Trip Duration 下載下傳計程車的資料,解壓得到如下資料集:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

接着進入 Byzer-Notebook 首頁,通過 上傳 功能上傳這個檔案:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

上傳後你應該可以在 Byzer-Notebook 的檔案系統裡看到這個檔案:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

這樣,我們資料就準備好了。

接下來,我們會分成三個步驟進行:

  1. 特征/模型訓練
  2. 特征部署和模型部署
  3. 端到端的預測能力

這三個步驟對應成三個 Notebook:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

安裝 Byzer-openmldb-3.0 插件

Byzer 和 OpenMLDB 通訊需要一個 Byzer 插件,可以在 Byzer-notebook 裡直接執行一條指令來安裝:

!plugin app add - "byzer-openmldb-3.0";      

注:如果是 sandbox 模式部署的 Byzer, 目前這個方式是無效的。

網速被限定 100k 以内,因為這個插件比較大,是以下載下傳時間較長,需要大家耐心等待。

另外,在 Log Message 标簽頁會顯示 下載下傳進度資訊。

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

特征/模型訓練部分

第一步,加載我們訓練的 csv 檔案看看:

load csv.`/tmp/upload/train.csv` 
where header="true" 
and inferSchema="true"
as taxi_csv_data;      

執行後輸出結果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

為了友善,我們把這個資料儲存到資料湖裡,然後再次從資料湖裡加載成一張表叫 ​

​taxi_tour_table_train_simple​

save overwrite taxi_csv_data 
as delta.`public.taxi_tour_table_train_simple` ;

load  delta.`public.taxi_tour_table_train_simple` 
as taxi_tour_table_train_simple;      

這樣我們的資料就通過 資料湖 管理起來了。資料湖具有版本管理等功能,速度相比 csv 檔案也更快。

但是 OpenMLDB 并不能直接通路資料湖,是以,我們還需要把資料導出一份到檔案系統中,供 OpenMLDB 使用。

save overwrite taxi_tour_table_train_simple 
as parquet.`/sample_data/data/taxi_tour_table_train_simple`;      

儲存完成後,在側面的檔案系統裡是可以看到下列内容:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

現在,我們需要讓 OpenMLDB 把這個資料加載進去:

-- load the data to FeatureStore offline
-- /home/williamzhu/byzer-home/allwefantasy
run command as FeatureStoreExt.`` where 
zkAddress="192.168.3.14:7181"
and `sql-0`='''
SET @@execute_mode='offline';
'''
and `sql-1`='''
SET @@job_timeout=20000000;
'''
and `sql-2`='''
LOAD DATA INFILE '${HOME}/sample_data/data/taxi_tour_table_train_simple' 
INTO TABLE t1 options(format='parquet', header=true, mode='append');
'''
and db="demo_db"
and actinotallow="ddl";      

點選執行後效果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程
這裡有點小遺憾, 測試的 OpenMLDB 版本的最後輸出是一個格式化的字元串,是以顯示比較淩亂。

值得注意的是,sql-2 是讓 OpenMLDB 加載前面我們産生的檔案,這裡我們需要傳遞 ​

​${HOME}​

​​ 做字首,因為 Byzer 是多租戶的引擎,目錄是虛拟目錄,隻有這樣不同使用者的目錄才不會覆寫。OpenMLDB 要通路 Byzer 的目錄,需要添加 ​

​${HOME}​

​ 這個字首。

注釋,如果發現 ${HOME} 這個無效,請使用 Byzer Notebook 配置檔案中的

OpenMLDB 是異步模式的,是以系統傳回給 Byzer 的是一個任務 ID 号。我們可以使用如下代碼看看任務是不是完成了:

run command as FeatureStoreExt.`` where 
zkAddress="192.168.3.14:7181"
and `sql-0`='''
SET @@execute_mode='offline';
'''
and `sql-1`='''
SET @@job_timeout=20000000;
'''
and `sql-2`='''
show jobs;
'''
and db="demo_db"
and actinotallow="ddl";

!lastCommand named jobs;
select application_id, id, state,end_time  from jobs order by id desc as output;      

輸出結果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

可以觀察下 state 狀态從 Running 變成 FINISHED, 然後可以繼續往下走。

資料被加載到 OpenMLDB 後,現在就可以利用它計算特征,計算的特征我們會儲存到 ​

​/tmp/feature_data​

​ 目錄中供 Byzer 後續模組化使用。

-- compute feature with OpenMLDB
run command as FeatureStoreExt.`` where 
zkAddress="192.168.3.14:7181"
and `sql-0`='''
SET @@execute_mode='offline';
'''
and `sql-1`='''
SET @@job_timeout=20000000;
'''
and `sql-2`='''
SELECT trip_duration, passenger_count,
sum(pickup_latitude) OVER w AS vendor_sum_pl,
max(pickup_latitude) OVER w AS vendor_max_pl,
min(pickup_latitude) OVER w AS vendor_min_pl,
avg(pickup_latitude) OVER w AS vendor_avg_pl,
sum(pickup_latitude) OVER w2 AS pc_sum_pl,
max(pickup_latitude) OVER w2 AS pc_max_pl,
min(pickup_latitude) OVER w2 AS pc_min_pl,
avg(pickup_latitude) OVER w2 AS pc_avg_pl,
count(vendor_id) OVER w2 AS pc_cnt,
count(vendor_id) OVER w AS vendor_cnt
FROM t1
WINDOW w AS (PARTITION BY vendor_id ORDER BY pickup_datetime ROWS_RANGE BETWEEN 1d PRECEDING AND CURRENT ROW),
w2 AS (PARTITION BY passenger_count ORDER BY pickup_datetime ROWS_RANGE BETWEEN 1d PRECEDING AND CURRENT ROW) INTO OUTFILE '${HOME}/tmp/feature_data';
'''
and db="demo_db"
and actinotallow="ddl";      

執行結果:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

然後我們到 Byzer-Notebook 側邊的檔案系統裡,可以看到生成了對應的目錄:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

現在,我們可以用 Byzer 加載 OpenMLDB 産生的特征資料了:

load csv.`/tmp/feature_data` where
header="true"
and inferSchema="true"
as feature_data;

-- !desc feature_data;      

執行效果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

對特征在做一些處理,比如類型轉換之類的:

select *, cast(passenger_count as double) as passenger_count_d,
cast(pc_cnt as double) as pc_cnt_d, 
cast(vendor_cnt as double) as vendor_cnt_d 
from feature_data
as new_feature_data;

-- !desc new_feature_data;      
【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

還可以看看特征之間的關系(這是個可選步驟,需要用到 Byzer 可視化插件,使用者感興趣可以參考文章——《祝威廉:Byzer-yaml-visualiaztion 插件介紹》 ,詳見知乎):

select 
passenger_count_d,
vendor_sum_pl,
vendor_max_pl,
vendor_min_pl,
vendor_avg_pl,
pc_sum_pl,
pc_max_pl,
pc_min_pl,
pc_avg_pl,
pc_cnt_d,
vendor_cnt
, trip_duration as label
from new_feature_data 
as visual_data1;

-- 每個 label 按比例抽樣
run visual_data1 as RateSampler.`` where sampleRate="0.9,0.1"
as visual_data2;

-- 獲得 10% 的資料
select * from visual_data2 where __split__=1 as visual_data;

!visualize visual_data '''
runtime: 
   env: source /home/williamzhu/miniconda3/bin/activate ray-1.12.0
   cache: false
control:
   ignoreSort: true
fig:
   scatter_matrix:       
      color: label
      dimensions: 
        vv_type: code
        vv_value: >- 
            ["passenger_count_d","vendor_sum_pl","pc_sum_pl"]
''';      

執行結果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

最後,我們來生成最後可以給算法直接用的資料:

select vec_dense(array(
passenger_count_d,
vendor_sum_pl,
vendor_max_pl,
vendor_min_pl,
vendor_avg_pl,
pc_sum_pl,
pc_max_pl,
pc_min_pl,
pc_avg_pl,
pc_cnt_d,
vendor_cnt
)) as features, cast(trip_duration as double) as label
from new_feature_data 
as trainning_table;      

執行結果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

接着我們開始訓練模型,使用 線性回歸 算法來訓練:

train trainning_table as LinearRegression.`/model/tax-trip` where

-- once set true,every time you run this script, MLSQL will generate new directory for you model
keepVersinotallow="true"

-- specify the test dataset which will be used to feed evaluator to generate some metrics e.g. F1, Accurate
and evaluateTable="trainning_table"

-- specify group 0 parameters
and `fitParam.0.labelCol`="label"
and `fitParam.0.featuresCol`="features"
and `fitParam.0.maxIter`="30";      

模型會被儲存在 ​

​/model/tax-trip​

​目錄裡。

執行結果如下:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

到此,我們模型訓練部分結束。

特征部署和模型部署

既然是端到端,那麼我們肯定需要把特征和模型代碼都進行部署。部署依然很簡單。

第一步部署特征工程:

-- deploy feature logical for online
run command as FeatureStoreExt.`` where 
zkAddress="192.168.3.14:7181"
and `sql-0`='''
SET @@execute_mode='online';
'''
and `sql-1`='''
SET @@job_timeout=20000000;
'''
and `sql-2`='''
DEPLOY demo SELECT trip_duration, passenger_count,
sum(pickup_latitude) OVER w AS vendor_sum_pl,
max(pickup_latitude) OVER w AS vendor_max_pl,
min(pickup_latitude) OVER w AS vendor_min_pl,
avg(pickup_latitude) OVER w AS vendor_avg_pl,
sum(pickup_latitude) OVER w2 AS pc_sum_pl,
max(pickup_latitude) OVER w2 AS pc_max_pl,
min(pickup_latitude) OVER w2 AS pc_min_pl,
avg(pickup_latitude) OVER w2 AS pc_avg_pl,
count(vendor_id) OVER w2 AS pc_cnt,
count(vendor_id) OVER w AS vendor_cnt
FROM t1
WINDOW w AS (PARTITION BY vendor_id ORDER BY pickup_datetime ROWS_RANGE BETWEEN 1d PRECEDING AND CURRENT ROW),
w2 AS (PARTITION BY passenger_count ORDER BY pickup_datetime ROWS_RANGE BETWEEN 1d PRECEDING AND CURRENT ROW);
'''
and db="demo_db"
and actinotallow="ddl";      

接着模拟一個線上實時資料,友善部署後的使用:

-- mock online data
run command as FeatureStoreExt.`` where 
zkAddress="192.168.3.14:7181"
and `sql-0`='''
SET @@execute_mode='online';
'''
and `sql-1`='''
SET @@job_timeout=20000000;
'''
and `sql-2`='''
LOAD DATA INFILE '${HOME}/sample_data/data/taxi_tour_table_train_simple' 
INTO TABLE t1 options(format='parquet', header=true, mode='append');
'''
and db="demo_db"
and actinotallow="ddl";      

最後部署下我們的線性回歸模型:

--%deployModel
--%url=http://192.168.3.14:9003

register LinearRegression.`/model/tax-trip` as tax_trip_model_predict;      

這些代碼都在 tax_trip_deploy.bznb 檔案裡:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

好了,現在我們來驗證下我們部署的 API 服務。

API 預測

這裡,我們可以用 Byzer 的 Shell 插件來使用 curl 來進行預測:

!sh curl -XPOST 'http://192.168.3.14:9003/model/predict' 
-d 'dataType=row&sql=select tax_trip_model_predict(vec_dense(slice(from_json(get_json_object(string(rest_request("http://192.168.3.14:9080/dbs/demo_db/deployments/demo","POST", map("body","{\"input\":[[\"id0376262\",1,1467302350000,1467304896000,2,-73.873093,40.774097,-73.926704,40.856739,\"N\",1]]}"),map("Content-Type" , "application/json"),map())),"$.data.data[0]"),"array<double>"),2,12))) as tax_duration&data=[{doc:[]}]';      

執行結果:

【轉載】Byzer + OpenMLDB 實作端到端的,基于實時特征計算的機器學習流程

随意給一條資料,就能預測計程車的時間了。

總結

通過整合 Byzer 和 OpenMLDB,我們不但能實作端到端的機器學習流程,同時還能完成實時特征工程,而且整個流程操作起來簡單高效。Byzer+OpenMLDB,未來前景不可限量。

相關連結

OpenMLDB 官網:​​https://openmldb.ai/​​