十大分析模型之路径分析
用户路径分析概述
现在的APP或网站功能丰富、页面路径多样,用户访问时如同参观画展,一千个哈姆雷特可能会有一千种参观方式。但对于网站来说,自然会有希望用户完成的核心路径。那么怎么来判断用户访问是否偏离了核心路径呢?这时候就需要使用用户路径分析模型了。
用户行为路径分析,顾名思义,是根据用户在APP或网站中的访问行为,分析用户在各模块中跳转规律与特点,挖掘出用户的群体特征,进而实现业务指标:如提升核心模块的到达率、APP产品设计的优化改版、流失用户去向分析等。在使用路径分析时,需要注意以下2个要点:
-
从目标场景出发,来思考选取合适的起始事件或结束事件,比如限定起始事件看结尾事件,或者限制结束事件看起始事件。如果你很明确的知道用户的切入点,那么这时候需要选择固定的起始事件;如果有明确的结果,那么这时候需要倒退看有什么事件影响了这个结果,这时候就需要选择固定的结束事件。例如当产品同学需要验证流量分发是否满足预期时可以选择起始事件为目标事件;另外我们从漏斗分析中找出的“流失用户”也可以通过设置初始事件来观察用户的去向。而如果我们要考虑一些重要行为的来源有哪些的话,那么就可以选择目标事件为结束事件,来看前序事件有哪些。
-
根据需求选择相关事件来分析,切忌选择全部。其实看用户行为路径的时候我们已经有了相对明确的问题,那么这时候需要把与问题无关的一些事件刨除,即使被刨除的这些事件有可能发生。因为这些不是观察的重点,而且会影响我们最终的判断,我们需要做的是聚焦在相关事件即可。另外,由于点击事件与页面浏览往往是相伴而生的,一般情况下可根据分析情况选择其一即可,这样可以在更少的步骤内,更高效的发现路径的规律。
用户路径分析应用示例
场景示例一:只有7%完成加入购物车,用户为什么流失了?
这是全球领先的某O2O服务平台的数据分析场景。在一次评估客户总体转化率过程中,运营人员通过漏斗分析发现:用户打开小程序后,加入购物车的客户仅有7%。运营人员希望通过用户路径分析客户流失的原因。因为目的是找到从小程序启动到加入购物车的流失用户的流失原因,所以可以选择起始事件为小程序页面浏览查看用户行为路径,如下图。

