
本文由瀚高基礎軟體社群作者赫慶賀創作貢獻
本文介紹Greenplum和MADlib在機器學習方面的基本概念、架構和原理。并結合MNIST資料集完成對0-9阿拉伯數字的圖形識别的應用執行個體。旨在為資料庫開發者和DBA提供簡單機器學習的了解和入門的方式。
1.1 Greenplum
Greenplum是全球首個開源MPP資料庫,核心基于PostgreSQL。作為PB級分布式資料庫,支援大規模并行資料計算,被廣泛應用于企業的OLAP業務場景。Greenplum叢集的節點類型主要有master和segment。master提供資料庫統一通路入口并協調各計算節點運作,segment作為實體存儲和資料計算節點。通過增加segment節點可以實作系統性能的線性擴充。
Greenplum的并行計算能力和線性擴充能力賦能于MADlib,使其有更好的并發度,用更全量的資料和更少的資料移動來做模型訓練。
1.2 MADlib
MADlib 是Apache 軟體基金會頂級開源項目。作為一個機器學習函數庫,MADlib能以擴充插件的形式嵌入到Greenplum和PostgreSQL資料庫中,提供SQL層的接口。資料庫使用者可以直接通過SQL語言調用MADlib的接口完成機器學習的各個過程。
MADlib的架構如下:
為了保證執行效率,MADlib底層算法主要由C++編寫,上層接口由python編寫。目前已支援超過50種常用算法,并且為開發人員提供了擴充算法的方式。
所有算法都支援在Greenplum各個segment節點上并行運算,并将各個segment上的運算結果彙聚到master節點形成最終結果,計算時的資料僅在資料庫内部移動。為了實作這一點,MADlib在資料庫内建立一系列的彙聚函數(UDA)和計算函數(UDF)。在MADlib安裝時這些函數會被建立在資料庫内部。
MADlib支援深度學習算法,內建Keras、Tensorflow、Scipy庫,并內建CUDA、CUDNN以支援GPU加速計算。
1.3 機器學習
機器學習是一門多領域交叉學科,涉及機率論、統計學、算法複雜度理論等多門學科。機器學習是人工智能(AI)的核心子領域,機器學習的理論基礎是能夠讓計算機可以自動學習的算法。算法按照學習政策、應用領域、學習形式等方式劃分為不同類别。常見機器學習算法有:樸素貝葉斯、線性回歸、神經網絡、決策樹、支援向量機等等。幸運的是,作為一個軟體開發者可以不用去了解算法的實作細節,直接調用函數庫接口就能使用這些算法。機器學習已在生物特征檢測、圖像識别、資料挖掘、語義分析等多個領域有廣泛應用。
傳統方式下,計算機對某一個事物分類的判别方式通常需要一組事先定義好的門檻值區間和一系列嚴格的判斷邏輯組合來完成。例如讓計算機判斷一個物體是不是蘋果,要事先告訴計算機蘋果的定義是什麼。
假設我們定義蘋果的屬性取值區間為:顔色為紅色或青色,直徑範圍是2cm-10cm,重量範圍20g-500g,口感香甜。
計算機判斷物體是不是蘋果的流程通常如下:
機器學習則提供了另一種思路來解決這類問題。我們不需要給計算機預先定義蘋果是什麼。我們隻需要告訴計算機這種東西是蘋果、這種東西是蘋果、這種東西也是蘋果......
所有的蘋果樣例組成了資料集。通過機器學習算法對資料集的處理(訓練)可以産生判斷蘋果的模型。随着資料集的變化,模型可以通過重複訓練來優化調整。有了模型便可以判斷一個新的物體是不是蘋果了。
以上示例,對事務的分類判别方式稱之為分類算法,分類算法僅僅是衆多機器學習算法中的一種。除了分類算法還有用于預測連續性輸出值的回歸類算法,用來挖掘事務之間的關聯關系的關聯規則類算法等等。
1.4 資料集
機器學習中用來訓練算法模型和測試算法正确性的資料。針對自身業務的機器學習模型訓練最好使用自身應用場景的資料。也有許多不同應用場景下的公開資料集供學習研究使用。本文使用MNIST資料集作為訓練和測試用資料。
MNIST來自美國國家标準與技術研究所(NIST),是被經常使用的典型資料集。MNIST由多人手寫0-9的阿拉伯數字組成,可以把每個手寫阿拉伯數字看做是一個28x28像素的圖檔,将圖檔轉換成像素值的矩陣再以位元組序的形式存儲到檔案中。
下載下傳檔案清單如圖:
下載下傳後可以用gunzip工具将每個壓縮檔案解壓。資料集包含60000個訓練資料樣本,10000個測試資料樣本。檔案分别以格式存儲資料。
1.5 資料處理代碼
MNIST資料集需要将資料檔案轉換并導入Greenplum後才能被MADlib使用。為了友善資料集的處理,參照1.4節的資料檔案格式,編寫了代碼檔案mnist_transform.py:
load_mnist函數讀取解壓後的MNIST資料檔案,并将資料放入numpy.array數組中。
array2csv函數将numpy.array數組中的資料裝換成CSV格式檔案,CSV檔案可以通過copy指令導入資料庫表,其格式與資料庫表的格式要一緻。請參考2.1節資料庫表的建立語句。
array2imgfile 函數可以将數組中的一個樣本轉換成圖檔檔案,以便通過圖檔檢視器對資料樣本進行可視檢視。
有了前面的各項準備工作,接下來我們要做的是以實作計算機對手寫阿拉伯數字0-9的識别為例子,進一步探索Greenplum+MADlib機器學習方式。
具體過程是先将MNIST的資料集導入到Greenplum資料庫中,使用MADlib提供接口,完成樸素貝葉斯算法模型的訓練,并且使用訓練的模型對測試資料進行識别。最後通過對比測試資料樣本和識别結果來檢驗MADlib中樸素貝葉斯算法是否能對MNIST測試資料進行識别。
在進行第二章節的執行個體之前,需要先将Greenplum系統搭建好。
安裝時需要確定Greenplum已經啟動,從源碼編譯安裝到Greenplum時需要将編譯好的函數庫分發到各segment上。
本執行個體使用軟體版本:
PostgreSQL 9.4.24 (Greenplum Database 6.0.0-beta.1 build dev)
MADlib version: 1.17.0
2.1 導入資料
以下步驟需要用用戶端軟體(如psql)連接配接到Greenplum資料庫進行操作,使用PostgreSQL資料庫時請酌情調整SQL。
建立訓練資料表:
CREATE TABLE mnist_example ( id int, label smallint, attributes smallint[]) DISTRIBUTED BY(id);
id 字段為樣本編号。
label字段表示樣本代表的阿拉伯數字。
attributes 字段是由784個元素構成的Array,用以儲存樣本圖檔的資料。
建立測試資料表:
CREATE TABLE mnist_topredict ( id int, label smallint, attributes smallint[]) DISTRIBUTED BY(id);
将MNIST的訓練資料和測試資料轉換成CSV格式:
運作mnist_transform.py檔案的轉換函數(python3):
得到CSV檔案:test_data.csv trans_data.csv
導入訓練資料到表mnist_example:
copy mnist_example from '/home/gpadmin/madlib/mnist/trans_data.csv' CSV;
導入測試資料到表mnist_topredict:
copy mnist_topredict from '/home/gpadmin/madlib/mnist/test_data.csv' CSV;
2.2 訓練模型
調用MADlib的API進行模型訓練。
SELECT * FROM madlib.create_nb_prepared_data_tables('mnist_example','label','attributes',784,'mnist_feature_probs','mnist_priors');
參數 'mnist_example' 為2.1步驟建立的訓練資料表名。
參數 'label' 指定以mnist_example表中的lable字段作為分類字段。
參數 'attributes' 指定以mnist_example表的attributes字段作為特征字段。
參數 784 表示資料特征的個數,在本例中圖檔的每個像素都作為一個特征,圖檔是28*28=784像素的。
參數'mnist_feature_probs' 指定特征機率輸出表的名稱
參數'mnist_priors' 指定分類輸出表的名稱,此表統計訓練資料中各個分類出現的次數。
2.3 樣本識别結果
建立可用來查詢識别結果的視圖 mnist_classified。
SELECT madlib.create_nb_probs_view('mnist_feature_probs','mnist_priors','mnist_topredict','id','attributes',784,'mnist_classified');
參數'mnist_feature_probs' 'mnist_priors'同2.2節
參數'mnist_topredict' 為待識别資料表,'id' 'attributes' 784參數指定該表的鍵和屬性字段以及特征數。
參數'mnist_classified'為建立的視圖名稱。
建立好的視圖結構如下,
key 字段對應輸入資料表(mnist_topredict)的id字段。
class 字段表示可能的阿拉伯數字
nb_prob 字段表示識别為對應class字段的機率,最大值為1。
對比檢視對編号(key/id)為0的測試資料的識别結果以及待識别資料原型。
檢視識别結果:
可以看到識别為數字 7的機率有1(100%).識别為其他是數字的機率都遠低于數字7.
檢視對應編号為0(id)的資料樣本:
編号為0的資料樣本對應的阿拉伯數字為7。
通過mnist_transform.py檔案裡的array2imgfile函數将編号為0的測試資料轉化為圖檔檔案。
得到圖檔檔案test_idx_0.png。
用圖檔檢視器打開圖檔檔案,驗證為手寫的數字 7。
對編号為0的測試資料樣本識别達到期望目标。
再來看一個識别失敗的例子。編号為1234的樣本機器識别結果為:
機器識别為極大機率是數字5,其次為數字3,較小機率為數字8.為其他數字的機率遠低于這三個。
對應的資料樣本為:
轉換後的圖檔為:
顯然對這張圖檔的識别未達到預期結果。
2.3 識别的正确率
我們将nb_prob值最大的一項對應的class值作為最終識别數字,然後統計一下對10000個測試資料的識别正确率。
在資料庫中建立PL/pgSQL函數mnist_stat():
執行統計過程:
輸出統計結果:
識别樣本總數10000,識别正确數為8377,識别錯誤數為1623.正确率為83.77%。
在沒有任何針對性優化的情況下,83.77%正确率可以說明Greenplum +MADlib進行圖像識别的可行性,并不能說明這種方式的優劣。因為機器學習算法識别的正确率與很多因素相關,如訓練資料數量、測試樣本、使用的機器學習算法、算法使用的參數等等。對于如何優化和提升還需進一步深入學習研究。
想學習機器學習算法?Greenplum原廠團隊親自操刀,和騰訊雲大學合作打造了《基于 Greenplum 的機器學習算法與實踐》系列課程。
十個章節,囊括了機器學習的前世今生、各大經典算法、深度學習、時間序列算法、圖算法、資料分析擴充語言等豐富的内容,算法理論配合Greenplum應用實踐。
十小時的精彩内容,免費貢獻給社群,掃碼即可開啟你的學習之旅!