电商销售数据分析案例(Oracle)

目录:

  • 项目背景
  • 项目目标
  • 字段说明
  • 数据预处理
    • 数据探索
    • 数据清洗
  • 用户行为分析
    • RFM模型
      • RFM模型建立
      • 用户价值分析
    • 新老客户占比
      • 每月新客占比
      • 新老客户消费比
    • 用户生命周期
    • 用户复购率
  • 商品分析
    • 商品基本信息
    • 商品ABC分类
    • 商品退货分析

一、项目背景

数据来源于Kaggle的电商数据集The UCI Machine Learning Repository,英国在线零售商在2010年12月1日到2011年12月9日的在线销售数据,该电商公司主要以销售各类礼品为主,多数客户都是批发商。

二、项目目标

使用Oracle 对数据进行处理与清洗,通过RFM模型、复购率、消费生命周期等对用户维度进行分析,利用ABC分类、退货率等维度展开剖析,结合Excel图表进行可视化展示,为精准营销与个性化服务提供支持。

三、字段说明

InvoiceNo: 发票编号,代表每笔交易的编号,如果编号开头为C,代表该笔交易取消
StockCode: 产品编号
Description: 产品名称
Quantity: 每笔交易的数量(含有负数,代表退货)
InvoiceDate: 交易时间
UnitPrice: 产品单价
CustomerID: 用户ID
Country: 产生交易国家

四、数据清洗/处理

1、选择字段

根据分析目的选择字段,数据集共8个字段,如果表格字段较多,视情根据分析目的的需要选择合适的字段。

2、删除重复值
CREATE TABLE new_ecommerce AS SELECT DISTINCT * FROM e_ecom;

创建备用表new_ecommerce,将旧表的数据去重添加进备用表。原有数据541909条, 去重后数据536641条,删除重复值5268条。

3、缺失值处理

检查缺失值

SELECT 
SUM(CASE WHEN CustomerID IS NULL THEN 1 ELSE 0 END)  "客户编号",
SUM(CASE WHEN InvoiceNo IS NULL THEN 1 ELSE 0 END )"发票编号",
SUM(CASE WHEN StockCode IS NULL THEN 1 ELSE 0 END )"产品编号",
SUM(CASE WHEN Quantity IS NULL THEN 1 ELSE 0 END )"发票编号",
SUM(CASE WHEN InvoiceDate IS NULL THEN 1 ELSE 0 END )"数量",
SUM(CASE WHEN UnitPrice IS NULL THEN 1 ELSE 0 END )"单价",
SUM(CASE WHEN Description IS NULL THEN 1 ELSE 0 END )"产品描述",
SUM(CASE WHEN Country IS NULL THEN 1 ELSE 0 END )"国家"
FROM new_ecommerce;

CustomerID存在缺失值135037条,Description出现缺失值1454条。数据都很大,不可能全部删除。Description产品描述不是项目分析,不用处理。



在实际工作中,像CustomerID客户ID缺失,首先找业务部门或者数据来源部门确认信息并且补上。本项目只有单一数据,无法找到相关人员确认,暂且把NULL值替换为0。

UPDATE new_ecommerce SET customerid = NVL(customerid,'0') ;

5、异常值处理

5.1检查日期是否在范围内(2010年12月1日到2011年12月9日)

SELECT MAX(InvoiceDate),MIN(InvoiceDate) FROM new_ecommerce


结果显示日期都在范围里,数据正常
5.2检查单价与销量数量,如出现负值与零值

SELECT MAX(UnitPrice)"最高价格",MIN(UnitPrice)"最低价格",MAX(Quantity)"最高销量",MIN(Quantity)"最低销量"
FROM new_ecommerce;

交易成功,销量不可能为负值或零值。如果销量为零或者负值情况,那么需要和业务/数据来源部门确认具体的原因。这里假设出现负值是客户退货情况。

DELETE FROM (SELECT * FROM new_ecommerce WHERE quantity <0 AND invoiceno NOT LIKE'C%');

检查发现交易销量小于0的发票编号大都是"C”开头的,有部分异常销量小于0但不是以"C"开头,这里做删除处理。

SELECT * FROM  new_ecommerce WHERE unitprice = 0;
DELETE FROM (SELECT * FROM new_ecommerce WHERE unitprice = 0);

检查发现有单价为0的免费单,共计1174。暂且不分析免费单,直接删除免费单的数据。

