数据分析-12-某电子产品销售数据分析报告及RFM模型(包含数据和代码)

文章目录

0. 获取数据集

关注公众号:『AI学习星球
回复:某电子产品销售数据分析报告及RFM模型 即可获取数据下载。
论文辅导算法学习可以通过公众号滴滴我

在这里插入图片描述

1. 项目背景

通过对某电子产品销售的数据进行清洗,对产品进行分析,对用户分析,销售情况分析,RFM模型分析。

2. 数据抽取

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

plt.rcParams['font.sans-serif'] = ['SimHei']  #设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False #正常显示负号

pd.set_option('display.float_format',lambda x : '%.2f' % x)#pandas禁用科学计数法

#忽略警告
import warnings
warnings.filterwarnings('ignore')
data = pd.read_csv('电子产品销售分析.csv',index_col=0,dtype={'category_id':'int64','user_id':'int64'},encoding='utf8')
data.head()

在这里插入图片描述

2.1 字段介绍

  • Unnamed: 行号
  • event_time:下单时间
  • order_id:订单编号
  • product_id:产品标号
  • category_id :类别编号
  • category_code :类别
  • brand :品牌
  • price :价格
  • user_id :用户编号
  • age :年龄
  • sex :性别
  • local:省份

2.2 创建新列-日期、月份、小时、周几

创建日期列

data['date'] = data.event_time.apply(lambda x: x.split(' ')[0])
#转换为日期格式
data['date'] = pd.to_datetime(data['date'])

创建月份列

data['month'] = data.date.dt.month

创建小时列

data['hour'] = data.event_time.apply(lambda x: x.split(' ')[1].split(':')[0])

创建周几列—周日为0,周一为1

data['weekday'] = data.date.apply(lambda x:x.strftime("%w"))

删除event_time列

del data['event_time']
data.head()

在这里插入图片描述

2.3 查看数据缺失、重复情况

data.shape

(564169, 14)

data.info()

在这里插入图片描述
缺失数据有category_code-产品类别brand-品牌这两列,对于category_code用"R"来代替缺失值而不是选择删除缺失值的数据
brand这一列数据缺失比较少,直接删除缺失值

data['category_code'] = data['category_code'].fillna("R")
#删除brand这一列有缺失值的数据
data = data[data.brand.notnull()]
data.info()

在这里插入图片描述

2.4 存在重复值,但是换个角度去想,这些重复值就是同笔订单下了多个数量的订单,所以不删除重复值,进而增加一列购买数量的列和总价的列

data.duplicated().sum()

634

data.duplicated()

在这里插入图片描述

#添加新的列:购买数量
#data = data.value_counts().reset_index().rename(columns={0:'buy_cnt'})
#由于python版本问题,旧的版本没有上面的功能,所以要写以下3行代码
df = data.groupby(['order_id','product_id']).agg(buy_cnt=('user_id','count'))
data = pd.merge(data,df,on=['order_id','product_id'],how='inner')
data = data.drop_duplicates().reset_index(drop=True)
#添加新的列:购买总金额
data['amount'] = data['price'] * data['buy_cnt']

2.5 查看数据是否有异常

2.5.1 把几个id的格式转化为object格式
data.order_id = data.order_id.astype('object')
data.product_id = data.product_id.astype('object')
data.category_id = data.category_id.astype('object')
data.user_id = data.user_id.astype('object')
2.5.2 把hour和weekday转化为int
data['hour'] = data.loc[:,'hour'].astype('int')
data['weekday'] = data.loc[:,'weekday'].astype('int')
data.info()

在这里插入图片描述

2.5.3 查看价格和年龄是否存在异常值
data.describe(percentiles=[0.01,0.25,0.75,0.99]).T

在这里插入图片描述

data.describe(percentiles=[0.01,0.25,0.75,0.99]).T

在这里插入图片描述
以上7个字段均没有异常值
评论:
price和amount最小值为0,这类商品应该就是免费类的商品,所以也不属于异常值。
应该进一步分析,购买了0元商品的用户,后续是否还有购买了其他的商品

2.5.4 检查其他字段是否有异常值
data.describe(include='all').T

在这里插入图片描述
发现date日期有异常值,显示为1970-01-01,把这些异常值删除

data = data[data.date>'1970-01-01']
data.date.min()

Timestamp(‘2020-01-05 00:00:00’)

3. 数据清洗完毕后,对数据进行分析

data.head()

在这里插入图片描述

data.shape

(535065, 16)

data.reset_index(drop=True,inplace=True)
#保存清洗后的数据
data.to_csv('data_clean.csv',index=False)

3.1 总的指标

3.1.1 总GMV:约1.15亿元
round(data['amount'].sum(),0)

114986636.0

3.1.2 每月的GMV
  • GMV8月之前都基本是处于上升状态,在7月8月的上升更是非常大,8月达到峰值,然后就开始下降了
GMV_month = data.groupby('month').agg(GMV=('amount','sum'))
GMV_month

在这里插入图片描述

plt.plot(GMV_month.index,GMV_month['GMV'])
plt.show()

在这里插入图片描述

3.1.3 客单价:1240元
#按客户数量
round(data['amount'].sum() / data['user_id'].nunique(),0)

1240.0

#按订单数量
round(data['amount'].sum() / data['order_id'].nunique(),0)

296.0

3.2 用户分析

