电商用户行为可视化分析

数据集说明

来源:阿里云 天池https://tianchi.aliyun.com/dataset/dataDetail?dataId=46

阿里巴巴提供的移动端淘宝用户的行为数据集,包含2014-11-18至2014-12-18共计一千多万条数据。

字段字段说明提取说明
user_id用户标识抽样&字段脱敏
item_id商品标识抽样&字段脱敏
behavior_type用户对商品的行为类型包括浏览、收藏、加购物车、购买,对应取值分别是1、2、3、4。
user_geohash用户位置的空间标识,可以为空由经纬度通过保密的算法生成
item_category商品分类标识字段脱敏
time行为时间精确到小时级别

分析思路

在这里插入图片描述

结论和建议

流量

1.PV、UV:

  • 非活动期间的PV在40或50万左右,UV在12000到13000之间。双十二当天PV达到80万,UV达到15000以上。活动期PV增长45%,UV增长25%左右,但活动结束后下降较快。
  • PV和UV在一周内有周期性变化,周二到周四的UV、PV最大,且保持稳定。周五最低。

2.新增PV和UV:

  • 总体呈下降趋势,活动前期新增UV保持50-60/天,活动的拉新效果比较稳定,但活动后新增访客快速下降,低至7/天。

3.留存率:

  • 次日留存率基本稳定在0.4到0.7,11.23到11.27、12.6的次日留存率过低。
  • 三日留存率基本稳定在0.6到0.8,12.7的数据过低。
  • 七日留存率较高,基本在0.7以上,12.1的数据过低。
  • 12月的留存率增长明显,可见双十二活动提高了留存率,但活动过后的留存率没有增长。

建议:

  • 对周五PV、UV低的情况,需要更长时间的数据分析其原因,建议结合用户行为和商品情况做进一步分析,是否可以提高周五的PV、UV。

  • 12.1到12.6的新增UV下降,但是新增PV维持稳定;12.18以后新增PV下降显著,建议对这两部分用户做进一步分析,为后续拉新和提升PV作参考。

  • 对于留存率过低的时间,建议分析原因,是否存在消息提醒不足或用户体验不佳等问题。

  • 建议关注活动后的留存率变化情况,通过会员、签到奖励等方式提高留存率。

消费习惯

1.每日用户行为:

  • 浏览、收藏、加购物车同样存在周期变化,但不明显。非活动期的用户行为数据稳定。
  • 活动期里,购买增加只在12,12当天。从12.10开始,收藏、加购物车显著增加,也就是说用户活跃期只有3天。

2.日均各时段用户行为:

  • 12.12当天,用户使用时间主要在20到零点,零点的购买、加购物车达到峰值。
  • 非活动期间,浏览、收藏、加购物车主要在18到23点,18到21点处于上升期。购买行为集中在10到23点,18点后有略微上升,21点是购买峰值。购买量受日均时段影响较小。

3.15天内复购率:

  • 非活动期的复购率一直在0.17到0.2之间,12.12当天达到0.45,说明活动前15天的购买转化效果比较明显。
  • 12.5到12.11的复购率明显较低,可能和后面的双十二活动有关,因为活动前的新增用户增加了,同时大多数会在活动当天购买,所以这几天复购率有所下降。
    活动过后的复购率仍在0.2左右,没有提高。

4.日均各时段购买率:

  • 用户总体购买率为88.27%。
  • 相比非活动期,12.12当天的购买率增加了10%左右。3到16点一直在0.2左右,17点下降了5%,随后开始增加,在零点达到峰值0.44,23-1点是购买高峰期。
  • 非活动期的购买高峰期在10到22点,购买率峰值在21点,其中18点下降显著,和用户作息时间有关。因此商品投放和促销活动应重点关注10-22点这段时间,尤其是18-21点。

建议:

  • 1.活动前的用户活跃期只有3天,建议延长活动预热时间,比如从12.5就开始,有利于提高新增用户和活跃率,对活动更有利。
  • 2.商品投放和促销活动应重点关注10-22点这段时间,尤其是18-21点,促销活动建议在19-23点间进行。
  • 3.购买量受日均时段影响较小,可分析各商品在不同时段的购买转化率,针对不同时段投放转化率相对高的商品。
  • 4.关注活动过后的复购率变化,趁活动余热未过、新增用户量还没流失,建议做新的活动和优惠方案,进一步提高用户粘性和复购率。

转化率

1.用户行为转化漏斗

  • 非活动期,从浏览到加购物车、收藏或购买的转化率分别为:4.46%、3.27%、1.4%,活动期的分别是5.59%、3.39%、2.38%。
  • 相比非活动期,活动期的各阶段的总体转化率提高了1%左右,效果不是很明显。

2.登陆天数与转化率

  • 加购物车和收藏的转化率随登陆天数增加,提高用户登陆天数,可促进加购物车和收藏的转化率,登陆6天的用户此指标异常,建议进一步分析寻找原因。
  • 浏览-购买转化率、加购或收藏-购买转化率随用户登陆天数减小,尤其在登陆19天后,购买转化率下降明显,可能和双十二活动后购买率显著下降有关。
  • 用户登陆5天后的购买转化率明显上升,登陆5-19天的用户购买转化率较高。
  • 由于受双十二活动影响,此处的分析不能准确表明常规时期的登陆天数与转化率关系,需要更长时间的数据作进一步分析。