DELETE FROM ( SELECT * FROM new_ecommerce WHERE unitprice < 0)

检查发现两笔坏账,单价都是负值,故把它删除。


6、一致化处理

根据分析目的,我们处理InvoiceDate日期数据。这里只做日期分析,不分析小时分钟,故转换为日期格式。

ALTER TABLE new_ecommerce ADD Date_id VARCHAR2(15)
UPDATE new_ecommerce SET DATE_id = to_char(invoicedate,'yyyy-mm-dd')

五、用户行为分析

根据分析目的,本次分析将采用RFM模型
在RFM模式中:
R:最近一次消费时间(最近一次消费到参考时间的间隔)
F:消费的频率(消费了多少次)
M:消费的金额 (总消费金额)
一般的分析型RFM强调以客户的行为来区分客户。

1、RFM值计算
  • R值计算
    数据集的时间距离间隔较远,我们选取2011-12-09(最后一天)作为判断最近一次消费的距离日期
SELECT customerid,(to_date('2011-12-09','yyyy-mm-dd')-to_date(MAX(date_id),'yyyy-mm-dd')) R_time
FROM new_ecommerce
GROUP BY customerid
ORDER BY R_time

根据最近一次消费与客户数的分析结果显示最长的天数差是373天,最短0天;80%的客户在200天内都有交易记录,说明客户忠诚度不错。

  • F值计算
    频率帮助我们了解客户进行了多少次消费。
SELECT customerid,count(DISTINCT invoiceno) F_times
FROM new_ecommerce
GROUP BY customerid;

分析显示,10次交易记录以内的客户占绝大部分,说明客户是很认可产品和服务。

  • M值计算
SELECT customerid,sum(Quantity*UnitPrice) M_times
FROM new_ecommerce
GROUP BY customerid;

在2010年12月1日到2011年12月9日期间,交易金额主要集中在 1000英镑以内和1000-3000英镑这两个范围内。

  • RFM数据汇总
    为方便后续数据处理,为RFM值创建视图
CREATE VIEW view_rfm AS
(select CustomerID,
       (to_date('2011-12-09','yyyy-mm-dd')-to_date(MAX(date_id),'yyyy-mm-dd')) "天数差",
       count(DISTINCT invoiceno) "消费次数",
       sum(Quantity*UnitPrice) "消费金额" 
from new_ecommerce 
group by CustomerID)
  • RFM评分
    现在需要给RFM评分,以便做客户分层处理,具体的评分需要根据业务进行处理。
SELECT CustomerID,天数差,消费次数,消费金额,(case when 天数差<=30 then 5
when  天数差 >30 and 天数差 <=90 then 4 
when 天数差>90 and 天数差<=180 then 3  
when 天数差>180 and 天数差<=365 then 2 else 1 END) "R评分",
(case when 消费次数<=10 then 1
when  消费次数 >10 and 消费次数 <=30 then 2 
when 消费次数>30 and 天数差<=50 then 3 
when 消费次数>50 and 消费次数<=80 then 4 else 5 END) "F评分",
(case when 消费金额<=1000 then 1
when  消费金额 >1000 and 消费金额 <=3000 then 2 
when 消费金额>3000 and 消费金额<=5000 then 3  
when 消费金额>5000 and 消费金额<=8000 then 4 else 5 END) "M评分"
from view_rfm;
  • 客户分层阈值
    RFM评分完成,保存视图为view_rfm1,用各自的平均值做为客户划分的阈值,再做最后的客户分层处理
select ROUND(avg(R评分),1) "R平均值",ROUND(avg(F评分),1) "F平均值",ROUND(avg(M评分),1) "M平均值"
FROM view_rfm1;
select CustomerID,
(case when R评分>3 then 1 else 0 END)  "R值",
(case when F评分>1 then 1 else 0 END)  "F值",
(case when M评分>1.1 then 1 else 0 END)  "M值"
FROM view_rfm1;
  • 客户分层
    根据RFM阈值和客户评分分层表,对客户行为进行分层处理。
SELECT CustomerID,
(case when R值=1 and F值=1 and M值=1 then '重要价值客户'
  when R值=0 and F值=1 and M值=1 then '重要唤回客户'
  when R值=1 and F值=0 and M值=1 then '重要发展客户'      
  when R值=0 and F值=0 and M值=1 then '重要挽留客户'
  when R值=1 and F值=1 and M值=0 then '一般价值客户'
  when R值=1 and F值=0 and M值=0 then '一般发展客户'
  when R值=0 and F值=1 and M值=0 then '一般保持客户' 
ELSE '一般挽留客户' END) "客户分层"
from view_rfm2


