From Spark Machine Learning to TensorFlow Deep Learning


今年剛runMachine Learning案子, 一邊著手整理這段期間運用的Apache Spark技術, 以及一些Hadoop Spark的觀念想法; 在收集資料, 與重新檢視Blog內容期間不由自主地湧進了許多的想法, 於是, 決定重新來架構整份文章內容, 從原本規畫的Spark技術語法, 和模型建構執行過程, 擴大到以三部曲的模式, 架構一套完整的人工智能系列文章。期望達到的目標有:

ü   以當前主流的Big Data平台:Spark Deep Learning平台: TensorFlow, 撰寫sample codes與實作應用分享

ü   補強Blog   Random Forests系列文章中, 所欠缺的Model Evaluation Algorithm Optimization, 以及Machine Learning專案實作上, 需要運用到的零零種種技術細節

先分享一份Random Forests模型和各Machine Learning的比較表


三部曲的順序為:
1.          Building Machine Learning Models on Apache Spark
2.          Deep Learning implementation by TensorFlow
3.          Cluster and Dimensionality Reduction using Scikit-learn



Data Science: From Python/R to Spark

在進入Data science領域初期, 一般都是選擇PythonR作為模型建置的技術語言工具; 走過了入門階段, 開始面對更為龐大的數據, 或長遠的系統規畫之後, 我們就會遇到Hadoop ecosystem 如何選擇自我發展或是公司的技術核心, 一直是資訊圈裡熱門的議論話題之一, 何時用Python/R? 何時用Hadoop? 常讓剛接觸這些大數據技術的新手困惑不已; 有一篇文章: 別老扯什麼Hadoop了,你的數據根本不夠大指出, 只有在數據量超過5TB的規模下,Hadoop才是一個合理的技術選擇, 提供了一個數字給我們作為判斷。然而在實務上, 我們所遭遇的狀況不總是可以簡單的二分法就能給出答案, 尤其在當前大數據熱潮下, 彷彿不用Hadoop就不是Big Data, 導入了Hadoop後又發現有許多不如預期的情況。面對這些議題, 我認為可從思考下列兩個迷思/問題下手, 從基本面釐清所面對的數據環境, 這樣能有助於團隊不會迷失在大數據浪潮中, 疲於追趕熱門技術。這兩個問題是:
1.          多大的數據才算是巨量數據?
2.          你是要處理、分析巨量數據? 還是要追求系統效能?

早期談大數據的文章, 常見的資料量是以GB為單位, 當時所謂的巨量是TB等級的數據集; 時至今日, TB成為到處可見的數據單位(連記憶體都升級到了TB等級), PB等級的數據量才是讓人望之興嘆的大數據。隨著時間與技術的演進, 數據越來越多, 硬體的DiskMemory的容量也在隨之向上成長, 因此以Hadoop考量大數據, 一個有意義的評估點應該在於, 你手頭上的機器Memory, 是否足夠處理你要處理的資料量?

假設目前你手邊有5台伺服器, 每台伺服器平均有50G~100G不等的記憶體, 你的數據分析專案要處理的, 約需cache 300G的資料在Memory中進行統計分析和機器學習, 你有甚麼方法可以架構此專案的系統?
第一, 你的專案有硬體預算, 直接買一台伺服器裝滿512G的記憶體就解決了。
如果你沒那麼好運, 就只有這5台機器, 那你可能想把5台的記憶體拔一拔移到同一台湊足300G, 那你需要的條件是, 你單一台機器的記憶體插槽夠, 而且這5台機器的記憶體是可以放到同一台共用的。

一般, 我們都沒有上面這些運氣; 雖然只是要” cache 300G的資料, 但是我們沒有一台機器可以有效率地執行分析。這時我們真正需要的, Distributed Computing – 分散式運算系統。分散式運算系統是透過網絡(network)聯結了許多單一機器(single physical machine)所組成的一套系統, 由於此系統是network based, 比起單一機器, 其運算的思維變成了更為複雜的network programming 。在Hadoop之前, 我們可以用Cluster - 叢集, 來架構系統, Cluster可以在OS, 也可以建在Application, Oracle Database就提供RAC架構建立DB cluster; 儲存端有使用SAN架構、RAID技術, 打造parallel I/OHigh Availability能力的File System


Hadoop是一個基於Distributed Computing, 針對data storage & analysis所打造出來的一套系統。下列的兩項Hadoop特徵描述其所解決的過去叢集與儲存技術所面對的瓶頸與困境:
1.          Hadoop cluster的系統效能和所聯結的機器數量呈線性增長關係如果今天你所處理的資料量增加了一倍系統的執行時間同樣也會相對地增加一倍但如果你增加了一倍和原本機器效能一模一樣的機器數量到Hadoop cluster, 那系統的執行時間就會回到原本的長度。這種線性關係並不一定從在關聯式資料庫中

