大数跨境
0
0

Python统计分析之电商平台零售数据分析

Python统计分析之电商平台零售数据分析 数据皮皮侠
2020-09-19
2
导读:前言 传统电商营销缺乏对客户需求的有效分析,使得营销决策具有较大的主观性和盲目性,而现代营销有赖于各种营销数

前言

传统电商营销缺乏对客户需求的有效分析,使得营销决策具有较大的主观性和盲目性,而现代营销有赖于各种营销数据库的建立和数据分析,数据的使用贯穿着整个营销过程的始末,对于营销效果起着至关重要的影响性作用。

数据来源

本次分析以英国礼品电商公司——Kaggle2010年12月1日至2011年12月9日在英国注册的非实体网上零售发生的所有交易数据为对象,Python作为分析工具,结合实际业务指标,分析其销售、退货等情况,且依据RFM模型对客户进行分类。最终得出数据及静态或动态的可视化结果,并对结果进行解读,同时针对不同业务和不同层级的客户提出相关对策和建议。

研究思路

数据处理

数据可视化分析

由于该公司位于英国,因此购买数量和交易额理所应当最多。除此之外,荷兰,爱尔兰,德国,法国也是主要消费国家,需要重点关注。

销量最佳的月份

销量最高的是11月份,其次是12月份,大部分销量较佳的月份集中在下半年,这是因为该产品是礼品,在下半年节日较多,加上促销优惠,所以销量比上半年月份多。

客户消费行为统计性描述

客户平均消费次数为4次,有的客户甚至消费高达210次,是产品的忠诚客户。客户平均消费金额为2053元,而75%的用户消费金额为1661元,低于平均消费金额,这说明有部分用户消费金额较大,是属于非常有价值的用户,需要公司对其保持重点关注。客户购买产品数量平均高达1194件,这是因为销售对象主要是批发商,则属于正常的数量。

退货率分析

退货率透视图中2010年的月份出现空值,这是因为数据最早是为2010年12月1日,其12月份的退货率为9.10%在平均退货率9.25%之下。2011年中,相比其他月份,1月和12月退货率高达19.04%和32.16%,视为异常值,这需要业务人员考虑是外部因素还是内部因素导致的,可以从产品、渠道、价格、促销四个方面去寻找和分析原因,以此改进业务。

客户分类

分类标准:

重要价值客户:三项指标都高的,即带来主要效益的客户

发展客户:消费频次比较低,但是金额和最近日期得分都高

重要保持客户:最近一次消费时间间隔较久,但消费频次和消费金额较高

挽留的客户:最近一次消费时间间隔较久,消费频次较低,但消费金额高

一般价值客户:最近一次消费时间间隔短,消费频次高,但消费金额较低

一般发展客户:最近一次消费时间间隔短,消费频次低,消费金额低

一般保持客户:最近一次消费时间间隔长,消费频次高,消费金额低

一般挽留客户:三项指标都低的

客户分类情况

根据可视化数据可知,该公司最多的是重要价值客户和重要发展客户,占比达到47.2%,这两类客户是该公司创造收益价值的主力军。企业应对此类客户多关心或多收集意见建议。

其次,是一般发展客户和一般挽留客户,占比为40.4%,针对一般发展客户,建议获取该类用户的详细数据信息和用户画像,了解该类用户的消费需求,进行更加精准的营销,及时推送产品信息。

对于近期交易较少的重要保持客户和重要挽留客户,以赠送优惠券或推送折扣信息等措施,增加用户活跃度。

总结

将客户分层,对不同分层的客户采取不同的营销手段,能够大大节约营销成本。根据每类客户的特征和相应的比例进行分配,使营销开支利用率最大化,同时也使营销效果最大化。

python代码块

代码块

# -*- coding: utf-8 -*-
#导入模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

import plotly as py
import plotly.graph_objs as go#绘图的函数

import os
os.chdir('C:\data\ecommerce-data')

#读取数据
df=pd.read_csv('data.csv',encoding='utf-8',dtype={'Customer':str})
df.shape
df.info()
df[df['InvoiceNo'].str[0]=='C']
#订单编号开头为字母C的属于退货订单


#数据清洗

df.drop(['Description'],axis=1,inplace=True)
df.apply(lambda x: sum(x.isnull())/len(x),axis=0)

df1=df.dropna(how='any').copy()
df1['InvoiceDate']=pd.to_datetime(df1['InvoiceDate'],errors='coerce')
#提取日期部分
df1['InvoiceDate']=df1['InvoiceDate'].dt.date
df1.info()
#新建销售金额字段
df1['Price']=df1.apply(lambda x: x[2]*x[4],axis=1)