3.2.1 结论先行
  • 各地区用户最多的是广东(21382),然后是上海(16031)、北京(15928),其他8个城市比较平均(在5400上下)
  • 广东人口基数是全国最高的,而且目前广东的用户仅占广东人口总数的0.017%,最高用户占比是北京:0.0728%,约为广东的4倍,所以在广东投入拉新活动性价比是比较高的
  • 男性和女性用户各占一半
  • 年龄分布也平均,总体上是在16-50岁之间
3.2.2 用户总数量
data = pd.read_csv('data_clean.csv')
#转换为日期格式
data['date'] = pd.to_datetime(data['date'])
data.user_id.nunique()

92755

3.2.3 各地区用户数量
local = data.groupby('local')['user_id'].nunique().reset_index()
local = local.rename(columns={'user_id':'用户数量'})
local = local.sort_values('用户数量').reset_index(drop=True)
local

在这里插入图片描述

plt.figure(figsize=(10,8))
plt.ylabel('用户数量')
plt.title('各地区用户数量')
plt.bar(local['local'],local['用户数量'])
for x,y in enumerate(local['用户数量']):
    plt.text(x,y+200,y,ha='center')
plt.show()

在这里插入图片描述

  • 广东的用户数量是最多的,然后就是北京和上海,其他八个城市用户比较平均,都是在5400左右。

根据2020年的全国人口普查,在网上得到了各省的人口数量数据,分析各省用户的占比,看看哪些省还可以进行用户拉新

population = pd.read_excel('2020年各省人口数量.xlsx')
population = population.iloc[:,:2]
population.head()

在这里插入图片描述

local = pd.merge(local,population,how='inner',left_on='local',right_on='地区')
local['占比'] = local['用户数量'] / local['人口数']
local = local.sort_values('占比',ascending=False).reset_index(drop=True)
local

在这里插入图片描述
从上表可以看到,用户数量占比前三是北京、上海、海南,第四是天津,广东排第五,广东的占比仅为第一名北京的五分之一,加上广东的人口数是最多的,所以在广东进行拉新活动的性价比是最高的

3.2.4 用户性别分布
sex =  data.groupby('sex')['user_id'].nunique().reset_index()
sex.rename(columns={'user_id':'用户数量'},inplace=True)
sex

在这里插入图片描述

plt.pie(sex['用户数量'],labels=sex['sex'],autopct='%1.2f%%')
plt.show()

在这里插入图片描述

男性女性用户各占一半

3.2.5 年龄分布
data.age.min()

16.0

data.age.max()

50.0

bins = [15,20,25,30,35,40,45,50]
labels = ['(15-20]岁','(20-25]岁','(25-30]岁','(30-35]岁','(35-40]岁','(40-45]岁','(45-50]岁']
data_ = data.copy()
data_['age_bin'] = pd.cut(x=data.age,bins=bins,right=True,labels=labels)
data_

在这里插入图片描述

age = data_.groupby('age_bin')['user_id'].nunique().reset_index()
age.rename(columns={'user_id':'用户数量'},inplace=True)
age

在这里插入图片描述

plt.figure(figsize=(10,4))
plt.bar(age['age_bin'],age['用户数量'])
plt.show()

在这里插入图片描述
用户年龄分布较平均,在16-50

data_.groupby('age')['user_id'].nunique().reset_index()

在这里插入图片描述

3.2.6 各年龄段的消费金额及下单数量

发现35-40岁的用户,贡献的消费金额与下订单的数量都是最低的,其他年龄段比较平均

age_bin_data = data_.groupby('age_bin').agg(消费金额=('amount','sum'),下单次数=('order_id','nunique'))
age_bin_data

在这里插入图片描述

fig,ax1 = plt.subplots(figsize=(16,8))
xticks = np.arange(len(age_bin_data.index))

ax1.bar(xticks,age_bin_data.消费金额,width=0.3,color='g')
ax1.set_ylabel('消费金额')
ax2 = ax1.twinx()

ax2.bar(xticks+0.3,age_bin_data.下单次数,width=0.3,color='b')
ax2.set_ylabel('下单次数')
plt.title('各年龄段的消费金额及下单次数')

ax1.set_xticks(xticks+0.15)
ax1.set_xticklabels(age_bin_data.index)
plt.show()

在这里插入图片描述

3.2.7 男性女性的消费金额及下单数量

发现男性女性的消费金额与下单次数均比较平均

sex_data = data_.groupby('sex').agg(消费金额=('amount','sum'),下单次数=('order_id','nunique'))
sex_data

在这里插入图片描述

3.2.8分析购买了0元产品的用户

从产品的类别可以知道,0元的商品应该是抽奖活动中奖的

  • 中奖的30个用户中,仅有1个用户没有购买过其他商品,而且这30个用户的客单价高达34832元(总的客单价为1240元)
data[data['price']==0]

在这里插入图片描述

#提取该批用户出来
user_0 = data[data['price']==0]['user_id'].reset_index(drop=True)
user_0

在这里插入图片描述

user_0.shape

(30,)

#30个中奖的用户中,只有一个用户没有产生消费
user_0[~user_0.isin(data[data['price']>0]['user_id'])]

0 1515915625468531712
Name: user_id, dtype: int64

data_user_0 = pd.merge(data,user_0,on='user_id')
data_user_0_amount = data_user_0.groupby('user_id').agg(消费金额=('amount','sum')).sort_values('消费金额',ascending=False)
data_user_0_amount