分析发现,该电商平台总交易客户数4372位。交易客户中,一般发展客户(可以说是新客户)最多,占总数的34%,其次是一般挽留客户(流失客户)29%,重要发展客户22%,重要价值客户10%,重要挽留客户5%和重要挽回客户0.16%。

  • 重要价值客户,RFM值都很高,可为其提供优质专属服务,提高其消费体验,增加客户忠诚度
  • 重要发展客户,消费频率低,但是R和M值都很高,可以进行定向推广或提供价格优惠,提高其消费频次
  • 重要保持客户,最近消费的时间较为久远,可能存在流失,但以前的消费金额与频率较高,需了解具体长时间未消费的原因,针对性提供对策
  • 重要挽留客户,消费金额高,但长时间未进行消费且消费频率低,可主动联系或举行老客户召回活动,尽可能挽留
2.新老客户占比

每月新客数量及其占比

SELECT mon,SUM(new_1),SUM(total) mon_total,ROUND(SUM(new_1)/SUM(total),4) first_per
FROM(SELECT mon,customerid,MAX(is_new)new_1,COUNT(DISTINCT CustomerID ) total
FROM(SELECT     a.*,
     b.first_pur,
     to_char(INVOICEDATE,'yyyy-mm') mon,
     (CASE WHEN b.first_pur = to_char(INVOICEDATE,'yyyy-mm') THEN 1 ELSE 0 END) is_new
FROM new_ecommerce a
JOIN (
     SELECT 
            CustomerID,
            MIN(to_char(INVOICEDATE,'yyyy-mm')) first_pur
     FROM new_ecommerce
     GROUP BY CustomerID)b ON b.CustomerID = a.customerid)
GROUP BY mon,customerid
)
WHERE mon !='2010-12'
GROUP BY mon



每月的新老客户的销售数量与销售金额

SELECT mon,is_new,SUM(total_q),SUM(total_a)
FROM(SELECT mon,customerid,is_new,SUM(quantity) total_q,SUM(quantity*unitprice) total_a
FROM(SELECT     a.*,
     b.first_pur,
     to_char(INVOICEDATE,'yyyy-mm') mon,
     (CASE WHEN b.first_pur = to_char(INVOICEDATE,'yyyy-mm') THEN 1 ELSE 0 END) is_new
FROM new_ecommerce a
JOIN (
     SELECT 
            CustomerID,
            MIN(to_char(INVOICEDATE,'yyyy-mm')) first_pur
     FROM new_ecommerce
     GROUP BY CustomerID)b ON b.CustomerID = a.customerid)
GROUP BY mon,customerid,is_new
)
WHERE mon !='2010-12'
GROUP BY mon,is_new


  • 新客户逐年下降明显,新客户的销售贡献比例也跟新客户数量走势基本匹配,销量的上升主要通过老客户的重复购买,证明商家的商品质量、服务质量以及对老客服务有一定保证,可以适度增加获客成本,设定新客获取通道和奖励营销活动促进新客以及老带新的转化率
3、用户生命周期分析

用户生命周期 = 最近一次购买时间 - 第一次购买时间

SELECT customerid,
       MIN(date_id) first_time,
       MAX(date_id) last_time,
       (MAX(to_date(date_id,'yyyy-mm-dd')) - MIN(to_date(date_id,'yyyy-mm-dd'))) life_time
FROM New_Ecommerce
GROUP BY customerid     

  • 用户生命周期平均为195天,中位数为203天,分布情况呈双峰型,一方面较多客户消费生命周期较短,可能是前期活动吸引较多新客户,当前数据集不能体现其完整的消费生命周期,另一方面较多客户的消费生命周期较长,说明商家培养了一定的忠诚客户,商家的营销比较理想