运营人员选取若干事件对客户购买路径进行深度分析,这里事件包含了用户从小程序页面浏览到加入购物车的过程中可能触发的所有事件。发现用户打开小程序后,约有37%的客户会点击Banner,约26%的客户会点击首页的各频道,约25%的用户会退出小程序,约4%的客户点击搜索入口。
运营人员进一步查看这4类用户的加入购物车的情况,发现直接进行“点击搜索”的用户进行提交订单比例最高,超过90%。而尽管“点击Banner”是更多客户打开小程序后的首选动作(约占总客户的37%),但这部分用户群体在浏览商品列表后,仅有10%的用户提交订单,说明Banner内的商品选择没有命中用户需求,需要加强Banner到活动详情页商品的对应承接,或者调整活动页的选品策略。
场景示例二:关联其它场景用法
用户行为路径分析,除了优化路径、找到运营着力点之外,还可以结合用户特征做综合分析,如结合生命周期查看不同周期用户行为,找到刺激用户留存和转化的功能页面等,是一个“大有可为”的分析模型。此外,路径分析也可以给其他分析提供思路。比如使用归因分析时,如果想保证结果的科学性,那么选择合适的待归因事件是一件至关重要的前提工作。如果不确定待归因事件是否合理或者完整,那么可以通过在用户路径中查看用户行为,以此来判断待归因事件的合理性和完整性。
在真实的用户行为路径中,其实是一个交叉反复的过程。以电商为例,企业希望买家从登录后依次完成首页浏览、搜索商品、加入购物车、提交订单、支付订单等环节,而用户真实的选购过程中可能在提交订单后返回首页继续搜索商品,也可能去取消订单,每一个路径背后都有不同的动机。所以在用户行为路径分析模型使用中,需要与其他分析模型配合进行深入分析,快速找到用户动机,从而引领用户走向最优路径或者期望中的路径。
基本概念
在进行具体的数据模型和工程架构设计前,先介绍一些基础概念,帮助大家更好的理解本文。
2.1 路径分析
用户路径分析,顾名思义,就是指用户在APP或网站中的访问路径。为了衡量网站优化的效果或营销推广的效果,以及了解用户行为偏好,时常要对访问路径进行分析。
路径分析是常用的数据挖据方法之一,主要用于分析用户在使用产品时的路径分布情况,挖掘出用户的频繁访问路径。与漏斗功能一样,路径分析会探索用户在您的网站或应用上逗留的过程中采取的各项步骤,但路径分析可随机对多条路径进行研究,而不仅仅是分析一条预先设定的路径。
2.2 Session和SessionTime
不同于WEB应用中的Session,在数据分析中的Session会话,是指在指定的时间段内在网站上发生的一系列互动。本模型中的Session Time的含义是,当两个行为间隔时间超过Session Time,我们便认为这两个行为不属于同一条路径。
2.3 桑基图
桑基图(Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小。如图4.1-1所示,每条边表示上一节点到该节点的流量。一个完整的桑基图包括以下几个内容:节点数据及节点转化率(下图红框部分)、边数据及边转化率(下图黑框部分)。转化率的计算详见【3.5. 转化率计算】。

用户访问路径的可视化通常使用桑基图。如下图所示,该图可真实还原用户的访问路径,包括页面跳转和页面访问次序。

桑基图需要我们提供每种页面跳转的次数,每个跳转由source/target表示,source指跳转起始页面,target表示跳转终到页面。
2.4 邻接表
构造桑基图可以简化为一个图的压缩存储问题。图通常由几个部分组成:
- 边(edge)
- 点(vertex)
- 权重(weight)
- 度(degree)
本模型中,我们采用邻接表进行存储。邻接表是一种常用的图压缩存储结构,借助链表来保存图中的节点和边而忽略各节点之间不存在的边,从而对矩阵进行压缩。邻接表的构造如下:

(a)中,左侧为顶点节点,包含顶点数据及指向第一条边的指针;右侧为边节点,包含该边的权重、出入度等边信息以及指向下一条边的指针。一个完整的邻接表类似于Hashmap的结构,如图(b),左侧是一个顺序表,保存的是(a)中的边节点;每个边节点对应一个链表存储与该节点相连接的边。页面路径模型中,为了适应模型的需要,我们对顶点节点和边节点结构做了改造,详情请见【4.1】节。
2.5 树的剪枝
剪枝是树的构造中一个重要的步骤,指删去一些不重要的节点来降低计算或搜索的复杂度。页面路径模型中,我们在剪枝环节对原始数据构造的树进行修整,去掉不符合条件的分支,来保证树中每条根节点到叶节点路径的完整性。
2.6 PV和SV
PV即Page View,访问次数,本模型中指的是一段时间内访问的次数;SV即Session View,会话次数,本模型中指出现过该访问路径的会话数。如,有路径一:A → B → C → D → A → B和路径二:A → B → D,那么,A → B的PV为2+1=3,SV为1+1=2。
技术实现demo
桑基图关键点
- source不能为空
- 不能存在环(需要生成步骤序号拼接页面ID)
1)建表语句
sql
DROP TABLE IF EXISTS ads_page_path;
CREATE EXTERNAL TABLE ads_page_path
(
`dt` STRING COMMENT '统计日期',
`recent_days` BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
`source` STRING COMMENT '跳转起始页面ID',
`target` STRING COMMENT '跳转终到页面ID',
`path_count` BIGINT COMMENT '跳转次数'
) COMMENT '页面浏览路径分析'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
LOCATION '/warehouse/gmall/ads/ads_page_path/';
2)数据装载
sql
insert overwrite table ads_page_path
select * from ads_page_path
union
select
'2020-06-14' dt,
recent_days,
source,
nvl(target,'null'),
count(*) path_count
from
(
select
recent_days,
concat('step-',rn,':',page_id) source,
concat('step-',rn+1,':',next_page_id) target
from
(
select
recent_days,
page_id,
lead(page_id,1,null) over(partition by session_id,recent_days) next_page_id,
row_number() over (partition by session_id,recent_days order by view_time) rn
from dwd_traffic_page_view_inc lateral view explode(array(1,7,30)) tmp as recent_days
where dt>=date_add('2020-06-14',-recent_days+1)
)t1
)t2
group by recent_days,source,target;
3)结果呈现