建议:

  • 1.活动期的各阶段的总体转化率提高了1%左右,效果不明显。建议进一步分析用户不同的行为路径以及阶段转化率,比如浏览-购买、收藏-购买、加购物车-购买的转化率,再决定从哪一阶段提高转化率。
  • 2.登陆5-19天的用户购买转化率较高,建议让用户登录时间达到5天及以上,可以通过发放优惠券、发送提醒、签到奖励等方式进行。
  • 3.登陆6天的用户购物车和收藏的转化率过低,建议从商品投放和推送分析原因。

商品偏好:

1.浏览,收藏,加购物车,购买的前十名的商品类别:

  • 各阶段的品类重合度在50%左右,有些浏览、收藏、加购很高的品类,购买量不在前十,比如5027、5894。而有的销量前十的品类,浏览、收藏、加购不在前十,
    比如6344、8877、7957。

2.购物车分析:前20商品及购买转化率

  • 加购物车量与购买率明显不成正比。有的商品购买率低,比如209323160、6703599、382513156。有的商品购买率高但收藏量低,如303205878、289649282、14087919。

3.购买分析:销量前10的商品类别、销量前20的商品

  • 品类分析:活动期和非活动期销量都在前十的品类有5个。活动期1683、6513两个品类的销量显著,其他前十品类的销量差距不大。非活动期1863、6344、5232三个品类的销量显著,其他前十品类的销量差距不大。6513这个品类在活动期销量显著,而平时销量不算高。6344这个品类平时销量很好,而活动期销量不太高。
  • 商品分析:活动期和非活动期销量都在前20的商品只有一个,这说明,活动期和非活动期用户购买的商品差距很大。

4.不同时段销售前十的商品类别:

  • 7-18时和18-24时销量都在前十的品类有8个,可见用户购买何种品类受时段影响不大。如进一步分析,建议查看每个商品日均时段的销量,在不同时段投放销量高的相应品类。

建议:

  • 1.对于浏览、收藏、加购很高,销量低的品类,或浏览、收藏、加购低,销量高的品类,建议结合商品特性进一步分析,是否存在推荐机制准确度不高、商品投放不精准的情况,同时挖掘有潜力的品类。
  • 2.对于购买率低、加购物车多的商品,建议从商品质量特点、用户评价、各销售环节分析原因。对于购买率率高但收藏量低的商品,考虑商品特性,分析推荐机制、投放时段和频率是否有问题,是否增加要曝光率或做主推商品。
  • 6513这个品类在活动期销量显著,而平时销量不算高,建议结合活动期的销售策率和商品特点分析,是否可作为后续活动的主推品类。6344这个品类平时销量很好,而活动期销量不太高,建议分析销售环节是否有问题。
  • 4.针对活动期和非活动期用户购买的商品差距大的情况,除了商品特性和优惠活动的原因外,建议分析平时的推荐机制是否准确。有些商品活动期销量高,而平时的销量不高,比如115052027,对于这样的商品,建议结合商品特点,考虑定价是否合理、是否可以做主推商品或新活动。

数据预处理

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline
plt.style.use('ggplot')    

读取数据

df = pd.read_csv('C:/Users/阿怪不会弹吉他/Desktop/用户行为分析/tianchi_fresh_comp_train_user.csv')
df.head()
user_iditem_idbehavior_typeuser_geohashitem_categorytime
010001082285259775197lk14c40762014-12-08 18
11000108243689071NaN55032014-12-12 12
210001082536167684NaN97622014-12-02 15
31000108299478711NaN28252014-11-28 20
410001082150720867195qoghe32002014-12-15 08

查看数据类型及结构

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15463110 entries, 0 to 15463109
Data columns (total 6 columns):
 #   Column         Dtype 
---  ------         ----- 
 0   user_id        int64 
 1   item_id        int64 
 2   behavior_type  int64 
 3   user_geohash   object
 4   item_category  int64 
 5   time           object
dtypes: int64(4), object(2)
memory usage: 707.8+ MB
df.describe()
user_iditem_idbehavior_typeitem_category
count1.546311e+071.546311e+071.546311e+071.546311e+07
mean7.015207e+072.023169e+081.153780e+006.827181e+03
std4.572019e+071.167524e+085.440445e-013.810410e+03
min4.920000e+023.700000e+011.000000e+002.000000e+00
25%3.021406e+071.014015e+081.000000e+003.687000e+03
50%5.638708e+072.022669e+081.000000e+006.054000e+03
75%1.166482e+083.035247e+081.000000e+001.025800e+04
max1.424430e+084.045625e+084.000000e+001.408000e+04

数据清洗:去重、丢空

#查看缺失值数量
df.isnull().sum()
user_id                0
item_id                0
behavior_type          0
user_geohash     8207386
item_category          0
time                   0
dtype: int64

因为不做地理数据的分析user_geohash 这列的缺失值不做处理

#查看数据重复数量
sum(df.duplicated())
0

数据分析及可视化

1.每日pv(浏览量)、uv(独立用户数)

转换日期格式,提取日期和时间

df['time'] = pd.to_datetime(df['time'])
df['day'] = df.time.dt.date
df['month'] = df.time.dt.month
df['hour'] = df.time.dt.hour
df['day_of_week'] = df.time.dt.weekday
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15463110 entries, 0 to 15463109
Data columns (total 10 columns):
 #   Column         Dtype         
