参考:https://zhuanlan.zhihu.com/p/82130467
提出问题及本项目思路
数据预处理
#数据处理包
import pandas as pd
import numpy as np
#数据可视化
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
from pyecharts import options as opts
from pyecharts.charts import Bar,Pie
from pyecharts.globals import ChartType, SymbolType
#时间处理包
import datetime
import time
#字体设置
plt.rcParams['font.sans-serif']=['SimHei']
df0=pd.read_csv('D:tianchi_mobile_recommend_train_user.csv',)
df0.info() #查看数据类型用df.dtypes
数据集一共12312542个值,user_geohash列的缺失值8402567,直接删除该列并不影响;本项目选取前1000000条数据进行分析
df1=df0.head(100000)
df1.info()
df1.head()
df1['behavior_type']=df1['behavior_type'].astype(str).map({
'1':'pv',
'2':'buy',
'3':'cart',
'4':'fav'})
#'behavior_type'列中的1-4,分别表示点击pv、购买buy、加购物车cart、喜欢fav
df1.head()
df1.drop_duplicates(subset=['user_id','item_id','time'],keep='first',inplace=True)
df1.info()
#重复值去除:本项目根据的是['user_id','item_id','time']来去重的【重复项1000000-913553】
df1['time']=pd.to_datetime(df1['time']) #将time列,由str转换为时间格式
df1.head()
#后续分析维度:周几、几点,所以要建立相关新列来存放具体的时间
df1['week']=df1['time'].dt.weekday #date.weekday()返回的0-6代表周一到周日
df1['day']=df1['time'].dt.day
df1['hour']=df1['time'].dt.hour
df1.head()
#将time列,分拆出date列并单独存放
df1['date']=df1['time'].astype(str).str.split(' ').apply(lambda x :x[0])
df1['date']=pd.to_datetime(df1['date'])
df1.info()
数据分析
二级标题
#一周活跃时间段:绘图
df1.groupby('week')['user_id'].count().plot()#date.weekday()返回的0-6代表周一--到周日
#一天时间段活跃度分布
df1.groupby('hour')['hour'].count().plot()
PV和UV的分析
#PV和UV的分析
df1.groupby(['date'])['user_id'].count().plot()
df1.groupby(['date','user_id']).count().reset_index().groupby('date')['user_id'].count().plot()
#用户PV和UV对应的小时活跃度
df1.groupby('hour')['user_id'].count().plot()
df1.groupby(['hour','user_id']).count().reset_index().groupby('hour')['user_id'].count().plot()
#用户不同行为的时间活跃度
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5))
#plt.plot(df1.groupby(['behavior_type'])['hour'].value_counts()['pv'].sort_index())
plt.plot(df1.groupby(['behavior_type'])['hour'].value_counts()['cart'].sort_index(),label = 'cart')
plt.plot(df1.groupby(['behavior_type'])['hour'].value_counts()['fav'].sort_index(),label = 'fav')
plt.plot(df1.groupby(['behavior_type'])['hour'].value_counts()['buy'].sort_index(),label = 'buy')
plt.legend()
plt.show()
#可以看出除了pv比较高,其它的行为都相差不大,用户的转化不高,我们接下来看看转化率
#用户购买的行为频数分布(用户购买次数分布)
df1[df1['behavior_type']=='buy'].groupby('user_id')['behavior_type'].count().reset_index().groupby('behavior_type')['user_id'].count().plot()
import seaborn as sns
freq=df1[df1['behavior_type']=='buy'].groupby('user_id')['behavior_type'].count()
sns.distplot(freq,kde=False)
plt.title('用户购买次数分布')
df1[df1['behavior_type']=='buy'].groupby('user_id')['behavior_type'].count().reset_index().groupby('behavior_type')['user_id'].count().head(20)
- 购买次数集中在1-7之间的均超过百人。用户购买欲望还可以刺激,可以利用各种补贴、活动、推荐等来提高消费次数。
用户行为转化漏斗
from pyecharts import options as opts
from pyecharts.charts import Bar,Pie
from pyecharts.globals import ChartType, SymbolType
from pyecharts.charts import Funnel
from pyecharts.charts import Bar #正确的引用方式
Funnel_behavior=df1.groupby(['behavior_type'])['user_id'].count().reset_index().rename(columns={'user_id':'Count'}).sort_values(by='Count',ascending=False)
value=Funnel_behavior['Count'].tolist()
x=Funnel_behavior['behavior_type'].tolist()
c=Funnel()
c.add('',[list(z) for z in zip(Funnel_behavior['behavior_type'],Funnel_behavior['Count'])],label_opts=opts.LabelOpts(position="inside"))
c.set_global_opts(title_opts=opts.TitleOpts(title="用户行为转化漏斗"))
c.render_notebook()
- 用户行为pv到cart的转化率极低(仅3%=25792 / 862526),想要提高转化率至少应该提高用户加入购物车的概率,说明推荐商品的准确率有点低,提高推荐精准率;
- 用户行为cart到buy达到了65%(=17164 / 25792),说明用户加入购物车后、购买率还是挺高的。
日平均用户消费金额
#因为没有金额,所以本项目添加随机产生的金额上去
random_price=[np.random.randint(0,1000) for i in range(len(df1['user_id']))]
df1['product_price']=pd.Series(random_price)
#对缺失值进行填充
df1['product_price'].fillna(df1['product_price'].mean(),inplace=True)
#np.random.randint(0,1000) 会产生空值??
Arppu=df1[df1['behavior_type']=='buy'].groupby('date').agg({'product_price':'sum','user_id':'count'})
#Arppu.apply(lambda x :round(x['product_price']/x['user_id']),axis=1).plot()
c=Bar()
c.add_xaxis(Arppu.index.tolist())
c.add_yaxis('ARPPU平均每付费用户收入',Arppu.apply(lambda x :round(x['product_price']/x['user_id']),axis=1).tolist())
c.render_notebook()
- 因为随机产生的金额而非真实数据,故上图整体波动不大
RFM模型
rfm=df1.pivot_table(index='user_id',
values=['date','item_id','product_price'],
aggfunc={
'date':'max',
'item_id':'count',
'product_price':'sum'
})
rfm.head()
#将R转化为天数
rfm['R']= -(rfm['date'] - rfm['date'].max())/np.timedelta64(1,'D')
rfm.rename(columns={'item_id':'F','product_price':'M'},inplace=True)
rfm.head()
def rfm_func(x):
level=x.apply(lambda x:'1' if x>=0 else '0')
label=level.R+level.F+level.M
d={
'111':'重要价值客户',
'011':'重要保持客户',
'101':'重要挽留客户',
'001':'重要发展客户',
'110':'一般价值客户',
'010':'一般保持客户',
'100':'一般挽留客户',
'000':'一般发展客户'
}
result=d[label]
return result
rfm['label'] = rfm[['R','F','M']].apply(lambda x : x-x.mean()).apply(rfm_func,axis=1)
#lambda x :rfm_func(x)
rfm.head()
rfm_data=rfm.groupby('label')['R'].count().reset_index().rename(columns={'R':'peoplecount'})
rfm_data
#绘制饼图
from pyecharts.charts import Page,Pie
x = rfm_data['label'].tolist()
y = rfm_data['peoplecount'].tolist()
c=Pie()
c.add('',[list(z) for z in zip(x, y)],radius=["50%", "70%"])
c.set_global_opts(title_opts=opts.TitleOpts(title="Pie-基本示例"),legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"))
c.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
c.render_notebook()
复购率
data_rebuy = df1[df1['behavior_type']=='buy'].groupby('user_id')['time'].apply(lambda x :len(x.unique()))
#data_rebuy为找出每个用户有消费行为的天数
print('复购率:',round(data_rebuy[data_rebuy>=2].count()/data_rebuy.count(),2))
复购率: 0.65
最受欢迎的商品类目(item_category)与购买率
##按“类目item_category ”统计点击量pv,更改Series名字为'pv_category'
pvtop=df1[df1['behavior_type']=='pv']['item_category'].value_counts().sort_values(ascending=False)
pvtop.name='pv_category'
#按“类目item_category ”统计购买量buy,更改Series名字为'buy_category'
buytop=df1[df1['behavior_type']=='buy']['item_category'].value_counts().sort_values(ascending=False)
buytop.name = 'buy_category'
# 合并(匹配 concat ,axis=1,按行拼接)并绘制散点图:
cattop=pd.concat([pvtop,buytop],axis=1,sort=False).fillna(0)
cattop.plot.scatter(x='pv_category',y='buy_category')
#给series命名是为了在scatter绘图里面x,y坐标轴用
大部门商品类目并没有吸引购买者:
可以看出分布集中在左下角,即大部分商品类目‘item_category’的转化率(pv_category / buy_category)在2%之间。
最受欢迎的商品(item_id)与购买率
#按“商品(item_id)”统计点击量pv,更改Series名字
pv_p_top=df1[df1['behavior_type']=='pv']['item_id'].value_counts().sort_values(ascending=False)
pv_p_top.name='pv_product'
#按“商品(item_id)”统计购买量buy,更改Series名字
buy_p_top=df1[df1['behavior_type']=='buy']['item_id'].value_counts().sort_values(ascending=False)
buy_p_top.name = 'buy_product'
# 合并(匹配 concat ,axis=1,按行拼接)并绘制散点图:
producttop=pd.concat([pv_p_top,buy_p_top],axis=1,sort=False).fillna(0)
producttop.plot.scatter(x='pv_product',y='buy_product')
#给series命名是为了在scatter绘图里面x,y坐标轴用
最受欢迎的商品浏览量在0-200之间、购买数在0-10之间,转化率是5%,用户的购买转化率较低,可以考虑提升一下商品的文案、图片等方面。
点击/购买前十的商品/类目及其购买量
## 点击量前十的商品类目及其购买量
pd.DataFrame(pvtop[:10]) # pv前十的类目,并转化为数据框df
# join按购买量排序的类目
pd.DataFrame(pvtop[:10]).join(buytop)#或者 df.join(pd.DataFrame(buytop))
#购买量前十的商品类目及其点击量
pd.DataFrame(buytop[:10]).join(pvtop)
#点击量pv前十的商品id和购买量
pd.DataFrame(pv_p_top[:10]).join(buy_p_top)
点击量大、但没人购买的商品(转化率非常不好),可以检查一下该商品的包装、价格等因素
#购买量buy前十的商品id和点击量
pd.DataFrame(buy_p_top[:10]).join(pv_p_top)
总结与结论:
1)基于RFM模型,根据不同类型用户精准运营,进行个性化推荐;
2)根据时间维度进行有效地拉新促活活动,以及老用户的访问。根据复购率来刺激用户的持续消费,根据留存监控用户的持续用户行为,防止流失并且对用户行为给与一定的刺激;
3)对高价值用户需要提供优惠策略使其保持活跃度,针对不同用户行为人群制定针对性策略从而刺激进一步的用户行为,针对不活跃用户以及大部分的低购买用户采取相应措施刺激或者提高活跃度。
4)针对一些转化率低的商品,做好包装、价格、图片等因素的改善,提高转化率
PV和UV的分析
五级标题
- 列表第一项
- 列表第二项
- 有序列表第一项
- 有序列表第二项
标题
[图片上传失败...(image-f4016e-1579525662317)]
斜体
粗体
引用段落