在这里插入图片描述

#该批用户的客单价为34832元
data_user_0_amount['消费金额'].sum() / 30

34832.36466666667

3.2.9 二八定律-找出累计贡献销售额80%的那批用户
  • 前27%的用户贡献了80%的销售收入,这批用户要做好跟进,一定要留住这批贡献大的客户
user_28 = data.groupby('user_id').agg(消费金额=('amount','sum')).sort_values('消费金额',ascending=False).reset_index()
user_28['累计销售额'] = user_28['消费金额'].cumsum()
user_28

在这里插入图片描述

#前27%的用户贡献了80%的销售收入
p = user_28['消费金额'].cumsum()/user_28['消费金额'].sum()  # 创建累计占比,Series
key = p[p>0.8].index[0] 
key

25408

key / user_28.shape[0]

0.2739259339119185

plt.plot(user_28.index,user_28['累计销售额'])
plt.show()

在这里插入图片描述

3.3.10 客户消费金额的分位数

用户平均消费金额大于75%分位数,即存在着高消费的客户

data.groupby('user_id').agg(消费金额=('amount','sum')).describe(percentiles=(0.01,0.1,0.25,0.75,0.9,0.99)).T

在这里插入图片描述

3.3.11 客户消费周期
  • 消费了两次及以上的客户有50%的消费周期为7天内,用户的消费周期还是比较短的。75%为26天内,消费周期适中。
purchase_day = data[data['amount']>0].sort_values('date').groupby('user_id').apply(lambda x: x['date'] - x['date'].shift()).dt.days
purchase_day

在这里插入图片描述

purchase_day[purchase_day>0].describe(percentiles=[0.01,0.1,0.25,0.75,0.9,0.99])

在这里插入图片描述

3.2.12 每月新客户、不活跃客户、回流客户、活跃客户的情况
pivoted_amount =data[data['amount']>0].pivot_table(index='user_id'
                                             ,columns='month'
                                             ,values='buy_cnt'
                                             ,aggfunc='sum').fillna(0)
columns_month = pivoted_amount.columns.astype('str')  #一定要把列名格式变为str不然后面就会报错
pivoted_amount.columns = columns_month
pivoted_purchase = pivoted_amount.applymap(lambda x:1 if x>0 else 0)
def active_status(data):
    status =[]
    for i in range(11):
        #若本月没有消费
        if data[i] ==0:
            if len(status)>0:  #如果不是第一个月,
                if status[i-1]=='未注册': #如果上个月已经是未注册,那么本月也是未注册
                    status.append('未注册') 
                else:  #如果上月已注册,则本月为不活跃
                    status.append('不活跃')
            else:  #如果是第一个月
                status.append('未注册') #则未注册
        #若本月消费
        else:
            if len(status)==0: #如果是第一个月,则为新注册用户
                status.append('新客户')
            else:  #如果不是第一个月
                if status[i-1]=='不活跃':  #如果上月为不活跃,那么本月为回流
                    status.append('回流')
                elif status[i-1]=='未注册':  #如果上月为未注册,那么本月为新注册
                    status.append('新客户')
                else:  #如果上月为活跃,本月也为活跃
                    status.append('活跃')
    return pd.Series(status,index=columns_month)
pivoted_purchase_status = pivoted_purchase.apply(lambda x:active_status(x),axis=1)
pivoted_purchase_status.head()

在这里插入图片描述

  • unreg 未注册
  • unactive 不活跃
  • new 新注册
  • active 活跃
  • return 回流–不活跃后第一次活跃即为回流
purchase_cnt = pivoted_purchase_status.apply(lambda x:x.value_counts())
#去除未注册的数据行
purchase_cnt = purchase_cnt[purchase_cnt.index != '未注册']
purchase_cnt = purchase_cnt.fillna(0)
#排序 可排可不排
purchase_cnt = purchase_cnt.loc[['新客户','回流','活跃','不活跃'],:]
purchase_cnt

在这里插入图片描述

purchase_cnt.T.plot(figsize=(16,8))

在这里插入图片描述

  • 回流人数

3.3 产品分析

data.head()

在这里插入图片描述

3.3.1 销量前十产品

对于热销产品,应该时刻关注他们的库存量,避免发生缺货情况

cnt = data.groupby('product_id').agg(销售总量=('buy_cnt','sum')).reset_index().sort_values('销售总量',ascending=False).reset_index(drop=True)
cnt.head(10)

在这里插入图片描述

3.3.2 销量少于10的产品

有12069个产品销量少于10,对于这批产品可以考虑促销活动对其进行清仓处理

cnt.describe(percentiles=(0.01,0.1,0.25,0.75,0.9,0.99))

在这里插入图片描述

cnt[cnt.销售总量<10]

在这里插入图片描述

3.3.3销售额前十产品

销售额并不代表利润,往往还需要结合产品的成本来看

amount = data.groupby('product_id').agg(销售总额=('amount','sum')).reset_index().sort_values('销售总额',ascending=False).reset_index(drop=True)
amount.head(10)

在这里插入图片描述

amount.describe(percentiles=(0.01,0.1,0.25,0.75,0.9,0.99))

在这里插入图片描述

3.3.4 销量前十的产品类别 category_code

最受欢迎的产品类别是smartphone-即手机,是第二名手提电脑的4倍

