CategoryResourceRepost/极客时间专栏/SQL必知必会/第四章:SQL项目实战/47丨如何利用SQL对零售数据进行分析?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

122 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="47丨如何利用SQL对零售数据进行分析" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/4a/f5/4a89ff436f212733f9a69beeaa8e0ef5.mp3"></audio>
我们通过OLTP系统实时捕捉到了用户的数据还需要在OLAP系统中对它们进行分析。之前我们讲解了如何对数据进行清洗以及如何对分散在不同地方的数据进行集成今天我们来看下如何使用SQL分析这些数据。
关于这部分内容,今天我们一起来学习下:
1. 使用SQL进行数据分析都有哪几种姿势
1. 如何通过关联规则挖掘零售数据中的频繁项集?
1. 如何使用SQL+Python完成零售数据的关联分析
## 使用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中抽取数据然后选择想要进行的机器学习算法包括传统机器学习和深度学习模型进行训练和预测。不过这个工具刚刚上线工具、文档、社区还有很多需要完善的地方。<br>
<img src="https://static001.geekbang.org/resource/image/e5/fd/e50038152a1b4e7a9940919be9634dfd.jpg" alt=""><br>
最后一个方法是SQL+Python也是我们今天要讲解的内容。刚才介绍的工具可以说既是SQL查询数据的入口也是数据分析、机器学习的入口。不过这些模块耦合度高也可能存在使用的问题。一方面工具会很大比如在安装SQLFlow的时候采用Docker方式下图为使用Docker安装sqlflow的过程进行安装整体需要下载的文件会超过2G。同时在进行机器学习算法调参、优化的时候也存在灵活度差的情况。因此最直接的方式还是将SQL与机器学习模块分开采用SQL读取数据然后通过Python来进行机器学习的处理。
<img src="https://static001.geekbang.org/resource/image/38/c8/38864b57d8d65728439b730d57d841c8.png" alt="">
## 案例:挖掘零售数据中的频繁项集与关联规则
刚才我们讲解了如何通过SQL来完成数据分析机器学习的5种姿势下面我们还需要通过一个案例来进行具体的讲解。
我们要分析的是购物篮问题,采用的技术为关联分析。它可以帮我们在大量的数据集中找到商品之间的关联关系,从而挖掘出经常被人们购买的商品组合,一个经典的例子就是“啤酒和尿布”的例子。
今天我们的数据集来自于一个面包店的21293笔订单字段包括了Date日期、Time时间、Transaction交易ID以及Item(商品名称)。其中交易ID的范围是[1,9684]在这中间也有一些交易ID是空缺的同一笔交易中存在商品重复的情况。除此以外有些交易是没有商品的也就是对应的Item为NONE。具体的数据集你可以从[GitHub](https://github.com/cystanford/SQLApriori)上下载。
我们采用的关联分析算法是Apriori算法它帮我们查找频繁项集首先我们需要先明白什么是频繁项集。
频繁项集就是支持度大于等于最小支持度阈值的项集,小于这个最小值支持度的项目就是非频繁项集,而大于等于最小支持度的项集就是频繁项集。支持度是个百分比,指的是某个商品组合出现的次数与总次数之间的比例。支持度越高,代表这个组合出现的频率越大。
我们来看个例子理解一下下面是5笔用户的订单以及每笔订单购买的商品
<img src="https://static001.geekbang.org/resource/image/58/38/58d7791f7b1fe08f810e9e630b03bf38.png" alt=""><br>
在这个例子中“牛奶”出现了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.02min_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:passwd@localhost/wucai')
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} -&gt; {coffee}, {cookies} -&gt; {coffee}, {hot chocolate} -&gt; {coffee}, {juice} -&gt; {coffee}, {medialuna} -&gt; {coffee}, {pastry} -&gt; {coffee}, {sandwich} -&gt; {coffee}, {toast} -&gt; {coffee}]
```
从结果中你能看到购物篮组合中商品个数为1的频繁项集有19种分别为面包、蛋糕、咖啡等。商品个数为2的频繁项集有14种包括面包蛋糕面包咖啡等。其中关联规则有8种包括了购买蛋糕的人也会购买咖啡购买曲奇的同时也会购买咖啡等。
## 总结
通过SQL完成机器学习往往还是需要使用到Python因为数据分析是Python的擅长。通过今天的学习你应该能体会到采用SQL工具作为数据查询和分析的入口是一种数据全栈的思路对于开发人员来说降低了数据分析的技术门槛。
如果你想要对机器学习或者数据分析算法有更深入的理解也可以参考我的《数据分析实战45讲》专栏相信在当今的数据时代我们的业务增长会越来越依靠于SQL引擎+AI引擎。
<img src="https://static001.geekbang.org/resource/image/88/63/886fc87f717463557457ef8e23218b63.png" alt=""><br>
我在文章中举了一个购物篮分析的例子,如下图所示,其中(牛奶、面包、尿布)的支持度是多少呢?
<img src="https://static001.geekbang.org/resource/image/a1/e6/a1767ae691f2c18d02f8009a687ba1e6.png" alt=""><br>
欢迎你在评论区写下你的思考,也欢迎把这篇文章分享给你的朋友或者同事,一起交流一下。