---  ------         -----         
 0   user_id        int64         
 1   item_id        int64         
 2   behavior_type  int64         
 3   user_geohash   object        
 4   item_category  int64         
 5   time           datetime64[ns]
 6   day            object        
 7   month          int64         
 8   hour           int64         
 9   day_of_week    int64         
dtypes: datetime64[ns](1), int64(7), object(2)
memory usage: 1.2+ GB
df.head()
user_iditem_idbehavior_typeuser_geohashitem_categorytimedaymonthhourday_of_week
010001082285259775197lk14c40762014-12-08 18:00:002014-12-0812180
11000108243689071NaN55032014-12-12 12:00:002014-12-1212124
210001082536167684NaN97622014-12-02 15:00:002014-12-0212151
31000108299478711NaN28252014-11-28 20:00:002014-11-2811204
410001082150720867195qoghe32002014-12-15 08:00:002014-12-151280
#查看日期范围
df.time.min(), df.time.max()
(Timestamp('2014-11-18 00:00:00'), Timestamp('2014-12-18 23:00:00'))
1.流量分析
1.1 每日pv,uv

计算每日pv(浏览量),uv(独立用户数)

#计算每日基于pv的用户行为
behavior_type_by_day = df.groupby(['day','behavior_type']).user_id.count()
behavior_type_by_day
day         behavior_type
2014-11-18  1                395982
            2                 13205
            3                 18703
            4                  6115
2014-11-19  1                405103
                              ...  
2014-12-17  4                  6530
2014-12-18  1                459362
            2                 13805
            3                 18095
            4                  6384
Name: user_id, Length: 124, dtype: int64
#每日pv(浏览量)
pv_by_day = behavior_type_by_day.xs(1, level = 1)
#uv(独立用户数)
uv_by_day = df.groupby('day').user_id.nunique()

PV和UV日变化趋势图

#每日用户浏览量变化趋势图
plt.figure(figsize = (18, 10))

plt.subplot(2,1,1)
plt.plot(pv_by_day, linestyle='-.', marker='o')
plt.title('PV by Day')
plt.xlabel('Date')
plt.ylabel('PV')

#每日用户浏览量变化趋势图
plt.subplot(2,1,2)
plt.plot(uv_by_day, linestyle='-.', marker='o')
plt.title('UV by Day')
plt.xlabel('Date')
plt.ylabel('UV')

在这里插入图片描述

1.2 访问深度:PV/UV
pv_uv = pv_by_day/uv_by_day

plt.figure(figsize = (18, 6))
plt.plot(pv_uv, linestyle='-.', marker='o')
plt.title('PV/UV by Day')
plt.xlabel('Date')
plt.ylabel('PV/UV')

在这里插入图片描述

PV、UV从11.10开始上升,在双十二当天达到峰值,11.13开始下降。非活动期间的PV在40或50万左右,UV在12000到13000之间。双十二当天PV达到80万,UV达到15000以上。
同时,可以看出PV和UV呈现周期性的起伏变化,结合用户访问深度,可看出波谷的日期11.21、11.28、12.5都是星期五,因此PV、UV可能是以星期为周期变化。

分析一周中PV和UV的变化趋势
双十二数据量过大,去除该天数据后再分析

import datetime
pv_by_week = df[~df.day.isin([datetime.date(2014,12,12)])].query('behavior_type == 1').groupby('day_of_week').user_id.count()
uv_by_week = df[~df.day.isin([datetime.date(2014,12,12)])].groupby('day_of_week').user_id.nunique()
#一周中用户浏览量变化趋势图
plt.figure(figsize = (18, 10))

plt.subplot(2,1,1)
plt.plot(pv_by_week, linestyle='-.', marker='o')
plt.title('PV by Week')
plt.xlabel('Day of week')
plt.ylabel('PV')

#一周中用户浏览量变化趋势图
plt.subplot(2,1,2)
plt.plot(uv_by_week, linestyle='-.', marker='o')
plt.title('UV by Week')
plt.xlabel('Day of week')
plt.ylabel('UV')

在这里插入图片描述

PV和UV在一周内有周期性变化,周二到周四的UV、PV最大,且保持稳定。周五UV、PV迅速降低,是一周中最低的一天。对周五PV、UV低的情况,需要更长时间的数据分析其原因,同时结合用户行为和商品情况做进一步分析,是否需要提高周五的PV、UV。

1.3 每日新增访客及浏览量
from copy import deepcopy
import datetime

user_pv = df[df.behavior_type == 1]
s = set()
days = []
nums = []
add_pv = []

for date in np.sort(user_pv['day'].unique(), axis = 0):#给日期排序!
    num1 = len(s)
    s1 = deepcopy(s)
    ids = user_pv[user_pv.day == date]['user_id'].values.tolist()#此日的user_id
    
    for i in ids:
        s.add(i)#目前为止所有的user_id
    
    add_users = s - s1#新增访客的id
    add_users_pvs = user_pv[user_pv.user_id.isin(add_users)].groupby('day')['behavior_type'].count()
    add_users_pv = add_users_pvs[date]#获取此日的新增PV
    num2  = len(s)#目前为止的所有访客数
    add_pv.append(add_users_pv)
    days.append(date)
    nums.append(num2-num1)#新增访客数
