是不是感觉被淘宝监控了!看啥立马就推送过来!用Python对淘宝用户行为进行分析!

Python 专栏收录该内容
141 篇文章 3 订阅

一、认识数据 

1.1 数据来源及介绍 

本数据来源于阿里云天池,是其随机选择约100万用户在2017年11月25日至12月3日之间发生的行为记录,具有包括点击、购买、加购物车和收藏商品的行为。

数据集的每一行表示一条用户行为,由用户ID、商品ID、商品类目ID、行为类型和时间戳组成,并以逗号分隔。 

 数据链接:https://tianchi.aliyun.com/dataset/dataDetail?dataId=649 

1.2 数据格式

字段说明:

  • User ID: 用户ID
  • Item ID: 商品ID
  • Category ID: 商品所属品类ID
  • Behavior type: 用户行为类型(pv=访问,fav=收藏,cart=加购物车,buy=支付)
  • Timestamp: 用户行为发生的时间戳

二、提出问题

所给数据集只有5个字段、时间维度限制在9天内、商品数据均为脱敏数据、行为数据只有4种,具有一定的局限性。结合电商平台分析指标和AARRR漏斗分析模型,比较有分析价值的是用户行为和时间这两个维度。可以初步计划从用户行为习惯、用户消费习惯和用户价值等方分析。

2.1 用户行为方面

  • 页面浏览量PV和独立访客数UV如何变化?和时间有关系吗?
  • 用户的平均访问深度是多少?平台的跳失率怎么样?
  • 用户从浏览到购买会经历哪些过程?最终的转化率如何?
  • 平台用户留存率怎么样?

2.2 用户消费方面

  • 平台的用户付费率是多少?用户复购的情况怎么样?
  • 平台商品销售情况是怎么样?
  • 商品销售之间有没有一定的联系?

2.3 用户价值方面

  • 如何判断用户价值?针对不同用户如何采取不同的运营策略?

将上述问题整理如下,便于之后有针对性的进行分析:

三、数据处理

3.1 数据导入

用python导入前120万条数据,原数据没有列名,导入的时候加上对应的列名。

​​查看数据类型,是否有缺失值,重复值。

​​data.isnull().any()
data.duplicated().sum()

3.2数据整理 

数据集原有的时间列采用时间戳存储,为了方便后续分析,这里将原有时间戳转为北京时间,并从中抽取出日期、时间和小时数据。

同时将date列转换为时间类型,我们研究的是从2017年11月25日至2017年12月3日之间的行为数据,挑选出这一区间的数据。最后按照user_id和时间进行排序。

import datetime 
data['time']=pd.to_datetime(data['time'],unit='s')+datetime.timedelta(hours=8)
data['date']=data['time'].map(lambda x:x.strftime('%Y-%m-%d %H').split(' ')[0])
data['hour']=data['time'].map(lambda x:x.strftime('%Y-%m-%d %H').split(' ')[1])
data['date']=pd.to_datetime(data['date'])
data = data[(data['date'] >= '2017-11-25') & (data['date'] <= '2017-12-03')]
data = data.sort_values(by = ['time','user_id'], ascending=True)
data = data.reset_index(drop=True)
data

​​

四、数据分析

(一)用户行为习惯分析

4.1.1 页面访问量PV和独立访客数UV

下面按照日期分析UV、PV的变化趋势:

#pv_daily记录每天用户操作次数,uv_daily记录每天不同的上线用户数量
pv_daily=data.groupby('date')['user_id'].count().reset_index().rename(columns={'user_id':'pv'})
uv_daily=data.groupby('date')['user_id'].apply(lambda x:x.drop_duplicates().count()).reset_index().rename(columns={'user_id':'uv'})
x=pv_daily["date"]
y1=pv_daily["pv"]
y2=uv_daily["uv"]
plt.figure(figsize=(10,6))
plt.plot(x,y1,label="pv")
plt.legend(loc=6)
plt.twinx()
plt.plot(x,y2,label="uv",color='r')
plt.legend()

​​

从折线图可以看出: 用户行为的基本规律是周末的数量高于工作日,周一,二相对而言行为数量较少。

这跟大部分人的工作休息时间相符。周末休息,有更多的时间用于网购。但12月2日和12月3日这个周末的行为数比上个周末多很多,核实是否平台在这个周末有做了促销活动。 

 接下来按照时间点分析用户的行为习惯: 

pv_hour=data.groupby('hour')['user_id'].count().reset_index().rename(columns={'user_id':'pv'})
uv_hour=data.groupby('hour')['user_id'].apply(lambda x:x.drop_duplicates().count()).reset_index().rename(columns={'user_id':'uv'})
x=pv_hour["hour"]
y1=pv_hour["pv"]
y2=uv_hour["uv"]
plt.figure(figsize=(10,6))
plt.plot(x,y1,label="pv")
plt.legend(loc=6)
plt.twinx()
plt.plot(x,y2,label="uv",color='r')
plt.legend(loc=2)