2.          Data Locality: 在巨量資料處理中系統的運作bottleneck會從我們所熟悉的computing 端變成了網路頻寬(network bandwidth), 也就是你會發現大量的CPU閒置著癡癡等待所有要處理的資料傳輸到位。Hadoop FileSystem(HDFS)透過Data Locality設計原則避免data 的網路傳輸大幅提高數據的處理效能

至於Apache Spark, Spark並非一定要在Hadoop的環境才可安裝執行, 而是在Hadoop的環境下, 透過其系統底層的設計結構, 可以極大化Big DataDistributed Computing的執行效能與管理。所以, 假設今天你要跑個大約2G資料量的machine learning 模型, 使用Spark ML並不會比使用PythonScikit-learn還要快多少(如果configure不佳, 還可能更慢) Spark技術我將在[Building Machine Learning Models on Apache Spark]一文中另行介紹。最後, 回到本節開頭上面的問題: 何時採用Hadoop/Spark? 透過對Hadoop/Spark基本認識, 和盤點各人所擁有的硬體資源, 每個人都可以勾勒出屬於各自本身與公司的技術發展藍圖。補充一點, Python PandasCreator Wes McKinney進來不斷在Python 數據處理效能上進行優化和改進, 有興趣提升Python分析效能技術的,可以到Wes McKinneyblog了解其最新的Apache ParquetApache Arrow兩個專案的最新狀況與實作。

Hyper-parameters Tuning

關於Spark machine learning hyper-parameter tuning, 書籍和能google到的資訊都不多, 我在第一篇文章中將詳細介紹如何使用Spark ml.tuning這個package進行grid search. 這裡先分享關於Random Forest模型兩個參數有趣的發現。查看Spark 線上文件, 可以查到RandomForestClassifier這個模型class的參數以及Default設定值如下:

class pyspark.ml.classification.RandomForestClassifier(self,
        featuresCol="features", labelCol="label",
        predictionCol="prediction", probabilityCol="probability",
        rawPredictionCol="rawPrediction", maxDepth=5, maxBins=32,
        minInstancesPerNode=1, minInfoGain=0.0, 
        maxMemoryInMB=256,cacheNodeIds=False,checkpointInterval=10, 
        impurity="gini",numTrees=20, featureSubsetStrategy="auto",
        seed=None,subsamplingRate=1.0)

如果你讀過我之前這篇關於Random Forest模型的介紹,   有寫到研究學者建議的[numTrees]這個參數也就是要用多少個Tree Model建立RF模型,設定為1,000以上, 在我的專案中也發現到, 這個數值以上的模型, 預測結果確實優於小於1,000的模型。

另外一個參數[impurity], 雖然研究學者表示ginientropy的差異不大, 但是在專案中和我第一篇所製作的範例, tuning的結果都是entropy預測結果較佳。Entropy這概念最早是由德國物理學家克勞修斯於1865年所提出, 物理學上將其定義為A measure of Disorder, 也就是說, 如果某一測量物件從有秩序的狀態朝混亂的狀態發展, Entropy的數值會向上增加。以水為例子, 當其為固體狀態- 冰的時候, Entropy最低, 當其漸漸融化變成水時, Entropy一直提高。有興趣了解Entropy, 可以看下面的這部影片



From Machine Learning to Deep Learning



20163, 彷若橫空出世的AlphaGo, 以嚇破一群專家眼鏡的驚人姿態, 4:1擊敗南韓圍棋九段棋手李世石, 引發了眾人對於Deep Learning的學習狂潮。現在有多少接觸深度學習的人都已經知道, Deep Learning並不是一個全新的技術模型, 它的基礎演算法 - Neural networks, 在之前學習Machine learning時都會接觸到, Deep Learning是在Neural networks, 增進堆疊上了更多的演算法, 達到今天我們所看到的Deep Learning在圖像辨識等應用上的驚人成果。Deep Learning領域要學習除了必備的Neural networks, 包括了Gradient descent optimization algorithms(SGD, Momentum, Adam, etc.), backpropagation之外, 還需了解Convolutional neural networks (CNNs), Recurrent neural networks (RNN), , Autoencoders, Reinforcement Learning.

