目录
Acquisition 获取(游戏行业需要分析DNU/DOU/DAU)
一、数据导入
数据来源: 可视化大赛-天池大数据竞赛-天池大赛-阿里云天池
使用工具:Mysql Workbench ,帆软FineBI
首先我们下载数据到本地,选择大小最大那个压缩包,里面的文件为CSV文件格式
然后我们打开workbench创建数据库并且导入CSV文件。
二、数据预处理
数据预处理包括,数据重复值、空缺值、异常值处理以及保持数据一致性
1、数据重复值
(a)查看数据重复值
select *,count(user_id) '重复数量' from data_
group by user_id,item_id,behavior_type,user_geohash,item_category,time
having count(user_id) > 1
order by '重复数量'desc;
结果
(b)重复值处理:
虽然可以看到有大量的重复数据,但是通过实际分析,time的精确到小时,而一个小时内可以发生多个用户购买行为,所以我们可以忽略掉这些重复的数据
2、数据空缺值
(a)查看数据空缺值
select count(user_id),count(item_id),count(behavior_type),count(user_geohash),count(item_category),count(time)
from data_
结果
我们可以看到time变量存在一个缺失值,首先对于空缺值我们可以选择以下四种做法
一、手工填写缺失值
二、忽略该组数据
三、使用机器学习的方法或者计算模型计算出空缺处的值
四、删除该组数据
而空缺值我们可以简单分为:1、随机缺失(MAR)2、完全随机缺失(MCAR)3、非完全缺失(MNAR)。
(b)分析空缺值属性以及原因:
根据实际分析 time属于一种完全随机丢失,即她的缺失是完全随机的,时间可以选在24小时中的任何时间,并且他不会因为时间早而缺失的多,也不依赖其他完全变量如user_id。所以与其他字段变量没有依赖关系,并且其缺失率非常低,缺失行中的重要属性较低所以我们可以选择删除该组数据,其做法简单并且系统影响不大。
(ps:还有出于一个考量,1、本次分析不采用机器学习中可以处理缺失值的模型2、缺失值再整体样本的分布占比较低,以及缺失值不具有明显的分布规律,所以也可以进行不处理的操作)
原因可能为人为因素没有被记录或者遗漏,或者机械故障等物理原因
(c)空缺值处理
先找到相应空缺行并且进行删除处理
select * from data_
where time is null;
delete from data_
where time is null;
重新执行查询空缺值语句,确认数据已被删除。
3、数据异常值
首先分析异常值通常从范围数值内入手或者是明显不符合实际逻辑的数据。
(a)查看behavio type的类型
select distinct behavior_type from data_;
有四种类型 分别对应点击量,收藏量,添加到购物车,付款量
(b)查看time的范围
select min(time) '时间最小值',max(time) '时间最大值'
from data_;
没有问题,符合数据集中的描述,时间是从2014年11月18号到2014年12月18号共一个月的时间。
4、数据一致性
对time进行拆分,可以使得数据反映在某天,也可以反映在某月,并对behavior_type进行一个更好的可视化处理
(a)分析思路:
对于time的处理,可以先创建新列,后覆盖掉旧列,对behavio_type列值进行简单的重命名
(b)修改time列
ALTER TABLE data_ ADD date date;
ALTER TABLE data_ ADD hour time;
UPDATE data_ SET date = LEFT(time,10);
UPDATE data_ SET hour = RIGHT(time,8);
ALTER TABLE data_ DROP time;
UPDATE data_ SET behavior_type = CASE behavior_type
WHEN 1 THEN '点击网页'
WHEN 2 THEN '收藏'
WHEN 3 THEN '加入购物车'
WHEN 4 THEN '付款'
end;
PS:检查数据库此字段的字符集与整理字符集是否与SQL语句传递数据的字符集相同;不相同则会引发MySQL1366错误。
三、数据分析
漏斗模型分析
首先分析前我们知道,转化率是指产出除以独立访客或者访问量,对于天猫这种电商网站,产出就是客户提交的订单(已付款),而使用独立访客量还是访问量取决于我们关心的模式,这需要根据实际业务需求来分析,但是我们可以通过一些简单的方法来分析,比如如果客户购买前会经过多次访问点击网页,这种行为比较普遍,我们购买前都会经过多次对比,商量后才决定购买,此时则使用独立访客量(UV)。
但是当我们的客户在一段时间内进行了多次购买,此时访问量(PV)更值得选择。
所以我们以一周作为时间长度,来分析客户在一周内是否发生多次购买行为来确定是否使用访问量来计算转化率。
## create view view_purchase_within_week as ## 视图无法在select有变量的情况下生成
CREATE temporary table tmp # tmp临时表为用户复购行为记录表,null为仅发生过一次付款行为或者为最后一次购买记录, 而0为当天进行了复购;若重复出现0,当天进行了多次购买,当天的购买次数买null数+0的数量
select A.user_id,A.date,TIMESTAMPDIFF(day,A.date,B.date) 距离下一次购买的时间间隔
from
(
select data_.*,(@i := @i + 1) as ord_num from data_ ,(select @i := 1) d where behavior_type = '付款' order by user_id,date
) as A LEFT JOIN
(
select data_.*,(@j := @j + 1) as ord_num from data_ ,(select @j := 0) c where behavior_type = '付款' order by user_id,date
)as B
on A.ord_num=B.ord_num and A.user_id=B.user_id
order by user_id,date,距离下一次购买的时间间隔
返回了1896条数据,与数据集中付款行为数据相同,且包括了以下三种情况
1、只有null,客户只进行了一次购买
2、有null,有0,客户当天进行了复购
3、有null,有0,有其他数字,客户一段时间进行了复购,并且在某天进行了多次复购
先通过排除NULL来筛选出没进行复购的用户,然后通过聚集函数来计算有多少个用户在一周时间内有多次购买行为。
select user_id,count(*)+1 客户一周时间内复购的次数 from tmp #加1是因为还有一个为null的最后一次购买行为记录
where 距离下一次购买的时间间隔 is not null and 距离下一次购买的时间间隔 <=7 #排除了就购买一次的与时间跨度超过7天的
group by user_id
返回结果
通过计算得到了355名用户在一周时间内进行了复购行为。约占总体独立用户(1631)的21.77%,另外,431名客户在一个月内进行了复购行为,总体复购率为52.82%
一周内大量发生复购行为占比较小,大多数人都是进行多次点击后才进行付款行为,故会产生大量的浏览点击记录,此时选择UV作为转化率的分母能够更好反映客户行为,并用此指标来搭建漏斗模型
select behavior_type '环节',count(behavior_type) '各环节PV数量', count(distinct user_id) '各环节UV数量'
from data_
group by behavior_type
接下来使用fineBI进行漏斗模型的可视化。
总结:
1、首先确认关键指标在UV与PV中选择UV,然后通过一周内复购率进行筛选,最后搭建漏斗模型。
2、在分析一周内用户复购行为时,发现无法创建视图,经过查阅资料,可以得知视图无法创建的原因有(1)视图的select语句包括了ORDER BY、INTO关键字;(2)使用了临时表创建视图;(3)创建视图时使用了表变量(@变量名)
AARRR模型分析
AARRR分析包括了:Acquisition 获取、Activation 激活、Retention 留存、Revenue 收益、Referral 推荐 这五个维度共同构成了一个闭环模型
Acquisition 获取(游戏行业需要分析DNU/DOU/DAU)
用户获取,首次访问数
代码:
select date,count(user_id) from(
select *,dense_rank() over(partition by user_id order by date) rk
from data_) a
where rk = 1
group by date
可以看出DNU指标从首日便开始骤减,原因是SQL中使用的是查询当前最小访问时间,而此前数据未可得,故导致在11月18日中的“新增用户”极大部分是来自于此前活跃用户,并非当日新增的用户。
而次日到三日的DNU数据也出现一定程度的骤减情况,原因为这些“新增用户”也有部分来自于此前活跃用户,故越到后面越呈现稳定状态,也更能代表DNU真实情况。
一般观测长度为一两个月,可以得知在后半个月新增用户比前半个月(除了11月24号此前数据)少了很多,可以猜测存在一定量的首登后无复用用户,但是影响不大
(问题:容易误会首日下降过多,应该分析其原因为此前累积的人数)
Activation 活跃度
先提取重要数据,如pv,uv等
create view 整体指标 as
select sum(user_pv) as PV, count(user_id) as UV, format(sum(user_pv)/count(user_id), 2) as 人均页面访问数
from
(
select user_id, count(behavior_type) as user_pv
from data_
where behavior_type = '点击网页'
group by user_id
) as a;
select * from 整体指标;
可以返回对应的PV,UV值,并且计算出人均页面的访问数
在操作过程中发现了(select distinct user_id from data_ where behavior_type = '点击网页')点击网页的distinct人数(test1)为1631,而直接搜索data_的distinct user_id集发现多一个(test),为1632个,说明有一个用户没有经过点击网页,而直接跳过进行其他操作。而后我选择使用左连接的方式,筛选出了没有经过点击网页的人。
#建立两个独立视图
create view test as select distinct user_id from data_;
create view test1 as select distinct user_id from data_
where behavior_type = '点击网页';
#筛选出那个没经过点击网页步骤的特殊值
select test1.user_id,test.user_id
from test left join test1
on test.user_id = test1.user_id
where test1.user_id is null;
可以看出这个user_id为'117489231'的用户并没有像正常的用户一样有点击网页的步骤,而是只有一个付款行为,因为数据的时间跨度只有一个月,有可能客户在一个月之前已经选择好,但是没有付款,而后补上,所以暂时没有对其进行处理。如果数据集有标注付款前必须点击页面的话应该视为异常值。后面想了一下如果不删除可能会导致后面计算pv的时候忘记了这个特别的存在,直接把distinct user_id 当成了pv 所以选择直接删除。
计算跳出率
Bounce Rate,蹦失率又称为跳出率。计算思路为只访问了一个页面就离开的访问次数占该页面总访问次数的比例。
create view bounce_rate as
select (select count(distinct user_id) from data_) as '总用户', #计算出数据库中总共的用户
count(distinct user_id) 'PV用户',
concat(format(count(distinct user_id)/(select count(distinct user_id) from data_)*100, 2), '%') as 浏览页跳失率 #跳失率的计算方式pv除以总用户
from data_
where user_id not in
(select distinct user_id from data_ where behavior_type = '加入购物车')
and user_id not in
(select distinct user_id from data_ where behavior_type = '收藏')
and user_id not in
(select distinct user_id from data_ where behavior_type = '付款'); #即没有参加过除了点击网页外的所有操作。
可以看到浏览页跳出率为19.62%,意味着五分之一的用户在第一次进入页面后就退出了页面,
原因分析:1、产品页面信息不够丰富,没有推送客户需要的产品(主要问题)
2、客户没有找到相应的链接来跳到其他步骤(UI设计不合理)(次要问题)
3、客户点错(我自己有时候也会点错。。。)
改善建议:1、优化UI设计,布局合理化,让客户可以更容易走向下一步
2、针对客户浏览页面时间进行,如果时间短,那大概率是没兴趣,应该及时推送优惠卷等吸引客人,如果时间长就回归到第一个改善建议。
计算关键页跳出率
关键页跳失率:用户有收藏或加购行为但无购买
create view view_key_bounce_rate as
select (select count(distinct user_id) from data_) as 总用户,
count(distinct user_id) as col_cart用户,
concat(format(count(distinct user_id)
/(select count(distinct user_id) from data_)*100, 2), '%') as 关键页跳失率
from data_
where user_id in
(select distinct user_id from data_ where behavior_type = '收藏')
or user_id in
(select distinct user_id from data_ where behavior_type = '加入购物车')
and user_id not in
(select distinct user_id from data_ where behavior_type = '付款');
分析:1、用户无付款行为占比较大
建议:1、可以多推出用户相关商品,如根据客户浏览较多的item_id进行购物篮子分析,减少跳失率。
时间维度分析用户活跃度情况
通过FineBI工具分析,以每日,每周,每月的维度来分析用户行为
日维度用户行为情况:
得到如下结果
我们可以看在“双12”前后两天的UV量达到一个峰值,而在平时的话处于一个相对稳定的状态。
各时段用户行为情况:
我们可以看出在晚上六点时候活跃度越来越高,晚上九点到晚上十点区间用户活跃度处于一个峰值,原因可能为6点后处于下班高峰期,人们喜欢下班后及逆行购物,在10点左右处于吃完饭后购物。
周维度用户行为情况:
从数据上可以看出周二到周五之间处于一个访问的带你分期
(数据集的规模影响实际效果,100w时显示的时周五最多)
小结:基于以上数据,12·12活动一般选择在11月底、12月初开始预热,至少提前1-2周进行;网站的客服、维护尤其要注意晚上20点—23点这一时段;日常的推新、促销选择在周四——周六这一时间段进行。
Rretention 留存率
代码部分:
#第一步创建一个视图来显示每个用户的第一次登陆时间与其后续登录的时间查
create view 留存率分析 as
select a.*, b.firstday, datediff(a.date, b.firstday) as day_diff
from (select user_id, date from data_ group by user_id, date) as a left join
(select user_id, min(date) as firstday from data_ group by user_id) as b
on a.user_id = b.user_id
order by user_id, date;
#第二步创建一个视图来分别显示首日留存人数,次日留存人数,三日留存人数,周留存人数及月留存人数,搭建留存天数模型
create view retention_day as
select firstday,
sum(case when day_diff=0 then 1 else 0 end) as day_0,
sum(case when day_diff=1 then 1 else 0 end) as day_1,
sum(case when day_diff=2 then 1 else 0 end) as day_2,
sum(case when day_diff=6 then 1 else 0 end) as day_week,
sum(case when day_diff=30 then 1 else 0 end) as day_month
from 留存率分析
group by firstday
order by firstday;
#第三步创建一个视图来显示留存率,只是对第二步进行一个显示格式的转化,搭建留存率模型
create view retention_rate as
select firstday, day_0,
concat(format(day_1/day_0*100, 2), '%') as day_1,
concat(format(day_2/day_0*100, 2), '%') as day_2,
concat(format(day_week/day_0*100, 2), '%') as day_week,
concat(format(day_month/day_0*100, 2), '%') as day_month
from retention_day;
分别对应的结果如下所示:
步骤一部分返回结果
步骤二部分返回结果
步骤三部分返回结果
通过FineBI进行可视化操作:
分析:
因为时间跨度只有一个月,所以我们不分析一个月留存率,直接分析次日、三日、一周留存率。从留存率曲线图来看,我们可以看到三项指标在“双十二”前留存率呈下降趋势,而“双十二”活动左右的一周时间内各项指标都出现比较大的波动而且总体是提高的趋势,可以看出活动对用户的吸引力还是很强的,在12.13号当天次日留存率达到顶峰值,可能为客户在购买完商品后对商品状态的关心而进行再次访问。
Referral 用户推荐
由可视化图可得,加入购物车转化率为2.9%,收藏转化率为2.2%,从加入购物车到付款的转化率为34.7%,而从收藏到付款的转化率为45.9%
分析:由上数据可得我们可以发现无论是加购还是收藏的转化率都十分低,用户花费了大量时间来寻找合适产品,故我们可以从UI设计,关键词搜索优化,推荐算法等方面进行提升客户体验。
而从加购或收藏到付款的转化率为34.7%与45.9%上来看客户对产品的满意度仍需提高,或许可以在价格上面再推上一把,比如通过发放活动优惠卷等来诱导客户进行付款。
Reveune 用户收益
因数据集未提供具体金额,所以暂时无法进行ARPU与ROI等分析,曲线救国地我们可以通过复购率来侧面放映用户收益情况
代码部分:
#创建一个显示用户付款转化率的视图
create view user_behavior_times as
select user_id,
sum(case when behavior_type='点击网页' then 1 else 0 end) as pv_times,
sum(case when behavior_type='付款' then 1 else 0 end) as buy_times,
concat(format(sum(case when behavior_type='付款' then 1 else 0 end)/sum(case when behavior_type='点击网页' then 1 else 0 end)*100,2), '%') as 用户付款转化率,
sum(case when behavior_type='付款' then 1 else 0 end)/sum(case when behavior_type='点击网页' then 1 else 0 end) as 排序列
from data_
group by user_id
order by 排序列 desc;
ps:mysql不支持对百分比的排序,故对”用户付款转化率“进行排序无效,需要重新添加一个排序列
用户复购数模型:
复购率代码部分:
#创建复购率视图repurchase_rate 计算公式为购买一次以上的人数/购买一次的人数
create view repurchase_rate as
select (select count(user_id) from user_behavior_times where buy_times>1)/(select count(user_id) from user_behavior_times where buy_times>0) as 复购率;
分析:从上图可以看出百分之八十的用户的用户的购买次数还是为单次购买,说明有可能商品的质量不符合大部分人的期望或者商品可能为长期使用产品,如吹风机,榨汁机等可以使用多年的商品,整体复购率为52.82%,较为理想,符合实际。
建议可将运营重点放在培养用户粘性上,从质量、价格、服务、物流等方面做出改进,刺激用户更高频次的消费。
RFM用户细分模型分析
因为该数据集中不涉及金额,可进行RF分析,更具
仅在会员(购买过商品的用户)范围内,进行价值划分,R/F等级为1-5,由于本项目的数据不涉及M(Monetary),所以只做4类划分。▼
通过RFM模型,了解每位顾客的特性,实现差异化营销。
根据我个人整理的RFM客户细分等级表,可以知道我们可以通过近度与频度来将用户分为价值用户,发展用户,保留用户,挽留用户
通过FineBI商业分析软件进行RFM模型搭建:
我们通过K-means的方式来评判指标的高低
python代码部分:
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.cluster import KMeans;
data = pd.read_csv("C:/Users/54316/Desktop/RFM分析数据集.csv")
Distance=[] # 保存每一个聚类的组间距离
for i in range(1,11): # 分别计算1-10个聚类的组间距离
# 初始化聚类算法
kmeans=KMeans(n_clusters=i,max_iter=300,n_init=10,init='k-means++',random_state=0)
# 用数据拟合算法
kmeans.fit(data)
# 将组间距离添加到列表中
Distance.append(kmeans.inertia_)
#显示一下数据图
plt.plot(range(1,11),Distance)
plt.title("The cluster number")
plt.xlabel("cluster number")
plt.ylabel("WCSS")
plt.show()
#显示出最佳聚类K值为4时的阈值
# 使用K-Means确定阈值
kmodes=KMeans(n_clusters=4) # 初始化K-Means
for col in data.columns: # 遍历数据文件的列名
kmodes.fit(data[[col]]) # 使用数据拟合K-Means
print(col) # 打印数据
center=kmodes.cluster_centers_ # 确定聚类中心,以列表形式显示
for c in center: # 遍历聚类中心,以文字形式显示
print(c[0]) # 打印聚类中心
得到的K-means代价函数与聚类数目K的关系图
由图中可见在聚类数为4之前,随着聚类数的增加会导致每个簇的聚合程度提高,欧氏距离也会下降得很快,而在聚类数为4之后,随着聚类数得增加,聚合程度减缓十分明显并趋于平缓,使用手肘法可判断聚类为4时为最佳初始聚类中心数,即K值为4
经过K-means算法后得出结果
故R维度中的阈值范围为R<3.1,3.2~8.2,8.3~17.2,17.3~27.0,27.1~R 分别评分为5、4、3、2、1分
F维度中的阈值范围为F<1.0,1.1~2.4,2.5~4.8,4.9~10.3,10.4~F 分别评分1、2、3、4、5
代码部分:
create view RF as
select *,
case when Recent_time <=3.1 then 5
when Recent_time between 3.2 and 8.2 then 4
when Recent_time between 8.3 and 17.2 then 3
when Recent_time between 17.3 and 27 then 2
else 1
end R,
case when Frequency <=1.0 then 1
when Frequency between 1.1 and 2.4 then 2
when Frequency between 2.5 and 4.8 then 3
when Frequency between 4.9 and 10.3 then 4
else 5
end F
from rfm;
select *,
(case
when R>3.34 and F>1.96 then '价值用户'
when R>3.34 and F<1.96 then '发展用户'
when R<3.34 and F>1.96 then '保留用户'
when R<3.34 and F<1.96 then '挽留用户'
end) as 用户类别
from rf;
通过计算R/F的平均值来区分具体等级,使用FineBI软件进行分组后得到的RFM用户分级明细表
看板汇总与总结
监视关键指标,实时做出措施
在大型营销行为前可提前进行预热,如预付款、邀请用户砍价等活动。应在晚上7点到晚上11点期间,重点关注用户动态,若出现指标异动需要及时调整策略,客服团队也要更加注意此时段客户的反应情况。
从时间维度来看用户行为情况来看,需要重点关心用户跳出率问题,尽量使用优惠卷,减免活动,推荐同类商品方法来留住客户,提升用户转化率。并且可以进行SEO或SEM的优化,提高商品浏览人数。
细分用户群体,针对性营销
对价值用户实施保留的投资策略,维持投资力度与人员调动,观察价值用户指标情况,根据实际可采用收获的策略,逐渐减少其低回报行为的投资,减少额外资金投入于营销动作。
对发展用户,应推荐高性价比、好评率高的产品来使更多的用户发展为价值用户,对保留用户应采取短信通知或平台提醒等方式,提示用户访问网站,而对于挽留用户可以通过促销活动唤起用户的消费欲望,并且对于回归用户给予一些额外的一些短期优惠。
参考书籍:《谷歌数据分析方法》、《高性能MySQL(第3版).Baron.Scbwartz》、《机器学习》清华大学出版社