# 需要去除类别为R的,因为是缺失数据
cnt_category = data[data.category_code != 'R'].groupby('category_code').agg(销量=('buy_cnt','sum')).reset_index().sort_values('销量',ascending=False).reset_index(drop=True)
cnt_category.head(10)

在这里插入图片描述

3.3.5 对于手机,销量前五的品牌-brand

销量前五分别为三星、苹果、小米、华为、OPPO,其中三星占了一半以上的份额,苹果占据了四分之一

brand_5 = data[data.category_code=='electronics.smartphone'].groupby('brand').agg(销量=('buy_cnt','sum')).reset_index().sort_values('销量',ascending=False)
brand_5.reset_index(drop=True,inplace=True)
brand_5.head(5)

在这里插入图片描述

brand_5['销量'].sum()

102169

plt.pie(data=brand_5.head(5)
        ,x='销量'
        ,labels='brand'
        ,autopct='%.1f%%'
        ,textprops={'fontsize':12, 'color':'k'} # 设置文本标签的属性值
        ,radius=2
        )
plt.show()

在这里插入图片描述

data[data.category_code=='electronics.smartphone'].groupby('brand').agg(销量=('amount','sum')).reset_index().sort_values('销量',ascending=False)

在这里插入图片描述

3.3.6 分析销量前五的手机品牌的人群特征
3.3.6.1 samsung品牌
  • 年龄分布比较平均
  • 男女比例也是平均
  • 广东、上海、北京占据了50%以上的销量
3.3.6.1.1 年龄分布
user_samsung = data_.loc[(data_['brand']=='samsung') & (data_['category_code']=='electronics.smartphone')]
user_samsung.head()

在这里插入图片描述

user_samsung.groupby('age_bin').agg(销量=('buy_cnt','sum'))

在这里插入图片描述

3.3.6.1.2 性别分布
user_samsung.groupby('sex').agg(销量=('buy_cnt','sum'))

在这里插入图片描述

3.3.6.1.3 地域分布
local_brand = user_samsung.groupby('local').agg(销量=('buy_cnt','sum')).sort_values('销量',ascending=False)
local_brand

在这里插入图片描述

plt.pie(x=local_brand['销量'].values
        ,labels=local_brand.index
        ,autopct='%.1f%%'
        ,textprops={'fontsize':12, 'color':'k'} # 设置文本标签的属性值
        ,counterclock = False # 是否逆时针,这里设置为顺时针方向
        ,startangle = 90 # 设置饼图的初始角度
        ,radius=2
        )
plt.show()

在这里插入图片描述

3.3.6.2 apple品牌

人群特征基本与samsung一致

3.3.6.2.1 年龄分布
user_apple = data_.loc[(data_['brand']=='apple') & (data_['category_code']=='electronics.smartphone')]
user_apple.head()

在这里插入图片描述

user_apple.groupby('age_bin').agg(销量=('buy_cnt','sum'))

在这里插入图片描述

3.3.6.2.2 性别分布
user_apple.groupby('sex').agg(销量=('buy_cnt','sum'))

在这里插入图片描述

3.3.6.2.3 地域分布
user_apple.groupby('sex').agg(销量=('buy_cnt','sum'))

在这里插入图片描述

plt.pie(x=local_brand_apple['销量'].values
        ,labels=local_brand_apple.index
        ,autopct='%.1f%%'
        ,textprops={'fontsize':12, 'color':'k'} # 设置文本标签的属性值
        ,counterclock = False # 是否逆时针,这里设置为顺时针方向
        ,startangle = 90 # 设置饼图的初始角度
        ,radius=2
        )
plt.show()

在这里插入图片描述

3.4 销售情况分析

3.4.1 结论先行

广东、上海、北京的销售额、销量以及客户数量都是最高的

  • 销售额与销量1-8月呈上升趋势,但是8月份之后就开始下降
  • 618和双十一活动效果基本没有得到有效的回报,复盘一下618与双十一活动的内容。
  • 销售额与销量在5月、7月、8月有均有上升,这三个月的新客户都有增长,幅度也不少,证明拉新活动效果不错;9月份下降,加上9月份的新客户下跌,还有9月份下订单的客户也减少了(其中新客下单的数量减少了四分之三,老客只是稍微下降一点点),是否因为9月份的拉新活动投入减少了呢?也可拆解是哪一渠道的新客减少了。
3.4.2 各省销量、销售额情况
local_situation = data.groupby('local').agg(销量=('buy_cnt','sum'),销售额=('amount','sum')).sort_values('销售额')
local_situation['销售额'] = local_situation['销售额'].astype('int')
plt.figure(figsize=(16,8))
plt.barh(local_situation.index,local_situation['销售额'])
for i,j in enumerate(local_situation['销售额']):
    plt.text(j+200,local_situation['销售额'].index[i],j)
plt.title('销售额')
plt.show()

在这里插入图片描述

plt.figure(figsize=(16,8))
plt.barh(local_situation.index,local_situation['销量'])
for i,j in enumerate(local_situation['销量']):
    plt.text(j+200,local_situation['销量'].index[i],j)
plt.title('销量')
plt.show()

在这里插入图片描述

3.4.3 按日期分析销售额与销量的总体走势

数据显示,618和双十一当天的销量和销售额并没有很高,反而处于低位(理论上不可能存在这种情况的-数据是否不够真实!!!)

  • 假设数据真实,那么可以证实618和双十一的活动效果是非常差的,进行复盘
  • 结合后面的分析,公司处于起步阶段,所以618与双十一的活动很难和其他已经开了好几年的公司拼。
