注:回顾,整理,扩充之前做的;下一步准备用SQL进行分许。
1、项目背景和目的
\quad \quad 随着互联网和电商的发展,人们习惯于网上购物。在国内,电商平台深受欢迎,每年的双11,双12活动,大量的用户在淘宝平台浏览商品,或收藏或加入购物车或直接购买。通过对用户的行为分析,探索用户购买的规律,了解商品的受欢迎程度,结合店铺的营销策略,实现更加精细和精准的运营,让业务获得更好的增长。
2、数据集简介
\quad \quad 本数据集来源:天池淘宝数据
\quad \quad 本数据集包含了淘宝11、12两月份的用户行为数据,(行为包含点击、购买、加购、喜欢)。每一行表示一条用户行为,由用户ID、商品ID、商品类目ID、行为类型和时间戳、用户位置组成。
-
user_id:整数类型,序列化后的用户ID;
-
item_id:整数类型,序列化后的商品ID;
-
behavior_type:字符串,包括(“pv”:相当于点击,“buy”:商品购买,“cart”:将商品加入购物车,“fav”:收藏商品)
-
user_geohash:纬度(行为发生时的用户位置,可以为空)
-
item_category:商品类别
-
time:行为发生的时间戳
3、数据处理
3.1 加载数据
导入相关库
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from datetime import datetime
1、此数据为zip形式,先解压至当前目前目录
# 1、解压文件
# -*-coding:utf-8 -*-
import os
import zipfile
import shutil
def unzipDir(path):
"""解压"""
zip_file = zipfile.ZipFile(path)
try:
zip_file.extractall(os.path.split(path)[0]) # 解压到当前目录
except Exception as e:
raise e
path='E:/tianchi_mobile_recommend_train_user.zip'
unzipDir(path)
2、读取数据
user_action=pd.read_csv('E:/tianchi_mobile_recommend_train_user.csv')
print(user_action.shape)
output:
(12256906, 6)
3、由于数据量太大,降低分析效率,故本次分析随机选取百分之5的数据(存放到一文件中)进行分析。
# random select 5% from dataset
sample = user_action.sample(frac=0.05, random_state=5, axis=0)
# export to csv file
sample.to_csv('E:/Userdata.csv',encoding='utf_8_sig')
user_data=pd.read_csv('E:/Userdata.csv')
3.2 数据概览
1、数据集大小、首尾数据
print(user_data.shape)
print(user_data.head().append(user_data.tail()))
Output:
(612845, 7)
(612845, 7)
Unnamed: 0 user_id item_id behavior_type user_geohash \
0 1165106 21660809 286436627 1 NaN
1 4884642 127429787 129402528 1 NaN
2 3706587 37780288 261186825 1 NaN
3 4148620 62969316 141908693 1 95qsrjo
4 5801818 15237890 195559483 1 NaN
612840 5299504 107109917 66920889 1 954f4l7
612841 6036343 56210078 257707426 1 NaN
612842 10363581 129809988 400224753 1 9q9g00w
612843 4975578 81904568 51594957 1 NaN
612844 5938559 45966877 210330569 1 95q6qed
item_category time
0 5263 2014-12-02 00
1 13547 2014-12-04 22
2 4370 2014-12-08 17
3 12147 2014-12-12 21
4 4116 2014-12-14 07
612840 4640 2014-12-08 21
612841 10079 2014-12-14 15
612842 11623 2014-12-17 23
612843 1863 2014-12-05 12
612844 2883 2014-12-13 21
2、基本信息
user_data.info()
Output:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 612845 entries, 0 to 612844
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Unnamed: 0 612845 non-null int64
1 user_id 612845 non-null int64
2 item_id 612845 non-null int64
3 behavior_type 612845 non-null int64
4 user_geohash 196204 non-null object
5 item_category 612845 non-null int64
6 time 612845 non-null object
dtypes: int64(5), object(2)
memory usage: 32.7+ MB
- Unnamed: 0这一特征是随机采样产生的特征,无用,可将这一列删除
- 经观察,只有user_geohash即用户位置有大量的缺失值,而且这一特征分析也没有意义,故也将其特征删除
3.3 数据清洗
1、删除无用数据列
#删除无用数据列
del user_data['user_geohash']
del user_data['Unnamed: 0']
user_data.columns
Output:
Index(['user_id', 'item_id', 'behavior_type', 'item_category', 'time'], dtype='object')
2、处理时间戳
#把数据自带的字符时间转换成datetime对象,可以更好的拿出需要的时间段
time = pd.to_datetime(user_data['time'])
user_data['hour'] = time.dt.hour
user_data['weekday'] = time.dt.weekday
user_data['date'] = time.dt.date
3、将用户行为标签由数字类型改为用字符表示
# 把用户行为对应成相对应的pv collect buy
behavior = {1:'pv',2:'collect',3:'cart',4:'buy'}
user_data['behavior_type'] = user_data['behavior_type'].apply(lambda x: behavior[x])
user_data.head()
Output:
4、数据分析
分析大纲
4.1 电商数据分析
4.1.1 流量分析
4.1.1.1 总体流量分析
# 总体访问量,收藏,加购,下单
total_liu=user_data.groupby(['behavior_type']).size()
pv=total_liu[3]
# 总访客数
uv=user_data['user_id'].nunique()
# 消费用户数
user_pay=user_data[user_data['behavior_type']=='buy']['user_id'].unique()
# 日均访问量
pv_per_day=pv/user_data['date'].nunique()
# 人均访问量
pv_per_user=pv/uv
# 消费用户访问量
pv_pay=user_data[user_data['user_id'].isin(user_pay)]['behavior_type'].value_counts().pv
# 消费用户数占比
user_pay_rate=len(user_pay)/uv
# 消费用户访问量占比
pv_pay_rate=pv_pay/pv
# 消费用户人均访问量
pv_per_buy_user=pv_pay/len(user_pay)
print('总访问量为',total_liu)
print('总访客数为 %i'%uv)
print('消费用户数为 %i'%len(user_pay))
print('消费用户访问量为 %i'%pv_pay)
print('日均访问量为 %.3f'%pv_per_day)
print('人均访问量为 %.3f'%pv_per_user)
print('消费用户人均访问量为 %.3f'%pv_per_buy_user)
print('消费用户数占比为 %.3f%%'%(user_pay_rate * 100))
print('消费用户访问量占比为 %.3f%%'%(pv_pay_rate * 100))
Output:
总访问量为 behavior_type
buy 6053
cart 17224
collect 12054
pv 577514
dtype: int64
总访客数为 9868
消费用户数为 3530
消费用户访问量为 300533
日均访问量为 18629.484
人均访问量为 58.524
消费用户人均访问量为 85.137
消费用户数占比为 35.772%
消费用户访问量占比为 52.039%
4.1.1.2 每日流量分析
# 每日流量
# 每日PV,收藏,加购,下单
#unstack() 这是一个根据索引行列转换的函数
day_liu=user_data.groupby(['date','behavior_type']).size().unstack()
print(day_liu)
# 每日uv
dayily_uv=user_data.groupby('date')['user_id'].apply(lambda x:x.drop_duplicates().count()).reset_index().rename(columns={'user_id':'uv'})
print(dayily_uv)
behavior_type buy cart collect pv
date
2014-11-18 202 540 349 17312
2014-11-19 171 508 360 17149
2014-11-20 168 493 351 16476
2014-11-21 154 416 313 15686
2014-11-22 166 497 331 16879
2014-11-23 193 535 357 18099
2014-11-24 167 533 374 17671
2014-11-25 188 486 352 17364
2014-11-26 175 452 364 17121
2014-11-27 155 482 388 17438
2014-11-28 160 439 311 15960
2014-11-29 179 526 359 17132
2014-11-30 198 569 397 19146
2014-12-01 201 560 371 18457
2014-12-02 168 533 389 19045
2014-12-03 205 568 388 19392
2014-12-04 197 602 422 18796
2014-12-05 165 487 337 16911
2014-12-06 162 502 435 18469
2014-12-07 167 593 472 18858
2014-12-08 156 557 433 18254
2014-12-09 179 565 432 18685
2014-12-10 175 656 437 19967
2014-12-11 168 782 455 23039
2014-12-12 723 1202 519 32229
2014-12-13 176 525 407 19301
2014-12-14 199 539 390 19332
2014-12-15 196 502 445 19075
2014-12-16 193 529 372 18587
2014-12-17 188 524 377 18130
2014-12-18 159 522 367 17554
date uv
0 2014-11-18 4235
1 2014-11-19 4261
2 2014-11-20 4193
3 2014-11-21 4041
4 2014-11-22 4101
5 2014-11-23 4302
6 2014-11-24 4313
7 2014-11-25 4166
8 2014-11-26 4255
9 2014-11-27 4210
10 2014-11-28 4071
11 2014-11-29 4109
12 2014-11-30 4450
13 2014-12-01 4441
14 2014-12-02 4485
15 2014-12-03 4522
16 2014-12-04 4415
17 2014-12-05 4232
18 2014-12-06 4349
19 2014-12-07 4443
20 2014-12-08 4428
21 2014-12-09 4459
22 2014-12-10 4534
23 2014-12-11 4942
24 2014-12-12 5858
25 2014-12-13 4604
26 2014-12-14 4544
27 2014-12-15 4615
28 2014-12-16 4539
29 2014-12-17 4462
30 2014-12-18 4363
- 可视化展示每日流量分布
dayily_uv.plot(figsize=(12,3))
#由于购买,收藏,加入购物车无法看清,所以还要进行单独plot
for i in day_liu.columns:
plt.figure()
ax=day_liu[i].plot(figsize=(12,3))
ax.set_title(i+" "+"day of analysis")
报告:
1.从图标可以得出,UV PV 收藏 加购各项指标在双十二活动的影响下都呈稳步上升趋势 而由于14年双12并没有预结尾款的活动,这也导致了整个活动积攒的购买量都堆积到了双12当年
2.收藏数 加购数在双12前一星期上升最快,说明用户在活动前一星期是最容易产生购买决策的时候,应该加大推送力度
4.1.1.3 每时流量分析
#每时PV,收藏,加购,下单
hour_liu = user_data.groupby(['hour','behavior_type']).size().unstack()
#每时UV
hour_uv = user_data.groupby('hour')['user_id'].apply(lambda x: x.drop_duplicates().count()).reset_index().rename(columns={'user_id':'uv'})
hour_uv.plot(figsize = (12,3))
#由于购买,收藏,加入购物车无法看清,所以还要进行单独plot
for i in hour_liu.columns:
plt.figure()
ax = hour_liu[i].plot(figsize = (12,3))
ax.set_title(i+" "+"hour of analysis")
报告:
1.从图标知,用户一天时间内集中活跃在早上6-10时,下午5点到晚上10点,
这也符合人们的日常作息时间,所以在这段时间内要做好用户喜好产品的推送
2. 用户的buy与PV 收藏 加购相比,上升幅度并不明显,说明用户有想要购买的产品,但是碍于各种原因并没有下单,
推测应该是想等更优惠或者资金充裕的时候购买,所以建议推送相关优惠卷以及推出相关用户花呗免息活动来促使用户消费
4.1.2 行为流量漏斗转化分析
pv_to_car_collect = (total_liu.cart+total_liu.collect)/total_liu.pv *100
car_collect_to_buy = total_liu.buy/(total_liu.cart+total_liu.collect) *100
pv_to_buy = (total_liu.buy/total_liu.pv)*100
print("浏览到收藏加入购物车的转化率为 %.3f%%"%pv_to_car_collect)
print("购物车收藏到购买的转化率为 %.3f%%"%car_collect_to_buy)
print("浏览到购买转化率 %.3f%%"%pv_to_buy)
浏览到收藏加入购物车的转化率为 5.070%
购物车收藏到购买的转化率为 20.674%
浏览到购买转化率 1.048%
可视化漏斗图
df_con=user_data[['user_id','item_id','time','behavior_type']]
#计算每个行为的人数
#计算每个行为的人数
loudou=df_con['behavior_type'].value_counts().reset_index()
loudou.loc[1,:]='collect+cart',loudou.loc[1,'behavior_type']+loudou.loc[2,'behavior_type']
loudou.drop(index = 2,inplace = True)
orders=[0,1,2]
loudou.index=orders
#print(loudou)
# 流量转化漏斗
# 增加列 每个阶段对应上个阶段的人数
jieduan0=list(loudou['behavior_type'])
#print(jieduan0)
jieduan1=[]
for j in range(len(jieduan0)):
if j==0:
jieduan1.append(jieduan0[j])
else:
jieduan1.append(jieduan0[j-1])
loudou['行为阶段1']=jieduan1
# 增加列,每个阶段的转化率
loudou['转化率']=loudou['behavior_type']/loudou['行为阶段1']
loudou
#绘制转化漏斗图
from pyecharts import options as opts
from pyecharts.charts import Funnel
#添加百分比显示
xinwei=list(loudou['index'])
zhuanhua=list(loudou['转化率'])
label=[]
for i in range(len(xinwei)):
l=xinwei[i]+str(round(zhuanhua[i]*100,2))+'%'
label.append(l)
c=(
Funnel()
.add('行为',[list(z) for z in zip(label,
list(loudou['behavior_type']))],
label_opts=opts.LabelOpts(is_show=True,position='inside'),
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{b} : {c}%")
)
.set_global_opts(title_opts=opts.TitleOpts(
title="流量转化漏斗图"
)
)
)
c.render_notebook()
报告:
1、可以看出,在收藏和加购之后的购买转化率远远大于其他的转化率,所以应该出活动鼓励用户多收藏或加购:例如加购减少额资金
2.、总的购买转化率超过了14年整个电商转化率的均值,说明淘宝的推送目标群体准确度还是很高的。
4.1.3 复购率
\quad \quad 复购率,指消费者对该品牌产品或者服务的重复购买次数,重复购买率越多,则反应出消费者对品牌的忠诚度就越高,反之则越低。
复购率 = 重复购买客户数量 / 客户样本数量。
### 复购率
cos_rebuy = user_data[user_data.behavior_type=='buy'].groupby('user_id')['date'].apply(lambda x:len(x.unique())).rename('rebuy_count')
print('复购率为 :',round(cos_rebuy[cos_rebuy>=2].count()/cos_rebuy.count(),4))
复购率为 : 0.3368
报告:
1、由此看来,顾客对淘宝店铺商品的喜爱程度较高,且满意度较高,所以愿意回购。也说明社会对产品本身的认可度比较高,说白了就是我们所卖的产品没有错,这个产品会让我们挣钱。
2、复购率高,我们就不用去花费高额的钱去拉新客户,因为获取一个新客户的成本比让一个老客户来购买的成本来要多。
4.1.4 跳失率
\quad \quad 跳失率,显示顾客通过相应入口进入,只访问了一个页面就离开的访问次数占该入口总访问次数的比例。
# 跳失率
attrition_rates=sum(user_data.groupby('user_id')['behavior_type'].count()==1)/(user_data['user_id'].nunique())
print('跳失率为 %.3f%%'%(attrition_rates * 100) )
跳失率为 1.621%
报告:
1、就这两月内而言,跳失率接近于0。说明没有用户只浏览了一个界面以后就离开,就像我们看短视频一样,这个视频对我们有着足够强烈的吸引力,让我们停留下来看完。由此可见淘宝的商品广告足够有创意或者吸引力。
2、但是此处缺乏用户在每个网页的停留时间,所以我们不进行网页驻留时间分析。
4.2 用户分析
4.2.1 用户行为数据统计
\quad \quad 对每个用户的不同行为(pv、collect、cart、buy)进行统计。
user_liu = user_data.groupby(['user_id','behavior_type']).size().unstack()
user_liu.fillna(0)
或者使用DataFrame交叉表
user_liu=pd.crosstab(user_data["user_id"],user_data["behavior_type"])
print(user_liu)
4.2.2 用户消费频次分析
1、前十用户消费次数直方图、复购率
# 单个用户消费总次数
total_buy_count=user_liu.buy.to_frame()
# 消费次数前10客户
topbuyer10=total_buy_count.sort_values(by='buy',ascending=False)[:10]
print(topbuyer10)
Output:
buy
user_id
122338823 39
123842164 33
51492142 22
56560718 20
33448326 13
14515063 13
60674956 11
71406451 10
35389479 10
71714329 9
topbuyer10.reset_index().style.bar(color='skyblue',subset=['buy'])
2、用户消费总次数占比可视化
# 用户消费总次数占比可视化
tbc_box = total_buy_count.reset_index()
fig, ax = plt.subplots(figsize=[16,6])
ax.set_yscale("log")
sns.countplot(x=tbc_box['buy'],data=tbc_box,palette='Set1')
for p in ax.patches:
ax.annotate('{:.2f}%'.format(100*p.get_height()/len(tbc_box['buy'])), (p.get_x() - 0.1, p.get_height()))
plt.title('用户消费总次数')
报告:
1、整个计算周期内,最高购物次数为39次,最低为1次,大部分用户的购物次数在6次以下,可适当增加推广,完善购物体验,提高用户消费次数。购物次数前10用户为1187177、502169等,应提高其满意度,增大留存率。
4.2.3 用户行为在时间纬度的分布
1、日消费次数、日活跃人数、日消费人数、日消费人数占比、消费用户日人均消费次数
# 日活跃人数(有一次操作即视为活跃)
daily_active_user=user_data.groupby('date')['user_id'].nunique()
# 日消费人数
daily_buy_user=user_data[user_data['behavior_type'] == 'buy'].groupby('date')['user_id'].nunique()
# 日消费人数占比
proportion_of_buyer=daily_buy_user / daily_active_user
# 日消费总次数
daily_buy_count=user_data[user_data['behavior_type'] == 'buy'].groupby('date')['behavior_type'].count()
# 消费用户日人均消费次数
consumption_per_buyer=daily_buy_count / daily_buy_user
# 日消费人数占比可视化
# 柱状图数据
pob_bar = (pd.merge(daily_active_user,daily_buy_user,on='date').reset_index()
.rename(columns={'user_id_x':'日活跃人数','user_id_y':'日消费人数'})
.set_index('date').stack().reset_index().rename(columns={'level_1':'Variable',0: 'Value'}))
# 线图数据
pob_line = proportion_of_buyer.reset_index().rename(columns={'user_id':'Rate'})
fig1 = plt.figure(figsize=[25,6])
ax1 = fig1.add_subplot(111)
ax2 = ax1.twinx()
sns.barplot(x='date', y='Value', hue='Variable', data=pob_bar, ax=ax1, alpha=0.8, palette='husl')
ax1.legend().set_title('')
ax1.legend().remove()
sns.pointplot(pob_line['date'], pob_line['Rate'], ax=ax2,markers='D', linestyles='--',color='teal')
x=list(range(0,16))
for a,b in zip(x,pob_line['Rate']):
plt.text(a+0.1, b+0.001, '%.2f%%'% (b*100), ha='center', va= 'bottom',fontsize=12)
fig1.legend(loc='upper center',ncol=2)
plt.title('日消费人数占比')
- 日活跃人数与日消费人数无明显波动,日消费人数占比均在3%以上。
# 消费用户日人均消费次数可视化
# 柱状图数据
cpb_bar = (daily_buy_count.reset_index().rename(columns={'behavior_type':'Num'}))
# 线图数据
cpb_line = (consumption_per_buyer.reset_index().rename(columns={0:'Frequency'}))
fig2 = plt.figure(figsize=[16,6])
ax3 = fig2.add_subplot(111)
ax4 = ax3.twinx()
sns.barplot(x='date', y='Num', data=cpb_bar, ax=ax3, alpha=0.8, palette='pastel')
sns.pointplot(cpb_line['date'], cpb_line['Frequency'], ax=ax4, markers='D', linestyles='--',color='teal')
x=list(range(0,16))
for a,b in zip(x,cpb_line['Frequency']):
plt.text(a+0.1, b+0.001, '%.2f'% b, ha='center', va= 'bottom',fontsize=12)
plt.title('消费用户日人均消费次数')
- 日消费人数在200以上,日人均消费次数大于1次。
2、每日高活跃用户数
dau3_df=user_data.groupby(['date','user_id'])['behavior_type'].count().reset_index()
dau3_df=dau3_df[dau3_df['behavior_type'] >= 3]
# 每日高活跃用户数(每日操作数大于3次)
dau3_num=dau3_df.groupby('date')['user_id'].nunique()
fig, ax = plt.subplots(figsize=[16,6])
sns.pointplot(dau3_num.index, dau3_num.values, markers='D', linestyles='--',color='teal')
x=list(range(0,16))
for a,b in zip(x,dau3_num.values):
plt.text(a+0.1, b+300,'%i'% b, ha='center', va= 'bottom',fontsize=14)
plt.title('每日高活跃用户数')
3、高活跃用户累计活跃天数分布
# 高活跃用户累计活跃天数分布
dau3_cumsum = dau3_df.groupby('user_id')['date'].count()
fig, ax = plt.subplots(figsize=[16,6])
ax.set_yscale("log")
sns.countplot(dau3_cumsum.values,palette='Set1')
for p in ax.patches:
ax.annotate('{:.2f}%'.format(100*p.get_height()/len(dau3_cumsum.values)), (p.get_x() + 0.2, p.get_height() + 100))
plt.title('高活跃用户累计活跃天数分布')
- 统计周期内,大部分高活跃用户累计活跃天数在六天以下,但也存在高达31天的超级活跃用户数量,对累计天数较高的用户要推出连续登录奖励等继续维持其对平台的黏性,对累计天数较低的用户要适当进行推送活动消息等对其进行召回。
4.2.4 用户漏斗转化分析
转化漏斗模型,是分析用户使用某项业务时,经过一系列步骤转化效果的方法。
转化分析的本质是为了促进企业的核心业务的流通,最大化每个营销漏斗的转化率。
在理想情况下,用户会沿着产品设计的路径到达最终目标事件,但实际情况是用户的行为路径是多种多样。
通过埋点事件配置关键业务路径,可以分析多种业务场景下转化和流失的情况,不仅找出产品潜在问题的位置,还可以定位每个环节流失用户,进而定向营销促转化。
现在有一份电商数据,用户行为数据,从浏览到交易成功数据,以此数据绘制每个行为阶段转化情况。
浏览商品-搜索-添加购物车-下单-付款-交易成功,每个环节的转化率=此阶段人数/上一阶段人数。
\quad \quad 从点击到下单购买,中间用户可能会收藏该商品,加购该商品,将这些可能性组合一下,我们认为,一共有四种购买路径:
# 导入相关包
from pyecharts import options as opts
from pyecharts.charts import Funnel# 构建漏斗图
import math
user_data['time'] = pd.to_datetime(user_data['time'],format ='%Y-%m-%d %H:%M:%S')
df_con=user_data[['user_id','item_id','time','behavior_type']]
df_pv = df_con[df_con['behavior_type'] == 'pv']
df_collect = df_con[df_con['behavior_type'] == 'collect']
df_cart = df_con[df_con['behavior_type'] == 'cart']
df_buy = df_con[df_con['behavior_type'] == 'buy']
#各种行为用户数
df_pv_uid = df_con[df_con['behavior_type'] == 'pv']['user_id'].unique()
df_collect_uid = df_con[df_con['behavior_type'] == 'collect']['user_id'].unique()
df_cart_uid = df_con[df_con['behavior_type'] == 'cart']['user_id'].unique()
df_buy_uid = df_con[df_con['behavior_type'] == 'buy']['user_id'].unique()
(1)点击–直接购买(PV——>Buy):
collect_cart_list=set(df_collect_uid)|set(df_cart_uid)
#浏览用户行为与消费用户行为交集
pv_buy_df=pd.merge(left=df_pv,right=df_buy,how='inner',on=['user_id','item_id'],suffixes=('_pv','_pay'))
#print(pv_pay_df)
#浏览用户不在收藏、加入购物车用户且浏览时间小于消费时间即为经过浏览就消费的用户数
pv_buy_df=pv_buy_df[(~pv_buy_df['user_id'].isin(collect_cart_list)) & (pv_buy_df['time_pv'] < pv_buy_df['time_pay'])]
uv = user_data['user_id'].nunique()
pv_buy_num = pv_buy_df['user_id'].nunique()
pv_buy_data = pd.DataFrame({'type':['浏览','付款'],'num':[uv,pv_buy_num]})
pv_buy_data['conversion_rates'] = (round((pv_buy_data['num'] / pv_buy_data['num'][0]),4) * 100)
print('点击到购买的转化率:',pv_buy_data['conversion_rates'][1])
点击到购买的转化率: 0.69
attr1=list(pv_buy_data.type)
values1=list(pv_buy_data.conversion_rates)
data1=[[attr1[i], values1[i]] for i in range(len(attr1))]
# 用户行为转化漏斗可视化
pv_pay=(Funnel(opts.InitOpts(width="600px", height="300px"))
.add(
series_name="",
data_pair=data1,
gap=2,
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{b} : {c}%"),
label_opts=opts.LabelOpts(is_show=True, position="inside"),
itemstyle_opts=opts.ItemStyleOpts(border_color="#fff", border_width=1)
)
.set_global_opts(title_opts=opts.TitleOpts(title="用户行为转化漏斗图"))
)
pv_pay.render_notebook()
(2)点击–加购不收藏–购买(pv - cart - buy):
pv_cart_df = pd.merge(left=df_pv,right=df_cart,how='inner',on=['user_id','item_id'],suffixes=('_pv','_cart'))
pv_cart_df=pv_cart_df[pv_cart_df['time_pv'] < pv_cart_df['time_cart']]
pv_cart_df=pv_cart_df[~pv_cart_df['user_id'].isin(df_collect_uid)]
pv_cart_buy_df=pd.merge(left=pv_cart_df,right=df_buy,how='inner',on=['user_id','item_id'])
pv_cart_buy_df=pv_cart_buy_df[pv_cart_buy_df['time_cart'] < pv_cart_buy_df['time']]
uv = user_data['user_id'].nunique()
pv_cart_num = pv_cart_df['user_id'].nunique()
pv_cart_buy_num = pv_cart_buy_df['user_id'].nunique()
pv_cart_buy_data = pd.DataFrame({'type':['浏览','加购','付款'],'num':[uv,pv_cart_num,pv_cart_buy_num]})
#print(pv_cart_buy_data)
num_0=list(pv_cart_buy_data['num'])
#print(num_0)
num1=[]
for j in range(len(num_0)):
if j==0:
num1.append(num_0[j])
else:
num1.append(num_0[j-1])
pv_cart_buy_data['num1']=num1
# 增加列,每个阶段的转化率
pv_cart_buy_data['转化率']=(round((pv_cart_buy_data['num']/pv_cart_buy_data['num1']),4)*100)
pv_cart_buy_data
# 用户行为转化漏斗可视化
#添加百分比显示
xinwei=list(pv_cart_buy_data['type'])
zhuanhua=list(pv_cart_buy_data['转化率'])
label=[]
for i in range(len(xinwei)):
l=xinwei[i]+str(zhuanhua[i])+'%'
label.append(l)
c=(
Funnel()
.add('行为',[list(z) for z in zip(label,
list(pv_cart_buy_data['num']))],
label_opts=opts.LabelOpts(is_show=True,position='inside'),
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a}")
)
.set_global_opts(title_opts=opts.TitleOpts(
title="流量转化漏斗图"
)
)
)
c.render_notebook()
(3)点击–收藏不加购–购买(pv-collect-buy):
pv_collect_df=pd.merge(left=df_pv,right=df_collect,how='inner',on=['user_id','item_id'],suffixes=('_pv','_collect'))
pv_collect_df=pv_collect_df[pv_collect_df['time_pv'] < pv_collect_df['time_collect']]
pv_collect_df=pv_collect_df[~pv_collect_df['user_id'].isin(df_cart_uid)]
pv_collect_buy_df=pd.merge(left=pv_collect_df, right=df_buy, how='inner',on=['user_id','item_id'])
pv_collect_buy_df=pv_collect_pay_df[pv_collect_buy_df['time_collect'] < pv_collect_buy_df['time']]
uv = user_data['user_id'].nunique()
pv_collect_num = pv_collect_df['user_id'].nunique()
pv_collect_buy_num = pv_collect_buy_df['user_id'].nunique()
pv_collect_buy_data = pd.DataFrame({'type':['浏览','收藏','付款'],'num':[uv,pv_collect_num,pv_collect_buy_num]})
num_0=list(pv_collect_buy_data['num'])
print(num_0)
num1=[]
for j in range(len(num_0)):
if j==0:
num1.append(num_0[j])
else:
num1.append(num_0[j-1])
pv_collect_buy_data['num1']=num1
# 增加列,每个阶段的转化率
pv_collect_buy_data['转化率']=(round((pv_collect_buy_data['num']/pv_collect_buy_data['num1']),4)*100)
pv_collect_buy_data
# 用户行为转化漏斗可视化
#添加百分比显示
xinwei=list(pv_collect_buy_data['type'])
zhuanhua=list(pv_collect_buy_data['转化率'])
label=[]
for i in range(len(xinwei)):
l=xinwei[i]+str(zhuanhua[i])+'%'
label.append(l)
pv_collect_buy=(
Funnel()
.add('行为',[list(z) for z in zip(label,
list(pv_collect_buy_data['num']))],
label_opts=opts.LabelOpts(is_show=True,position='inside'),
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a}")
)
.set_global_opts(title_opts=opts.TitleOpts(
title="流量转化漏斗图"
)
)
)
pv_collect_buy.render_notebook()
)
(4)点击–加购且收藏–购买(pv-cart+collect-buy):
pv_collect = pd.merge(left=df_pv,right=df_collect,how='inner',on=['user_id','item_id'],suffixes=('_pv','_collect'))
pv_collect=pv_collect[pv_collect['time_pv'] < pv_collect['time_collect']]
pv_collect_cart=pd.merge(left=pv_collect, right=df_cart, how='inner',on=['user_id','item_id'])
pv_collect_cart=pv_collect_cart[pv_collect_cart['time_collect']<pv_collect_cart['time']]
pv_collect_cart_buy = pd.merge(left=pv_collect_cart,right=df_buy, how='inner',on=['user_id','item_id'],suffixes=('_cart','_buy'))
pv_collect_cart_buy=pv_collect_cart_buy[pv_collect_cart_buy['time_cart']<pv_collect_cart_buy['time_buy']]
uv = user_data['user_id'].nunique()
pv_collect_n = pv_collect['user_id'].nunique()
pv_collect_cart_n = pv_collect_cart['user_id'].nunique()
pv_collect_cart_buy_n = pv_collect_cart_buy['user_id'].nunique()
pv_collect_cart_buy_data = pd.DataFrame({'type':['浏览','收藏','加购','付款'],'num':[uv,pv_collect_n,pv_collect_cart_n,pv_collect_cart_buy_n]})
num_0=list(pv_collect_cart_buy_data['num'])
#print(num_0)
num1=[]
for j in range(len(num_0)):
if j==0:
num1.append(num_0[j])
else:
num1.append(num_0[j-1])
pv_collect_cart_buy_data['num1']=num1
# 增加列,每个阶段的转化率
pv_collect_cart_buy_data['转化率']=(round((pv_collect_cart_buy_data['num']/pv_collect_cart_buy_data['num1']),4)*100)
pv_collect_cart_buy_data
- 由于数据我是随机抽取的,所以出现这样的结果也不为怪
#添加百分比显示
xinwei=list(pv_collect_cart_buy_data['type'])
zhuanhua=list(pv_collect_cart_buy_data['转化率'])
label=[]
for i in range(len(xinwei)):
l=xinwei[i]+str(zhuanhua[i])+'%'
label.append(l)
pv_collect_cart_buy=(
Funnel()
.add('行为',[list(z) for z in zip(label,
list(pv_collect_cart_buy_data['num']))],
label_opts=opts.LabelOpts(is_show=True,position='inside'),
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a}")
)
.set_global_opts(title_opts=opts.TitleOpts(
title="流量转化漏斗图"
)
)
)
pv_collect_cart_buy.render_notebook()
4.2.5 用户留存率分析
#留存率
first_day = datetime.date(datetime.strptime('2014-11-20', '%Y-%m-%d'))
fifth_day = datetime.date(datetime.strptime('2014-11-25', '%Y-%m-%d'))
tenth_day = datetime.date(datetime.strptime('2014-11-30', '%Y-%m-%d'))
fifteenth_day = datetime.date(datetime.strptime('2014-12-16', '%Y-%m-%d'))
#第一天新用户数
user_num_first = user_data[user_data['date'] == first_day]['user_id'].to_frame()
#第五天留存用户数
user_num_fifth = user_data[user_data['date'] == fifth_day ]['user_id'].to_frame()
#第十留存用户数
user_num_tenth = user_data[user_data['date'] == tenth_day]['user_id'].to_frame()
#第十五天留存用户数
user_num_fifteenth = user_data[user_data['date'] == fifteenth_day]['user_id'].to_frame()
#第五天留存率
fifth_day_retention_rate = round((pd.merge(user_num_first, user_num_fifth).nunique())
/ (user_num_first.nunique()),4).user_id
#第十天留存率
tenth_day_retention_rate = round((pd.merge(user_num_first, user_num_tenth ).nunique())
/ (user_num_first.nunique()),4).user_id
#第十五天留存率
fifteenth_day_retention_rate = round((pd.merge(user_num_first, user_num_fifteenth).nunique())
/ (user_num_first.nunique()),4).user_id
retention_rate = pd.DataFrame({'n日后留存率':['第五天留存率','第十天留存率','第十五天留存率'],
'Rate':[fifth_day_retention_rate,tenth_day_retention_rate,fifteenth_day_retention_rate]})
retention_rate
# 留存率可视化
fig, ax = plt.subplots(figsize=[16,6])
sns.barplot(x='n日后留存率',y='Rate', data=retention_rate,
palette='Set1')
x=list(range(0,3))
for a,b in zip(x,retention_rate['Rate']):
plt.text(a,b+0.001,'%.2f%%'% (b*100),ha='center', va='bottom',fontsize=12)
plt.title('用户留存率')
-
留存率反应了产品质量和保留用户的能力,按照Facebook平台流传出留存率“40–20–10”规则(规则中的数字表示的是次日留存率、第7日留存率和第30日留存率),统计周期内第五日留存率为58.45%,第15日留存率为56.81%。
-
反映出平台的用户依赖性较高,也因平台发展已经到达稳定阶段,用户保留率不会发生较大波动,数据量足够的情况下可以以年为单位,计算按月的留存率。要合理安排消息推送,推出签到有奖等机制提高用户粘性,进一步提高留存率。
4.2.6 用户RFM价值分析
\quad \quad RFM模型是衡量客户价值和客户创利能力的重要工具和手段。这三个要素构成了数据分析最好的指标:
- 最近一次消费(Recency)
- 消费频率(Frequency)
- 消费金额(Monetary)
\quad \quad 本数据集中不包括M数据,本次不考虑该指标。
#根据用户进行分组且行为为购买
#由于缺少M(金额)列,仅通过R(最近一次购买时间)和F(消费频率)对用户进行价值分析
buy_group = user_data[user_data['behavior_type']=='buy'].groupby('user_id')['date']
#将2014-12-30作为每个用户最后一次购买时间来处理即现在时间
final_day=datetime.date(datetime.strptime('2014-12-30','%Y-%m-%d'))
# 距今购买间隔R
recent_buy_time = buy_group.apply(lambda x:final_day-x.max())
recent_buy_time = recent_buy_time.reset_index().rename(columns={'date':'recent'})
recent_buy_time['recent'] = recent_buy_time['recent'].map(lambda x:x.days)
recent_buy_time
#购物频率F
buy_freq=buy_group.count().reset_index().rename(columns={'date':'freq'})
buy_freq
#合并R、F
RFM=pd.merge(recent_buy_time,buy_freq,on='user_id')
# pd.qcut分箱
RFM['R'] = pd.qcut(RFM.recent,2,labels=['1','0'])
#天数小标签为1天数大标签为0
RFM['F'] = pd.qcut(RFM.freq.rank(method='first'),2,labels=['0','1'])
#频率大标签为1频率小标签为0
RFM
#RFM标签
RFM['RFM'] = RFM['R'].astype(int).map(str) + RFM['F'].astype(int).map(str)
RFM['RFM']
dict_n={'01':'重要保持客户',
'11':'重要价值客户',
'10':'重要挽留客户',
'00':'一般发展客户'}
#用户标签
RFM['用户等级'] = RFM['RFM'].map(dict_n)
RFM
#饼状图
RFM_pie=RFM['用户等级'].value_counts().reset_index()
RFM_pie['Rate'] = RFM_pie['用户等级'] / RFM_pie['用户等级'].sum()
fig, ax = plt.subplots(figsize=[16,6])
plt.pie(RFM_pie['Rate'],labels = RFM_pie['index'],startangle =90,autopct="%1.2f%%",
counterclock=False,colors = ['yellowgreen','gold','lightskyblue','lightcoral'])
plt.axis('square')
plt.title('RFM用户分层')
不同类型用户占比差异较小,应提升重要价值各户的占比,减小一般发展客户的占比。
通过RFM模型对用户价值进行分类,对不同价值用户应采取不同的运营策略:
-
对于重要价值客户来说,要提高该部分用户的满意度,服务升级,发放特别福利,增大该部分用户留存率,在做运营推广时也要给与特别关注,避免引起用户反感。
-
对于重要保持客户,他们购物频次较高,但最近一段时间没有消费,可以推送相关其他商品,发放优惠卷、赠品和促销信息等,唤回该部分用户。
-
对于重要挽留客户,他们最近消费过,但购物频次较低,可以通过问卷有礼的方式找出其对平台的不满,提升购物体验,增大用户粘性。
-
对于一般发展客户,做到定期发送邮件或短信唤回,努力将其转化为重要保持客户或重要挽留客户。
4.3 商品分析
# 商品总数
user_data['item_id'].nunique()
465623
4.3.1 SKU下单量、浏览量
1、各个商品的下单量
item_num=user_data.groupby('item_id').behavior_type.value_counts().unstack().fillna(0).sort_values('buy',ascending=False)
item_num['buy']
2、不同行为top10商品
plt.figure(figsize=(20,7))
product_1= user_data[user_data.behavior_type == 'pv']['item_id'].value_counts().head(10) # 商品统计
X=product_1.index
Y=product_1.values
plt.bar(range(len(X)),Y,tick_label=X,color='g',width=0.5)
for x,y in enumerate(Y):
plt.text(x,y+10,y,ha='center',fontsize=18)
font={'size':18,}
plt.ylabel('数量',font)
plt.xlabel('商品ID',font)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend()
plt.title('浏览量Top10商品',fontsize=18)
plt.show()
plt.figure(figsize=(20,7))
product_3= user_data[user_data.behavior_type == 'collect']['item_id'].value_counts().head(10)
X=product_3.index
Y=product_3.values
plt.bar(range(len(X)),Y,tick_label=X,color='g',width=0.5)
for x,y in enumerate(Y):
plt.text(x,y,y,ha='center',fontsize=18)
font={'size':18,}
plt.ylabel('数量',font)
plt.xlabel('商品ID',font)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend()
plt.title('收藏量Top10商品',fontsize=18)
plt.show()
plt.figure(figsize=(20,7))
product_2= user_data[user_data.behavior_type == 'cart']['item_id'].value_counts().head(10)
X=product_2.index
Y=product_2.values
plt.bar(range(len(X)),Y,tick_label=X,color='g',width=0.5)
for x,y in enumerate(Y):
plt.text(x,y,y,ha='center',fontsize=18)
font={'size':18,}
plt.ylabel('数量',font)
plt.xlabel('商品ID',font)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend()
plt.title('加入购物车数量Top10商品',fontsize=18)
plt.show()
plt.figure(figsize=(20,7))
product_4= user_data[user_data.behavior_type == 'buy']['item_id'].value_counts().head(10)
X=product_4.index
Y=product_4.values
plt.bar(range(len(X)),Y,tick_label=X,color='g',width=0.5)
for x,y in enumerate(Y):
plt.text(x,y,y,ha='center',fontsize=18)
font={'size':18,}
plt.ylabel('数量',font)
plt.xlabel('商品ID',font)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend()
plt.title('付款量Top10商品',fontsize=18)
plt.show()
3、对销售前10的商品种类分析,从点击和购买率分析
# 分析销量前十的具体商品
# 获得商品ID和用户行为的DataFrame
item_10['pv2_buy']=item_10['buy']/item_10['pv']
item_10.replace(np.inf,0,inplace=True)
#清楚异常值
item_10[(item_10.pv2_buy>0) & (item_10.pv2_buy<1)].head(10)
1.转化率极高(0.6,1),该商品也许是特定群体非常需要的,他们搜索和点击的目标比较明确。电商平台可以收集用户信息,分析用户画像,结合商品特点,核实是否如此。如果是某类特征明显的用户群体购买更多,可以集中向该类用户多推送。如果没有明显的群体需求,建议对这类商品多做推广,因为原有的购买量比较高,若是能够提高点击量,可能购买量也会再上一个台阶。
2.转化率一般(0.15,0.6),电商平台应该重点推送该商品,因为该商品有市场,并且可以多做活动,吸引更多的潜在客户变成购买客户。
3.转化率极低(0,0.15),该商品应该首先从商品本身进行分析,部分转化率极低而销量却排在靠前的商品可能通过广告赚取了一定的点击量,但是购买量相对点击量极低可能是因为用户因为广告推广点击了但是这类商品本身不是用户需要的,又或者是价格过高?社会热点造成了炒作营销导致用户好奇的点击?更深的原因需要结合更多的信息进行进一步分析。
4.3.2 商品种类分析
category_10 = user_data.groupby('item_category').behavior_type.value_counts().unstack().fillna(0).sort_values('buy',ascending = False)
category_10['cate_pv2_buy'] = (category_10['buy']/ category_10['pv'])
sns.distplot(category_10[(category_10['cate_pv2_buy']<=1)&(category_10['cate_pv2_buy']>0)]['cate_pv2_buy'],
kde=True)
plt.show()
category_10[(category_10.cate_pv2_buy>0) & (category_10.cate_pv2_buy<=1)].head(10)
结论: 1,无论从总体还是前10种类的转化率来看,转化率都大部分在{0,0.015},少部分优秀的能到0.02
说明这类商品转化率低可能因为同一类商品包含很多种商品,用户存在“货比三家”的心理,
用户对于需要的该类商品可能不会购买多种商品,而是在该类商品中购买具体的一个商品。
建议: 提高这类商品的转化率,推荐精确与否是关键,可以考虑这类商品的精准定位,预测用户感兴趣的物品,
然后从用户可能感兴趣的商品类目中推荐有比较性的具体商品,这样可以减少用户比较多个商品来回跳转的点击量,
能在更短的时间做出比较并选择需要购买的商品。
4.3.3 帕累托分析
category_10['cumsum'] = category_10['buy'].cumsum()
key = category_10['buy'].sum()*0.8
category_10['class'] = category_10['cumsum'].map(lambda x: '80%' if x<=key else '20%' )
category_10['class'].value_counts(1)
20% 0.911596
80% 0.088404
Name: class, dtype: float64
前80%销量有8%左右的商品品类提供,后20%的销量由92%左右的商品品类提供,接近二八定律所表示的由少数商品品类掌控了大部分的销量
5、总结
整体终结与建议:
1.总体用户活跃具有规律性,在活动前一周加购和收藏数上升,在每天的早上7-10 下午17:00-20:00用户访问会增加,而在工作日用户会比休息日要活跃,建议在这断时间加大推送以及直播带货等。
2. 在收藏加购后的购买率能达到百分之20,推出加购收藏优惠活动,提高加购收藏率。
3. 留存率相对稳定,为进一步提高留存率,可以定期推出秒杀活动,推出专享优惠券,推出签到有礼环节,增加用户浏览时长和深度,提高用户粘性。分析用户对产品的真实使用感受与评价,提高用户忠诚度。
4. 通过RFM分析,得出重要挽留部分占36.55%,重要发展占24.22%,重要价值客户占21.8%,重要保持客户17%。
重要价值用户:推出更个性化服务,推荐更贴近这类客户需求的商品
重要发展:想办法提高消费频率,推送购物车收藏里面的优惠卷,花呗免息等
重要挽留:分析哪出了问题,推送感兴趣的商品,并促进消费
重要保持:主动联系他们,例如活动推送,其他网站广告引流等。
有针对性的采取不同的营销方法进行精准化营销,用有限的公司资源优先服务于公司最重要的客户。
5.商品分析: 整体的类别转化率过低
推出更精确的推送,例如买别的网站数据等,在销量前十的商品中,有的转化率很高可以模仿一下。
可以增加渠道推广投入,进行精准人群推广,推出新用户福利,吸引新用户,推出团购、分享有礼等活动促进老带新,推出促销活动刺激老用户,提高访客数和浏览量。提高产品质量,提高商品详情页对用户的吸引力,降低跳失率。