(PySpark版)如何完成從頭到尾完成一個資料科學專案
Tags: Data Visualization, Pyspark, Data Science Projects

大家好，繼上禮拜的這篇出來後，覺得應該也能用不同的方法來處理資料以及做出最後的機器學習模型，因為之前每篇Python的文章都是以Pandas為主，而Pandas在處理超級大量資料時不一定會非常的快速與便捷，所以在這篇文章中，我將使用PySpark來當作我的主力Library，讓各位也能多會一個技能，並且在處理超大量資料以及在使用分散式系統的環境下，也能很快就上手，如果你想要再複習如何用Pandas和Scikit Learn如何完成一個資料科學專案，可以參考這篇。

那我會根據以下的流程來完成這篇文章，步驟如下，

Hadoop介紹 Spark介紹 資料集 處理資料 用PySpark和Plotly來做EDA 模型訓練與預測 結論

1. Hadoop介紹

介紹PySpark前要先介紹Hadoop，相信各位或多或少多有聽過Hadoop是個群集的結果，原文為Cluster結構，是有一個Master Node和多個Slave Node組成，變成一個分散式系統，舉例來說，當你有一個超級大的File(超過10TB)，你無法儲存在你的本機電腦中因為容量不夠，那我們應該要怎麼儲存資料呢?這時候就可用Hadoop，你會有一個主要機器(Master Node)，搭配非常多的小機器(Slave Node)來儲存，當你機器一多，就可以將File分成好幾份，也能同時再複製幾份儲存在不同的小機器中，每份資料在整個系統中都有好幾份，如果一台小機器毀損，也能確保資料依然存在。

2. Spark介紹

那既然Hadoop聽起來這麼厲害，為什麼還需要使用Spark呢?因為在Hadoop中分析資料是使用MapReduce的海量資量處理方式，關於MapReduce的詳細資訊，可以參考以下文章。因為MapReduce雖然可以解決一般的資料篩選需求，但遇到大量資料時，計算效率還較慢，詳細資料可以參考這裡，所以後人發展出了Spark，而其採用的計算方式則是RDD。

Spark 的核心由 Scala 驅動，但學習曲線高且無法快速支援機器學習需求，故衍伸出 Pysaprk、Rspark 等支援框架，輔助資料科學家使用 Hadoop 資源。Spark處理資料的方法有三種: RDD, DataFrame, SparkSQL本篇文章會主要介紹如何使用PySpark和使用DataFrame方法來完成這個資料科學專案。

3. 資料集

資料集我們將繼續沿用上篇文章所使用的UCI的銀行行銷資料，來自這裡。

4. 處理資料

我這邊會直接使用語法來完成我想要完成的資料處理，如果你想快速學習PySpark的語法的話，可以參考DataCamp上的PySpark Cheatsheet。

進行處理前，我們要啟動PySpark的Cluster。

spark = SparkSession.\

builder.\

appName('Marketing Project').\

getOrCreate()

算是告訴Spark，你要開始啟動你的專案，給它一個專案名稱，並未來的一切都會從這個開始繼續往下延伸。

再來，就是最重要的部分，沒有它，剩下的專案都無法完成，就是讀取資料集。

df = spark.read.csv('bank-additional/bank-additional-full.csv',

sep=';',

header=True,

inferSchema=True) df.show(5, False)

PySpark的DataFrame呈現方式不像Pandas的DataFrame的那麼平易近人，有點像古老的感覺(我自己這樣覺得)

再來，因為在PySpark中，如果Columns是用 ’.’ 來連接，可以選擇轉成 ’_’的形式來處理error

# 可以透過.toDF來更改column名稱

df = df.toDF(*[c.replace('.', '_') for c in df.columns])

接下來我會檢視資料集的狀況，同樣的事情我在上一篇也曾使用過，只是如果使用pyspark的話會稍微有點tricky，我也會針對稍微特別的語法去做解釋

可以看到’Missing’的那行code，這是pyspark計算缺失值數量的一種方法，可以從import的看出，這幾個functions都是來自pyspark的sql處理方法，所以可以用sql的思考角度來想。

count(when(isnull(c), c)).alias(c) for c in df.columns

isnull表示判斷是不是null值，當是null值時，就返回該資料，其他的則被判定成nan，而在計算期column下的數量

5. 用PySpark和Plotly來做EDA

在上一篇文章中，我是使用Pandas + Matplotlib來完成類別型變數和連續型變數的EDA，所以，藉由這次轉換成PySpark，我也可以嘗試用相對比較不熟悉的Plotly來作圖，畢竟Plotly的圖表都可以很輕易地檢視圖中所顯示的資訊。

那我們一開始會從類別型變數Jobs(工作型態)開始， 會直接向各位呈現語法和最終的圖表，分析的部分可以參考上一篇所寫。

Plotly厲害的地方在於其可敘述性的能力非常的強，能夠移動你的鼠標到你所想要暸解的地方，就能輕易呈現你想看的數據。

現在換到連續型變數age(年紀)，這次我會在稍微變換一下PySpark的用法，將Dataframe轉成rdd的情況來做處理，彼此間的轉換可以參考這篇文章，寫得非常棒。

6. 模型訓練與預測

PySpark在進行機器學習模型訓練時，並不像sklearn的那麼容易，需要調整dataframe的儲存方式，並且需要有個它希望的型態給模型去做訓練。

首先，我們必須處理類別型變數，將其Onehotencoding，並將全部的變數和其值整合在一個特徵下，這個特徵就叫feature，而預測的y值就放在名為label的column下

之後當然就是需要把這個data給區分成train, test兩個資料集

trainingData, testData = data.randomSplit([0.8, 0.2])

最後來到模型的部分，模型主有是使用pyspark的mllib裡面所有的機器學習演算法，我也將使用在上篇使用的三個演算法

from pyspark.ml.classification import LogisticRegression, RandomForestClassifier, GBTClassifier logr = LogisticRegression(featuresCol='indexedFeatures',

labelCol='label')

rf = RandomForestClassifier(featuresCol='indexedFeatures',

labelCol='label')

gbt = GBTClassifier(featuresCol='indexedFeatures',

labelCol='label') model = algo.fit(train) # algo就帶入你使用的演算法

predictions = model.transform(test)

將預測結果放入上篇所使用的函式中

這樣就畫出來了!也能很快的評估結果

7. 結論

其實到了最後，我個人認為，如果你不是真的資料量非常大，運算效能已經是你必須考量的點了，我覺得你都可以自由自在的使用Pandas當做你資料分析的首選，而PySpark就是可以讓你去分散空間，以不讓你的Python給crash掉為要旨的一個好Library。