项目背景与分析说明
(1)项目背景
基于淘宝平台数据,通过相关指标对用户行为进行分析,探究用户的交易行为模式。
(2)数据及字段说明
本文使用的数据集来自天池的公开数据:
天池-淘宝交易行为数据集
本文使用的数据集时间段为2014.11.18-2014.12.18,包含了淘宝移动端的用户行为数据,总计12256906条数据,共6列。
- user_id: 用户id
- item_id: 商品id
- behavior_type: 用户行为类型(1:点击;2:收藏;3:加入购物车;4:支付)
- user_geoshash: 地理位置
- item_category: 用户行为发生的时间
(3)分析维度
- 流量指标分析
- 用户行为分析
- 漏斗流失分析
- 用户价值RFM分析
(4)电商常用分析方法
数据预览及数据预处理
(1)导入库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator
import seaborn as sns
import warnings
#设置seaborn绘图风格
sns.set(style='darkgrid',font_scale=1.5)
#设置显示中文标签
plt.rcParams["font.family"] = "SimHei"
#设置正常显示字符
plt.rcParams["axes.unicode_minus"] = False
#有时候运行代码时会有很多warning输出,像提醒新版本之类的,如果不想这些乱糟糟的输出,可以使用如下代码
warnings.filterwarnings("ignore")
(2)数据预览
导入数据并先粗略查看数据情况
df = pd.read_csv('./taobao.csv',dtype=str)
df.info()
df.head(10)
结果如下:
(3)计算缺失率
df.apply(lambda x:sum(x.isnull())/len(x),axis=0)
结果如下:
由结果可知,地理位置缺失率过高且无法填充,由于地理位置对本次分析作用不大,所以我们选择删除此列
df.drop(["user_geohash"],axis=1,inplace=True)
(4)处理时间列
将时间列拆分为日期列和小时列,并将time,date转化为标准日期格式,hour转化为int格式
df['date'] = df.time.str[0:-3]
df['hour'] = df.time.str[-2:]
df.head(5)
结果如下:
(5)将数据按time升序排列
df.sort_values(by='time',ascending=True,inplace=True)
df.head(5)
结果如下:
(6)删除原始索引,重新生成新的索引
df.reset_index(drop=True,inplace=True)
df.head(5)
结果如下:
(7)使用describe()函数查看数据的分布情况
# 查看所有object字符串类型的数据分布状况
df.describe(include=['object'])
# describe()默认只会统计数值型变量的数据分布情况。
df.describe()
# 查看所有数据类型的数据分布状况
df.describe(include='all')
结果如下:
模型构建
(1)流量指标的处理:
pv:指的是页面总浏览量。每个用户没刷新一次网页,就会增加一次pv。
uv:指的是独立访客数。一台电脑一个ip就是一个独立访客,实际认为一个独立访客代表一个用户。
1)总计pv和uv
total_pv = df['user_id'].count()
print("总计pv:",total_pv)
total_uv = df['user_id'].nunique()
print('总计uv:',total_uv)
结果如下:
结果分析:总浏览量为12256906次,独立访客数有10000个。
2)日期维度下的pv和uv
uv_daily = df.groupby('date')['user_id'].apply(lambda x: x.nunique())
uv_daily.head(5)
pv_uv_daily = pd.concat([pv_daily,uv_daily],axis=1)
pv_uv_daily.columns = ['pv','uv']
pv_uv_daily.head(5)
结果如下:
绘图:
plt.figure(figsize=(20,10))
plt.subplot(211)
plt.plot(pv_daily,c='r')
plt.title('每天页面的总访问量(pv)')
#设置横坐标为5的倍数,避免横坐标重叠不美观
ax1=plt.gca()
ax1.xaxis.set_major_locator(MultipleLocator(5))
plt.subplot(212)
plt.plot(uv_daily,c='g')
plt.title('每天页面的独立访客数(uv)')
plt.tight_layout()
plt.savefig('pv和uv的变化趋势',dpi=300)
ax1=plt.gca()
ax1.xaxis.set_major_locator(MultipleLocator(5))
plt.show()
绘图结果如下:
结果分析:从图中可以看出,pv和uv数据呈现高度的正相关。双12前后,pv和uv都在350000-400000之间波动,双十二的时候,页面访问量急剧上升,证明这次活动的效果很好。
3)时间维度下的pv和uv
pv_hour = df.groupby("hour")['user_id'].count()
pv_hour.head()
uv_hour = df.groupby("hour")['user_id'].apply(lambda x: x.nunique())
uv_hour.head()
pv_uv_hour = pd.concat([pv_hour,uv_hour],axis=1)
pv_uv_hour.columns = ["pv_hour","uv_hour"]
pv_uv_hour.head()
结果如下:
绘图
fig = plt.figure(figsize=(20,10))
pv_uv_hour["pv_hour"].plot(c="steelblue",label="每个小时的页面总访问量")
plt.ylabel("页面访问量")
pv_uv_hour["uv_hour"].plot(c="red",label="每个小时的页面独立访客数",secondary_y=True)
plt.ylabel("页面独立访客数")
plt.xticks(range(0,24),pv_uv_hour.index)
fig.legend(loc='upper left',bbox_to_anchor=(0.07,0.95))
plt.grid(True)
plt.tight_layout()
plt.savefig("每个小时的PV和UV的变化趋势",dpi=300)
plt.show()
绘图结果如下:
结果分析:由图可看出,晚上22:00-凌晨5:00,该时间段大多数人处于睡眠休息中,页面独立访客数量和总访问量逐渐降低;早上6:00-10:00总访问用户数量逐渐上升,且从图中可以看出大多数用户会在这个时间段打开淘宝,有可能是上班上学路上打发时间;10:00-18:00较为平稳,该时间段大多是人们工作学习的时间;18:00-22:00总访问量再次增长,在21:00左右达到最大值,该时间段是大多数用户结束一天工作学习后选择娱乐放松的休闲时间;运营人员可以针对早高峰时间以及夜晚黄金时间的用户活跃时间段,进行一些活动。
(2)用户行为指标
1)总计点击、收藏、添加购物车、支付用户的情况
type_1 = df[df['behavior_type']=='1']['user_id'].count()
type_2 = df[df['behavior_type']=='2']['user_id'].count()
type_3 = df[df['behavior_type']=='3']['user_id'].count()
type_4 = df[df['behavior_type']=='4']['user_id'].count()
print('点击用户:',type_1)
print('收藏用户:',type_2)
print('添加购物车用户:',type_3)
print('支付用户:',type_4)
结果如下:
结果分析:由结果可知,用户在页面进行点击 -> 收藏和加入购物车 -> 支付 这个过程中,数量逐渐减少,关于这一部分在后文用漏斗图进一步说明。
2)日期维度下,点击、收藏、添加购物车、支付用户的情况
#调用数据透视表pivot_table
pv_date_type = pd.pivot_table(df,index='date',columns='behavior_type',values='user_id',aggfunc=np.size)
pv_date_type.columns = ['点击','收藏','加入购物车','支付']
pv_date_type.head(5)
结果如下:
#绘图
plt.figure(figsize=(20,10))
#因为点击量数据较之其他数据过于庞大,因此此处不绘制点击数据的曲线以免过度压缩其他数据的曲线
sns.lineplot(data=pv_date_type[['收藏','加入购物车','支付']])
plt.tight_layout()
plt.savefig('不同日期不同用户行为的pv变化趋势',dpi=300)
plt.show()
绘图结果如下:
3)时间维度下,点击、收藏、添加购物车、支付用户的情况
pv_hour_type = pd.pivot_table(df,index='hour',
columns='behavior_type',
values='user_id',
aggfunc=np.size)
pv_hour_type.columns=['点击','收藏','加入购物车','支付']
pv_hour_type.head(5)
结果如下:
绘图:
plt.figure(figsize=(20,10))
sns.lineplot(data=pv_hour_type[['收藏','加入购物车','支付']])
fig = pv_hour_type['点击'].plot(c='r',label='点击',secondary_y=True)
fig.legend(loc='best')
plt.tight_layout()
plt.savefig('不同小时不同用户行为的PV变化趋势',dpi=300)
plt.show()
绘图结果如下:
4)支付次数前10的用户行为细分
df['user_id1'] = df['user_id']
buy_no = pd.pivot_table(df,index='user_id',
columns='behavior_type',
values='user_id1',
aggfunc='count')
buy_no.columns = ['点击','收藏','加入购物车','支付']
buy_no10 = buy_no.sort_values(by='支付',ascending=False)[:10]
buy_no10
结果如下:
绘图:
plt.figure(figsize=(20,10))
plt.subplot(311)
plt.plot(buy_no10['点击'],c='r')
plt.title('点击数的变化趋势')
plt.subplot(312)
plt.plot(buy_no10['收藏'],c='g')
plt.title('收藏数的变化趋势')
plt.subplot(313)
plt.plot(buy_no10['加入购物车'],c='b')
plt.title('加入购物车的变化趋势')
plt.xticks(np.arange(10),buy_no10.index)
plt.tight_layout()
plt.savefig('支付数前10的用户,在点击、收藏、加入购物车的变化趋势',dpi=300)
plt.show()
绘图结果如下:
结果分析:可以看出,购买次数最多的用户,点击、收藏、加入购物车的次数不一定是最多的,这一类用户应该购物目标比较明确且比较果断,可以通过进一步分析其常浏览的感兴趣类目,通过推荐给其感兴趣的商品来提高这部分用户的点击及购买;对于频繁加入购物车确没有付款的用户群进一步分析他们犹豫的原因,针对原因采取措施提高他们的转化。
5)日均付费用户的支付次数分析:
total_custome = df[df['behavior_type'] == '4'].groupby(['date','user_id'])['behavior_type'].count().reset_index().rename(columns={'behavior_type':'total'})
# total_custome.columns = ['date','user_id','total']
total_custome.head()
total_custome2 = total_custome.groupby('date').sum()['total']/total_custome.groupby('date').count()['total']
total_custome2.head(10)
结果如下:
绘图:
# 绘图如下
plt.figure(figsize=(20,10))
x = len(total_custome2.index.astype(str))
y = total_custome2.index.astype(str)
plt.plot(total_custome2.values)
plt.xticks(range(0,30,7),[y[i] for i in range(0,x,7)])
plt.title('每天的人均消费次数')
plt.tight_layout()
plt.savefig('每天的人均消费次数',dpi=300)
plt.show()
绘图结果如下:
6)日均所有用户的支付次数分析:
df['operation'] = 1
user_openum = df.groupby(['date','user_id','behavior_type'])['operation'].count().\
reset_index().rename(columns={'operation':'total'})
user_openum.head(5)
user_paynum = user_openum.groupby('date').\
apply(lambda x:x[x['behavior_type']=='4']['total'].sum()/x['user_id'].nunique())
user_paynum.head(5)
结果如下:
绘图:
#绘图
plt.figure(figsize=(20,10))
x = len(user_paynum.index.astype(str))
y = user_paynum.index.astype(str)
plt.plot(user_paynum.values)
plt.xticks(range(0,30,7),[y[i] for i in range(0,x,7)])
plt.title('所有用户的日均消费次数')
plt.tight_layout()
plt.savefig('所有用户的日均消费次数',dpi=300)
plt.show()
绘图结果如下:
7)付费率分析: 拆解为 付费率 = 支付人数/总用户数
payrate = user_openum.groupby('date').\
apply(lambda x: x[x['behavior_type']=='4']['total'].count()/x['user_id'].nunique())
payrate.head(10)
结果如下:
绘图:
plt.figure(figsize=(20,10))
x = len(payrate.index.astype(str))
y = payrate.index.astype(str)
plt.plot(payrate.values)
plt.xticks(range(0,30,7),[y[i] for i in range(0,x,7)])
plt.title('付费率分析')
plt.tight_layout()
plt.savefig('付费率分析',dpi=300)
plt.show()
绘图结果如下:
8)复购率分析:
rebuy = df[df['behavior_type']=='4'].groupby('user_id')['date'].\
apply(lambda x: x.nunique())
rebuy_rate = rebuy[rebuy >= 2].count() / rebuy.count()
print('复购率:',rebuy_rate)
结果如下:
(3)漏斗分析:
type_count = df.groupby('behavior_type').size().reset_index().\
rename(columns={'behavior_type':'环节',0:'人数'})
type_dict = {
'1':'点击',
'2':'收藏',
'3':'加入购物车',
'4':'支付'
}
type_count['环节'] = type_count['环节'].map(type_dict)
a = type_count.iloc[0]['人数']
b = type_count.iloc[1]['人数']
c = type_count.iloc[2]['人数']
d = type_count.iloc[3]['人数']
type_count_1 = pd.DataFrame({'环节':['点击','收藏及加入购物车','支付'],'人数':[a,b+c,d]})
type_count_1['总体转化率'] = [i/type_count_1['人数'][0] for i in type_count_1['人数']]
type_count_1['单一转化率'] = np.array([1.0,2.0,3.0])
for i in range(0,len(type_count_1['人数'])):
if i == 0:
type_count_1['单一转化率'][i] = 1.0
else:
type_count_1['单一转化率'][i] = type_count_1['人数'][i] / type_count_1['人数'][i-1]
type_count_1
结果如下:
绘图:
import plotly.express as px
import plotly.graph_objs as go
trace = go.Funnel(
y = ['点击','收藏及加入购物车','支付'],
x = [type_count_1['人数'][0],type_count_1['人数'][1],type_count_1['人数'][2]],
textinfo = 'value+percent initial',
marker=dict(color=['deepskyblue', 'lightsalmon', 'tan']),
connector = {'line': {'color': 'royalblue', 'dash': 'solid', 'width': 3}})
data = [trace]
fig = go.Figure(data)
fig.show()
结果分析:由于收藏和加入购物车都可以视为一种有购买意向的表现,故将它们归为一类,从上面数据可以看出,从浏览到产生购买意向转化率为5%,到产生购买行为的转化率为1%,若单看从具有购买意向到产生购买行为的转化率为20%;说明从浏览到收藏和加入购物车的阶段,是指标提升的重要阶段。运营人员可以着重引导用户对商品进行收藏和加入购物车。
(4)客户价值分析(RFM分析):
from datetime import datetime
# 最近一次购买距离现在的天数
recent_buy = df[df['behavior_type']=='4'].groupby('user_id')['date'].\
apply(lambda x:datetime(2014,12,20) - x.sort_values().iloc[-1]).reset_index().\
rename(columns={'date':'recent'})
recent_buy['recent'] = recent_buy['recent'].apply(lambda x: x.days)
recent_buy[:10]
# 购买次数计算
freq_buy = df[df['behavior_type']=='4'].groupby('user_id')['date'].count().reset_index().\
rename(columns={'date':'freq'})
freq_buy[:10]
# 将上述两列数据,合并起来
rfm = pd.merge(recent_buy,freq_buy,on='user_id')
rfm[:10]
rfm.describe()
# 给不同类型打分
r_bins = [0,3,5,8,10,35]
f_bins = [1,3,7,9,20,900]
rfm['r_score'] = pd.cut(rfm['recent'],bins=r_bins,labels=[5,4,3,2,1],right=False).astype('float')
rfm['f_score'] = pd.cut(rfm['freq'],bins=f_bins,labels=[1,2,3,4,5],right=False).astype('float')
rfm.head(5)
rfm.describe()
rfm['r'] = np.where(rfm['r_score']>rfm['r_score'].mean(),'高','低')
rfm['f'] = np.where(rfm['f_score']>rfm['f_score'].mean(),'高','低')
rfm['value'] = rfm['r'].str[:] + rfm['f'].str[:]
rfm.head(5)
def trans_labels(x):
if x == '高高':
return '重要价值客户'
elif x == '低高':
return '重要唤回客户'
elif x == '高低':
return '重要深耕客户'
else:
return '重要挽回客户'
rfm['标签'] = rfm['value'].apply(trans_labels)
rfm['标签'].value_counts()
结果如下:
绘图:
plt.figure(figsize=(6,6),dpi=100)
labels = ['重要价值客户','重要唤回客户','重要深耕客户','重要挽回客户']
explode = (0.1, 0, 0.1, 0)
plt.pie(rfm['标签'].value_counts(),explode=explode,labels=labels,shadow=True,
startangle=90,autopct='%1.1f%%')
plt.show()
绘图结果如下:
结果分析:所有用户群体里面重要价值客户占38.6%,可针对这部分用户的用户行为分析有价值的用户特征;重要唤回客户占比达到28.6%,运营方面应该多加注意这一部分用户的需求;重要深耕客户占21.9%;重要挽回客户占10.9%。