英国电商数据分析报告(Python实现)

英国电商数据分析报告

一、背景介绍

通过对某在线电商公司一年的销售数据进行分析,探索这一年内的运营情况以及主要客户群体的特点,为该公司下一年的运营和营销活动提供决策支持。为此需要分析以下问题:
1、这一年的总体销售情况如何?
2、各个国家的客户在消费水平方面存在怎么样的差异?针对这种差异制定针对性的运营策略。
3、统计一天中客户下单的高峰时段,一年中属于销售旺季的月份,便于公司提前安排网站维护、产品采购、物流配送等方面的工作。
4、分析商品的单品退货情况以及整体退货情况,为公司找到造成客户退货的主要问题所在。
5、统计客户的复购率、回购率,以及回流率等指标,分析公司的客户质量情况。
6、对客户进行RFM模型划分,以便有侧重地对不同的客户进行不同的营销活动。

二、数据理解

分析所用数据集E-Commerce Data来源于kaggle网站,由伦敦南岸大学工程学院公共分析小组主任陈大庆博士提供。
E-Commerce Data数据集是一家英国电商公司从2010年12月1号到2011年12月9号的真实交易数据,共541909个记录。 该电商公司主要销售的商品是各类礼品,其客户有相当一部分是各类批发商。
本数据集包含以下特征:
发票编号:对应每笔订单所分配唯一的6位数编号,其中退货订单的代码以字母'C'开头。
商品编号:每个不同的商品分配唯一的5位数编号。
商品描述:对每件商品的简略描述。
商品数量:订单内的每种商品的交易数量。
交易时间:每笔订单发生的日期和时间。
单价:商品的价格。
客户ID:每个客户分配唯一的5位整数编号。
国家:每个客户所在国家/地区的名称。

三、数据处理

预处理

通过对数据集进行初步观察,发现“商品描述”以及“客户ID”两个特征存在缺失值,分别为1454和135080个记录,此外,“商品数量”以及“单价”两个特征存在负值等异常值。
由于“客户ID”特征则影响较大且无法进行补偿,且进一步观察发现“客户ID”缺失的记录在“国家”、“交易时间”等特征的分布上较为随机,故将“客户ID”缺失的记录剔除不加入分析。而“商品描述”特征对分析过程作用不大,故不进行处理。
对进行缺失值处理后的数据中,“商品数量”以及“单价”两个特征为负值的记录进行观察,发现“单价”为负值的记录在缺失值处理后已经全部剔除,而“商品数量”为负值的记录对应的“发票编号”均以“C”开头,即退货订单,为了后续需要的退货率分析,将“商品数量”为负值的记录保留。
由于2011年12月的数据仅记录到12月9号,未达到一个月的统计周期要求,故将2011年12月的数据剔除,不加入分析。

特征工程:

根据本次分析的问题,需要额外为数据集增加以下特征:
商品总价:订单中每种商品的总价。
退货商品数量:退货订单内的每种商品的交易数量。
交易月份:每笔订单发生的日期所在的年月份。
交易时段:每笔订单发生的时间所在的时段。
退货商品总价:退货订单中每种商品的总价。

四、分析过程:

总体交易情况

2010年12月至2011年11月,该电商公司交易总额达到839万元。月交易额总体呈上升趋势,由年初的57万元增长至年底的116万元,月平均增长率为6.64%,增长形势良好。


image.png

各国消费水平情况

从交易额占比的区域分布来看,英国本土是该公司的最主要的市场,其交易额占比高达82%,海外国家仅占交易总额的18%,而从海外国家的占比排名来看,前五位是荷兰、爱尔兰、德国、法国以及澳大利亚,占比分别为17.81%、16.56%、14.28%,13.04%以及8.64%,其余海外国家占比均在4%以下。该公司的海外市场以英国周边的欧洲国家以及同属英联邦成员的澳大利亚为主,这些国家以及英国本土的客户是重点维持的对象。