data_date = data.groupby('date').agg(销售额=('amount','sum'),销量=('buy_cnt','sum'))
data_date

在这里插入图片描述

plt.figure(figsize=(20,5))
plt.plot(data_date.index,data_date['销售额'])
#plt.xticks([]) #隐藏坐标轴
#plt.xticks([data_date.index.min(),'2020-06-18','2020-11-11'])
plt.title('销售额')
plt.show()

在这里插入图片描述

plt.figure(figsize=(20,5))
plt.plot(data_date.index,data_date['销量'])
#plt.xticks([]) #隐藏坐标轴
#plt.xticks([data_date.index.min(),'2020-06-18','2020-11-11'])
plt.title('销量')
plt.show()

在这里插入图片描述

3.4.4 按月份对销售额和销量进行分析
  • 销售额1-8月呈上升趋势,但是8月份之后就开始下降
  • 销量基本与销售额呈一致的趋势
data_month = data.groupby('month').agg(销售额=('amount','sum'),销量=('buy_cnt','sum'))
plt.figure(figsize=(16,5))
plt.plot(data_month.index,data_month['销售额'])
plt.title('销售额')
plt.xticks(data_month.index)
plt.show()

在这里插入图片描述

plt.figure(figsize=(16,5))
plt.plot(data_month.index,data_month['销量'])
plt.title('销量')
plt.xticks(data_month.index)
plt.show()

在这里插入图片描述

3.4.4.1 新客老客的销售额与销量对比
#划分每个用户的首次购买月份(用来确认用户在几月份是属于新客户)
data_user = data.groupby('user_id').agg(首次购买月份=('month','min')).reset_index()

user_all = pd.merge(data,data_user,on='user_id')
user_all['新老客户'] = np.where(user_all['month']==user_all['首次购买月份'],'新客户','老客户')
user_all.head()

在这里插入图片描述

#每月新客的销售额和销量
user_all_new = user_all[user_all['新老客户']=='新客户'].groupby('month').agg(销售额=('amount','sum'))
user_all_new['销量'] = user_all[user_all['新老客户']=='新客户'].groupby('month').agg(销量=('buy_cnt','sum'))
user_all_new

在这里插入图片描述

user_all_old = user_all[user_all['新老客户']=='老客户'].groupby('month').agg(销售额=('amount','sum'))
user_all_old['销量'] = user_all[user_all['新老客户']=='老客户'].groupby('month').agg(销量=('buy_cnt','sum'))
user_all_old

在这里插入图片描述

3.4.4.2 新老客户销售额对比图

从数据中发现,基本每个月都是新客的贡献度都大于老客,证明公司处于起步阶段,老客户的黏性还不够高

plt.figure(figsize=(16,8))
line1, = plt.plot(user_all_new.index,user_all_new['销售额'],c='r')
line2, = plt.plot(user_all_old.index,user_all_old['销售额'],c='b')
plt.legend([line1,line2],['新客','老客'])
plt.xticks(user_all_new.index)
plt.title('新老客户销售额对比')
plt.show()

在这里插入图片描述

3.4.4.3 新老客户销量对比图
plt.figure(figsize=(16,8))
line1, = plt.plot(user_all_new.index,user_all_new['销量'],c='r')
line2, = plt.plot(user_all_old.index,user_all_old['销量'],c='b')
plt.legend([line1,line2],['新客','老客'])
plt.xticks(user_all_new.index)
plt.title('新老客户销量对比')
plt.show()

在这里插入图片描述

3.4.5 按周分析
  • 0为周日,6为周六
  • 从数据中得出:销售额与销量在周末会比工作日高,客户比较喜欢在周末进行购物,可以在周末多推送商品给用户,适当推销一两款要清仓的商品给用户
data_weekday = data.groupby('weekday').agg(销售额=('amount','sum'),销量=('buy_cnt','sum'))
plt.figure(figsize=(16,5))
plt.plot(data_weekday.index,data_weekday['销售额'])
plt.title('销售额')
plt.xticks(data_weekday.index)
plt.show()

在这里插入图片描述

plt.figure(figsize=(16,5))
plt.plot(data_weekday.index,data_weekday['销量'])
plt.title('销量')
plt.xticks(data_weekday.index)
plt.show()

在这里插入图片描述

3.4.6 按小时分析
  • 销售额与销量在凌晨1点以后就开始上升,到达9点的时候达到峰值,然后又下降。
  • 用户喜欢在早上6点至中午12点之间进行购物,可以在这个时间段发送推荐内容给用户
  • 理论上,应该会是大概早上8点以后呈上升趋势,然后到达下午1点以后又下降,到达下午5点之后又会开始上升至凌晨12点的
data_hour = data.groupby('hour').agg(销售额=('amount','sum'),销量=('buy_cnt','sum'))
plt.figure(figsize=(16,5))
plt.plot(data_hour.index,data_hour['销售额'])
plt.title('销售额')
plt.xticks(data_hour.index)
plt.show()

在这里插入图片描述

plt.figure(figsize=(16,5))
plt.plot(data_hour.index,data_hour['销量'])
plt.title('销量')
plt.xticks(data_hour.index)
plt.show()

在这里插入图片描述