df_new_uv = pd.DataFrame(data = {'新增访客数': nums, '新增访客的浏览量': add_pv}, index = days)

df_new_uv.iloc[0, :] = [0,0]
df_new_uv
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

plt.figure(figsize = (18,10))

plt.subplot(2, 1, 1)
plt.plot(df_new_uv['新增访客数'].iloc[7:], linestyle='-.', marker='o')
plt.title('每日新增访客')
plt.xlabel('时间')
plt.ylabel('新增访客数')

plt.subplot(2,1,2)
plt.plot(df_new_uv['新增访客的浏览量'].iloc[7:], linestyle='-.', marker='o')
plt.title('每日新增访客的浏览量')
plt.xlabel('时间')
plt.ylabel('新增浏览量')

在这里插入图片描述

由于此数据集的时间较短(仅一个月),所以新增UV计算不准确,仅看11.25后的数据。
新增PV和UV总体呈下降趋势,12.5到12.12期间新增UV较稳定,活动期的拉新效果比较稳定,但活动后流失率较高。
12.1到12.6期间新增UV下降,但是新增PV维持稳定;12.18以后新增PV下降太多,可对这两部分用户做进一步分析,提高后续拉新和PV。

1.4 新增用户留存分析

(次日留存、3日留存、7日留存)
新增用户留存率:首次使用后第N天内有使用行为的用户/首次登录日的用户

#n日留存率函数: 首次使用后第n天内有使用行为的用户/第i天首次登陆的用户

import datetime

import warnings
warnings.filterwarnings('ignore')

def cal_retention(data, n): #n日留存率
    user = []
    retention_rates=[]
    data1 = data[data['behavior_type']==1]#获取浏览行为的所有数据
    date = pd.Series(data1.day.unique()).sort_values()[:-n]#日期截至最后一天的前n天
    
    for i in date:
        new_user = set(data1[data1.day==i].user_id.unique()) - set(user)#获取新用户的id
        
        user.extend(new_user)  #将新用户加入用户集合中
        
        user_nday = data1[data1.day >i][data1.day <= i+datetime.timedelta(n)].user_id.unique()#获取第i+n天内的user_id
        a = 0
        for s in user_nday:
            if s in new_user:#第i+n天内再次登陆的用户数
                a += 1
        retention_rate = a/len(new_user)#第n日留存率        
        retention_rates.append(retention_rate)
    retention = pd.Series(retention_rates, index = date)
    
    return retention 
#新增用户次日、3日、7日留存率
click_r1 = cal_retention(df, 1)
click_r3 = cal_retention(df, 3)
click_r7 = cal_retention(df, 7)

click_retention = pd.concat([click_r1, click_r3, click_r7], axis = 1)
click_retention = click_retention.rename(columns = {0:'次日留存', 1:'三日留存', 2:'七日留存'})
click_retention
#新增用户次日、3日、7日留存率
click_retention.plot(style = '--.',alpha = 0.8,grid = True,figsize = (18,10),
       subplots = True,#是否分别绘制子图,False则绘制在一张图上
       layout = (3,1),#更改子图布局,按顺序填充
       sharex = False)#是否共享坐标

在这里插入图片描述

次日留存率基本稳定在0.4到0.7,11.23到11.27、12.6的次日留存率过低,需进一步分析原因。
三日留存率基本稳定在0.6到0.8,12.7的数据异常,需分析近三日的用户行为。
七日留存率较高,基本在0.8以上,12.1的数据异常,需分析近七日的用户行为。
活动期间的留存率有所增长,但活动后的留存率显著下降,需要提高活动后的留存率。

2.消费习惯
2.1 每日用户行为分析
def behavior_type_by_day(data):

    behavior_type_by_day = data.groupby(['day','behavior_type']).user_id.count()
    click1 = behavior_type_by_day.xs(1, level = 1)
    collect1 = behavior_type_by_day.xs(2, level = 1)
    add_to_cart1 = behavior_type_by_day.xs(3, level = 1)
    payment1 = behavior_type_by_day.xs(4, level = 1)

    pv_by_behavior_type_day = pd.DataFrame({'浏览': click1, '收藏': collect1,  '加购物车': add_to_cart1, '购买': payment1})

    return pv_by_behavior_type_day
df_behavior =  behavior_type_by_day(df)

plt.figure(figsize = (18, 10))

#每日用户行为
plt.subplot(2,1,1)
plt.plot(df_behavior, label = df_behavior.index, linestyle='-.', marker='o')
plt.title('每日用户行为')
plt.xlabel('日期')
plt.ylabel('次数')
plt.legend(df_behavior)

plt.subplot(2,1,2)
plt.plot(df_behavior.iloc[:,1:], label = df_behavior.iloc[:,1:].index, linestyle='-.', marker='o')
plt.title('每日用户行为')
plt.xlabel('日期')
plt.ylabel('次数')
plt.legend(df_behavior.iloc[:,1:])

在这里插入图片描述

用户行为同样有以星期为周期的变化特点,但是不明显。非活动期的数据较稳定。
活动期里,购买增加只在12,12当天。从12.10开始,收藏、加购物车才显著增加,也就是说用户活跃期只有3天,是否可以延长活动预热时间,比如从12.5就开始,有利于提高新增用户和活跃率,对活动更有利。