4、用户复购率分析
SELECT mon,ROUND(SUM(CASE WHEN user_mon_buy_times >1 THEN 1 ELSE 0 END)/COUNT(1),2) "复购率"
FROM(SELECT mon,COUNT(invoiceno) user_mon_buy_times
       FROM(  SELECT to_char(invoicedate,'yyyy-mm')mon,customerid,invoiceno
              FROM NEW_ECOMMERCE
              WHERE quantity >0
              GROUP BY to_char(invoicedate,'yyyy-mm'),customerid,invoiceno)
GROUP BY mon,customerid)
GROUP BY mon

  • 复购率比较有波动,结合前面的新老客分析,新客数量呈下降趋势,且当新客获取成本居高不下时,商家应花费成本与新用户成功的建立起联系,提高新客转化率。再加强培养老客户对品牌和商家的忠诚度,防止老客户流失,保持客户再次购买并且持续购买,才能有效增长长期利润。
5、商品分析
  • 1、商品销量与单价
SELECT stockcode,
       SUM(quantity) sales,
       MAX(unitprice) price --销售价格存在折扣,取原价(最大值)
FROM new_ecommerce
WHERE quantity > 0  --销量存在退货
GROUP BY stockcode
ORDER BY sales; 
  • 2、商品ABC分类
  • 计算商品销售额占总销量,按销量额降序排序
SELECT stockcode,sales,SUM(sales/total_sales) OVER(ORDER BY sales DESC) per_sales,row_number() OVER(ORDER BY sales DESC) RANK
FROM(SELECT DISTINCT stockcode,
       SUM(quantity*unitprice) OVER(PARTITION BY stockcode) sales,
       SUM(quantity*unitprice) OVER() total_sales
FROM new_ecommerce
WHERE quantity > 0)  
  • 划分ABC等级,累计销量占比在50%范围以内为A类产品,累计销量占比在50%~80%的范围为B类产品,累计销量占比在80%范围以上为C类产品
--创建商品销售额占比的视图,即是上面代码的视图 view_sales
SELECT stockcode,
       sales,
       per_sales,
       CASE WHEN per_sales <0.5 THEN 'A'
            WHEN per_sales <0.8 THEN 'B'
            ELSE 'C' END CLASS
FROM view_sales   
  • 统计分类情况
SELECT CLASS,
       SUM(sales) total_sales,
       COUNT(CLASS) total_class  
FROM(SELECT stockcode,
       sales,
       per_sales,
       CASE WHEN per_sales <0.5 THEN 'A'
            WHEN per_sales <0.8 THEN 'B'
            ELSE 'C' END CLASS
FROM view_sales)       
GROUP BY CLASS
  • A类产品大约在221种左右,为公司畅销的商品,货物应陈列显眼主推位置,且需保持足够库存应对销售
  • B类产品需注意库存水平,商品陈列位置位于A类产品后
  • C类产品数量达到了3120种,陈列位置应靠后,但也需增加让利促销活动,加快促销周转速度,释放存货资金,后续调整库存水平

商品退货分析

  • 计算商品退货率
SELECT stockcode,
       COUNT(1) sales_times,
       SUM(CASE WHEN quantity < 0 THEN 1 ELSE 0 END) return_times,
       SUM(CASE WHEN quantity < 0 THEN 1 ELSE 0 END)/COUNT(1) return_rate
FROM NEW_ECOMMERCE
GROUP BY stockcode 
ORDER BY sales_times DESC      
  • 月度退货金额
SELECT
    to_char(invoicedate,'yyyy-mm') mon,
    SUM(CASE WHEN Quantity < 0 THEN Quantity*Unitprice ELSE 0 END) return_amount,
    SUM(CASE WHEN Quantity > 0 THEN Quantity*Unitprice ELSE 0 END) sales
FROM New_Ecommerce
GROUP BY to_char(invoicedate,'yyyy-mm') 

结合ABC分类进行分析,选取退货率大于均值且为A级的商品(主要是综合上文提及的ABC分类和退货率计算,通过创建view的形式进行联结后筛选,创建退货率视图为view_return_rate,ABC分类视图为view_class),这里筛选出64个商品。

SELECT vc.stockcode,sales,sales_times,return_times,return_rate
FROM view_class vc
JOIN view_return_rate vr
ON vc.stockcode = vr.stockcode
WHERE CLASS = 'A' AND return_rate > (SELECT AVG(return_rate) FROM view_return_rate)  
  • 数据集的时间段有限,因此退货的商品购买时间可能发生在数据集时间以前,所以计算上存在缺陷,仅做分析参考
  • 部分商品退货率较高,尤其是A类畅销产品,需要重点关注,查看是否与商品批次的质量与把控不严有关,与客户取得联系,了解退货原因,及时制定改进措施,防止损坏公司形象
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容