SQL必知必會(實戰:利用SQL對零售數據進行分析)

使用 SQL 進行數據分析的 5 種姿勢

在 DBMS 中,有些數據庫管理系統很好地集成了 BI 工具,可以方便我們對收集的數據進行商業分析。

SQL Server 提供了 BI 分析工具,我們可以通過使用 SQL Server 中的 Analysis Services 完成數據挖掘任務。SQL Server 內置了多種數據挖掘算法,比如常用的 EM、K-Means 聚類算法、決策樹、樸素貝葉斯和邏輯回歸等分類算法,以及神經網絡等模型。我們還可以對這些算法模型進行可視化效果呈現,幫我們優化和評估算法模型的好壞。

PostgreSQL 是免費開源的對象 - 關系數據庫(ORDBMS),它的穩定性非常強,功能強大,在 OLTP 和 OLAP 系統上表現都非常出色。同時在機器學習上,配合 Madlib 項目可以讓 PostgreSQL 如虎添翼。Madlib 包括了多種機器學習算法,比如分類、聚類、文本分析、回歸分析、關聯規則挖掘和驗證分析等功能。這樣我們可以通過使用 SQL,在 PostgreSQL 中使用各種機器學習算法模型,幫我們進行數據挖掘和分析。

2018 年 Google 將機器學習(Machine Learning)工具集成到了 BigQuery 中,發布了 BigQuery ML,這樣開發者就可以在大型的結構化或半結構化的數據集上構建和使用機器學習模型。通過 BigQuery 控制臺,開發者可以像使用 SQL 語句一樣來完成機器學習模型的訓練和預測。

SQLFlow 是螞蟻金服于 2019 年開源的機器學習工具,我們通過使用 SQL 就可以完成機器學習算法的調用,你可以將 SQLFlow 理解為機器學習的翻譯器。我們在 SELECT 之后加上 TRAIN 從句就可以完成機器學習模型的訓練,在 SELECT 語句之后加上 PREDICT 就可以使用模型來進行預測。這些算法模型既包括了傳統的機器學習模型,也包括了基于 Tensorflow、PyTorch 等框架的深度學習模型。

從下圖中你也能看出 SQLFlow 的使用過程,首先我們可以通過 Jupyter notebook 來完成 SQL 語句的交互。SQLFlow 支持了多種 SQL 引擎,包括 MySQL、Oracle、Hive、SparkSQL 和 Flink 等,這樣我們就可以通過 SQL 語句從這些 DBMS 中抽取數據,然后選擇想要進行的機器學習算法(包括傳統機器學習和深度學習模型)進行訓練和預測。不過這個工具剛剛上線,工具、文檔、社區還有很多需要完善的地方。

最后一個方法是 SQL+Python,也是我們今天要講解的內容。剛才介紹的工具可以說既是 SQL 查詢數據的入口,也是數據分析、機器學習的入口。不過這些模塊耦合度高,也可能存在使用的問題。一方面工具會很大,比如在安裝 SQLFlow 的時候,采用 Docker 方式(下圖為使用 Docker 安裝 sqlflow 的過程)進行安裝,整體需要下載的文件會超過 2G。同時,在進行機器學習算法調參、優化的時候也存在靈活度差的情況。因此最直接的方式,還是將 SQL 與機器學習模塊分開,采用 SQL 讀取數據,然后通過 Python 來進行機器學習的處理。

案例:挖掘零售數據中的頻繁項集與關聯規則

剛才我們講解了如何通過 SQL 來完成數據分析(機器學習)的 5 種姿勢,下面我們還需要通過一個案例來進行具體的講解。

我們要分析的是購物籃問題,采用的技術為關聯分析。它可以幫我們在大量的數據集中找到商品之間的關聯關系,從而挖掘出經常被人們購買的商品組合,一個經典的例子就是“啤酒和尿布”的例子。

今天我們的數據集來自于一個面包店的 21293 筆訂單,字段包括了 Date(日期)、Time(時間)、Transaction(交易 ID)以及 Item(商品名稱)。其中交易 ID 的范圍是 [1,9684],在這中間也有一些交易 ID 是空缺的,同一筆交易中存在商品重復的情況。除此以外,有些交易是沒有商品的,也就是對應的 Item 為 NONE。

我們采用的關聯分析算法是 Apriori 算法,它幫我們查找頻繁項集,首先我們需要先明白什么是頻繁項集。

頻繁項集就是支持度大于等于最小支持度閾值的項集,小于這個最小值支持度的項目就是非頻繁項集,而大于等于最小支持度的項集就是頻繁項集。支持度是個百分比,指的是某個商品組合出現的次數與總次數之間的比例。支持度越高,代表這個組合出現的頻率越大。

我們來看個例子理解一下,下面是 5 筆用戶的訂單,以及每筆訂單購買的商品:

在這個例子中,“牛奶”出現了 4 次,那么這 5 筆訂單中“牛奶”的支持度就是 4/5=0.8。同樣“牛奶 + 面包”出現了 3 次,那么這 5 筆訂單中“牛奶 + 面包”的支持度就是 3/5=0.6。