3.4.7 每月新增用户:首次购买即为新增用户
  • 4月比3月新增用户多了差不多2倍,5月又比4月多了2.3倍,证明4月5月的拉新活动有比较好的效果;
  • 但是6月份又下跌了35%,
  • 7月份比6月份增多了1.5倍,8月份与7月份持平,也是证明7月8月的拉新效果不错;
  • 9月-11月一致持下降趋势,9月更是比8月下跌了63%;
  • 进一步分析是哪一个拉新渠道导致9月份新客的下跌?还是9月份开始就减少了拉新活动的投入?
new_user = data.groupby('user_id').agg({'month':'min'}).reset_index()
new_user.head()

在这里插入图片描述

new_user_month = new_user.groupby('month').agg(新用户数量=('user_id','nunique'))
new_user_month['环比'] = new_user_month.pct_change()
new_user_month

在这里插入图片描述

plt.figure(figsize=(16,5))
plt.plot(new_user_month.index,new_user_month['新用户数量'])
plt.title('新用户数量')
plt.xticks(new_user_month.index)
plt.show()

在这里插入图片描述

3.4.8 每月复购率 = 当月购买次数大于2的用户数/总购买人数 (同一天购买多次视为1次)
  • 第一次复购人数增长较多是在5月份,贡献最多的是新客(新客是老客的2倍多);
  • 第二次复购人数增长较多是在7月份,8月份也上涨了,贡献最多的依然是新客;
  • 然后9月份开始下降,新客复购人数下降了63%,老客仅下降了13%,贡献率第一次被老客反超新客;
  • 复购率1-3月在上升,然后4月份下降到比1月份还低,进一步分析,4月份进行了拉新活动,较多新客当月只购买了一次(有可能是因为拉新活动启动比较晚,新客的复购周期还没到;也有可能这品新客在4月的购买满意度较低,应该着重分析这批客户是否有投诉),所以造成复购率下降;
  • 复购率5月份开始上升,直至11月份下降,11月份新客户的复购率大幅下降,而从9月开始,新客与老客的复购人数都在减少,加上新客数的骤降就导致复购率下降了。老客的复购率都在下降,那么很可能是老客对我们店铺的满意度不够,应该做好产品的优化与服务,维系好老客,还有加强拉新。
data_buy = data.groupby(['user_id','month','date']).agg(是否购买=('user_id','nunique')).reset_index()
data_buy_month = data_buy.groupby(['user_id','month']).agg(每月购买次数=('是否购买','sum')).reset_index()
data_repurchase = data_buy_month[data_buy_month['每月购买次数']>=2].groupby('month').agg(每月复购人数=('user_id','nunique'))
data_repurchase['每月购买人数'] = data.groupby('month').agg(每月购买人数=('user_id','nunique'))
data_repurchase['复购率'] = data_repurchase['每月复购人数'] / data_repurchase['每月购买人数']
data_repurchase

在这里插入图片描述

fig,ax1 = plt.subplots(figsize=(16,5))
line1, = ax1.plot(data_repurchase.index,data_repurchase['复购率'],c='r')
ax1.set_ylabel('复购率')

ax2 = ax1.twinx() #twinx将ax1的X轴共用与ax2

line2, = ax2.plot(data_repurchase.index,data_repurchase['每月复购人数'])
ax2.set_ylabel('每月复购人数')
plt.title('每月复购率及复购人数')
plt.xticks(data_repurchase.index)

plt.legend([line1,line2],['复购率','每月复购人数'])
plt.show()

在这里插入图片描述

plt.subplots(figsize=(16,5))
plt.plot(data_repurchase.index,data_repurchase['每月购买人数'],c='r')
plt.title('每月购买人数')
plt.xticks(data_repurchase.index)
plt.show()

在这里插入图片描述

#划分每个用户的首次购买月份(用来确认用户在几月份是属于新客户)
data_user = data.groupby('user_id').agg(首次购买月份=('month','min')).reset_index()

#data_buy_month 是上面求得的:每个用户每月的购买次数
user = pd.merge(data_buy_month,data_user)
user['新老客户'] = np.where(user['month']==user['首次购买月份'],'新客户','老客户')
#新客户购买人数
user_buy = user[user['新老客户']=='新客户'].groupby('month').agg(新客购买人数=('user_id','nunique'))
#老客户购买人数
user_buy['老客购买人数'] = user[user['新老客户']=='老客户'].groupby('month').agg(老客购买人数=('user_id','nunique'))
user_buy = user_buy.fillna(0)
user_buy

在这里插入图片描述

plt.subplots(figsize=(16,5))
line1, = plt.plot(user_buy.index,user_buy['新客购买人数'],c='r')
line2, = plt.plot(user_buy.index,user_buy['老客购买人数'])
plt.title('新老客购买人数')
plt.xticks(user_buy.index)

plt.legend([line1,line2],['新客','老客'])
plt.show()

在这里插入图片描述

3.4.9 每月回购率
  • 回购率最高的是2月和5月,整体的回购率在下降,在5月份反弹上升了,然后就走向下坡了
  • 回购人数在不断上升,直至到9月开始下降
  • 虽然回购人数上升,但是整体回购率在下降,可见老客的回头率在不断下降,也就证明我们的产品留不住大部分的客户,应该要进一步分析到底是哪里出错了?