2.2 日均各时段用户行为(活动期和非活动期)

双十二当天数据量过大,把活动期和非活动期拆开分析:

#不同时段的用户行为分析函数
def behavior_type_by_hour(data):

    behavior_type_by_hour = data.groupby(['hour','behavior_type']).user_id.count()
    click1 = behavior_type_by_hour.xs(1, level = 1)
    collect1 = behavior_type_by_hour.xs(2, level = 1)
    add_to_cart1 = behavior_type_by_hour.xs(3, level = 1)
    payment1 = behavior_type_by_hour.xs(4, level = 1)

    pv_by_behavior_type_hour = pd.DataFrame({'浏览': click1, '收藏': collect1,  '加购物车': add_to_cart1, '购买': payment1})

    return pv_by_behavior_type_hour

活动期间不同时段的用户行为分析

#活动期用户行为
df_activity = df.query('day == datetime.date(2014,12,12)')
a = behavior_type_by_hour(df_activity)

非活动期间不同时段的用户行为分析

#非活动期用户行为
df_noactiv = df[~df.day.isin([datetime.date(2014,12,12)])]
b = behavior_type_by_hour(df_noactiv)
plt.figure(figsize = (18, 10))

#活动期日均各时段用户行为

plt.subplot(2,1,1)
plt.plot(a, label = a.index, linestyle='-.', marker='o')
plt.title('活动期日均各时段用户行为')
plt.xlabel('小时')
plt.ylabel('次数')
plt.xticks(range(0, 24, 1))
plt.legend(a)


#非活动期日均各时段用户行为
plt.subplot(2,1,2)
plt.plot(b, label = b.index, linestyle='-.', marker='o')
plt.title('非活动期日均各时段用户行为')
plt.xlabel('小时')
plt.ylabel('次数')
plt.xticks(range(0, 24, 1))
plt.legend(b)

在这里插入图片描述

#活动期去掉浏览
plt.figure(figsize = (18, 10))

plt.subplot(2,1,2)
plt.plot(a.iloc[:, 1:], label = a.iloc[:, 1:].index, linestyle='-.', marker='o')
plt.title('活动期日均各时段用户行为')
plt.xlabel('小时')
plt.ylabel('次数')
plt.xticks(range(0, 24, 1))
plt.legend(a.iloc[:, 1:])


#非活动期去掉浏览
plt.subplot(2,1,2)
plt.figure(figsize = (18, 6))
plt.plot(b.iloc[:, 1:], label = b.iloc[:, 1:].index, linestyle='-.', marker='o')
plt.title('非活动期日均各时段用户行为')
plt.xlabel('小时')
plt.ylabel('次数')
plt.xticks(range(0, 24, 1))
plt.legend(b.iloc[:, 1:])

在这里插入图片描述
在这里插入图片描述
12.12当天,用户使用时间主要在20到零点,零点的购买、加购物车达到峰值。
非活动期间,浏览、收藏、加购物车主要在18到23点,18到21点处于上升期,因此应重点关注18到21点的商品投放。购买行为集中在10到23点,18点后有略微上升,21点是购买峰值,促销活动可以在19-23点间进行。
购买受日均时段影响较小,可分析各商品在不同时段的购买转化率,针对不同时段投放转化率相对高的商品。

2.3 15天内复购率

当天再次购买的用户数/前15天内购买用户数

#n日复购率函数: 当天再次购买的用户数/前n天内购买用户数

import datetime

import warnings
warnings.filterwarnings('ignore')

def cal_repay(data, n): #n日内复购率
   
    repay_rates=[]
    data1 = data[data['behavior_type'] == 4]#获取购买行为的所有数据
    date = pd.Series(data1.day.unique()).sort_values()[n:]#日期从n天后开始
    
    for i in date:
        user = data1[data1.day==i].user_id.unique()#获取当天购买的用户id
        
        user_n = data1[data1.day < i][data1.day >= i - datetime.timedelta(n)].user_id.unique()#获取在前n天内购买过的user_id
        a = 0
        for s in user_n:
            if s in user:#n天内再次购买的用户数
                a += 1
        repay_rate = a/len(user_n)#n日内复购率        
        repay_rates.append(repay_rate)
    repay = pd.Series(repay_rates, index = date)

    return repay 
repay_15 = cal_repay(df, 15)
repay_15
#15天内复购率
plt.figure(figsize = (18, 6))
plt.plot(repay_15, label = repay_15.index, linestyle='-.', marker='o')
plt.title('15天内复购率')
plt.xlabel('日期')
plt.ylabel('15天内复购率')

在这里插入图片描述

非活动期的复购率一直在0.17到0.2之间,12.12当天达到0.45说明活动前15天的转化效果比较明显。
12.5到12.11的复购率明显较低,可能和后面的双十二活动有关,因为活动前的新增用户增加了,同时大多数会在活动当天购买,所以这几天复购率有所下降。
活动过后的复购率仍在0.2左右,没有提高,是否可借助活动余热未过、新增用户量还没流失,做新的活动和优惠,进一步提高用户粘性和复购率。

用户购买率:产生购买行为的用户/所有用户

pay_user = df.query('behavior_type == 4').user_id.nunique()
toal_user = df.user_id.nunique()

repay_rate = pay_user/toal_user
repay_rate
0.8827