#填充,用U表示客户编号缺失的客户
df['CustomerID']=df['CustomerID'].fillna('U')
# 拆分订单日期,并增加年、月、日、日期四个字段,以及合计购买字段
#日期
df['date']=[x.split(' ')[0for x in df['InvoiceDate']]
#时间
df['time']=[x.split(' ')[1for x in df['InvoiceDate']]
df['year']=[x.split('/')[2for x in df['date']]
df['month']=[x.split('/')[0for x in df['date']]
df['day']=[x.split('/')[1for x in df['date']]
#删除原字段
df.drop(['InvoiceDate'],axis=1,inplace=True)
#查看
df[['date','year','month','day']].head()
df['date']=pd.to_datetime(df['date'])
#合计购买,消费金额=消费数量*单价
df['amount']=df['Quantity']*df['UnitPrice']
df=df.drop_duplicates()

#单价异常值
df.describe()
df2=df.loc[df['UnitPrice']<=0]
df2.shape[0]/df.shape[0]
df2['UnitPrice'].groupby(df2['UnitPrice']).count()


# 数据分析与可视化

#问题一
df1[df1['Quantity']>0].groupby('Country').sum()['Quantity'].sort_values(ascending=False).head(10)
quantity_10=df1[df1['Quantity']>0].groupby('Country').sum()['Quantity'].sort_values(ascending=False).head(10)
trace_basic=[go.Bar(x=quantity_10.index.tolist(),y=quantity_10.values.tolist(),
                   marker=dict(color='orange'),opacity=0.50)]
layout=go.Layout(title='购买商品前10的国家',xaxis=dict(title='国家'))
figure_basic=go.Figure(data=trace_basic,layout=layout)
py.offline.plot(figure_basic,filename='购买商品前十的国家.html')

#问题二
price_10=df1[df1['Quantity']>0].groupby('Country').sum()['Price'].sort_values(ascending=False).head(10)
trace_basic=[go.Bar(x=price_10.index.tolist(),y=price_10.values.tolist(),
                   marker=dict(color='orange'),opacity=0.50)]
layout=go.Layout(title='交易额前10的国家',xaxis=dict(title='国家'))
figure_basic=go.Figure(data=trace_basic,layout=layout)
py.offline.plot(figure_basic,filename='交易额前十的国家.html')

#问题三
#创建月份字段
df1['month']=pd.to_datetime(df1['InvoiceDate'],errors='coerce').dt.month
month=df1[df1['Quantity']>0].groupby('month').sum()['Quantity'].sort_values(ascending=False)
sns.set(style='whitegrid',font_scale=1.2)
df1[df1['Quantity']>0].groupby('month').sum()['Quantity'].sort_values(ascending=False).plot(kind='bar')
plt.title("月份销量",fontsize=12)
plt.xlabel("月份")
plt.ylabel("销量")
plt.xticks(rotation=45)
plt.rcParams['font.sans-serif']=['Simhei'

#问题四
sumprice=df1[df1['Quantity']>0]['Price'].sum()
count_ID=df1[df1['Quantity']>0]['InvoiceNo'].count()
avgPrice=sumprice/count_ID
print(avgPrice)

#问题五
#不同用户的汇总
customer=df1[df1['Quantity']>0].groupby('CustomerID').agg({'InvoiceNo':'nunique',
                                                         'Quantity':np.sum,
                                                         'Price':np.sum})
customer.describe()

# 问题六 退货率
t=df.loc[df['Quantity']<=0]
tt=pd.pivot_table(t,index=['year'],columns=['month'],values=['amount'],aggfunc={'amount':np.sum},margins=False)
p=df[(df['Quantity']>0)&(df['UnitPrice']>0)]
pp=pd.pivot_table(p,index=['year'],columns=['month'],values=['amount'],aggfunc={'amount':np.sum},margins=False)

np.abs(tt/pp)#透视图
np.abs(tt/pp).loc['2011'].mean()

from plotly.graph_objs import Scatter
trace0=Scatter(x=np.arange(1,13),
                 y=[0.190433,0.048836,0.047753,0.08306,0.061359,0.092788,0.052807,0.071692,0.036764,0.071135,0.031744,0.321562])
layout=go.Layout(title="2011年退货率趋势", xaxis_title="月份", yaxis_title="退货率")
fig=go.Figure(data=[trace0], layout=layout)
py.offline.plot(fig,filename='2011年退货率趋势.html')

#问题七 客户分类
R_value=p.groupby('CustomerID')['date'].max()#最近的购买日期
#把最后一次购买距离截止日期的天数作为参考时间
p['date'].max()

R_value=(p['date'].max()-R_value).dt.days#间隔天数
F_value=p.groupby('CustomerID')['InvoiceNo'].nunique()#消费频次
M_value=p.groupby('CustomerID')['amount'].sum()#消费金额

R_value.describe()
plt.rcParams['savefig.dpi']=500#图片像素
plt.rcParams['figure.dpi']=120#分辨率
sns.set(style='whitegrid')
plt.hist(R_value,bins=30)
plt.title("最近一次消费时间间隔", fontsize=12)
plt.xlabel("天数")
plt.ylabel("数量")
plt.rcParams['font.sans-serif']=['Simhei']
plt.show()

M_value.describe()
plt.hist(M_value[M_value<2000],bins=30)
plt.title("总金额小于2000的分布", fontsize=12)
plt.xlabel("金额"
plt.ylabel("数量")
plt.rcParams['font.sans-serif']=['Simhei']
plt.show()

F_value.describe()
plt.hist(F_value[F_value<25],bins=30)
plt.title("频次小于25的分布", fontsize=12)
plt.xlabel("频次")  
plt.ylabel("数量")
plt.rcParams['font.sans-serif']=['Simhei']
plt.show()

#依据分位数和最大值对三个指标R、F、M进行分级
R_value.quantile([0.1,0.2,0.3,0.4,0.5,0.9,1])
F_value.quantile([0.1,0.2,0.3,0.4,0.5,0.9,1])
M_value.quantile([0.1,0.2,0.3,0.4,0.5,0.9,1])

R_bins=[0,30,90,180,360,720]
F_bins=[1,2,5,10,20,5000]
M_bins=[0,500,2000,5000,10000,200000]

R_score=pd.cut(R_value,R_bins,labels=[5,4,3,2,1],right=False)
F_score=pd.cut(F_value,F_bins,labels=[1,2,3,4,5],right=False)
M_score=pd.cut(M_value,M_bins,labels=[1,2,3,4,5],right=False)

rfm=pd.concat([R_score,F_score,M_score],axis=1)
rfm.rename(columns={'date':'R_score','InvoiceNo':'F_score','amount':'M_score'},inplace=True)
rfm.info()

#数据类型转换
for i in ['R_score','F_score','M_score']:
    rfm[i]=rfm[i].astype(float)
rfm.describe()

# 分层
rfm['R']=np.where(rfm['R_score']>3.82,'高','低')
rfm['F']=np.where(rfm['F_score']>2.03,'高','低')
rfm['M']=np.where(rfm['M_score']>1.89,'高','低')

rfm['value']=rfm['R'].str[:]+rfm['F'].str[:]+rfm['M'].str[:]#新建一个价值字段
rfm['value']=rfm['value'].str.strip()#去除空格

def trans_value(x):
    if x=='高高高':
       return'重要价值客户'
    elif x=='高低高':
       return'重要发展客户'
    elif x=='低高高':
       return'重要保持客户'
    elif x=='低低高':
       return'重要挽留客户'

    elif x=='高高低':
       return'一般价值客户'

    elif x=='高低低':
       return'一般发展客户'

    elif x=='低高低':
       return'一般保持客户'

    else:
        return'一般挽留客户'

rfm['客户分类']=rfm['value'].apply(trans_value)
rfm['客户分类'].value_counts()

#不同类型客户的情况
trace_basic=[go.Bar(x=rfm['客户分类'].value_counts().index,
                   y=rfm['客户分类'].value_counts().values,
                   marker=dict(color='orange'),opacity=0.50)]
layout=go.Layout(title='客户分类情况',xaxis=dict(title='用户重要度'))
figure_basic=go.Figure(data=trace_basic,layout=layout)
py.offline.plot(figure_basic,filename='客户分类情况.html')

#不同类型客户的占比
trace=[go.Pie(labels=rfm['客户分类'].value_counts().index,
                   values=rfm['客户分类'].value_counts().values,
                   textfont=dict(size=12,color='white'))]
layout=go.Layout(title='客户分类比例')
figure_basic=go.Figure(data=trace,layout=layout)
py.offline.plot(figure_basic,filename='客户分类比例.html')



数据皮皮侠

您的关注是我们更新的动力

长按识别二维码关注我们

【声明】内容源于网络
0
0
数据皮皮侠
社科数据综合服务中心,立志服务百千万社科学者
内容 2137
粉丝 0
数据皮皮侠 社科数据综合服务中心,立志服务百千万社科学者
总阅读615
粉丝0
内容2.1k