夜的独白

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

电商平台零售数据分析

前面的博客中已经有使用在线零售业务数据进行数据分析,但是在这一篇,我们以不同的角度重新对这些数据进行分析。

数据来源及数据结构

国外的在线零售业务的交易数据, 数据下载地址

现在以表格的形式解释一下里面的字段:

字段 说明
InvoiceNo 订单编号,含有6个整数,退货订单编号开头有字母C
StockCode 产品编号,由5个整数构成
Description 产品描述
Quantity 产品数量,有负号表示退货
InvoiceDate 订单日期和时间
UnitPrice 单位 英镑 单位产品的价格
CustomerID 客户编号,由5位数字组成
Country 国家的名称 每个客户所在的国家/地区的名称

分析目的

  • 用户分类(RFM模型),对比分析不同用户群体在时间、地区等维度下交易量,交易金额指标,并根据分析结果提出优化建议
  • R:最近一次消费时间(最近一次消费到参考时间的长度)
  • F:消费的频次(单位时间内消费多少次)
  • M:消费的金额(单位时间内总消费金额)

首先说一下思路:
1、清洗数据,去除掉退单的数据和异常值
2、按照RFM模型公式,计算各个模块的数值
3、 通过数据的划分,将模型的三个模块按照重要性进行划分。
4、 通过自定义函数,将模型进行整理
5、 通过柱状图和饼状图对模型所划分的区域进行展示。

下面来看代码,里面有详细代码注释:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import plotly as py
    import  plotly.graph_objects as go
    import seaborn as sns
    
    sns.set_style('darkgrid')
    data = pd.read_csv('data/data.csv')
    # print(data.head(10))
    
    #进行数据清洗
    # print(data.info())
    #从输出信息上来看,CustomerID 发现大量缺失,Description发现少量缺失
    
    #去除掉重复值的值
    data = data.drop_duplicates()
    #通过描述信息查看是否出现异常值
    print(data.describe())
    #通过结果发现,UnitPrice出现负值,我们只需要正值  并且 退货数据必须剔除掉
    data=data[(data['UnitPrice']>0)&(data['Quantity']>0)]
    
    #接下来将缺失的CustomerID归为一类 代号U
    data['CustomerID'].fillna('U',inplace=True)
    
    #统计最近一次消费时间【-----
    
    
    #时间格式转化成datatime 这里我们暂时不需要具体的时间,所以只留下年月日
    data['Data'] = [i[0] for i in data['InvoiceDate'].str.split(' ')]
    
    data['InvoiceDate'] = pd.to_datetime(data['Data'],errors='coerce')
    #增加三列 分别记录年、月、日
    data['Year'] = data['InvoiceDate'].dt.year
    data['Month'] = data['InvoiceDate'].dt.month
    data['Day'] = data['InvoiceDate'].dt.day
    
    #我们以所有订单的最新日期为参考时间
    Customerdata =data['InvoiceDate'].max()- data.groupby('CustomerID')['InvoiceDate'].max()
    R_Customer = Customerdata.dt.days
    
    # print(Customerdata.describe())#统计均值 标准差 最大最小值
    plt.hist(R_Customer,bins=30)
    plt.title("统计最近一次消费时间")
    # plt.show()
    #---】
    
    #统计消费的频次  也就是每个客户购买的订单数
    F_Custumer = data.groupby('CustomerID')['InvoiceNo'].nunique()
    
    #统计消费的金额
    data['Amount'] = data['UnitPrice']*data['Quantity']
    M_Custumer = data.groupby('CustomerID')['Amount'].sum()
    
    #好了 我们需要统计的都统计完了 接下来就进行分组和数据可视化
    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_Customer,R_bins,labels=[5,4,3,2,1],right=False)#right=False 所划分区间是左闭右开
    F_score = pd.cut(F_Custumer,F_bins,labels=[1,2,3,4,5],right=False)
    M_score = pd.cut(M_Custumer,M_bins,labels=[1,2,3,4,5],right=False)
    
    rfm = pd.concat([R_score,F_score,M_score],axis=1)
    #从结果中看到,列名默认是采用原数据自带的列名  这里我们做一下修改
    rfm.rename(columns={'InvoiceDate':'R_score','InvoiceNo':'F_score','Amount':'M_score'},inplace=True)
    
    rfm = rfm.astype(float)#z转换数据类型,方便之后进行计算
    
    print(rfm.describe())# 通过查看平均值来对用户进行分级
    #R_scpre-mean():3.82
    #F_score-mean():2.02
    #M_score-mean():1.88
    
    rfm['R_score'] = np.where(rfm['R_score']>3.82,'高','低')
    rfm['F_score'] = np.where(rfm['F_score']>2.02,'高','低')
    rfm['M_score'] = np.where(rfm['M_score']>1.88,'高','低')
    
    #将这三个拼接到一块
    rfm['All'] = rfm['R_score'].str[:]+rfm['F_score'].str[:]+rfm['M_score'].str[:]
    rfm['All'] = rfm['All'].str.strip()
    
    def CheckClass(x):
        if(x=='高高高'):
            return '重要价值客户'
        elif x=='高低高':
            return '重要发展客户'
        elif x=='高高低':
            return '一般价值用户'
        elif x=='高低低':
            return '一般发展客户'
        elif x=='低高高':
            return '重要保持客户'
        elif x=='低高低':
            return '重要发展客户'
        elif x=='低低高':
            return '重要挽留客户'
        elif x=='低低低':
            return '一般挽留客户'
    
    rfm['用户等级'] = rfm['All'].apply(CheckClass)
    
    #用户等级数量可视化-
    Bar = go.Bar(x=rfm['用户等级'].value_counts().index,y=rfm['用户等级'].value_counts(),opacity=0.5,marker=dict(color='orange'))
    layout = go.Layout(title = "不同用户等级柱状图")
    fig = go.Figure(data=[Bar],layout=layout)
    py.offline.plot(fig,filename='CustomerNumber.html')
    
    #将用户等级可视化-饼状图
    Pie = go.Pie(labels=rfm['用户等级'].value_counts().index,values=rfm['用户等级'].value_counts())
    layout = go.Layout(title = "不同用户等级")
    fig = go.Figure(data=[Pie],layout=layout)
    py.offline.plot(fig,filename='CustomerClass.html')
    
    
    

输出两个结果图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200223200528831.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x6eDE1OTk1MQ==,size_16,color_FFFFFF,t_70)

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200223200552229.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x6eDE1OTk1MQ==,size_16,color_FFFFFF,t_70)

结论和总结

本次实践主要是简单描述用户画像,对用户进行分层。从图表中我们可以看到,重要价值客户和重要发展客户占比最多,对于前者,由于其购买时间间隔比较长,可以采取优惠卷或者相应打折力度,增加这种用户的回购频率;对于后者客户,除了购买时间间隔长之外,还存在购买频率比较低的问题,对于这客户,同样可以策划相应的活动。此数据还可以从另外角度分析,比如
按月份进行订单量统计,并对比去年同期数据,查看是否出现大的波动等等。

在这里插入图片描述

posted on 2021-07-12 14:38  夜的独白  阅读(733)  评论(0)    收藏  举报