需求2:建表sql
sql
create table demo_path_src(
guid string,
ts bigint,
sessionid string,
eventid string,
pgid string
)
row format delimited fields terminated by ','
;
load data local inpath '/root/path.dat' into table demo_path_src;
g01,137001,s01,pgview,A
g01,137002,s01,pgview,C
g01,137003,s01,pgview,F
g01,137004,s01,pgview,E
g01,137005,s01,pgview,G
g01,137006,s02,pgview,A
g01,137007,s02,pgview,D
g01,137011,s02,pgview,F
g01,137012,s02,pgview,B
g01,137013,s02,pgview,C
g01,137014,s02,pgview,A
g02,137015,s03,pgview,U
g02,137016,s03,pgview,D
g02,137017,s03,pgview,F
g02,137018,s03,pgview,B
g02,137021,s03,pgview,A
g03,137022,s04,pgview,U
g03,137025,s04,pgview,X
g03,137026,s04,pgview,F
g03,137027,s04,pgview,B
g03,137028,s04,pgview,A
-- sql
create table demo_path_dwd_dtl(
guid string,
ts bigint,
sessionid string,
eventid string,
pgid string,
step int,
pre_pg string
)
stored as orc
;
g01,s01,pgview,A,1 ,N
g01,s01,pgview,C,2 ,A
g01,s01,pgview,F,3 ,C
g01,s01,pgview,E,4 ,F
g01,s01,pgview,G,5 ,E
g01,s02,pgview,A,1 ,N
g01,s02,pgview,D,2 ,A
g01,s02,pgview,F,3 ,D
g01,s02,pgview,B,4 ,F
g01,s02,pgview,C,5 ,B
g01,s02,pgview,A,6 ,C
insert into table demo_path_dwd_dtl
select
guid ,
ts ,
sessionid ,
eventid ,
pgid ,
row_number() over(partition by guid,sessionid order by ts) as step,
lag(pgid,1,null) over(partition by guid,sessionid order by ts) as pre_pg
from demo_path_src
;
--sql 统计3个指标
步骤号,页面id,前一页id,路径会话数,步骤会话数,页面会话数
2 C A 15 20 100
2 C X 5 20 100
2 D X 8 15 80
3 C U 30 100
-- 计算逻辑:
-- 计算逻辑:
指标1: 某页面上的所有会话总数:group by pgid 求:count(distinct sessionid)
指标2: 特定步骤上的特定页面发生的会话数:group by rn,pgid 求:count(sessionid)
指标3: 特定步骤上的特定页面且特定来源页发生的会话数 group by rn,pgid,pre_pgid 求:count(sessionid
实现方式1: **先统计指标3,然后根据step+pgid去join指标2结果**
**然后根据pgid去join指标1结果**
实现方式2:
先计算指标3
步骤号,页面id,前一页id,路径会话数 || 步骤会话数 页面会话数
2 C A 15 || 20 30
2 C X 5 || 20 30
2 D X 8 || 8 8
3 C U 10 || 10 30
然后,在此基础上,计算步骤会话数、页面会话数
sql实现:
select
step,
pgid,
pre_pg,
count(1) as path_se_cnts,
sum(count(1)) over(partition by step,pgid rows between unbounded preceding and unbounded following) as step_se_cnts,
sum(count(1)) over(partition by pgid rows between unbounded preceding and unbounded following) as page_se_cnts
from demo_path_dwd_dtl
group by step,pgid,pre_pg
;


end