image.png

image.png

在成交金额前五的海外国家中,爱尔兰、荷兰和澳大利亚同时也占据了客单价排名前五席位中的三席,其中最高的爱尔兰的客单价达到了8.8万元。
上述的三个国家以及新加坡的客单价均远高于其他国家的客单价平均水平0.18万元,客户类型以批发商为主。此外,新加坡的客单价水平是成交金额较低的海外国家中最为突出的,为2.1万元,应列为重点发展的国家。


image.png

下单高峰期与销售旺季

从一天中各个时段的订单数量来看,下单高峰期位于上午10点至下午3点这个时间段内,由于网站访客数量以及下单量较为集中,将对该公司网站的稳定性提出挑战,应安排工作人员在这个时间段加强监控和维护。


image.png

每月订单数量和每月交易金额的变化走势基本上是一致的,其中由于复活节以及英联邦纪念日等节日对礼品需求的增加,该公司的订单数量在3月和5月存在小高峰,而从9月份开始则进入一年的销售旺季,客户大量购买礼品以迎接万圣节、圣诞节等重大节日的到来。因此,在3月、5月以及9月开始到年底的这段时间里,应提前针对节日的特点做好礼品品类的采购,以及相应物流仓储准备。


image.png

退货情况分析

在退货商品中,商品编号为“23843”以及“23166”的商品占比分别达到了29.47%和27.11%,占到了总数的一半以上,其他的1918个品类的商品占比也仅有43.42%,有必要针对“23843”和“23166”这两类商品进行重点检查,确定退货数量多的具体原因是包装运输过程还是商品本身质量造成的。


image.png

从区域对比的层面来看,美国是退货率最高的国家,接近60%,是需要进行改进的重点。进一步分析美国退货商品的种类,发现每类退货商品的件数均为1到2件,但种类数量很多,占到销售种类数量的67.5%,由此推测美国退货率这么高的原因并非某些种类商品的质量问题,而是由于远距离运输造成商品在运输过程损坏。


image.png

客户质量分析

全年每月的用户复购率均在30%以上,在5月份以及年底由于节日的推动更是接近40%,总体客户质量较高。


image.png

全年每月用户回购率总体在40%左右,并呈缓慢上升的趋势,说明随着时间的推进客户忠诚度得到培养,表现为下个月继续在该公司网站购买商品。


image.png

对比每月活跃率、回流率以及新用户率的走势,前期的购买用户以新用户和活跃用户为主,回流用户很少,随着时间推移,活跃用户和回流用户的比例逐渐增加,新用户减少,而在接近年末由于重大节日的推动,新用户比例由有所回升,但总体仍以活跃用户和回流用户为主,年末是一个将潜在客户转化为新客户的有利时间段,可针对性对潜在客户推送商品优惠信息。


image.png

构建RFM模型

分别以R、F、M三个指标的中位数对客户进行划分,便于针对性地对不同的客户人群进行营销活动。


image.png

五、总结

1.全年交易额总体呈上升趋势,月平均增长率达到6.64%,增长形势良好。
2.英国本土是最主要的市场,而海外市场则以英国的周边以及同属英联邦成员的国家如荷兰、爱尔兰、德国、法国以及澳大利亚为主,这些国家以及英国本土的客户是重点维持的对象。 此外,新加坡客户的客单价处于高水平,应列为重点发展的国家。
3.一天中的下单高峰期集中于上午10点至下午3点,应安排工作人员在这个时间段内加强对网站稳定性监控和维护。在3月、5月以及9月开始到年底的这段时间里,应提前针对节日的特点做好礼品品类的采购,以及相应物流仓储准备。
4.编号为“23843”以及“23166”的商品占到退货商品总数的一半以上,应对这两类商品进行重点检查,确定导致客户退货具体原因是包装运输过程还是商品本身质量造成的,并进行改进。此外,美国是退货率最高的国家,其退货率高的原因推测是由于远距离运输造成商品在运输过程损坏,应特别加强对运输往美国的商品的包装保护以及对运输过程的监管。
5.复购率和回购率稳定于较高水平,说明总体客户质量和忠诚度较高。前期的购买客户以新用户和活跃用户为主,而后期则以活跃用户和回流用户为主,但年末是一个将潜在客户转化为新客户的有利时间段,可针对性对潜在客户推送商品优惠信息。
6.通过构建RFM模型客户类型进行划分,针对性地对不同的客户人群进行营销活动。

