用户消费行为分析:消费习惯分析
下面我们演示一个使用Hive来统计某电商用户消费行为的案例。主要包括内容:
- 创建Hive表结构,并加载数据;
- 不同性别用户的消费频次差异;
- 统计用户的消费周期;
- 不同年龄用户的消费金额差异;
- 统计用户消费的二八法则。
数据集说明
在PBLP平台的~/data/hive/user_order/目录下,我们提供了两个数据文件。一个是订单数据文件order_info_utf.csv,一个是用户数据文件user_info_utf.csv。其中:
order_info_utf.csv数据格式如下:
订单id,用户id,支付状态,支付价格,日期 1,11211,已支付,833,2016/3/1 0:04 2,11211,已支付,487,2016/3/1 0:03 3,11211,未支付,794, 4,74553,已支付,737,2016/3/1 0:02 5,37799,已支付,647,2016/3/1 0:01 ...
user_info_utf.csv数据格式如下:
用户id,性别,出生日期 1,女,1969/1/21 2,女,1978/9/6 3,男,1973/9/3 4,女,1982/4/27 5,男,1970/7/30 ...
创建Hive表结构,并加载数据
首先创建订单信息表orderinfo:
CREATE TABLE IF NOT EXISTS ORDERINFO (
ORDERID string,
USERID string,
ISPAID string,
PRINCE string,
PAIDTIME string
) ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
然后创建用户信息表userinfo:
CREATE TABLE IF NOT EXISTS USERINFO (
USERID string,
SEX string,
BIRTH string
) ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
执行下面两个load语句,分别导入两个数据文件到相应的Hive表中:
load data local inpath "/home/hduser/data/hive/user_order/order_info_utf.csv" into table ORDERINFO; load data local inpath "/home/hduser/data/hive/user_order/user_info_utf.csv" into table USERINFO;
测试数据导入是否成功:
select * from orderinfo limit 5; select * from userinfo limit 5;
统计男女用户的消费频次是否有差异
思路:将order_info表与user_info表进行内部联结inner join,对'用户id'和对应的'性别sex'进行分组,并统计每个用户的消费次数,最后再对性别进行分组,求出'男'&'女'对应的平均消费次数。
select sex as `性别`, round(avg(ct),4) as `平均消费次数`
from (select o.userid,sex,count(o.userid) as ct
from orderinfo as o
inner join (SELECT * FROM userinfo where sex <> '') as s
on o.userid = s.userid
where ispaid = '已支付'
group by o.userid,sex
) as b
group by sex;
执行以上代码,查询结果如下:
性别 平均消费次数 女 1.7829 男 1.8035
统计多次消费,第一次消费和最后一次消费的间隔是多少
思路:先筛选出'已支付'的'userid',并对用户进行分组group by,再挑选出消费次数>1的用户id,最后得出第一次消费和最后一次消费的时间点及时间差。
select userid as `用户`,
max(paidate) as `最后一次消费`,
min(paidate) as `第一次消费`,
datediff(max(paidate),min(paidate)) as `两次消费的时间差`
from (select *, from_unixtime(unix_timestamp(paidtime,"yyyy/MM/dd HH:mm"),"yyyy-MM-dd") as paidate
from orderinfo
where ispaid='已支付') as t
group by userid
having count(userid) > 1;
执行以上代码,查询结果如下(部分):
...... 87889 2016-03-27 2016-03-26 1 8789 2016-04-20 2016-03-01 50 87892 2016-03-27 2016-03-25 2 87895 2016-04-29 2016-03-25 35 87896 2016-03-26 2016-03-26 0 879 2016-04-23 2016-04-21 2 87909 2016-04-14 2016-03-26 19 87911 2016-04-14 2016-03-26 19 87914 2016-03-26 2016-03-26 0 8792 2016-04-11 2016-04-11 0 87921 2016-04-05 2016-03-26 10 87926 2016-03-26 2016-03-26 0 87927 2016-03-27 2016-03-26 1 87942 2016-03-26 2016-03-26 0 87945 2016-03-28 2016-03-27 1 87948 2016-03-27 2016-03-26 1 8795 2016-04-22 2016-04-17 5 87951 2016-03-26 2016-03-26 0 87959 2016-03-26 2016-03-26 0 8796 2016-04-06 2016-03-04 33 87962 2016-03-28 2016-03-26 2 87975 2016-04-25 2016-03-26 30 ......
计算平均消费间隔
select round(avg(jg),4) as `平均消费间隔`
from(
select userid as `用户`,datediff(max(paidate),min(paidate)) as jg
from (select *, from_unixtime(unix_timestamp(paidtime,"yyyy/MM/dd HH:mm"),"yyyy-MM-dd") as paidate
from orderinfo
where ispaid='已支付') as t
group by userid
having count(userid) > 1
) t2;
执行以上代码,查询结果如下:
平均消费间隔 15.6484
统计不同年龄段,用户的消费金额是否有差异
思路:先对数据进行筛选,再以10年为时间间隔进行划分各个年龄段,最后再挑出各用户、年龄段及各年龄段的人数,最后再进行统计分析。
select j.age, round(avg(j.sp),2) as `平均消费金额`
from(
select o.userid, u.age, sum(o.prince) as sp
from orderinfo as o
inner join(select t.userid, ceil((year(CURRENT_DATE()) - year(t.birthday))/10)*10 as age
from (select *, from_unixtime(unix_timestamp(birth,"yyyy/MM/dd"),"yyyy-MM-dd") as birthday from userinfo) t
where t.birthday is not null
) as u
on o.userid=u.userid
where o.ispaid='已支付'
group by o.userid, u.age
) j
group by j.age;
执行以上代码,查询结果如下:
10 1320.7 20 819.67 30 1007.79 40 1158.24 50 1202.3 60 1107.06 70 1043.28 80 948.13 90 747.55 100 57804.91 130 699.0
统计消费的二八法则:消费top20%的用户贡献了多少额度
思路:先统计全部的消费用户数,计算出其20%的用户数大致是多少。
select (count(distinct userid) * 0.2) as `百分之20的用户数` from orderinfo where ispaid = '已支付';
执行以上代码,查询结果如下:
百分之20的用户数 17129.8
思路:根据上一步得到的20%的用户数,计算用户的消费总额并进行排序。
select userid, cast(sum(prince) as decimal(18,2)) as total from orderinfo where ispaid = '已支付' group by userid order by total desc limit 17130;
执行以上代码,查询结果如下:
11211 231167990.00 57282 457232.00 62590 223636.00 14427 221821.00 53616 203981.00 68226 162415.29 25263 108717.00 14271 108385.00 44050 100229.00 57018 96293.00 68215 77072.82 53527 66345.00 54166 61648.00 5775 56393.00 17507 54415.00 64012 47553.00 68229 46474.52 21442 45302.00 25291 42519.60 ......
思路:根据上步得到的结果,算出前20%的用户的消费总额。
select cast(sum(t.total) as decimal(12,2)) as `top20的消费总额`
from (
select userid, sum(prince) as total
from orderinfo
where ispaid = '已支付'
group by userid
order by total desc
limit 17130
) t;
执行以上代码,查询结果如下:
top20的消费总额 272203771.46
思路:计算全部的已支付用户的消费总额
select cast(sum(prince) as decimal(12,2)) as `全部消费总额` from orderinfo where ispaid='已支付';
执行以上代码,查询结果如下:
全部消费总额 318503081.55
综合上面几步,一次性计算top 20用户消费占比。
with
top as (
select cast(sum(t.total) as decimal(12,2)) as t20
from (
select userid, sum(prince) as total
from orderinfo
where ispaid = '已支付'
group by userid
order by total desc
limit 17130
) t
),
total as (
select cast(sum(prince) as decimal(12,2)) as tt
from orderinfo
where ispaid='已支付'
)
select top.t20 as `top20消费金额`, total.tt as `总消费金额`, round(top.t20/total.tt,4) as `top20消费占比`
from top, total;
执行以上代码,查询结果如下:
top20消费金额 总消费金额 top20消费占比 272203771.46 318503081.55 0.8546
分析总结
通过以上分析,可以得出以下结论:
- 1. 男女的平均消费频次为1.8035、1.7827,可见男女在消费频次上并不会存在较大的差异;
- 2. 由消费间隔的统计可知,多次消费的用户的平均消费间隔为15天左右;
- 3. 由"不同年龄段的平均消费金额"结果可知,青年及中年的消费力度较高,而少年及中老年可能因为经济等相关原因而导致消费力度相对较低;
- 4. 由消费的二八法则统计得知:消费top20%的用户贡献了近272203771.46元的消费额度,占到了总消费额度的85.46%,是值得该公司重点维护的主要客户。