​​从上图可发现:从19点开始用户行为数稳步上升,21、22点是一天的最高峰,23点开始有所下滑,1点至7点之间用户行为数都很少,7点后缓慢上升,到中午13点左右有一个小高峰,然后17、18点是个低谷。

这跟人们的睡眠、通勤、吃饭等时间点比较吻合,所以平台上新或者开展活动时间最好根据用户行为习惯,选择20点至23点之间的流量高峰期。 

4.1.2 平均访问深度和跳失率

uv_count = data.user_id.nunique()
pv_count = data[data.behaviour_type == 'pv'].shape[0]
print('平均访问深度是 %.1f' % (pv_count / uv_count))
pv_count_perUser = data[data['behaviour_type'] == 'pv'].groupby('user_id')['behaviour_type'].count().reset_index().rename(columns = {'behaviour_type':'pv_count'})
# 计算只浏览过一次界面的用户数量
bounce_user_count = pv_count_perUser[pv_count_perUser['pv_count'] == 1].shape[0]
print('跳失率是 %.3f%% ' % (100 * (bounce_user_count / uv_count)))

平均访问深度是 92.1 跳失率是 0.086% 

 可以得到用户的平均访问深度为92.1,也就是说在11月25到12月3日9天内平均每个用户每天要访问10个界面,可见淘宝用户粘度很高。 

 按照 跳失率=只浏览一次界面/总用户 计算的话,发现Bounce Rate 只有 0.086% 左右,平台整体流失率相当低。

4.1.3 用户转化情况

了解一下用户浏览、收藏、加购物车和购买行为的整体分布趋势。

#不同行为类型用户pv分析
import seaborn as sns
pv_detail=data.groupby(['behaviour_type','hour'])['user_id'].count().reset_index().rename(columns={'user_id':'total_pv'})
plt.subplots(figsize = (10,5))
sns.pointplot(data=pv_detail,hue='behaviour_type',x='hour',y='total_pv')

​​另外三条不是很清晰,再画一次。

plt.subplots(figsize = (10,5))
sns.pointplot(data=pv_detail[pv_detail.behaviour_type!='pv'],hue='behaviour_type',x='hour',y='total_pv')

​​ 四种用户行为的波动情况基本一致,其中浏览页面pv数远大于其他三项,用户加购物车、收藏和购买数依次降低,可以通过漏斗模型整体分析用户转化情况。

data['behaviour_type'].value_counts().sort_values()
buy       24363
fav       33294
cart      66145
pv      1075608
Name: behaviour_type, dtype: int64

from pyecharts import Funnel
attrs = ['pv','cart','fav','buy']
attr_value = [1075608,66145,33294,24363]
fun= Funnel("用户行为漏斗图",title_pos='center')
 
fun.add(name="商品交易环节",           # 指定图例名称
            attr=attrs,                # 指定属性名称
            value = attr_value,        # 指定属性所对应的值
            is_label_show=True,        # 指定标签是否显示
            label_formatter='{c}%',    # 指定标签显示的格式
            label_pos="outside",        # 指定标签的位置
            legend_orient='vertical',  # 指定图例的方向
            legend_pos='left',         # 指定图例的位置
            is_legend_show=True)       # 指定图例是否显示
 
fun.render()
fun

​​最后购买的转换率为2.27%左右。

统计每个行为的独立用户数,计算是UV到各环节的转化率:

#独立访客数UV
uv=data['user_id'].unique().shape[0]
#有过点击行为的用户数即pv
pv0=data[data["behaviour_type"]=="pv"]["user_id"].drop_duplicates()
pv=pv0.shape[0]
#有过加购物车行为的用户数即cart
cart0=data[data["behaviour_type"]=="cart"]["user_id"].drop_duplicates()
cart=cart0.shape[0]
#有过收藏行为的用户数即fav
fav0=data[data["behaviour_type"]=="fav"]["user_id"].drop_duplicates()
fav=fav0.shape[0]
#有过购买行为的用户数即buy
buy0=data[data["behaviour_type"]=="buy"]["user_id"].drop_duplicates()
buy=buy0.shape[0]
#每个行为的独立用户数
uniqueuser=pd.Series([uv,pv,cart,fav,buy],
                     index=['uv','pv','cart','fav','buy'])
uniqueuser
uv      11675
pv      11636
cart     8775
fav      4603
buy      8007
dtype: int64

attrs = ['uv','pv','cart','fav','buy']
attr_value = uniqueuser.values
fun1= Funnel("用户行为漏斗图",title_pos='center')
 
