Azure Databricks — 分析及視覺化資料

Where
11 min readNov 14, 2020

如果對於 Azure Databricks 不熟悉的朋友,可以先閱讀這篇:Azure Databricks — 基本介紹及環境準備

本篇教學程式碼參考 Hands-on Workshop: using Apache Spark & Azure Databricks,此份程式碼包含了原始資料集和 notebook 檔案,可以直接匯入做練習。

資料存放

這次的練習,會將資料集存放在 Azure 的 Blob Storage 中,想練習的朋友們,可以到 Hands-on Workshop: using Apache Spark & Azure Databricks 下載範例資料 data / ml-latest-small.zip 裡的 csv 檔案上傳到 Blob Storage 中, Blob Storage 資源建立和檔案上傳方式,應該不需要我再撰寫,應該都 google 的到吧?

此資料集使用到的是 MovieLens 的資料集,Small MovieLens 資料集描述了電影推薦服務 MovieLens 的 5 星等評分和在網站上的 tag 資料。它包含 9125部電影、100004則評分資料和1296 tag 數據,日期從 1995年1月9日至2016年10月16日之間並由大約 671位使用者創建,此資料集於 2016 年 10 月 17日建立

資料讀取

在進行建立模型、模型訓練等,第一步驟是先了解你手上的資料型態、分析資料的分佈,透過視覺化的方式,可以更好的掌握其中的 insight。

首先,先建立一個新的 Notbook,在首頁中選擇 New Notebook,並選擇要使用的語言和先前已建立好了 Cluster,接下來的範例會使用 Python。

Notebook建立好後,就可以開始進行coding的部分

先引用會使用到的 library,

from pyspark.sql.functions import split, explode, col, udf
from pyspark.sql.types import *

因為資料集是存在 Blob Storage,資料來源要從 Blob Storage 而來,先設定 Blob Storage 的相關連線設定。

# Setting storage account connectioncontainer_name = "YOUR_CONTAINER_NAME"
storage_account_name = "YOUR_STORAGE_NAME"
storage_account_access_key = "YOUR_SAS_KEY"
spark.conf.set("fs.azure.account.key." + storage_account_name +".blob.core.windows.net",storage_account_access_key)

如果你不知道SAS key 在哪裡取得,回到 Azure Portal 中 Blob Storage 的頁面,找到 Access Key 可以找到 Key1 或 Key2,即是此處要填的 SAS Key。

下一步,便是取得資料的位置和資料內容

# Get stroage data location
ratingsLocation = "wasbs://" + container_name +"@" + storage_account_name + ".blob.core.windows.net/ratings.csv"
moviesLocation = "wasbs://" + container_name +"@" + storage_account_name +".blob.core.windows.net/movies.csv"
# Get ratings and movies data
ratings = spark.read.format("csv") \
.option("inferSchema", "true") \
.option("header", "true") \
.load(ratingsLocation)
movies = spark.read.format("csv") \
.option("inferSchema", "true") \
.option("header", "true") \
.load(moviesLocation)

這裡,我們使用到了 Spark API 和 Databricks APIs 來取得 storage 的位置和對 spark 做資料來源的設定

資料來源設定完成後,就是把 ratings 和 資料顯示出來

display(ratings)
display(movies)

透過 display() 的方式可以很輕易的將讀取到的資料顯示出來

資料整理及分析

很多時候, raw data 的資料並不能直接拿來進行分析,會需要做資料清理、整理的動作,比如說轉換格式、資料的合併或整理成可以供訓練的資料集等

如本篇的練習範例,我們可以觀察到 ratings 這個資料表的 timestamp 欄位資料與我們一般常用的格式不相同,因此需要將其轉換成我們常用的 ”西元年-月-日” 這種格式

# transform the timestamp data column to a date column
# first we cast the int column to Timestamp
ratingsTemp = ratings \
.withColumn("ts", ratings.timestamp.cast("Timestamp"))

# then, we cast Timestamp to Date
ratings = ratingsTemp \
.withColumn("reviewDate", ratingsTemp.ts.cast("Date")) \
.drop("ts", "timestamp")
display(ratings)

同時,我們也觀察到手邊現在有 user 對於電影的評分的資料表(ratings)以及電影的ID、名稱和類型,如果我想將 rating 的資料和 movie 的資料做整合,從一張表中得知使用者是對哪部電影、該電影的類型、電影上映日期以及使用者對於影片的評等

# use a Spark UDF(user-defined function) to get the year a movie was made, from the title

def titleToYear(title):
try:
return int(title[title.rfind("(")+1:title.rfind(")")])
except:
return None
# register the above Spark function as UDF
titleToYearUdf = udf(titleToYear, IntegerType())
# add the movieYear column
movies = movies.withColumn("movieYear", titleToYearUdf(movies.title))
# explode the 'movies'.'genres' values into separate rows
movies_denorm = movies.withColumn("genre", explode(split("genres", "\|"))).drop("genres")
# join movies and ratings datasets on movieId
ratings_denorm = ratings.alias('a').join(movies_denorm.alias('b'), 'movieId', 'inner')
# Show merged data table
display(ratings_denorm)

使用 SQL

在 Azure Databricks 中你也可以使用 SQL 的語法對資料表進行查詢

從 ratings 的表格中撈出 movieID、userID、rating 和 reviewDate 欄位的資料

%sqlSELECT movieId, userId, rating, reviewDate
FROM ratings

當然,你也可以透過 spark.sql() 的方式以 Python 來呼叫執行 SQL 語法,結果也會是一樣的

# This would be equivalent to using the spark.sql() function call in Python:
result = spark.sql("SELECT movieId, userId, rating, reviewDate FROM ratings")
display(result)

除了選取表格之外,也可以做運算、排序,這邊用到的是前面整合過的 rating_denorm 資料表

%sqlSELECT genre, COUNT(rating) as total_ratings, AVG(rating) AS average_rating 
FROM ratings_denorm
GROUP BY genre
ORDER BY average_rating DESC;

儲存資料表

如果要將重新 merge 或整理過的新資料表做儲存供之後使用,可以透過write.saveAsTable() 的方法來做儲存,而這邊的範例是將資料儲存成 parquet,相較於儲存成 csv,parquet 相對來說更佳的輕量

ratings_denorm.write.saveAsTable('ratings_denorm', format='parquet', mode='overwrite')

在 Data 的地方便可以看到以儲存的資料表,當然你也可以直接透過 Add Data 添加既有的資料

視覺化資料

用表格的形式呈現,可能不好了解整個資料的散佈情形,以範例資料來說,如果我想知道大眾對於各類型電影的平均評分分佈情況,我可以先透過 SQL 將這些我需要的資料撈出來

%sqlSELECT genre, COUNT(rating) as total_ratings, AVG(rating) AS average_rating 
FROM ratings_denorm
GROUP BY genre
ORDER BY average_rating DESC;

接著,在 result 的地方選擇以 Bar 的形式呈現

從表格的形式轉換成條狀圖呈現資料分布的情形,可以得知使用者對於恐怖類型的電影的平均評分是最低的

總結

先立 flag,下篇將會講解如何透過此資料集透過 Azure Databricks 實作電影的推薦系統

--

--