與其他機器學習模型相比, 一般將Neural networksSVM這類模型視為一個黑盒子(Black Box), 人類無法理解黑盒子的運作過程與其預測的邏輯是什麼, 但是, 我們可以藉由大量的資料訓練, 調校黑盒子(模型)的各項參數, 以取得極佳的預測學習效果。個人很喜歡台大李宏毅教授對於Neural networks模型的解構說法: 在使用像是Regression或是決策樹等統計模型執行Data Science專案時, Features engineering是一個重要影響模型效能的過程, 我們花費大量的時間在調校、組合、甚至創建, 與預測結果有影響性的數據特徵; 反之 , Neural networks / Deep Learning模型成效的好壞轉變成Model的設計上, 我們將成千上萬的Features丟進Neural networks, 透過一層又一層的神經網路, 讓機器自動幫助我們extract 出有意義的Features, 因此如何設計出好的神經網路模型架構 需要建幾層神經網路? 單一神經元的function為何? 模型中各項cost function, activation function是甚麼等等, 才是模型效能的關鍵所在。 在我看來此方法與Ensemble演算法- Stacking有所類似。Stacking的方法是, 先使用多個演算法(Ex: Random Forest, Boosted Tree, SVM…)對數據進行預測產生output, 然後將這些模型所有的預測結果outputs作為Input Features, 放入最後一個模型(Ex: Logistic Regression)產生最終的預測結果。這類型的演算法設計在於, 試圖透過模型的架構以及大量的資料訓練, 由機器自動找出有效用的features


Deep Learning 與GPU加速

其實早在2012, Deep Learning就已經開始震撼世界; 2012這一年, Alex Krizhevsky, Ilya Sutskever,  Geoffrey Hinton三位來自University of Toronto學者, created了一個”large, deep Convolutional neural networks”, 在被譽為” Olympics of computer vision” ImageNet比賽中, 創造了前所未見的15.3% test error – 比起第二名的26.2% error rate高出10%以上, 一舉震驚了整個computer vision社群; 如果不清楚ImageNet, 可以參考這個Ted演講:



Deep Learning的成功除了上述CNN等演算法的大幅改進之外(一般將CNN演算法的發明credit to Yann Lecun 1998Lenets paper), 另外一個重大突破點在於導入GPU的運算, 大幅加速了Deep network的訓練學習時間; 過去僅懂得使用CPU進行訓練的CNN模型, 可能需要花費3天的時間才能training完成, 加入了GPU之後只要3個小時就能訓練完畢。除了時間成本之外, 硬體成本也隨著導入GPU之後大幅下降, 過去可能只有像是Google這種等級的公司, 能夠花費高達5billion美金去打造一個擁有1,000CPU, 高達16,000 cores 的系統來訓練超大型的神經網路模型, 如今,Stanford利用了GPU打造了一個deep net, 花費不到33,000美金, 就能獲得與前述的硬體設備同樣機器學習預測效能。

為何GPU有如此神效? 那你前面還和我說一堆的Hadoop, Spark做啥? 等等, GPU這神效僅適用於Deep learning模型上, 至於為何GPU能大幅改善Deep network的訓練速度, 那你必須稍微拉近一點來看看Neural networks模型的結構。我們用一個極為簡單的network架構來看: 10input[x1,x2,x3,…x10], 神經元的公式為每一個input x1, 乘上每一個input對應的weights w1 再加上個bias b, 這個簡單的神經元架構就有點像是:

w1 * x1 +b
w2 * x2 +b
w3 * x3+b
.   .       .
.   .       .
.   .       .
w10*x10+b


Neural networks的訓練就是Function estimation的過程, 去求得上面這組算式的weightsbias, 而這過程主要就是進行matrix multiplicationsGPU的強項就在於matrix operation我借用李宏毅教授的視頻教材另外圖示兩個神經元的計算概念

所以並非整個Deep learning訓練過程都是用GPU在運算, 而是需要matrix operation, 才去call一下GPU幫忙計算一下結果。2006之前, 研究人員需要了解low levelgraphic processing才能撰寫相對應的演算法程式來呼叫執行GPU, 2006Nvidia發表了一個名為CUDA的高階語言, 讓研發人員開始大為輕鬆的撰寫程式與GPU進行互動; 如果你在研究TensorFlow的過程當中有看到CUDA這個字眼的出現, 現在, 你知道這是甚麼玩意兒了。

Cluster Analysis

前兩個部份談的機器學習模型, 主要都是屬於Supervised Learning, 最後這一篇將來討論機器學習的另外一塊領域, Unsupervised Learning演算法。Unsupervised Learning是由機器檢視一組, 沒有被標記(labeled)、未被人類分類的資料集, 然後由演算法決定這資料集中, 哪些資料是一組。在這領域廣為使用的演算法是 K-means cluster

Cluster Analysis目前主要運用在行銷領域上, 幫助客群分析人員進行客戶市場區隔分群; 另外Cluster algorithm也被運用在fraud detection, 整合入各種的交易系統(Ex: 網路拍賣、信用卡交易等), 即時分析交易紀錄, 並對可能的異常交易發出警訊。

題外話, 如果你和我一樣, 在剛開始接觸K-means cluster,老是和另外一個名字很像的KNN搞混的話, 這裡我做個簡單的整理
l   K-means clusterUnsupervised Learning; KNNSupervised Learning, 也就是說, KNN的訓練資料是已經Labeled了的
l   KNN的全名為k-nearest neighbors; KNNKK-means clusterK, 用意是一樣的: 兩者都是模型的hyper-parameter, 由訓練人員在模型training之前先決定K的數值
l   中文翻譯上, KNN會用分類這個字眼描述此模型; K-means則是會用分群或是”, 所以如果你看到中文是分群這個字眼的, 應該就是Unsupervised Learning