purchase_cnt = purchase_cnt.T
purchase_cnt['老客户'] = purchase_cnt.sum(axis=1) - purchase_cnt['新客户']
purchase_cnt['回购'] = purchase_cnt['回流'] + purchase_cnt['活跃']
purchase_cnt['回购率'] = purchase_cnt['回购'] / purchase_cnt['老客户']
purchase_cnt

在这里插入图片描述

plt.figure(figsize=(16,8))
plt.plot(purchase_cnt.index,purchase_cnt['回购率'])
plt.title('每月回购率')
plt.show()

在这里插入图片描述

plt.figure(figsize=(16,8))
plt.plot(purchase_cnt.index,purchase_cnt['回购'])
plt.title('每月回购人数')
plt.show()

在这里插入图片描述

3.4.10 每月的新客、老客复购人数分析(老客定义:首次购买次月即成为老客)
#划分每个用户的首次购买月份(用来确认用户在几月份是属于新客户)
data_user = data.groupby('user_id').agg(首次购买月份=('month','min')).reset_index()
data_user

在这里插入图片描述

# data_buy_month 是上面求得的:每个用户每月的购买次数
user = pd.merge(data_buy_month,data_user)
user['新老客户'] = np.where(user['month']==user['首次购买月份'],'新客户','老客户')
# 筛选出每月购买次数大于等于2的数据
user_2 = user[user['每月购买次数'] >= 2]
# 每月新客户的复购人数
user_repurchase = user_2[user_2['新老客户']=='新客户'].groupby('month').agg(新客户复购人数=('user_id','nunique'))
user_repurchase

在这里插入图片描述

#每月老客户的复购人数
#1月只有新客户 所以老客户复购人数为0
user_repurchase['老客户复购人数'] = user_2[user_2['新老客户']=='老客户'].groupby('month').agg(老客户复购人数=('user_id','nunique'))
user_repurchase = user_repurchase.fillna(0)
user_repurchase['老客户复购人数']  = user_repurchase['老客户复购人数'].astype('int')
user_repurchase

在这里插入图片描述

user_repurchase['每月购买人数'] = data_repurchase['每月购买人数']
user_repurchase['新客户复购率'] = user_repurchase['新客户复购人数'] / user_repurchase['每月购买人数']
user_repurchase['老客户复购率'] = user_repurchase['老客户复购人数'] / user_repurchase['每月购买人数']
user_repurchase

在这里插入图片描述

plt.subplots(figsize=(16,5))
line1, = plt.plot(user_repurchase.index,user_repurchase['新客户复购率'],c='r')
line2, = plt.plot(user_repurchase.index,user_repurchase['老客户复购率'])
plt.title('每月新老客户的复购率')
plt.xticks(user_repurchase.index)
plt.legend([line1,line2],['新客户复购率','老客户复购率'],loc=4)
plt.show()

在这里插入图片描述

4 RFM模型

4.1 结论

  • 重要的客户共有44129人

  • 其中重要价值客户有20012人,约占重要客户的50%,对于重要价值客户,要给与他们VIP式的服务,时刻留意他们的购买反馈

  • 重要发展客户有4415人,这类客户消费频率不够高,要想办法提高他们的消费频率,例如发放满减卷等

  • 重要保持客户有11368人,这类客户最后一次购买时间距离现在已经很远了,应该发送信息,或者电话联系他们,也可以发放满减卷给他们,提高他们的复购率

  • 重要挽留客户有8334人,要想办法挽回这批将近流失的客户,也可以通过短信召回,发放优惠券.

  • 一般的客户共有48626人

  • 对于一般价值、一般发展、一般保持的客户,在处理好重要客户的情况下,可以酌情去发展维系这批客户。

  • 其中一般挽留用户有26843人,这类客户是要流失的,所以在没有多余资源的情况下,就放弃这批客户吧。

用户同一天购买多次视为一次

  • R:最近一次消费(Recency)
  • F:消费频率(Frequency)
  • M:消费金额(Monetary)
user_rfm = data.groupby(['user_id','date']).agg(消费金额=('amount','sum')).reset_index()
user_rfm.head()

在这里插入图片描述

user_rfm = user_rfm.groupby('user_id').agg(最后购买日期=('date','max')
                                           ,M=('消费金额','sum')
                                           ,F=('date','count')
                                          ).reset_index()
user_rfm

在这里插入图片描述

user_rfm['最后购买日期'] = pd.to_datetime(user_rfm['最后购买日期'])
user_rfm['R'] = user_rfm['最后购买日期'].apply(lambda x:user_rfm['最后购买日期'].max() - x)
user_rfm['R'] = user_rfm['R'].dt.days
user_rfm = user_rfm[['user_id','R','F','M']]
user_rfm

在这里插入图片描述

user_rfm['user_id'] = user_rfm['user_id'].astype('object')
user_rfm.describe(percentiles=(0.01,0.1,0.25,0.75,0.9,0.95,0.99)).T

在这里插入图片描述
R的打分:

  • (30-60]:4分
  • (60-90]:3分
  • (90-120]:2分
  • 120以上:1分
    F的打分:
  • 1次:1分
  • 2次:2分
  • 3次:3分
  • 4次:4分
  • 5次及以上:5分
    M的打分:
  • (200-500]:2分
  • (500-1000]:3分
  • (1000-2000]:4分
  • 2000以上:5分