用户总体购买率为88.27%。

2.4 日均各时段购买率
def repay_rate_by_hour(data):
    pay_user = data.query('behavior_type == 4').groupby('hour').user_id.nunique()
    toal_user = data.groupby('hour').user_id.nunique()
    repay_rate = pay_user/toal_user
    return repay_rate
#活动期日均各时段购买率
repay_rate = repay_rate_by_hour(df_activity)
#非活动期日均各时段购买率
repay_rate1 = repay_rate_by_hour(df_noactiv)
plt.figure(figsize = (18, 10))

#活动期日均各时段购买率

plt.subplot(2,1,1)
plt.plot(repay_rate, label = repay_rate.index, linestyle='-.', marker='o')
plt.title('活动期日均各时段购买率')
plt.xlabel('小时')
plt.ylabel('购买率')
plt.xticks(range(0, 24, 1))

#非活动期日均各时段用户行为
plt.subplot(2,1,2)
plt.plot(repay_rate1, linestyle='-.', marker='o')
plt.title('非活动期日均各时段购买率')
plt.xlabel('小时')
plt.ylabel('购买率')
plt.xticks(range(0, 24, 1))

在这里插入图片描述

12.12当天的购买率3到16点一直在0.2左右,17点下降了5%,随后开始增加,在零点达到峰值0.44,23-1点是购买高峰期。相比非活动期,购买率增加了10%左右。
非活动期的购买高峰期在10到22点,购买率峰值在21点,其中18点下降显著,和用户作息时间有关。因此商品投放和促销活动应重点关注10-22点这段时间,尤其是18-21点。

3. 转化分析
3.1 用户行为转化漏斗:

浏览-收藏/加购物车-购买

#活动期总体转化漏斗
import datetime
vr_activity = df.query('day == datetime.date(2014,12,12)').groupby('behavior_type').user_id.count().sort_values(ascending=False)
total_vr = vr_activity/vr_activity[1]
total_vr = total_vr.round(decimals=4) #总体转化率
vr1_activity = pd.DataFrame({'用户行为':['浏览','加购物车','收藏','购买'], '数量':vr_activity, '总体转化率':total_vr })
vr1_activity
用户行为数量总体转化率
behavior_type
1浏览8330191.0000
3加购物车465930.0559
4收藏282340.0339
2购买198110.0238
#转化漏斗图
from pyecharts import Funnel
# 从pyecharts包中导出创建漏斗图的函数

attr = list(vr1_activity.用户行为)
values = list(vr1_activity.总体转化率*100)
funnel1 = Funnel('活动期总体转化漏斗图', title_pos='center')
funnel1.add('用户行为',
            attr,  # 指定属性名称
            values,  # 指定属性所对应的值
            is_label_show=True,  # 确认显示标签
            label_formatter='{b}{c}%',  # 指定标签显示的方式
            label_pos='outside',  # 指定标签的位置,inside,outside
            legend_orient='vertical',  # 指定图例显示的方向
            legend_pos='left')  # 指定图例的位置

funnel1

在这里插入图片描述

vr_noactivity =df[~df.day.isin([datetime.date(2014,12,12)])].groupby('behavior_type').user_id.count().sort_values(ascending=False)
total_vr1 = vr_noactivity/vr_noactivity[1]
total_vr1 = total_vr1.round(decimals=4) #总体转化率
vr1_noactivity = pd.DataFrame({'用户行为':['浏览','加购物车','收藏','购买'], '数量':vr_noactivity, '总体转化率':total_vr1 })
vr1_noactivity
用户行为数量总体转化率
behavior_type
1浏览133204221.0000
3加购物车5935420.0446
2收藏4356680.0327
4购买1858210.0140
#转化漏斗图
from pyecharts import Funnel
# 从pyecharts包中导出创建漏斗图的函数

attr = list(vr1_noactivity.用户行为)
values = list(vr1_noactivity.总体转化率*100)
funnel2 = Funnel('非活动期总体转化漏斗图', title_pos='center')
funnel2.add('用户行为',
            attr,  # 指定属性名称
            values,  # 指定属性所对应的值
            is_label_show=True,  # 确认显示标签
            label_formatter='{b}{c}%',  # 指定标签显示的方式
            label_pos='outside',  # 指定标签的位置,inside,outside
            legend_orient='vertical',  # 指定图例显示的方向
            legend_pos='left')  # 指定图例的位置

funnel2

在这里插入图片描述
非活动期,从浏览到加购物车、收藏或购买的转化率分别为:4.46%、3.27%、1.4%,活动期的分别是5.59%、3.39%、2.38%。
相比非活动期,活动期的各阶段的总体转化率提高了1%左右,效果不是很明显。建议进一步分析用户不同的行为路径以及阶段转化率,比如浏览-购买、收藏-购买、加购物车-购买的转化率,再决定从哪一阶段提高转化率。

3.2 登陆天数与转化率
#每个用户的登陆天数
sign_in = df.query('behavior_type == 1').drop_duplicates(['user_id','day']).groupby('user_id').behavior_type.count()
#每个用户的浏览量
click = df[df.behavior_type.isin([1])].groupby('user_id').behavior_type.count()
#每个用户的收藏或加购次数
collect_or_cart_sum = df[df.behavior_type.isin([2,3])].groupby('user_id').behavior_type.count()
#每个用户的支付次数
pay_sum = df[df.behavior_type.isin([4])].groupby('user_id').behavior_type.count()
#合并
retain_by_day = pd.DataFrame({'登陆天数':sign_in,'click':click,'collect_or_cart':collect_or_cart_sum,'pay':pay_sum})
retain_by_day.head() 
登陆天数clickcollect_or_cartpay
user_id
49214.0202.07.04.0
372617.0196.03.04.0
191377.035.01.0NaN
364658.035.02.01.0
3710123.0679.026.03.0
#按登陆天数计算收藏、加购、购买率
retain_by_day = retain_by_day.fillna(0)
retain_by_day1 = retain_by_day.groupby('登陆天数').sum() 
#计算转化率
retain_by_day1['加购或收藏转化率'] = retain_by_day1['collect_or_cart']/retain_by_day1['click']
retain_by_day1['浏览-购买转化率'] = retain_by_day1['pay']/retain_by_day1['click']
retain_by_day1['加购或收藏-购买转化率'] = retain_by_day1['pay']/retain_by_day1['collect_or_cart']
retain_by_day1.head()
clickcollect_or_cartpay加购或收藏转化率浏览-购买转化率加购或收藏-购买转化率
登陆天数
0.00.00.07.0NaNinfinf
1.01950.0159.0109.00.0815380.0558970.685535
2.07273.0601.0264.00.0826340.0362990.439268
3.011014.0794.0358.00.0720900.0325040.450882
4.016346.01112.0354.00.0680290.0216570.318345
retain_by_day1.iloc[4:,3:].plot(style = '--.',alpha = 0.8,grid = True,figsize = (18,10),
       subplots = True,#是否分别绘制子图,False则绘制在一张图上
       layout = (3,1),#更改子图布局,按顺序填充
       sharex = False)#是否共享坐标

在这里插入图片描述

加购物车和收藏的转化率随登陆天数增加,提高用户登陆天数,可促进加购物车和收藏的转化率,登陆6天的用户此指标异常,建议进一步分析寻找原因。
浏览-购买转化率、加购或收藏-购买转化率随用户登陆天数减小,尤其在登陆19天后,购买转化率下降明显,可能和双十二活动后购买率显著下降有关。
用户登陆5天后的购买转化率明显上升,登陆5-19天的用户购买转化率较高,建议让用户登录时间达到5天及以上,可以通过发放优惠券、发送提醒、签到奖励等方式进行。
由于受双十二活动影响,此处的分析不能准确表明常规时期的登陆天数与转化率关系,需要更长时间的数据作进一步分析。

4.商品偏好分析
#商品数量、商品类别数量
df.item_id.nunique(), df.item_category.nunique()
(4758484, 9557)
4.1 不同类别商品的用户行为(top10):

浏览,收藏,加购物车,购买的前十名的商品类别

click_10 = df.query('behavior_type == 1').groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]#浏览前十
collect_10 = df.query('behavior_type == 2').groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]#收藏前十
cart_10  = df.query('behavior_type == 3').groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]#加购前十
pay_10 = df.query('behavior_type == 4').groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]#购买前十

#画图
plt.figure(figsize = (18, 10))

#浏览,收藏,加购物车,购买的前十名的商品类别

plt.subplot(2,2,1)
click_10.plot.barh()
plt.title('浏览前十名的商品类别')
plt.xlabel('浏览量')
plt.ylabel('商品类别')

plt.subplot(2,2,2)
collect_10.plot.barh()
plt.title('收藏前十名的商品类别')
plt.xlabel('收藏量')
plt.ylabel('商品类别')

plt.subplot(2,2,3)
cart_10.plot.barh()
plt.title('加购前十名的商品类别')
plt.xlabel('加购物车量')
plt.ylabel('商品类别')

plt.subplot(2,2,4)
pay_10.plot.barh()
plt.title('购买前十名的商品类别')
plt.xlabel('购买量')
plt.ylabel('商品类别')

在这里插入图片描述
对比各阶段TOP10品类的重合度在50%左右,有些浏览、收藏、加购很高的品类,购买量不在前十,比如5027、5894。而有的销量前十的品类,浏览、收藏、加购不在前十,
比如6344、8877、7957。
建议结合商品特性进一步分析,是否存在推荐机制准确度不高、商品投放不精准的情况。

4.2 购物车分析:前20商品及购买转化率
#加购物车前20的商品
cart_item_20  = df.query('behavior_type == 3').groupby('item_id').item_id.count().sort_values(ascending=False).iloc[:20]
#购买转化率
cart_user_20 = cart_item_20.index
pay_df = df.query('behavior_type == 4')
pay_item_20 = pay_df[pay_df.item_id.isin(cart_user_20)].groupby('item_id').item_id.count()#加购物车前20的商品的销量
cart_20 = pd.DataFrame({'加购物车量':cart_item_20, '销量':pay_item_20})
cart_20['购买率'] = cart_20['销量']/cart_20['加购物车量']
#画图:不同商品及购买转化率(top20)

fig,axes = plt.subplots(2,1, figsize=(18,10))

cart_20.sort_values('加购物车量', ascending=False)[['加购物车量', '销量']].plot(ax = axes[0], kind='bar',title = '购物车前20商品及销量')

cart_20.sort_values('加购物车量', ascending=False)['购买率'].plot(ax = axes[1], kind='bar')
plt.title('购物车前20商品的购买率')
plt.xlabel('商品id')
plt.ylabel('购买率')
fig.tight_layout()

在这里插入图片描述

加购物车与购买率明显不成正比。对于购买率低的商品,比如209323160、6703599、382513156,建议从商品质量特点、用户评价、各销售环节分析原因。对于转化率高但收藏量低的商品,如303205878、289649282、14087919,考虑商品特性,分析推荐机制、投放时段和频率是否有问题,是否增加要曝光率或做主推。

4.3 购买分析:
销量前10的商品类别、销量前20的商品
#活动期:
#销量前10的商品类别
pay_activity = df.query('behavior_type == 4').query('day == datetime.date(2014,12,12)')
pay_category_10 = pay_activity.groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]
#销量前20的商品
pay_id_10 = pay_activity.groupby('item_id').item_id.count().sort_values(ascending=False).iloc[:20]
#非活动期
pay_noactiv = df[~df.day.isin([datetime.date(2014,12,12)])].query('behavior_type == 4')
#销量前10的商品类别
pay_category_10_no = pay_noactiv.groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]
#销量前20的商品
pay_id_10_no = pay_noactiv.groupby('item_id').item_id.count().sort_values(ascending=False).iloc[:20]


#画图:销量前10的商品类别、销量最高品类中的前20种商品
plt.figure(figsize = (18, 10))

plt.subplot(2,2,1)
pay_category_10.plot.barh()
plt.title('活动期销量前10的商品类别')
plt.ylabel('商品类别')

plt.subplot(2,2,2)
pay_id_10.plot.barh()
plt.title('活动期销量前20的商品')
plt.ylabel('商品id')

plt.subplot(2,2,3)
pay_category_10_no.plot.barh()
plt.title('非动期销量前10的商品类别')
plt.ylabel('商品id')
plt.ylabel('商品类别')

plt.subplot(2,2,4)
pay_id_10_no.plot.barh()
plt.title('非活动期销量前20的商品')
plt.ylabel('商品id')

在这里插入图片描述
在这里插入图片描述
品类分析:活动期和非活动期销量都在前十的品类有5个。活动期1683、6513两个品类的销量显著,其他前十品类的销量差距不大。非活动期1863、6344、5232三个品类的销量显著,其他前十品类的销量差距不大。6513这个品类在活动期销量显著,而平时销量不算高,建议结合活动期的销售策率和商品特点分析,是否可作为后续活动的主推品类。6344这个品类平时销量很好,而活动期销量不太高,建议分析销售环节是否有问题。

商品分析:活动期和非活动期销量都在前20的商品只有一个,这说明,活动期和非活动期用户购买的商品差距很大,除了商品特性和优惠活动的原因外,建议分析平时的推荐机制是否准确。有些商品活动期销量高,而平时的销量不高,比如115052027,对于这样的商品,建议结合商品特点,考虑定价是否合理、是否可以做主推或新活动。

商品重合度分析

pay_category = pd.concat([pay_category_10, pay_category_10_no], axis = 1).dropna()#销量前十的重合品类
pay_id = pd.concat([pay_id_10, pay_id_10_no], axis = 1).dropna()#销量前十的重合商品
pay_category.columns = ['活动期', '非活动期']

fig,axes = plt.subplots(1,2, figsize=(18,6))
pay_category.plot(ax = axes[0], kind='bar',title = '活动期和非活动期销量前十的品类')


pay_id.plot(ax = axes[1], kind='bar',title = '活动期和非活动期销量前20的商品')
plt.xlabel('商品id')
plt.ylabel('销量')
plt.legend(['活动期','非活动期'])

不同时段销售前十的商品类别:

根据日均各时段用户行为分析,7-18时、18-0时为用户活跃时段,故分析这两个时段的商品销量。

#7-18时销售前十的商品类别
pay_df = df.query('behavior_type == 4')
pay_7_18 = pay_df.query('hour >= 7').query('hour <= 18').groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]
#18-0时销售前十的商品类别
hour_18_0 = [18,19,20,21,22,23,0]  
pay_18_0 = pay_df[pay_df.hour.isin(hour_18_0)].groupby('item_category').item_id.count().sort_values(ascending=False).iloc[:10]
#画图:不同时段销售前十的商品类别:
plt.figure(figsize = (18, 6))


plt.subplot(1,2,1)
pay_7_18.plot.barh()
plt.title('7-18时销售前十的商品类别')
plt.ylabel('商品类别')

plt.subplot(1,2,2)
pay_18_0.plot.barh()
plt.title('18-0时销售前十的商品类别')
plt.ylabel('商品类别')

pay_7_0 = pd.concat([pay_7_18 , pay_18_0], axis = 1).dropna()#销量前十的重合商品类别
pay_7_0.columns = ['7-18时','18-24时']

#画图
pay_7_0.plot(kind='bar',title = '7-18时和18-24时销量前十的品类',figsize = (12,6))

在这里插入图片描述
在这里插入图片描述

7-18时和18-24时销量都在前十的品类有8个,可见用户购买何种品类在不同时段的变化不大。如进一步分析,建议查看每个商品日均时段的销量,在不同时段投放销量高的相应品类。

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值