六、附录

数据集来源:https://www.kaggle.com/carrie1/ecommerce-data

七、分析过程代码

导入需要用到的工具库。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

读取待分析的数据集,并显示前五行初步观察数据特征。

df = pd.read_csv(r'D:\360安全浏览器下载\ecommerce-data\data3.csv',encoding = 'GB2312')
df.head()

对数据进行描述性统计,显示各个变量的样本数、平均值、最值、标准差等统计量。

df.describe()

统计各个变量存在的空值数量。

df.isnull().sum()

将空值数量最多的变量“客户ID”的空值删除。

df = df[df['客户ID'].notnull()]

由于2011年12月的数据不完整,故即将这部分数据剔除

df = df[df['交易月份']!='2011-12']

构建新变量“退货商品数量”,并将该变量中的空值用0填充,同时将原变量“商品数量”中小于0的值转换为0。

df['退货商品数量'] = -df[df['商品数量'] < 0]['商品数量']
df['退货商品数量'] = df['退货商品数量'].fillna(0)
df.loc[df['商品数量'] < 0,'商品数量'] = 0

构建新变量“商品总价”、“退货商品总价”、“交易月份”、“交易时段”。

df['商品总价'] = df['商品数量']*df['单价']
df['退货商品总价'] = df['退货商品数量']*df['单价']
df['交易时间'] = pd.to_datetime(df['交易时间'])
df['交易月份'] = df['交易时间'].map(lambda x: '%d%s%02d'%(x.year,'-',x.month))
df['交易时段'] = df['交易时间'].map(lambda x: '%02d%s'%(x.hour,':00'))

统计前年的交易总额。

df[df['商品数量']>0]['商品总价'].sum()

统计各个月的交易金额。

df[df['商品数量']>0].groupby('交易月份')['商品总价'].sum()

统计各个国家的交易金额占比。

df[df['商品数量']>0].groupby('国家')['商品总价'].sum().sort_values()/df['商品总价'].sum()

统计除英国外各个国家的交易金额占比并按交易金额占比排序。

df[(df['商品数量']>0)&(df['国家']!='United Kingdom')].groupby('国家')['商品总价'].sum().sort_values(ascending=False)/df[(df['商品数量']>0)&(df['国家']!='United Kingdom')]['商品总价'].sum()

统计各个国家客户的客单价并按客单价排序。

(df[df['商品数量']>0].groupby('国家')['商品总价'].sum()/df[df['商品数量']>0].groupby('国家')['客户ID'].nunique()).sort_values(ascending=False)
统计每个月的订单数量。
df[df['商品数量']>0].groupby('交易月份')['发票编号'].nunique()
统计一天中每个时段的订单量。
df[df['商品数量']>0].groupby('交易时段')['发票编号'].nunique()

建立各类商品的退货商品数量和商品数量的数据透视表,并计算出各类商品的退货数量占比,并进行排序。

df_thl = df.pivot_table(index='商品编号',values=['退货商品数量','商品数量'],aggfunc={'退货商品数量':'sum','商品数量':'sum'})
df_thl['商品退货率'] = df_thl['退货商品数量']/df_thl['商品数量']
df_thl.sort_values('商品退货率',ascending=False)['商品退货率']

建立客户每月购买次数的数据透视表。

pivot_purchase_times = df.pivot_table(index='客户ID',columns='交易月份',values='发票编号',aggfunc='nunique')

