一. 项目来源:
数据来源: https://www.kaggle.com/jr2ngb/superstore-data?select=superstore_dataset2011-2015.csv
数据来自kaggle网站, 是全球某大型超市2011年至2014年的销售数据, 参考电商分析8类基本指标,并结合数据集特点,即电商基础的“人、货、场”进行分析。
二. 分析思路
1. 整体运营情况分析(场):
销售额分析(每年销售额, 每年销售额业绩增长率, 每年每月销售额, 每年每月销售业绩增长率),
利润分析(每年利润额, 每年利润增长率, 每年利润率, 每年每月利润及利润率)
市场布局分析: 全球不同分店销售额对比
2. 商品结构分析(货): 整体销售( 销售结构, 爆款)
3. 客户价值分析(人):
用户概览: (不同类型客户分析)
用户数量: (新客户用户数, 老客户用户数, 新老客户用户数)
用户质量: (活跃用户数, 沉睡用户数, 复购率, 回购率, RFM模型)
三. 处理
1. 读取数据:
data=pd.read_excel('E:\superstore_dataset2011-2015.xls', encoding='utf8')
data.head()
2. 数据清洗
data.isna().any()
可以看到Postal Code 数据部分缺失, 不过后面的分析并不需要用到这个字段.
data.describe()
无异常值发现
第20066行前后日期格式不一致, 统一转化为datetime格式
data['Order Date']=pd.to_datetime(data['Order Date'])
#新建年,月列, 便于后续分析
data['year']=data['Order Date'].dt.year
data['month']=data['Order Date'].dt.month
data['year_month']=data['Order Date'].values.astype('datetime64[M]')
3. 构建模型
3.1整体运营情况分析
#选取销售分析数据子集
data_sales=data[['Order Date','Sales','Profit','year','month']]
data_sales.head()
3.1.1#整体浏览
fig=plt.figure(figsize=(20,3))
sales_tem=data_sales[['Order Date','Sales','Profit']]
sales_tem.index=sales_tem['Order Date'].astype('object')
sales_tem[['Sales','Profit']].plot(kind='line',style='--g.',colormap='Accent_r', figsize=(10,4),title='four years Sales and Profit table',)
plt.grid()
#计算年度&月度销售额/利润
gb=data_sales.groupby(['year','month'])
sales_year=gb.sum()
sales_year
year_2011=sales_year.loc[(2011,slice(None)),:].reset_index()
year_2012=sales_year.loc[(2012,slice(None)),:].reset_index()
year_2013=sales_year.loc[(2013,slice(None)),:].reset_index()
year_2014=sales_year.loc[(2014,slice(None)),:].reset_index()
year_2011
year_2012
year_2013
year_2014
#构建销售表
sales=pd.concat([year_2011['Sales'],year_2012['Sales'],
year_2013['Sales'],year_2014['Sales']],axis=1)
sales.columns=['Sales_2011','Sales_2012','Sales_2013','Sales_2014']
sales.index=['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
sales
#构建利润表
profit=pd.concat([year_2011['Profit'],year_2012['Profit'],
year_2013['Profit'],year_2014['Profit']],axis=1)
profit.columns=['Profit_2011','Profit_2012','Profit_2013','Profit_2014']
profit.index=['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
profit
3.1.2销售额分析
#计算2011-2014年年度总销售额及增长率
#计算年度销售额并图表展示
sales_sum=sales.sum()
sales_sum.plot(kind='bar',colormap = 'RdYlGn_r',alpha=0.5)
plt.grid()
#计算每年增长率
rise_12=sales_sum[1]/sales_sum[0]-1
rise_13=sales_sum[2]/sales_sum[1]-1
rise_14=sales_sum[3]/sales_sum[2]-1
rise_rate=[0,rise_12,rise_13,rise_14]
#表格显示增长率
sales_sum=pd.DataFrame({'sales_sum':sales_sum})
sales_sum['rise_rate']=rise_rate
sales_sum
sales.plot.area(colormap = 'Accent_r',stacked=False)
#2011-2014月度销售额对比表
sales.style.background_gradient(cmap='Greens',axis =0)
#2011-2014销售额折线图
sales.plot.area(colormap = 'Accent_r',stacked=False)
#计算每月同比增长率
rise=pd.DataFrame()
rise['rise_2012']=(sales['Sales_2012']-sales['Sales_2011'])/sales['Sales_2011']
rise['rise_2013']=(sales['Sales_2013']-sales['Sales_2012'])/sales['Sales_2012']
rise['rise_2014']=(sales['Sales_2014']-sales['Sales_2013'])/sales['Sales_2013']
rise
rise.style.background_gradient(cmap='Greens',axis =1,low=0,high=1)
#计算2011年个月份销售占比及贡献最大月份(2012, 2013, 2014代码类似此处省略)
sales_11_sort=sales['Sales_2011'].sort_values(ascending=False)
sales_11_sort.plot(kind='bar',color='g',alpha=0.5,figsize=(10,6))
plt.ylabel('monthly sales of 2011')
p=sales_11_sort.cumsum()/sales_11_sort.sum() #创建累计占比,Series
key=p[p>0.8].index[0]
key_num=sales_11_sort.index.tolist().index(key)
print('超过80%累计占比的节点值索引为:' ,key)
p.plot(style='--ko', secondary_y=True) #y副坐标轴
plt.axvline(key_num,hold=None,color='r',linestyle='--',alpha=0.8)
plt.text(key_num+0.2,p[key],'cumulative proportion: %.3f%%' %(p[key]*100),color='r')
plt.ylabel('proportion of cumulative sales')
key_num = sales_11_sort[:key_num+1]
print('核心月份为:')
print(key_num)
3.1.3利润分析
#计算2011-2014年年度总利润及增长率
#计算年度总利润并图表展示
profit_sum=profit.sum()
profit_sum.plot(kind='bar',colormap = 'RdYlGn_r',alpha=0.5)
plt.grid()
#计算每年增长率
rise_12=profit_sum[1]/profit_sum[0]-1
rise_13=profit_sum[2]/profit_sum[1]-1
rise_14=profit_sum[3]/profit_sum[2]-1
rise_rate=[0,rise_12,rise_13,rise_14]
#表格显示增长率
profit_sum=pd.DataFrame({'profit_sum':profit_sum})
profit_sum['rise_rate']=rise_rate
profit_sum
profit.plot.area(colormap = 'Accent_r',stacked=False)
#计算每月同比增长率
rise_p=pd.DataFrame()
rise_p['rise_2012']=(profit['Profit_2012']-profit['Profit_2011'])/profit['Profit_2011']
rise_p['rise_2013']=(profit['Profit_2013']-profit['Profit_2012'])/profit['Profit_2012']
rise_p['rise_2014']=(profit['Profit_2014']-profit['Profit_2013'])/profit['Profit_2013']
rise
rise_p.style.background_gradient(cmap='Greens',axis =1,low=0,high=1)
#计算2011年每月利润率占比变化(2012, 2013, 2014代码类似此处省略)
profit_rate=pd.DataFrame()
profit_rate['p-rate-11']=profit['Profit_2011']/sales['Sales_2011']
profit_rate_2011=profit['Profit_2011']/sales['Sales_2011']
sales['Sales_2011'].plot(kind='bar',color='g',alpha=0.5)
profit['Profit_2011'].plot(kind='bar',color='g',alpha=0.7)
profit_rate_2011.plot(style='--r.', secondary_y=True,alpha=0.5,label='profit_rate_2011')
plt.legend(loc='upper center')
plt.grid()
分析: 通过以上计算结果和图表展示可以发现,超市2011-2014年每年业绩呈现上升趋势,销售额、利润额、销售量、利润率都在上升,销售额从2011年的226w到2014年的430w,说明经营在逐步稳定。但是从销售额对比亚马逊/沃尔玛这种大型超市,还是有一定差距,可以继续努力。
从增长率来看,销售额、利润额、销售量、利润率从11年到13年均在稳步提升,其中2013年销售额增长率达到了27.2%,从业绩增长率来看,对比沃尔玛公开数据显示(2012-2014年均增长率为4.5%),还是非常有竞争力的(但是沃尔玛的基数大,增长率会放缓,所以要结合销售额和增长率一起看),但我们也可以发现,14年的销售额、利润额、销售量、利润率的增长率相较13年,均有所回落,其中利润增长明显放缓,2014年利润增长率为23.9%(2013年为32.4%,),同时比2014年销售额增长率(26.25%)低,猜测和14年促销活动让利过多导致利润下降。但是利润率总体平稳,稳定在11%-12%之间。此外,结合年度销售额/利润额/销量及增长率,再结合公司整体战略规划,可以预测或制定下一年度总销售额业绩指标。
3.1.3市场布局分析
sales_market=data.groupby('Market')['Sales'].sum()
sales_market.plot(kind='pie', autopct="%1.1f%%", title='2011-2014总销售额占比')
分析: 从占比图中可以看出APAC地区销售额占比最大为28.4%,而Canada地区的销售额占比最少,并且只有0.5%,说明市场几乎没有打开,可以根据公司的总体战略部署进行取舍,从而根据销售额占比分配下一年的销售额指标。
sales_market_year=data.groupby(by=['Market', 'year'])['Sales'].sum().reset_index()
#2011-2014不同地区销售额对比
sales_market_year2=pd.pivot_table(sales_market_year, index='Market', columns='year', values='Sales')
sales_market_year2.plot(kind='bar', title='2011-2014不同地区销售额对比')
分析: 从上面的图形中可以看出,各个地区的2011年-2014年销售总额均是增长的趋势,在APAC地区和EU地区的增长速度比较快速,可以看出市场占有能力也在不短增加,企业市场前景比较好,下一年可以适当加大运营成本,其他地区可以根据自身地区消费特点,吸取上面两个地区的运营模式。
#不同类型产品在不同地区销售额对比
category_sales_market=data.groupby(by=['Market', 'Category'])['Sales'].sum().reset_index()
category_sales_market2=pd.pivot_table(category_sales_market, index='Market', columns='Category', values='Sales')
category_sales_market2.plot(kind='bar', title='不同类型产品在不同地区销售额对比', figsize=(10, 8))
分析: 所有产品我们按照三个大的类型进行了区分,分别是Furniture(家具)、Technology(电子产品)、Office Supplies(办公用品)。通过上图我们大致可以看出,在各大地区销售额都比较高是电子产品,可以根据企业的整体战略部署适当的加大对各地区该品类的投入,以便扩大优势。
3.1.4销售淡旺季分析
year_month=data.groupby(by=['year','month'])['Sales'].sum()
sales_year_month=year_month.reset_index()
sales_year_month=pd.pivot_table(sales_year_month, index='month', columns='year', values='Sales')
sales_year_month.plot(title='各年各月的总销售额')
分析: 通过图表我们基本可以看出,该超市2011年-2014年每一年的销售额同比上一年都是上升趋势,所以很容易发现该超市的旺季是下半年,另外,我们在上半年销售额中发现6月份的销售额也是比较高的,所以可以在6月份开始加大一些运营成本,进而更大一步提高销售额,但是需要注意是下半年的7月份和10月份销售额会有明显的下降,可以针对这些下降的月份多举行一些营销活动。
4. 商品结构分析(货)
4.1销售数量前十
Top10_quantity=data.groupby('Product ID').agg({'Customer ID':'count', 'Sales':'sum'}).reset_index().sort_values(by=['Customer ID'], ascending=False)[['Product ID', 'Sales']].head(10)
Top10_quantity
4.2销售金额前10
Top10_amount=data.groupby("Product ID").agg({'Customer ID':'count','Sales':'sum'}).reset_index().sort_values(by=['Sales'],ascending=False)[['Product ID','Sales']].head(10)
Top10_amount
分析: 我们可以发现销售数量最多的是office产品,而销售金额最多是电子,家具等大额商品
4.3各类物品销售金额, 利润率和销售额累计占比
data['Category_Sub_Category'] = data[['Category','Sub-Category']].apply(lambda x:str(x[0])+'_'+str(x[1]),axis=1)
data_Category_Sub_Category=data.groupby('Category_Sub_Category').agg({'Profit':'sum','Sales':'sum'}).reset_index().sort_values(by=['Sales'],ascending=False)[['Category_Sub_Category','Sales','Profit']]
data_Category_Sub_Category['cumSales'] = data_Category_Sub_Category['Sales'].cumsum()/data_Category_Sub_Category['Sales'].sum()
data_Category_Sub_Category
#可视化
bar_width = 0.45
n = len(data_Category_Sub_Category['Category_Sub_Category'])
x = np.arange(len(data_Category_Sub_Category['Category_Sub_Category']))
ax = plt.subplots(1,1)
ax = plt.bar(x-bar_width/2, data_Category_Sub_Category['Sales'], bar_width)
ax = plt.bar(x+bar_width/2, data_Category_Sub_Category['Profit'], bar_width)
plt.xticks(x, list(data_Category_Sub_Category['Category_Sub_Category']), rotation=90)
plt.xlabel('Category_Sub_Category', fontsize=12)
plt.ylabel('Sales/Profit', fontsize=12)
plt.legend(('Sales', 'Profit'), fontsize=15)
plt.show()
分析: 从图表中可以很清晰的看到不同产品的销售额贡献对比,可以判断出furniture(家具)中Bookcases(书柜)、Chairs(椅子)、Tables(桌子),Office supplies(办公用品)中Appliances(电器)、Storage(储藏箱),Technology(电子技术产品)中Accessories(附件)、Copiers(复印机)、Machines(机器)、Phones(电话/手机),是整体产品中销售比较好的。
从著名的帕累托二八法则分析也可以看出,这几款产品的总销售占比达到84%,应该是自家优势主营产品,后续经营中应继续保持,可以结合整体战略发展适当加大投入,逐渐形成自己的品牌。
同时,也可以发现,末尾占比16%的产品中,Binders(粘合剂)、Furnishings(家具)、Art(艺术品)、Paper(纸)、Supplies(供应品)、Envelopes(信封)、Fasteners(紧固件)、Labels(标签)均是办公用品中的小物件。可以参考“啤酒与尿布”的故事,与其他主营产品结合,连带销售。(也有可能现在的这些小产品主要就是靠连带销售来的销售额,由于篇幅有限,后续会专题对关联销售进行分析~)。
但是值得关注的是,Tables(桌子)的利润是负,表明这个产品目前处于亏损状态,应该是促销让利太多。通过检查原数据,发现Tabels大部分都在打折,打折的销量高达76%。如果是在清库存,这个效果还是不错的,但如果不是,说明这个产品在市场推广上遇到了瓶颈,或者是遇到强竞争对手,需要结合实际业务进行分析,适当改善经营策略。
5. 客户价值分析(人):
5.1用户概览
#不同类型客户分析
data_Segment_Year_Sales=data.groupby(['Segment', 'year']).agg({'Sales':'sum'}).reset_index()
data_Segment_Year_Sales
#每年客户类型数量
data_Segment_Year_Sales['Segment_Year_count']=data_Segment_Year_Sales.apply(lambda x: Segment_Year_Customer_count(x), axis=1)
#每年各类型客户人均销售额
data_Segment_Year_Sales['Segment_Year_price']=data_Segment_Year_Sales.apply(lambda x: x[2]/x[3], axis=1)
#每年各类型客户销售额占比
data_Segment_Year_Sales['Segment_year_prop']=data_Segment_Year_Sales.apply(lambda x:x[3]/data.loc[(data['year']==x[1])].drop_duplicates(subset=['Customer ID'], keep='first')['Customer ID'].count()*100, axis=1)
data_Segment_Year_Sales
#2011年不同类型客户占比(2012, 2013, 2014代码类似)
plt.style.use('ggplot')
plt.pie(x=data_Segment_Year_Sales['Segment_year_prop'].loc[data_Segment_Year_Sales['year']==2011],
labels=data_Segment_Year_Sales['Segment'].loc[data_Segment_Year_Sales['year']==2011],
explode=(0.05, 0, 0), autopct='%.1f%%', textprops={'fontsize':15})
plt.title('2011年客户占比')
#不同类型客户每年人数
sns.barplot(x='year', y='Segment_Year_count', hue='Segment', data=data_Segment_Year_Sales)
#不同类型客户每年销售额
sns.barplot(x='year', y='Sales', hue='Segment', data=data_Segment_Year_Sales)
分析: 从上我们可以看到,超过一半的客户为普通消费者consumer,且每类客户每年均在保持增长的趋势,客户结构还是非常不错的,其中corporate和home office维系的好,一般属于稳定长期客户,还可以有增长的空间
5.2用户数量
#各年各月的新客户数
data2=data.drop_duplicates(subset=['Customer ID'])
new_customer=data2.groupby(by=['year', 'month']).size()
new_customer=new_customer.reset_index()
sale_year_month=pd.pivot_table(new_customer, index='month', columns='year', values=0)
sale_year_month
def Segment_Year_Customer_count(x):
for i in data['Segment'].drop_duplicates():
for j in data['year'].drop_duplicates():
if x[0]==i and x[1]==j:
return (data.loc[(data['Segment']==i) & (data['year']==j)].drop_duplicates(subset=['Customer ID'], keep='first')['Customer ID'].count())
#可视化
sale_year_month.plot(title='各年各月的新客户数')
分析: 因为数据是从2011年开始统计,在2011年第一次消费的消费者都被定位新客户,所以2011可以忽略不看。但根据图表可以看出,从2012年开始到2014年总体看,每一年的新增客户数还是逐年减少的趋势,可以看出该超市对保持老用户是有效的,超市的运营状况较为稳定。但是,新客户获取率比较低,可以不定期的进行主动推广营销,从而增加新客户数。
5.3用户质量
#统计每月购买次数
pivoted_counts=data.pivot_table(index='Customer ID',
columns='year_month',
values='Order Date',
aggfunc='count').fillna(0)
pivoted_counts
df_purchase=pivoted_counts.applymap(lambda x: 1 if x>0 else 0)
df_purchase.head()
#定义状态函数并进行标记
def active_status(data):
status = []
for i in range(48):
if data[i] == 0:
if len(status)>0:
if status[i-1] == "unreg":
status.append("unreg")#未注册客户
else:
status.append("unactive")#不活跃用户
else:
status.append("unreg")
#若本月消费了
else:
if len(status) == 0:
status.append("new")#新用户
else:
if status[i-1] == "unactive":
status.append("return")#回归用户
elif status[i-1] == "unreg":
status.append("new")
else:
status.append("active")
return pd.Series(status)
purchase_stats = df_purchase.apply(active_status,axis =1)
purchase_stats.head()
#新用户, 回归用户, 活跃用户情况图
purchase_stat_ct=purchase_stats.replace('unreg', np.NaN).apply(lambda x:pd.value_counts(x))
purchase_stat_ct.fillna(0).T.plot.area()
分析: 从上可以发现活跃客户、新客户和回归客户,每年呈一定的规律起伏,这可能和年终年末大促有关,需要更多数据进行佐证;同时可以发现新客数量每年均在减少,说明该商家新客获取率较低,如果能在新客户获取上取得突破,会给商家带来很大的增长空间。
#复购率计算指标: 用户在该月购买过一次以上算复购
purchase_r = pivoted_counts.applymap(lambda x :1 if x>1 else np.NaN if x==0 else 0)
(purchase_r.sum()/purchase_r.count()).plot()
#回购率: 在该月购买过, 在下月也购买时计入回购
def purchase_back(data):
status=[]
for i in range(47):
if data[i] ==1:
if data[i+1] == 1:
status.append(1)
if data[i+1] == 0:
status.append(0)
else:
status.append(np.NaN)
status.append(np.NaN)
return status
purchase_b = df_purchase.apply(purchase_back,axis =1,result_type='expand')
(purchase_b.sum()/purchase_b.count()).plot()
分析: 从上可以发现复购率基本大于0.525,且呈总体上升趋势,说明客户忠诚度高,回购率在年中年末呈峰形态,可能与商家折扣活动或节日有关。
#RFM模型
用户精细化运营分类,通过各类运营手段提高不同类型的用户在产品中的活跃度、留存率和付费率。如何将用户从一个整体拆分成特征明显的群体决定了运营的成败。在用户价值领域,最具有影响力并得到实证验证的理论与模型有:用户终生价值理论、用户价值金字塔模型,策论评估矩阵分析法和RFM客户价值分析模型等。本文使用RFM用户分群模型模型对用户进行分类。RFM定义如下:
R(Recency):客户最近一次交易时间的间隔。R值越大,表示客户交易发生的日期越久,反之则表示客户交易发生的日期越近。
F(Frequency):客户在最近一段时间内交易的次数。F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃。
M(Monetary):客户在最近一段时间内交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低。
RFM模型是衡量用户价值和用户创利能力的经典工具,依托于用户最近一次购买时间、消费频次以及消费金额。在应用RFM模型时,要有用户最基础的交易数据,至少包含用户ID,交易金额,交易时间三个字段。根据R,F,M这三个维度,我们可以将客户分为以下8种类型:
在这个表中,我们将每个维度都分为高低两种情况,进而将客户群体划分为8种类型,而这8种类型又可以划分成A、B、C三个等级。接下来对R、F和M进行计算,步骤如下:
#排序函数
def order_sort(group):
return group.sort_values(by='Order Date')[-1:]
#按数据将客户分组
data_group=data2.groupby(by='Customer ID', as_index=False) #as_index = False是“SQL风格”的分组输出。
#将每个分组对象的数据排序, 并取出日期最大的数据
data_rfm=data_group.apply(order_sort)
data_rfm
data_rfm['R']=-(data_rfm['Order Date']-data_rfm['Order Date'].max())/np.timedelta64(1, 'D')#np.timedelta64()函数, 用于控制时间间隔,间隔多少年/月/天/时/分/秒/
data_rfm['F']=data_group.size().values
data_rfm['M']=data_group.sum()['Sales'].values
data_rfm
data_rfm[['R', 'F', 'M']].apply(lambda x:x-x.mean())#基于平均值比较
def rfm_func(x):
level=x.apply(lambda x:'1' if x>0 else '0')
level=level.R+level.F+level.M
d={'111':'重要价值客户',
'101':'重要发展客户',
'011':'重要保持客户',
'001':'重要挽留客户',
'110':'一般价值客户',
'100':'一般发展客户',
'010':'一般保持客户',
'000':'一般挽留客户'
}
result=d[level]
return result
data_rfm['label']=data_rfm[['R', 'F', 'M']].apply(lambda x:x-x.mean()).apply(rfm_func, axis=1)
data_rfm
size=data_rfm.groupby(['label']).size().to_frame()
size['rfm_pct']=["%.2f%%"%(i/sum(size.values)*100) for i in size.values]
size
#对重要价值客户和重要保持客户进行可视化
data_rfm.loc[data_rfm.label=='重要价值客户', 'color']='g'
data_rfm.loc[data_rfm.label=='重要发展客户', 'color']='b'
data_rfm.loc[data_rfm.label=='重要保持客户' , 'color']='gray'
data_rfm.loc[data_rfm.label=='重要挽留客户' , 'color']='gray'
data_rfm.loc[data_rfm.label=='一般价值客户' , 'color']='gray'
data_rfm.loc[data_rfm.label=='一般发展客户' , 'color']='gray'
data_rfm.loc[data_rfm.label=='一般保持客户' , 'color']='gray'
data_rfm.loc[data_rfm.label=='一般挽留客户' , 'color']='gray'
data_rfm.plot.scatter('F', 'R', c=data_rfm.color)
分析: 根据RMF模型分类出8种客户,根据他们对平台的贡献度排序如下:一般挽留客户→一般发展客户→一般保持客户→一般价值客户→重要挽留客户→重要发展客户→重要保持客户→重要价值客户。
通过RFM识别不同的客户群体,能够衡量客户价值和客户利润创收能力,可以指定个性化的沟通和营销服务,为更多的营销决策提供有力支持,为企业创造更大的利益。
从统计结果中看,该平台重要价值客户占总体2.64%,说明该公司已经沉淀了一批优良客户,但这个比例较小。但有41.51%的重要保持客户,这批客户是曾高频购买且消费金额大的客户,但是这批客户近期没有成交行为说明已经有流失倾向,这批客户需要着重关注。另外一般发展用户也占了26.48%的比例,说明在用户新增的阶段做的还不错,但是一般挽留客户也占了24.4%,一般挽留客户代表已经流失的客户,说明客户保持方便做的比较差。这组数据说明了这个平台整体已经处于客户流失的阶段,用户整体活跃行为已经降低,需要维护现有忠诚的客户的同时,也要花精力在新用户往重要价值客户的转化上。
如需转载, 请注明出处.