一、概览
首先和大家分享下业务场景和技术架构。文中的Demo数据都是脱敏后的假数据,业务场景也换成了一些更通用的基于信息流和电商的场景,这些场景与各种互联网场景都是适用的。
1、业务场景
用户路径是用户在网站或APP中的行为路径。上图的上半部分是一个用户路径的例子,所有的互联网场景在大的层面分为三部分:聚合页、列表页和正文页,我们的用户路径其实就是在这些不同类型的页面来回切换。
用户路径分析的价值主要体现在如下几方面:
- 描绘用户生命周期:作为数据从业者,常常需要看清某个业务或场景,除了BI工具以外,用户路径分析也是一个比较行之有效的方法,通过图表能够一目了然地看清流量走向。
- 识别用户体验问题:用户增长成本高昂,由于各种体验问题,造成大量用户流失,在这中间能够找到一些业务增长点。
- 提升数据质量:除了被产品和运营提需求、被发现数据bug外,我们希望能够主动地提升数据质量。用户路径分析可以使业务展示更加清晰,能够识别出用户数据的各种问题;另外,当把一个数据、场景或基于Event的日志式的数据结构变成基于Session的数据结构后,它就有了次序和关联,这样就很容易发现数据中的问题。
2、方案和技术架构
整体的技术架构由底层的数据集成、中间的存储、上面的应用和服务部分组成。这里重点分享下与Session有关的部分。
- 数据集成:底层数据集成中数据治理是非常重的,在这部分我们试图对跨业务的场景做统一串联,拼接用户行为日志。因为大部分的互联网产品都是模块化开发,由内容、电商、广告等模块组成,不同团队的日志结构很可能是不一样的,因此要做好用户路径分析,数据治理是很重要的工作。
- 数据存储:对于Session数据,先用Spark或Hive批处理,然后结合类似ClickHouse的OLAP方案可以很好地解决性能问题。该层还有一个方案是腾讯的开源图数据库,可以很好地展现路径情况,是知识图谱场景外的一个比较好的图数据库应用场景。
- 应用和服务部分:除了之后要介绍的开源方案,还有一个重要的部分,就是Jupyter Notebook部分。我们内部做的很多场景中,都是先把做好的数据经过数据治理之后放到ClickHouse数据库中,然后用Jupyter直接去连ClickHouse数据库,这样可以很快得到一个结果。当然Jupyter有它的性能问题,所以我们需要做抽样,将抽样数据放到Jupyter中,这样做是非常快和高效的。这个流程是我们实践过并且落地的,在相关场景中用的比较频繁,可以快速验证各种各样的灵感和想法。
- 数据集市:开源方案也是一个自助式的分析工具。
二、业务实践
接下来将分享我们的一些业务实践,主要包括数据处理和算法挖掘两大部分。
1、数据处理
(1)切分会话
上图左边是切分会话的方式,右边是公开资料中的微信小程序的生命周期,其实左边这张图是右边这张图的技术变体。
我们从APP启动-进入首页-关闭-再启动-浏览各种各样页面-各种各样点击-看短视频-关闭APP,这其实是一个很长的过程。在一个类似信息流的地方,比较高频的刷,每天的曝光少则几十,多则人均曝光四五百。所以曝光日志加上各种各样非曝光日志(比如APP生命周期的启动、关闭及Push),整个链路是非常长的,如何去切分就非常关键,通常主要有两种切法:
- 按照事件去切,比如按照启动和关闭切分。
- 按照时间去切,右边放的微信小程序给的方案是30分钟一次,我们也是按照30分钟一次去切的,是一个常见值。但是如果大家的APP更加高频,时间是可以做调整的。这里只是一个例子,真正的业务场景中比较好用的数据集不止是切这种日志,还有最细粒度的行为层面的日志,我们可以30分钟切一次,也可以1个小时或是1天切一次。
在业务实践中,切分的方式有很多,也是很灵活的,比如可以基于首启进行切分,每天用户看的第一个内容是什么,也可以基于Push切分,用户每天点的第一条推送是什么,也可以基于最后一条记录切分,用户每天最后看的内容是什么。
这里有两点建议:
- 具体的切分方式按照业务场景确定,比如:看流失,可以看流失前的最后三条;看用户增长,可以看漏斗的第一条;看下单,可以看用户购物车的部分。
- 在过去几年的实践过程中,也有很多跟技术有关的迭代。实际中比较好的方式是在埋点SDK层面去做SessionId,就是将SessionId直接写到埋点中,但是这种方式麻烦的地方就是各个不同模块需要用同一个埋点SDK。在很多历史比较久的企业或者迭代很多版本的地方可能很难做到统一的SDK,但是这里还是强烈建议统一的SDK。比较好的方法是,SDK分前端和后端,但是前端和后端SDK分别去报自己的Session_ID和Sub_Session_ID,将其全部保存至Kafka中。有一点需要注意,同一用户的时间要保持一致,不同用户的时间次序不需要完全对得上,比如一个人先看什么,后买什么这个时间次序要保证,但是不需要和另外一个人完全对得上。其实实践中,对于性能和效率可以做很多取舍。
(2)数据处理
数据处理,主要包含两部分内容:
- 异常数据处理,将异常数据去掉才能得出一个相对比较中立的结论。
- 数据抽样,无偏抽样永远是做好数据分析的第一步。
在看所有的分析报告时,异常数据是非常值得关注的。这里有三点需要注意:
- 区分真实页面日志。日志上报生成多条记录,好多日志是多报并且重复的,这会让整个场景变得非常的杂乱,所以该部分我们做了大量的工作去区分什么是真实的页面和日志,在实践中,我们将自己的所有行为全部录下来,然后进行对比,看是否完全一样,所以区分真实页面是非常重要的。
- 合并重复页面。用户在首页来回刷、来回滑动,会造成某些页面大量的数据重复,合并后可以得到更清晰的结果。
- 剔除明显异常用户。我们是按照3σ原则进行剔除的。分析时大家不要去看这些异常日志,但是并不是丢掉,应该将异常数据放在某个地方,专门去看异常用户存在的原因。剔除这些异常用户日志是为了分析,但是异常数据、异常用户还是值得关注的。
数据抽样是为了快速地分析。有两种方法,一种是使用开源系统,另一种是使用算法挖掘。我们内部的做法是将ClickHouse数据直接读到内存中,然后用Jupyter计算,在Jupyter中有很多挖掘算法,因此非常需要抽样。
我们应注意的是抽样的合理性——无偏抽样,这本身也是数据科学中非常重要的内容。看抽样是否合理主要有以下方法:
- 分布应该与大盘一致。
- 参数检验法,比如Z检验、T检验等,可以使用已有工具进行参数检验。
- 非参检验,类似于KS、KL检验等。
以上三个内容可以做成模板或者包,这样每次做数据分析的时候,跑一下这个流水线,结论就出来了。
(3)数据结构
这里介绍下数据结构,也建议大家直接将其做成流水线。
- 原始事件表:按照时间戳记录用户的所有行为及页面曝光,互联网常见是基于Event的日志表;
- Session明细表:就是某个人在某个时间做了什么,整理成Session表,Session表中有Session_ID,Session里还有Sub_Session_ID;
- 用户Session表:将Session和用户串起来,一行代表一个用户,每个Session节点变成一列;
- 图结构数据表:按照From-To的方式存储图的边和节点,这样我们可以用图算法去做数据挖掘。
在实践过程中,这四大类型的表是我们做一个完整的基于Session的数据工程或数据平台所必须的。从分析的角度,不建议非要全量,因为它算起来会比较麻烦,计算量非常大,我们应该做抽样。
一些垂类场景,比如搜索、信息流,本来就是一个非常强的基于时间次序的日志,应用得很多。但是从搜广推场景往外发展到跟产品相关的,Session日志相对来说没有那么多的成熟应用。我们看漏斗、用户增长等还是比较偏原始Event日志。建议大家考虑下自己的业务场景有没有可能把Session用起来,把Session之后的挖掘算法用起来。建议把一些与会话强相关的业务场景转换为Session日志,将基于Event的日志串成Session日志,这样更容易做分析。
2、算法挖掘
我们整理的数据,不能只靠业务直觉判断,需要用算法进行正确的分析。接下来将分享算法挖掘的一些工作。
关于频次挖掘,大家一定都听说过“啤酒与尿布”的例子。这里分享一些与Session有关的频次挖掘。
上图中左上角是一个Session,浏览了页面A、B、C、D,它天然是一个对话的句子,量化行为路径的思路是:
- 把每个动作想象成一个词,把这些词串起来,每一个Session天生就是一个句子。这样就可以用NLP相关的算法来解决这个问题。
- 用Word2vec计算各个页面的n维向量。
- 对每个向量定制化权重,比如每个页面权重都一样1/n,或者用TF-IDF去做,也可以根据场景去设置权重。
- 用降维算法将n维向量降为2维向量,在实际中具体降到几维可以根据具体情况确定,降维主要为了获取特征向量。
上面已通过降维后的2维向量获取到特征向量,就可以做聚类了。上图的左边是聚类的一个示例,不同颜色标代表不同的人群。
下一步就是频次挖掘。聚类后的人群是什么,这个是不知道的,因为它是一个Embedding的高维空间,所以需要用频次挖掘的算法,将人群放到各种各样的挖掘算法中,最后会得到分类。例如有薅羊毛的用户、闲逛的用户等。这样做的好处是,用Embedding和NLP相关的算法挖掘,而不是依赖于纯产品的预判去做数据分析,也可能看到让我们惊喜的部分。
现在我们开始有大语言模型了,过去的做法是将其放到频次挖掘算法中,未来或许可以让GPT告诉我们用户到底关注什么。下一步将尝试用大模型取代Apriori、GSP等传统机器学习的算法来解决问题。
接下来介绍图挖掘算法,数据分析的关键就是我们想要看到平时想不到和未知的部分,这里介绍一个Louvain算法。上图的例子是有一个非常复杂的页面,如果将大量的页面显示出来,是无从分析的,根据这个算法聚类之后,用图的方法就可以很快形成像右下角这个图,就明显很多。聚类有以下好处:
- 便于对路径进行分类;
- 丰富用户画像;
- 便于定位问题,发掘优化点。
这里用到了图数据库,因为图数据库本身有预处理的过程,性能要好很多。这里参考了腾讯云的KonisGraph解决方案,图数据库非常多,大家也可以用其他开源方案。
三、开源方案
下面分享SessionAnalytis这个开源方案,主要介绍工程实现和Demo示例。
1、工程实现
SessionAnalytics开源方案可以在GitHub中找到。该开源方案相对来说比较完备,有前端、后端、数据库以及Demo数据库,下载下来可以直接使用。该开源项目是将我们理解可以固化的部分尽量固化下来了,所以推荐给大家。
我们的项目架构如上图所示,主要包括:
- 数据集成:支持CSV上传、支持mysql数据库,做日志解析同时也有任务调度,系统可以自动去跑数据流水线。
- 数据计算:数据清洗然后做Session切分,切好后可以做结果表的聚合。
- 数据存储:存在mysql中,后续计划换成其他开源方案的,比如Neo4j这样图数据库。
- 可视化:主要是基于Echats的,有许多对Echats的自定义的改动。
- 后端框架:SpringBoot,当时开源的时候也是本着成本低、好上手并且好复用的方式去做的。
数据结构为:
- 用户行为日志表:最左边的表。
- Session日志表:中间的部分,处理成Session日志的时候,会做两个版本,一个版本是重复事件不合并,另一个是合并重复事件。
- 维度表和结果表:参考Kimball建模,生成两种,一种是比较偏Session型的,一种是From-To式的图数据库。
接下来讲下开源方案是怎么做的。左边是例子,右边是对应的代码供大家参考。数据导入后,可以指定用什么事件或什么时间间隔来切分。在这里,我们计算Session切割点,然后生成了Session_ID及Sub_Session_ID。
现在很多平台都支持用户路径,但是使用过程中,发现很多不好用的地方。比如Echarts随机生成桑基图颜色。例子中“娱乐”的每层颜色是不一样的,我们的解决方案是用颜色表,只要是相同的页面,每层颜色都是一样的,这是第一个优化点。
第二个是层级一致性,Echarts自带插件无法按照层级进行排列,数据显示比较混乱,我们将相同层级放到同一列,这是另外一个定制。
第三个是全局筛选,在实际业务场景中,数据量比较大的时候,维度是非常多的,所以该开源平台提供了全局筛选的能力。
第四个是联动筛选,数据量太大了,不想影响用户的关注,做了联动筛选。
第五个是维度分布,点桑基图的每一步,会弹出来一个框,显示具体的人群是什么,展示了细节的指标和分布,可以下钻。
我们要更多地站在用户的角度,去看为什么我们的数据平台用不起来,它遇到的问题是什么,其实很多是跟交互有关的。用户路径是一个例子,原生的桑基图出来之后,是非常散的颜色都是乱的,大家没法看,所以很多优化是在可视化方面。
最后一个是跟性能有关的异步上传,因为当用户量很大时,我们要离线跑流水线,不让用户等。
2、Demo示例
场景一是关于流量异动的,用它很容易看出来流量到底从哪儿变了。比如可能是Push带来很多人,后来又流失了很多。其实在看桑基图之前,我们会有一个直觉的判断,但是看到之后可能发现我们的直觉判断是不准的。尤其是像互联网这种用户增长,渠道分享到某个地方,或者某个地方来了很多黑产用户,或者某个业务场景忽然吸引了很多人,这种都会引起流量非常大的波动。因为我们做一个产品,真正用户喜欢什么,其实也很难完全百分百猜出来,通过这种桑基图,就容易确定问题和原因。
场景二与挖掘有关,举例是开源平台支持的时序聚类。在信息流或推荐系统场景中,一个很大的问题就是冷启动,包括用户冷启动和内容冷启动。因为冷启动的时候,我们没有那么多的上下文信息,我们并不知道什么东西会被喜欢,我们遇到一个很大的问题是一个很好的文章或视频就是分发不起来,或者一个不是很好的视频忽然火了,很难知道原因。但是对于我们做推荐的人或者内容分发的同学,就要去研究一个内容起来或没起来的原因。这种场景就比较偏爱时序聚类了,把维度换一下,用户换成文章,UserId换为DocId,也可以做基于内容的Session。所以遇到内容冷启动,也推荐使用时序聚类。
场景三与漏斗有关,这里分享一个关于用户增长的例子:Push拉活进入APP之后,用户莫名其妙的就丢了。
早期我们只看用户增长的时候,只是说一个漏斗流下来,当100个人漏到50个人的时候,后面的50可能来自另外100个人。但是现在有了时序和Session的好处是我们能够明确这50个人是基于这100个人的,用Session将其串起来是有明确价值的。
建议大家有了Session挖掘的框架之后,可以根据具体业务场景进行替换。
- 我们的用户路径User Session可以换成Doc Session,变成内容路径。
- 可以将点击日志和曝光日志换成时长日志,就可以看出这100分钟怎么变成20分钟的,100分钟与20分钟之间是断的,加上漏斗是50%,但是它隔的时间不一样,有些地方间隔很长,间隔时间特别长的地方也有可能有很大的业务价值。
该应用可以发散出很多场景,维度和指标都是可以换的,可以帮助我们发现很多想象不到的现象。
四、对比
很多数仓是基于Event的,基于Session的正慢慢兴起。在有些场景中,Session变成至关重要的日志。这里从多个角度对比,基于Session的用户路径分析与基于Event的用户事件分析,能够提供的额外价值。
- 业务和日志:Session可以很好地反映用户的行为次序。在统一的用户Id体系中,将各场景的行为日志统一,并按照时间次序分析关联和影响。
- 可视和交互:可视化方法多样,交互分析强大:基于桑葚图、和弦图、树状图等图表,可以很容易将用户看清。
- 统计方法:我们把日志换成不同格式之后,可以用NLP、Apriori和DTW等挖掘算法的智能分析。
- 分析效率:基于ClickHouse、Jupyter对海量数据进行快速分析。
五、Q&A
Q1:页面曝光实际是有多个控件都需要上报吗?具体时间是SDK做自动采集还是代码埋点,如何保证上报逻辑一致?终端后台是否session合并起来?
A:在实际做的过程中,我们是把能上报的尽量放到一起,能用的先用起来。因为数据团队相对比较偏下游,对上游很难做到完全不遗漏的数据治理,所以尽量把那些能用起来的先用起来。对于保证逻辑一致,我建议两种做法,一种做非常重的监控,因为我们没有办法完全保证上游,所以做非常重的智能监控,将各种各样的都监控起来,有问题后马上去查;第二种建议考虑所有场景采用无埋点的SDK去解决这个问题,报上来的东西同一套标准,就可以比较好的解决这个问题。
Q2:key要选什么样的trick,聚成几类?
A:聚成几类,可以按k-means做法中的手肘原则,或者有轮廓系数等参数。开源框架中会预先帮大家把手肘的那个图画出来,也会预先帮大家将轮廓系数算出来,在实践中也是这样参考的。
Q3:用户路径数据分析可用到推荐系统的方面有哪些?
A:跟推荐系统有关的有两大部分,一个是跟算法关系特别强的,一个是比较偏运营的部分。主要还是看有次序的日志,算法本来就有类似LSTM等去串次序。除此之外,我们把用户依次序来看,比如多次召回,之后又做多次Ranking,这中间的用户和内容的变化关系,是可以深入分析的。
Q4:策略产品可以做什么?
A:关于策略,这里分享两个点,一个是用户冷启动,一个是内容冷启动。我相信做推荐的同学,经常被灵魂拷问的就是一个内容怎么推荐不来,好文章为什么起不来。内容冷启动,可以去看为什么起不来。在次序的角度去看内容是特别多的场景。然后就是用户冷启动,那把日志串起来去看用户的热身过程。
Q5:可否具体介绍一下冷启动?
A:用户冷启动就是在用户画像不足的时候,一个用户进来到底推什么,有很多算法可以做,比方说MAB多臂老虎机,或者算法中这种E&E问题,关键还是用户进来的前几百条日志,也就是对前几百个行为去更深地看细节。内容冷启动解决的问题是一个好的内容怎么快速热起来,因为通常来说一个经验值吧,一个好的文章进来,如果24小时起不来那基本就很难起来了。一个好的视频进来,我的经验是2-3天起不来,那也就起不来了,那在这个时候会做很多工作去细看那些出不来是怎么样。
Q6:怎么做渠道归因?
A:渠道归因有很多做法。通过不同渠道拉来的用户都是不一样的。很多快速做法是看首启。比较智能的做法是,用机器学习和训练的方式来做,比如定义关键影响指标为Y,在多重渠道X的情况下,去看每个渠道对最终结果的影响,相当于每个渠道的权重系数是智能的。如果跟用户路径有关,可以结合次序定义参数,其实很多时候比较麻烦的是:今天买了一个商品,可能是因为看了一个短视频,购物车逛了一下,又逛了下信息流,然后别人又给社交推荐,它有多个次序,单看单个动作是很难归因的。这种用户量级比较大场景多变复杂的时候,我们去用统计或机器学习的方法,就方便得出量化参数。