同時,我們還需要理解一個概念叫做“置信度”,它表示的是當你購買了商品 A,會有多大的概率購買商品 B,在這個例子中,置信度(牛奶→啤酒)=2/4=0.5,代表如果你購買了牛奶,會有 50% 的概率會購買啤酒;置信度(啤酒→牛奶)=2/3=0.67,代表如果你購買了啤酒,有 67% 的概率會購買牛奶。

所以說置信度是個條件概念,指的是在 A 發生的情況下,B 發生的概率是多少。

我們在計算關聯關系的時候,往往需要規定最小支持度和最小置信度,這樣才可以尋找大于等于最小支持度的頻繁項集,以及在頻繁項集的基礎上,大于等于最小置信度的關聯規則。

使用 SQL+Python 完成零售數據的關聯分析

針對上面的零售數據關聯分析的案例,我們可以使用工具自帶的關聯規則進行分析,比如使用 SQL Server Analysis Services 的多維數據分析,或者是在 Madlib、BigQuery ML、SQLFlow 工具中都可以找到相應的關聯規則,通過寫 SQL 的方式就可以完成關聯規則的調用。

除此以外,我們還可以直接使用 SQL 完成數據的查詢,然后通過 Python 的機器學習工具包完成關聯分析。下面我們通過之前講解的 SQLAlchemy 來完成 SQL 查詢,使用 efficient_apriori 工具包的 Apriori 算法。整個工程一共包括 3 個部分。

第一個部分為數據加載,首先我們通過 sql.create_engine 創建 SQL 連接,然后從 bread_basket 數據表中讀取全部的數據加載到 data 中。這里需要配置你的 MySQL 賬戶名和密碼

第二步為數據預處理,因為數據中存在無效的數據,比如 item 為 NONE 的情況,同時 Item 的大小寫格式不統一,因此我們需要先將 Item 字段都轉換為小寫的形式,然后去掉 Item 字段中數值為 none 的項。在數據預處理中,我們還需要得到一個 transactions 數組,里面包括了每筆訂單的信息,其中每筆訂單是以集合的形式進行存儲的,這樣相同的訂單中 item 就不存在重復的情況,同時也可以使用 Apriori 工具包直接進行計算。

最后一步,使用 Apriori 工具包進行關聯分析,這里我們設定了參數 min_support=0.02,min_confidence=0.5,也就是最小支持度為 0.02,最小置信度為 0.5。根據條件找出 transactions 中的頻繁項集 itemsets 和關聯規則 rules。

具體的代碼如下:

from efficient_apriori import apriori
import sqlalchemy as sql
import pandas as pd
# 數據加載
engine = sql.create_engine('mysql+mysqlconnector://root:123456@localhost/school')
query = 'SELECT * FROM bread_basket'
data = pd.read_sql_query(query, engine)
# 統一小寫
data['Item'] = data['Item'].str.lower()
# 去掉 none 項
data = data.drop(data[data.Item == 'none'].index)
 
# 得到一維數組 orders_series,并且將 Transaction 作為 index, value 為 Item 取值
orders_series = data.set_index('Transaction')['Item']
# 將數據集進行格式轉換
transactions = []
temp_index = 0
for i, v in orders_series.items():
    if i != temp_index:
       temp_set = set()
       temp_index = i
       temp_set.add(v)
       transactions.append(temp_set)
    else:
       temp_set.add(v)
# 挖掘頻繁項集和頻繁規則
itemsets, rules = apriori(transactions, min_support=0.02,  min_confidence=0.5)
print('頻繁項集:', itemsets)
print('關聯規則:', rules)

運行結果:

頻繁項集: {1: {('alfajores',): 344, ('bread',): 3096, ('brownie',): 379, ('cake',): 983, ('coffee',): 4528, ('cookies',): 515, ('farm house',): 371, ('hot chocolate',): 552, ('juice',): 365, ('medialuna',): 585, ('muffin',): 364, ('pastry',): 815, ('sandwich',): 680, ('scandinavian',): 275, ('scone',): 327, ('soup',): 326, ('tea',): 1350, ('toast',): 318, ('truffles',): 192}, 2: {('bread', 'cake'): 221, ('bread', 'coffee'): 852, ('bread', 'pastry'): 276, ('bread', 'tea'): 266, ('cake', 'coffee'): 518, ('cake', 'tea'): 225, ('coffee', 'cookies'): 267, ('coffee', 'hot chocolate'): 280, ('coffee', 'juice'): 195, ('coffee', 'medialuna'): 333, ('coffee', 'pastry'): 450, ('coffee', 'sandwich'): 362, ('coffee', 'tea'): 472, ('coffee', 'toast'): 224}}
關聯規則: [{cake} -> {coffee}, {cookies} -> {coffee}, {hot chocolate} -> {coffee}, {juice} -> {coffee}, {medialuna} -> {coffee}, {pastry} -> {coffee}, {sandwich} -> {coffee}, {toast} -> {coffee}]

從結果中你能看到購物籃組合中,商品個數為 1 的頻繁項集有 19 種,分別為面包、蛋糕、咖啡等。商品個數為 2 的頻繁項集有 14 種,包括(面包,蛋糕),(面包,咖啡)等。其中關聯規則有 8 種,包括了購買蛋糕的人也會購買咖啡,購買曲奇的同時也會購買咖啡等。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容