From Spark Machine Learning to TensorFlow Deep Learning
今年剛run了Machine Learning案子, 一邊著手整理這段期間運用的Apache Spark技術, 以及一些Hadoop 和 Spark的觀念想法; 在收集資料, 與重新檢視Blog內容期間, 不由自主地湧進了許多的想法, 於是, 決定重新來架構整份文章內容, 從原本規畫的Spark技術語法, 和模型建構執行過程, 擴大到以三部曲的模式, 架構一套完整的人工智能系列文章。期望達到的目標有:
ü 以當前主流的Big Data平台:Spark和 Deep Learning平台: TensorFlow, 撰寫sample codes與實作應用分享
ü 補強Blog Random Forests系列文章中, 所欠缺的Model Evaluation 與 Algorithm Optimization, 以及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領域初期, 一般都是選擇Python或R作為模型建置的技術語言工具; 走過了入門階段, 開始面對更為龐大的數據, 或長遠的系統規畫之後, 我們就會遇到Hadoop ecosystem。 如何選擇自我發展或是公司的技術核心, 一直是資訊圈裡熱門的議論話題之一, 何時用Python/R? 何時用Hadoop? 常讓剛接觸這些大數據技術的新手困惑不已; 有一篇文章: 別老扯什麼Hadoop了,你的數據根本不夠大指出, 只有在數據量超過5TB的規模下,Hadoop才是一個合理的技術選擇, 提供了一個數字給我們作為判斷。然而在實務上, 我們所遭遇的狀況不總是可以簡單的二分法就能給出答案, 尤其在當前大數據熱潮下, 彷彿不用Hadoop就不是Big Data, 導入了Hadoop後又發現有許多不如預期的情況。面對這些議題, 我認為可從思考下列兩個迷思/問題下手, 從基本面釐清所面對的數據環境, 這樣能有助於團隊不會迷失在大數據浪潮中, 疲於追趕熱門技術。這兩個問題是:
1.
多大的數據才算是巨量數據?
2.
你是要處理、分析巨量數據? 還是要追求系統效能?
早期談大數據的文章, 常見的資料量是以GB為單位, 當時所謂的巨量是TB等級的數據集; 時至今日, TB成為到處可見的數據單位(連記憶體都升級到了TB等級), PB等級的數據量才是讓人望之興嘆的大數據。隨著時間與技術的演進, 數據越來越多, 硬體的Disk和Memory的容量也在隨之向上成長, 因此以Hadoop考量大數據, 一個有意義的評估點應該在於, 你手頭上的機器Memory, 是否足夠處理你要處理的資料量?
假設目前你手邊有5台伺服器, 每台伺服器平均有50G~100G不等的記憶體, 你的數據分析專案要處理的, 約需cache 300G的資料在Memory中進行統計分析和機器學習, 你有甚麼方法可以架構此專案的系統?
第一, 你的專案有硬體預算, 直接買一台伺服器裝滿512G的記憶體就解決了。
如果你沒那麼好運, 就只有這5台機器, 那你可能想把5台的記憶體拔一拔移到同一台湊足300G, 那你需要的條件是, 你單一台機器的記憶體插槽夠, 而且這5台機器的記憶體是可以放到同一台共用的。
第一, 你的專案有硬體預算, 直接買一台伺服器裝滿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/O和High 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 Data和Distributed Computing的執行效能與管理。所以, 假設今天你要跑個大約2G資料量的machine learning 模型, 使用Spark 的ML並不會比使用Python的Scikit-learn還要快多少(如果configure不佳, 還可能更慢)。 Spark技術我將在[Building Machine Learning Models on Apache Spark]一文中另行介紹。最後, 回到本節開頭上面的問題: 何時採用Hadoop/Spark? 透過對Hadoop/Spark基本認識, 和盤點各人所擁有的硬體資源, 每個人都可以勾勒出屬於各自本身與公司的技術發展藍圖。補充一點, Python Pandas的Creator Wes McKinney進來不斷在Python 數據處理效能上進行優化和改進, 有興趣提升Python分析效能技術的,可以到Wes McKinney的blog了解其最新的Apache Parquet和Apache 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)
seed=None,subsamplingRate=1.0)
如果你讀過我之前這篇關於Random Forest模型的介紹, 有寫到研究學者建議的[numTrees]這個參數, 也就是要用多少個Tree Model建立RF模型,設定為1,000以上, 在我的專案中也發現到, 這個數值以上的模型, 預測結果確實優於小於1,000的模型。
From Machine Learning to Deep Learning
2016年3月, 彷若橫空出世的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 networks和SVM這類模型視為一個黑盒子(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
1998年Lenets 的paper), 另外一個重大突破點在於導入GPU的運算, 大幅加速了Deep network的訓練學習時間; 過去僅懂得使用CPU進行訓練的CNN模型, 可能需要花費3天的時間才能training完成, 加入了GPU之後只要3個小時就能訓練完畢。除了時間成本之外, 硬體成本也隨著導入GPU之後大幅下降, 過去可能只有像是Google這種等級的公司, 能夠花費高達5個billion美金去打造一個擁有1,000個CPU, 高達16,000 cores 的系統來訓練超大型的神經網路模型, 如今,Stanford利用了GPU打造了一個deep net, 花費不到33,000美金, 就能獲得與前述的硬體設備同樣機器學習預測效能。
為何GPU有如此神效? 那你前面還和我說一堆的Hadoop, Spark做啥? 等等, GPU這神效僅適用於Deep learning模型上, 至於為何GPU能大幅改善Deep network的訓練速度, 那你必須稍微拉近一點來看看Neural networks模型的結構。我們用一個極為簡單的network架構來看: 10個input[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的過程, 去求得上面這組算式的weights和bias, 而這過程主要就是進行matrix
multiplications。而GPU的強項就在於matrix
operation! 我借用李宏毅教授的視頻教材另外圖示兩個神經元的計算概念
所以並非整個Deep learning訓練過程都是用GPU在運算, 而是需要matrix operation時, 才去call一下GPU幫忙計算一下結果。2006之前, 研究人員需要了解low level的graphic processing才能撰寫相對應的演算法程式來呼叫執行GPU,
2006年Nvidia發表了一個名為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 cluster是Unsupervised Learning; KNN是Supervised Learning, 也就是說, KNN的訓練資料是已經Labeled了的
l KNN的全名為k-nearest neighbors; KNN的K和K-means cluster的K, 用意是一樣的: 兩者都是模型的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 Learning中Dimensionality 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.
6/13/2017
|
標籤:
Cluster,
Deep Learning,
Machine Learning,
Spark
|
訂閱:
張貼留言 (Atom)
0 意見:
張貼留言