建立客户每月是否复购的数据透视表,并统计出复购率

pivot_repurchase = pivot_purchase_times.applymap(lambda x: 1 if x > 1 else 0 if x == 1 else np.NaN)
pivot_repurchase.sum()/pivot_repurchase.count()

建立客户每月回购情况的数据透视表,并统计出回购率。

pivot_purchase = pivot_purchase_times.applymap(lambda x: 1 if x>0  else  0)
pivot_backpurchase  =(pivot_purchase.shift(-1,axis=1).fillna(0)+pivot_purchase).applymap(lambda x: 1 if x>1 else 0 )
pivot_backpurchase.sum()/pivot_purchase.sum()

定义对客户类型进行标记的函数。

def C_l(x):
    label=[]
    for i in range(len(x)):
        if x[i] == 0:
            if len(label) > 0:
                if label[i-1] == '潜在用户':
                    label.append('潜在用户')
                else:
                    label.append('不活跃用户')
            else:
                label.append('潜在用户')
        else:
            if len(label) > 0:
                if label[i-1] == '潜在用户':
                    label.append('新用户')
                elif label[i-1] == '不活跃用户':
                        label.append('回流用户')
                else:
                    label.append('活跃用户')
            else:
                label.append('新用户')
    return pd.Series(label)

建立客户标记的表格。

Customer_label = pd.DataFrame(pivot_purchase.apply(lambda x: C_l(x),axis=1))
Customer_label.columns = ['2010-12','2011-01','2011-02','2011-03','2011-04','2011-05','2011-06','2011-07','2011-08','2011-09','2011-10','2011-11','2011-12']

计算每月的的新用户、回流用户、活跃用户占比。

Customer_label.apply(lambda x : pd.value_counts(x)).loc['新用户']/Customer_label.apply(lambda x : pd.value_counts(x)).sum()
Customer_label.apply(lambda x : pd.value_counts(x)).loc['回流用户']/Customer_label.apply(lambda x : pd.value_counts(x)).sum()
Customer_label.apply(lambda x : pd.value_counts(x)).loc['活跃用户']/Customer_label.apply(lambda x : pd.value_counts(x)).sum()

建立客户RFM统计量的数据透视表,

pivot_RFM=df.pivot_table(index='客户ID',values=['交易时间','发票编号','商品总价'],aggfunc={'交易时间':'max','发票编号':'nunique','商品总价':'sum'})
pivot_RFM['R']=(df['交易时间'].max()-pivot_RFM['R']).dt.days

定义进行RFM客户划分的函数。

def C_L2(x):
    if x.R<=0 and x.F>0 and x.M>0:
        label = '重要价值客户'
    if x.R>0 and x.F>0 and x.M>0:
        label = '重要保持客户'
    if x.R<=0 and x.F<=0 and x.M>0:
        label = '重要发展客户'
    if x.R>0 and x.F<=0 and x.M>0:
        label = '重要挽留客户'
    if x.R<=0 and x.F>0 and x.M<=0:
        label = '潜力客户'
    if x.R>0 and x.F>0 and x.M<=0:
        label = '一般保持客户'
    if x.R<=0 and x.F<=0 and x.M<=0:
        label = '待开发新客户'
    if x.R>0 and x.F<=0 and x.M<=0:
        label = '流失客户'
    return label

对客户RFM数据透视表的客户进行划分。

pivot_RFM['R'] = pivot_RFM['R'] - pivot_RFM['R'].median()
pivot_RFM['F'] = pivot_RFM['F'] - pivot_RFM['F'].median()
pivot_RFM['M'] = pivot_RFM['M'] - pivot_RFM['M'].median()
Customer_RFM_label=pivot_RFM.apply(lambda x: C_L2(x),axis=1)

计算每类客户的占比。

Customer_RFM_label.value_counts()/Customer_RFM_label.count()

你可能感兴趣的:(英国电商数据分析报告(Python实现))