Python|是不是感觉被淘宝监控了!看啥立马就推送过来!用Python对淘宝用户行为进行分析!
一、认识数据
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: 用户行为发生的时间戳
2.1 用户行为方面
- 页面浏览量PV和独立访客数UV如何变化?和时间有关系吗?
- 用户的平均访问深度是多少?平台的跳失率怎么样?
- 用户从浏览到购买会经历哪些过程?最终的转化率如何?
- 平台用户留存率怎么样?
- 平台的用户付费率是多少?用户复购的情况怎么样?
- 平台商品销售情况是怎么样?
- 商品销售之间有没有一定的联系?
- 如何判断用户价值?针对不同用户如何采取不同的运营策略?
三、数据处理 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 = https://www.it610.com/article/data[(data['date'] >= '2017-11-25') & (data['date'] <= '2017-12-03')] data = https://www.it610.com/article/data.sort_values(by = ['time','user_id'], ascending=True) data = https://www.it610.com/article/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日这个周末的行为数比上个周末多很多,核实是否平台在这个周末有做了促销活动。
接下来按照时间点分析用户的行为习惯:
【Python|是不是感觉被淘宝监控了!看啥立马就推送过来!用Python对淘宝用户行为进行分析!】
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=https://www.it610.com/article/pv_detail,hue='behaviour_type',x='hour',y='total_pv')
?
文章图片
文章图片
??另外三条不是很清晰,再画一次。
plt.subplots(figsize = (10,5)) sns.pointplot(data=https://www.it610.com/article/pv_detail[pv_detail.behaviour_type!='pv'],hue='behaviour_type',x='hour',y='total_pv')
?
文章图片
文章图片
?? 四种用户行为的波动情况基本一致,其中浏览页面pv数远大于其他三项,用户加购物车、收藏和购买数依次降低,可以通过漏斗模型整体分析用户转化情况。
data['behaviour_type'].value_counts().sort_values()
buy24363 fav33294 cart66145 pv1075608 Name: behaviour_type, dtype: int64
from pyecharts import Funnel attrs = ['pv','cart','fav','buy'] attr_value = https://www.it610.com/article/[1075608,66145,33294,24363] fun= Funnel("用户行为漏斗图",title_pos='center') fun.add(name="商品交易环节",# 指定图例名称 attr=attrs,# 指定属性名称 value = https://www.it610.com/article/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
uv11675 pv11636 cart8775 fav4603 buy8007 dtype: int64
attrs = ['uv','pv','cart','fav','buy'] attr_value = https://www.it610.com/article/uniqueuser.values fun1= Funnel("用户行为漏斗图",title_pos='center') fun1.add(name="商品交易环节",# 指定图例名称 attr=attrs,# 指定属性名称 value = https://www.it610.com/article/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 12699 21876 31253 4742 5460 6299 7209 8123 985 1058
?
文章图片
文章图片
??由上图可知,购买次数为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 10012 21 11741 51 61 .. 1017938159471 1017960159504 159512 1017972159544 1017997159566 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 自取即可,对于这快有疑问的,有不会的小伙伴可以直接进去提问哈!
小编看到会第一时间回复大家!
如果觉得此篇文章对你有帮助记得给小编点赞评论哦!能转发一下就更好拉!谢谢大家!
推荐阅读
- python学习之|python学习之 实现QQ自动发送消息
- 逻辑回归的理解与python示例
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- Python基础|Python基础 - 练习1
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- 不让记忆、感觉、情绪成为孩子的负累|不让记忆、感觉、情绪成为孩子的负累|《全脑教养法》(四)
- Python(pathlib模块)
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- Python数据分析(一)(Matplotlib使用)