rfm_score = user_rfm.copy()
for i,j in enumerate(rfm_score['R']):
    if j <= 30:
        rfm_score['R'][i] = 5
    elif j <= 60:
        rfm_score['R'][i] = 4
    elif j <= 90:
        rfm_score['R'][i] = 3
    elif j <= 120:
        rfm_score['R'][i] = 2
    else :
        rfm_score['R'][i] = 1
for i,j in enumerate(rfm_score['F']):
    if j <= 1:
        rfm_score['F'][i] = 1
    elif j <= 2:
        rfm_score['F'][i] = 2
    elif j <= 3:
        rfm_score['F'][i] = 3
    elif j <= 4:
        rfm_score['F'][i] = 4
    else :
        rfm_score['F'][i] = 5
for i,j in enumerate(rfm_score['M']):
    if j <= 200:
        rfm_score['M'][i] = 1
    elif j <= 500:
        rfm_score['M'][i] = 2
    elif j <= 1000:
        rfm_score['M'][i] = 3
    elif j <= 2000:
        rfm_score['M'][i] = 4
    else :
        rfm_score['M'][i] = 5
rfm_score

在这里插入图片描述

rfm_score['R'].mean()

2.498830251738451

rfm_score['F'].mean()

1.996366772680718

rfm_score['M'].mean()

2.581930893213304

rfm = pd.DataFrame()
rfm['user_id'] = rfm_score['user_id']
rfm['R'] = rfm_score['R'].apply(lambda x: '1' if x >= rfm_score['R'].mean() else '0')
rfm['F'] = rfm_score['F'].apply(lambda x: '1' if x >= rfm_score['F'].mean() else '0')
rfm['M'] = rfm_score['M'].apply(lambda x: '1' if x >= rfm_score['M'].mean() else '0')
rfm

在这里插入图片描述

rfm['result'] = rfm['R'] + rfm['F'] + rfm['M']
rfm

在这里插入图片描述

for i,j in enumerate(rfm['result']):
    if j == '111':
        rfm['result'][i] = '重要价值客户'
    elif j == '101':
        rfm['result'][i] = '重要发展客户'
    elif j == '011':
        rfm['result'][i] = '重要保持客户'
    elif j == '001':
        rfm['result'][i] = '重要挽留客户'
    elif j == '110':
        rfm['result'][i] = '一般价值客户'
    elif j == '100':
        rfm['result'][i] = '一般发展客户'
    elif j == '010':
        rfm['result'][i] = '一般保持客户'
    elif j == '000':
        rfm['result'][i] = '一般挽留客户'
rfm = rfm[['user_id','result']]
rfm

在这里插入图片描述

rfm['result'].value_counts()

在这里插入图片描述

plt.figure(figsize=(16,8))
plt.bar(rfm['result'].value_counts().index,rfm['result'].value_counts().values)
for x,y in enumerate(rfm['result'].value_counts()):
    plt.text(x,y+100,y,ha='center')
plt.show

在这里插入图片描述

关注公众号:『AI学习星球
回复:某电子产品销售数据分析报告及RFM模型 即可获取数据下载。
论文辅导算法学习可以通过公众号滴滴我

在这里插入图片描述

  • 55
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RFM模型是电商用户大数据分析中常用的一种模型,用于衡量用户价值和忠诚度。RFM模型包括三个指标: R (Recency):最近一次购买时间距离当前时间的天数,表示用户的活跃度。 F (Frequency):用户购买的次数,表示用户的忠诚度。 M (Monetary):用户购买的总金额,表示用户的价值。 以下是一个电商平台的用户RFM模型分析案例和对应的 SQL 语句: 1. 计算每个用户的R、F、M值 ```sql SELECT user_id, DATEDIFF(NOW(), MAX(purchase_time)) AS R, COUNT(*) AS F, SUM(amount) AS M FROM purchase_table GROUP BY user_id; ``` 2. 对R、F、M值进行分组,并计算每个组的平均值和标准差 ```sql SELECT CASE WHEN R < 30 THEN '1. 0-30' WHEN R < 60 THEN '2. 31-60' WHEN R < 90 THEN '3. 61-90' ELSE '4. 91+' END AS R_Group, CASE WHEN F < 2 THEN '1. 1-2' WHEN F < 4 THEN '2. 3-4' WHEN F < 6 THEN '3. 5-6' ELSE '4. 7+' END AS F_Group, CASE WHEN M < 100 THEN '1. 0-100' WHEN M < 200 THEN '2. 101-200' WHEN M < 500 THEN '3. 201-500' ELSE '4. 501+' END AS M_Group, COUNT(*) AS user_count, AVG(R) AS avg_R, AVG(F) AS avg_F, AVG(M) AS avg_M, STDDEV(R) AS std_R, STDDEV(F) AS std_F, STDDEV(M) AS std_M FROM (SELECT user_id, DATEDIFF(NOW(), MAX(purchase_time)) AS R, COUNT(*) AS F, SUM(amount) AS M FROM purchase_table GROUP BY user_id) AS RFM GROUP BY R_Group, F_Group, M_Group; ``` 这里的 R_Group、F_Group、M_Group 分别代表 R、F、M 指标的分组,分别将用户的 R、F、M 值分成四组,分别是 0-30、31-60、61-90、91+ 天,1-2、3-4、5-6、7+ 次,0-100、101-200、201-500、501+ 元。可以根据实际业务场景进行适当调整。 通过RFM模型的分析,可以对用户进行分类,进而制定更有针对性的营销策略,提高用户忠诚度和购买频率,从而提高电商平台的销售额。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值