fun1.add(name="商品交易环节",       # 指定图例名称
            attr=attrs,                # 指定属性名称
            value = attr_value,        # 指定属性所对应的值
            is_label_show=True,        # 指定标签是否显示
            label_formatter='{c}%',    # 指定标签显示的格式
            label_pos="outside",        # 指定标签的位置
            legend_orient='vertical',  # 指定图例的方向
            legend_pos='left',         # 指定图例的位置
            is_legend_show=True)       # 指定图例是否显示
 
fun1.render()
fun1

​​可以看到uv到最终购买的转化率为68.58%,流失率为31.42%。

对于流失率,电商平台要结合行业数据,以及以往数据,分析流失率是否是正常范围。

 上面近32%的“流失用户”中,有的可能在不久的将来还会成为购买用户,因为有的加购或收藏了商品;但是上文提到的“跳失用户”只进行了一次点击,再成为活跃用户的可能性很小。 

(二)用户消费习惯分析

4.2.1 用户付费率PUR(Paying User Rate)

根据 用户付费率 = 有购买记录的用户 / 活跃用户 计算:

 

# 用户付费率分析
paying_user_count = data[data.behaviour_type == 'buy'].user_id.nunique()
 
print('用户付费率是 %.2f%%' % ( 100 * paying_user_count / uv_count))
用户付费率是 68.58%

4.2.2 用户购买次数

根据 总购买次数 / 总付费用户 计算:

# 用户购买次数情况分析
import matplotlib.pyplot as plt
#用户,购买次数
user_buy=data[data.behaviour_type=='buy'].groupby('user_id')['behaviour_type'].count().reset_index().rename(columns={'behaviour_type':'cnt'})
#根据次数再分组画图
ub=user_buy.groupby('cnt')['user_id'].count()
plt.bar(ub.index,ub.values)

cnt
1     2699
2     1876
3     1253
4      742
5      460
6      299
7      209
8      123
9       85
10      58

​​由上图可知,购买次数为1次的用户数量最多

4.2.3 用户复购率

根据 用户复购率 = 多次购买用户数 / 总付费用户 计算:

 

#复购用户数量 通过筛选支付次数>=2 
paying_retention_user_count = user_buy[user_buy['cnt'] >= 2]['user_id'].count()
print('复购率是 %.2f%%' % (100 * paying_retention_user_count / paying_user_count))
复购率是 66.29%

4.2.4 用户复购的间隔时间

#计算用户复购的间隔时间
buy=data[data.behaviour_type=='buy'].groupby(['user_id','date'])['item_id'].count().reset_index()
buy_day=buy.groupby('user_id').date.apply(lambda x:x.diff(1).dropna())
buy_day=buy_day.map(lambda x:x.days)
buy_day

user_id       
100      1        2
         2        1
117      4        1
         5        1
         6        1
                 ..
1017938  15947    1
1017960  15950    4
         15951    2
1017972  15954    4
1017997  15956    6
Name: date, Length: 7951, dtype: int64 

buy_day.value_counts().plot(kind='bar')

​​

4.2.5 商品销售分析

对于一类商品,衡量其市场情况,应该同时分析点击量和购买量。关于这个问题的探讨,先分别按“item_id”和“product_id”统计点击量和购买量,通过散点图看相关性。

(1)先看“item_id”的点击量和购买量整体情况:

pv_item=data[data["behaviour_type"]=="pv"].groupby("item_id")["user_id"].count().sort_values(ascending=False)
buy_item=data[data["behaviour_type"]=="buy"].groupby("item_id")["user_id"].count().sort_values(ascending=False)
merge=pd.merge(pv_item,buy_item,on=["item_id"],how="outer").fillna(0)
x=merge["user_id_x"]
y=merge["user_id_y"]
plt.figure(figsize=(8,6))
plt.scatter(x,y,marker="o")
#商品类目点击量和购买量关系图

​​从点击量和购买量的散点图可以看出,大部分商品类目都是点击量和购买量都比较低,整体是正相关,有少量类目的点击量或购买量很大,或点击量和购买量都比较大。

(2)再看“product_id”的点击量和购买量整体情况:

pv_product=data[data["behaviour_type"]=="pv"].groupby("product_id")["user_id"].count().sort_values(ascending=False)
buy_product=data[data["behaviour_type"]=="buy"].groupby("product_id")["user_id"].count().sort_values(ascending=False)
merge=pd.merge(pv_product,buy_product,on=["product_id"],how="outer").fillna(0)
x=merge["user_id_x"]
y=merge["user_id_y"]
plt.figure(figsize=(8,6))
plt.scatter(x,y,marker="o")

​​同商品类目的情况类似,大部分商品是点击量和购买量都比较低,有一定的相关性,但同时发现点击量大但购买量小的商品较多,即偏右下、偏右中的点,有一个左上角突出的点,表示有一个商品点击量不大但购买量很大。

(3)下面分析商品类目 点击量和购买量的前十:

购买top10

buytop=pd.pivot_table(data,values="user_id",columns="behaviour_type",index="item_id",aggfunc="count").sort_values(by=["buy"],ascending=False).head(10)
buytop['转化率']=buytop['buy']/buytop['pv']
buytop['转化率']=buytop['转化率'].apply(lambda x: format(x, '.2%')) 
buytop

​​

点击top10

pvtop=pd.pivot_table(data,values="user_id",columns="behaviour_type",index="item_id",aggfunc="count").sort_values(by=["pv"],ascending=False).head(10)
pvtop['转化率']=pvtop['buy']/pvtop['pv']
pvtop['转化率']=pvtop['转化率'].apply(lambda x: format(x, '.2%')) 
pvtop 

​​

两表合并

pd.merge(buytop,pvtop,how='inner',on='item_id')

​​

 这6个类目的点击量和购买量都是前十,说明是很受用户欢迎的类目,无疑是重点类目,但发现其实这些类目的转化率也不是很高,电商平台应该重点推送这几类商品,因为这类商品有市场,并且可以多做活动,吸引更多的潜在客户变成购买客户。

 而购买量比较高,但是点击量不突出的这类商品,也许是特定群体非常需要的,他们可能搜索和点击的目标比较明确。电商平台可以收集用户信息,分析用户画像,结合商品特点,核实是否如此。

如果是某类特征明显的用户群体购买更多,可以集中向该类用户多推送。如果没有明显的群体需求,建议对这类商品多做推广,因为原有的购买量就比较高,若是能够提高点击量,可能购买量也会再上一个台阶。 

 但是点击量很高,但购买量偏低的这类商品,应该先从商品本身分析,是否是用户真正需要的。为什么大部分用户点击,但购买较少,是因为价格太高?还是其他原因?调查清楚原因之后再对症下药。

三)用户价值分析 这里利用RFM模型去分析用户价值,以便针对不同用户采取不同措施。

RFM模型的概念如下: R(Recency):客户最近一次交易时间的间隔。R值越大,表示客户交易发生的日期越久,反之则表示客户交易发生的日期越近。

 F(Frequency):客户在最近一段时间内交易的次数。

F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃。

 M(Monetary):客户在最近一段时间内交易的金额。

M值越大,表示客户价值越高,反之则表示客户价值越低。

 由于所给数据集不包含用户购买金额,所以只考虑最近消费时间R和购买频率F,将客户分为重要客户、保持客户、发展客户和挽留客户。 

# 1 R: 最近一次消费距今天数统计
nowDate = datetime.datetime(2017,12,4) # 假定当前时间为(2017,12,4)
user_recent_pay = data[data['behaviour_type'] == 'buy'].groupby('user_id')['date'].apply(lambda x: nowDate - x.sort_values().iloc[-1])
user_recent_pay = user_recent_pay.reset_index().rename(columns={'date':'recent'})
 
# 2 F: 消费次数统计
user_freq = data[data['behaviour_type'] == 'buy'].groupby('user_id').date.count()
user_freq = user_freq.reset_index().rename(columns={'date':'freq'})
 
# 3 通过user_id将R、F合并
rfm = pd.merge(user_recent_pay, user_freq, left_on='user_id', right_on='user_id')
 
# 4 给R、F打分score
rfm['score_recent'] = pd.qcut(rfm['recent'], 2, labels = ['1', '0'])
rfm['score_freq'] = pd.qcut(rfm['freq'], 2, labels = ['0', '1'])
 
# 5 得分拼接
rfm['rfm'] = rfm['score_recent'].str.cat(rfm['score_freq'])
 
# 6 根据RFM分类
rfm = rfm.assign(user_type = rfm['rfm']
           .map({'11':'重要客户', '01':'保持客户', '10':'发展客户', '00':'挽留客户'}))
 
pi=rfm.groupby('user_type')['user_id'].count()
pi
user_type
保持客户     951
发展客户    2131
挽留客户    2444
重要客户    2481

plt.figure(1, figsize=(6,6))
plt.pie([951,2131,2444,2481],labels=['保持客户','发展客户','挽留客户','重要客户'],autopct='%1.2f%%')
plt.title("R F M")

​​

结束

如果还是有小伙伴通过文章感觉没学会的!

需要完整视频教程或者源码的可以点击蓝色字体:点击这里 领取 或者加Q羣:754370353 自取即可,对于这快有疑问的,有不会的小伙伴可以直接进去提问哈!

小编看到会第一时间回复大家!

如果觉得此篇文章对你有帮助记得给小编点赞评论哦!能转发一下就更好拉!谢谢大家!

  • 8
    点赞
  • 7
    评论
  • 17
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值