OK, 回到K-means cluster。要正確的使用此模型, 請務必緊記K-means cluster演算法對於訓練資料的下列假設條件(assumptions), 如果你的資料集根本不符合以下條件(是所有的條件, 而不是擇一符合), K-means cluster無法將資料做正確的分群歸類。
1.          K-means 假設資料集的特徵(features/attributes), 其差異/離散的分佈(variance of the distribution)是呈現球狀(spherical)
2.          所有特徵(features/attributes) 的差異/離散是一樣的
3.          K-means 假設分群後的資料集, 其每一個群聚(cluster)擁有相似數量的資料
也就是說, K-means 假設資料集是呈現下面這個樣子(資料集僅有兩個特徵, 分別顯示於X軸和Y)

你可以使用下列python code產生如上的數據點和圖型

from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=150, 
                  n_features=2, 
                  centers=3, 
                  cluster_std=0.5, 
                  shuffle=True, 
                  random_state=2)

import matplotlib.pyplot as plt
plt.scatter(X[:, 0], X[:, 1], c='black', marker='o', s=50)


然後, 如果你可以給予正確的K, K-means就可以很漂亮的將資料分群

Python code:

from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, 
            #init='random', 
            n_init=10, 
            max_iter=300,
            tol=1e-04,  #0.0001
            random_state=0)
y_km = km.fit_predict(X)

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50,
            c='blue',
            marker='v',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50,
            c='green',
            marker='o',
            label='cluster 2')
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 1],
            s=50,
            c='orange',
            marker='s',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250,
            marker='*',
            c='red',
            label='centroids')
plt.legend()

但是如果K值不正確, K-means分群後的結果可能就會不如人意

我們將會在文章中展示其他不同的資料分佈狀況, 在應用K-means時會出現的問題狀況,另外, 將解說如何使用elbow method, 來幫助我們尋找K-means cluster中最佳的K值。

PCA and t-SNE

PCA(Principal Component Analysis)t-SNE(t-Distributed Stochastic Neighbor Embedding)Machine LearningDimensionality Reduction的演算法。我將這個方法放入這篇討論Cluster主題的文章中, 並非要研究curse of dimensionality議題, 而是要展示Dimensionality Reduction演算法所提供的另外一個很實用的功用” - Data Visualization, 幫助我們藉由圖形化的資料發掘數據pattern, 進而cluster資料集。

Dimensionality Reduction演算法怎麼會和Data Visualization -資料視覺化有關聯? 假設我們有一個資料集, 僅有2個特徵變數(feature), 既使資料集有上萬筆, 我們依然可以很容易的用,像是散佈圖(Scatter Diagram, Scatter Plot)的圖形將資料視覺化。由上一節cluster的圖可以發現, 這樣的2(2-D)的圖形可以幫助我們輕易地了解資料分佈的模式, 進而能用我們自己的眼睛就可以將資料clustering如果今天的資料集特徵變數超過3個、甚至是上百個, 我們就無法將此資料集視覺化! 此時, 我們就需要運用Dimensionality Reduction演算法。PCA, t-SNE和其他各類的Dimensionality Reduction方法, 可以將資料集特徵變數, 轉換成最少一個新的特徵變數, 這個新的特徵變數, 變成了原資料集的特徵變數的代表特徵變數; 依照演算法執行結果, 我們可以選擇top 3的代表特徵變數, 進行資料視覺化。(3維圖形應該是一般人類圖形繪製與辨識的上限)


PCA(Principal Component Analysis)基本上是運用線性代數(linear algebra)的運算公式, 將矩陣(matrices)資料進行線性轉換(linear transformations), 得出特徵向量(Eigenvector) 及特徵值(Eigenvalue)。假設一個資料集m筆資料和n個特徵變數, 我們可以把這些特徵變數視為一個m*n的矩陣(matrices), 透過上述的運算, 我們可以取得一個向量(vector), 經過這樣的過程, 我們就將一個N維的資料轉變成了1維的資料。


Wiki的這個圖式, 清楚了表達了上述的轉換過程


其中
1.          A就是原始的矩陣(matrices)
2.          v is an eigenvector of the linear transformation A
3.          The scale factor λ is the eigenvalue corresponding to that eigenvector. 

由上述可知, PCA是一個線性的(linear)演算法, 因此在文章最後, 另外討論了一個nonlinear techniques : t-SNE。經由學習這兩種Dimensionality Reduction演算法, 應足以應付超過8成以上的實務狀況。

by J.D. 

0 意見: