(数据和教程来自公众号:@秦路)
数据:CDNOW_master.txt(CDNow网站的用户购买明细,包含用户ID,购买日期,购买数量和购买金额四个字段。)
工具:Jupyter Notebook
一、数据读取
函数read_table导入txt格式文件,数据不包含表头,需为表头赋值。原数据以空格隔开,sep为分隔符,\s+表示匹配任意空格。
二、数据概述
从pcs列看出,用户平均购买数量为2.4个,标准差2.3,具有一定的波动性;最小值为1,最大值为99,跨度较大;中位数为2,75分位数为3,说明大多数购买数量很少。 order_amount列显示的趋势和pcs列一致。注意到同一个用户可在一天内购买多次。
数据为69659行×4列,数据类型为数字,没有空值。
user_id:用户ID
order_dt:购买日期
pcs:购买数量
order_amount:购买金额
三、转换格式
order_dt列表示时间,但非时间格式,需要转换数据类型。
增加一列,将第二列字符串转换为时间格式,其中,%Y匹配四位数字%y匹配两位,%m%d各匹配两位,%h小时%M分钟%s秒,若字符串为1997-01-01则用%Y-%m-%d。
增加一列月份,[M]表示月份,则订单的发生时间均显示为每月月初,表示将月份作为消费行为的主要时间窗口。
可见,新增的两列数据格式是datetime64。
四、分析和作图
4.1用户角度
创建一个新对象,根据用户ID分组,并求和,注意到日期格式的列并未执行求和。从用户角度来看,平均消费数量7,标准差较大,有一定浮动;最小值为1,最大值1033,跨度很大,存在狂热用户;中位数5,75分位数7,说明大多数用户总消费量还是比较少。消费金额与消费数量趋势一致。
4.2月份角度
按月份分组,并将购买金额求和。可见,前几个月销量异常高,而后期则非常平稳。
同样地,再将购买数量按月分分组并求和,其趋势与购买金额一致。
4.3散点图
每笔订单散点图,可见样本点大部分分布在Y=0.1X附近,说明每个商品价格在10元左右;订单金额极值很少,大部分在600以下,同样地订单数量极值也很少。
对每个用户绘制散点图,其规律性比单笔订单更强。金额和数量呈线性关系,离群点很少。样本点大多数集中在前半段,说明消费能力特别强的用户不多。
4.4绘制子图
figure为尺寸函数,subplot用于绘制子图,参数121表示1行×2列区域的第一个图,122表示第二个图。第一个直方图显示大部分订单金额较小,第二个直方图显示大部分用户购买数量很少。说明大部分用户消费能力不高,几乎没有高消费用户。
4.5消费时间节点
每个用户第一次消费时间。
将第一次消费时间计数并排序,发现所有用户第一次消费时间都集中在前三个月。
每个用户最后一次消费时间。
将最后一次消费时间计数并排序,可见大部分用户的最后一次消费时间也集中在前三个月,后续时间内依然有用户消费,但数量较少。
4.6复购率
pivot_table函数生成数据透视表,得到每个用户每个月的订单数量,由于单个用户并非在每个月都消费,故有很多值为空。fillna(0)表示将空值填入0。
复购率:某时间窗口内消费两次及以上的用户在总用户中的占比。
此处时间窗口为每月,将消费两次及以上记为1,消费1次记为0,没有消费记为NaN。
applymap针对dataframe里的所有数据,lambda内没有elif的用法,故用两个if…else。
count和sum函数都不会计入NaN。count统计所有0和1 的个数,即所有消费用户个数,包括消费1次和两次以上的。sum函数则计算出消费两次以上用户个数,两者相除为复购率。作用于列,得到每月的复购率。
可见,复购率在前期比较低,是由于大量新用户的加入,后期复购率则较稳定。
4.7回购率
回购率:某一时间窗口内消费的用户,在下一个时间窗口内仍消费的比例。时间窗口仍为月。
求出每个用户每月消费金额平均数的数据透视表。
将消费过的记为1,没有消费过的记为0。
定义函数,status=[ ]用于存储回购结果,对于每行的18个月数据做循环判断,如果本月和次月都购买过,返回1;本月购买次月未购买,返回0;本月未购买,返回NaN。一共18个月,rang取17,因为最后一个月不能判断返回NaN。将该函数应用于每行,得到回购结果。
用同样方法得到回购率图,可见,用户的回购率整体高于复购率,且波动性较强。回购率也是前期较低,后期有所提升。
4.8用户分层
按用户消费行为将用户分层:新用户、活跃用户、不活跃用户、回流用户。
时间窗口仍为月份,例如,user1在1月消费第一次消费,在1月定义为新用户new;在2月有消费,则在2月定义为活跃用户active;在3月没有消费,则3月为不活跃用户unactive;在4月再次消费,为回流用户return。
定义函数,一共18个月,判断一本月未消费:若为首月则unreg;若前一个月unreg则仍为unreg;其他情况均为unactive。判断二本月消费了:若为首月则new;若前一个月unreg则仍为new;若前一个月unactive则return;其他情况均为active。将函数运用到每行,得到每个用户分层结果。
未来的新客不能用来计数,用NaN替代;得到分层用户每月的数量统计。
将NaN替换成0。
从面积图来看,return和active用户数比较稳定,new前期较多,unactive后期比例大。
求出每个月分层用户比例。
用户回流占比图,可见用户回流后期有下降趋势。
活跃用户即连续消费用户后期占比也呈下降趋势,活跃用户质量在一定程度上高于回流用户。后期回流用户占比略大于活跃用户。
4.9用户质量
按每个用户的总消费金额升序排列,使用reset_index函数将结果显示为dataframe。
使用cumsum函数增加一列消费金额逐行累加数。最后一个数字为总消费金额。
增加一列占比,每个用户个人总消费金额累计占所有用户总消费金额的比例。
横坐标为按用户总消费金额排序的序号,纵坐标为累计占比。前20000名用户贡献了总消费的40%,后3569名用户贡献了60%。
同样地,按用户分组,并将每个用户的购买总量求和升序排列。增加一列购买量逐行累加值,最后一个数字为所有用户总购买量。再增加一列每行用户累加购买量占比。
同样地,前20000名用户贡献了40%的购买数量,后3569名用户贡献了60%。
4.10用户生命周期
定义第一次消费至最后一次消费为总生命周期。
用每个用户的第一次消费时间和最后一次消费时间相减,得到每个用户的生命周期。
平均生命周期为134天,标准差较大,有明显浮动;最小值0,最大值544,跨度较大;中位数0,75分位数294,说明大部分用户只消费了1次。
lastpurchase-firstpurchase数据格式为timedelta64,不能直接画图,要先转换成数值。转换方法为将lastpurchase-firstpurchase直接除以数据格式,(1,‘D’)表示单位为1天。得到生命周期的直方图。
可见大部分用户只消费了一次,生命周期为0。
转换成dataframe。
增加一列数值化的life_time。
排除只消费一次的用户,剩余用户的生命周期直方图,仍有一些用户生命周期靠拢在0天。图形呈双峰趋势,部分质量差的用户,虽然消费超过一次,但持续时间短,应在首次消费30天内尽量引导;50-350天之间的用户为普通用户;350天以后的用户为高质量用户。
消费两次以上用户平均生命周期276天远高于整体生命周期平均数134天。应在用户首次消费后加强继续消费的引导,提高生命周期的增量。
4.11留存率
留存率:用户第一次消费后,进行第二次消费的比例。留存率有多个时间窗口,注意与return率的区别。
将第一次消费时间转换成dataframe。
将原始数据和第一次消费时间这两个dataframe做inner join,根据是user_id,suffixes的两个参数表示若有重复的列名,分别如何添加后缀。这样原始数据增加了一列第一次消费时间。
增加一列date_diff为每一次消费与第一次消费的时间差。
增加一列,将date_diff的格式数值化。
增加一列,将时间差分桶,0天没有被划分,因为仅消费一次或一天内消费多次之后没有消费,留存率都为0。
做每个用户在各个留存区间的数据透视表,将每个期间的消费金额相加。
每一个时间段留存用户的平均消费金额。可见,虽然后续时段金额稍高,但区间跨度大,综合来看,第一次消费后一周内更可能消费更多。
有后续消费标记为1,没有为0。
得到每个时间窗口的用户留存率,可见,时间窗口较小时,留存率并不高,需在提高用户粘性方面增加应对措施。
将user_retention按user_id分组,应用自定义的diff函数,diff函数作用于每个group,shift(-1)表示series向前移一位,求出每组的date_diff_trans列前一个数与后一个数之差,即得到每次消费和下一次的时间间隔,NaN表示没有下一次。
得到所有用消费间隔均值为68.97天。所以召回用户的策略应在60天内进行。
大部分用户消费间隔时间比较短,可在第一次消费后赠送优惠券,在10、30、60的节点设置营销策略。
