查看原文
其他

如何从0到1构建一个好的用户画像平台?——快手画像平台服务端负责人

张型龙 DataFunSummit
2024-09-10

导读 张型龙,2015 年毕业于中科院研究所,其后入职百度国际化产品部,主要做海外产品服务端研发工作;2018 年入职快手,先后工作于用户增长部和用户理解中心,从事增长和用户画像研发工作。鉴于百度和快手较大的用户量级,很多业务涉及到高并发和分布式的场景,所以在相关领域积累了很多的实践经验。

在快手从 0 到 1 搭建起快手画像平台,也见证了平台在各个业务端应用的过程,基于这些工作经验的总结和沉淀,其编写了《用户画像:平台构建与业务实践》一书,本次分享的内容大部分也包含在本书中。本文主要包括以下五部分内容:

1. 画像平台及其价值

2. 画像平台常见功能

3. 画像平台常见架构及开源实现方案

4. 画像平台工程优化思路

5. 业界发展现状

分享嘉宾|张型龙 快手 画像平台服务端负责人 

编辑整理|李梦

内容校对|李瑶

出品社区|DataFun


01
画像平台及其价值

当我们说一个用户是北京市男性用户的时候,其实就是在描述画像信息。每一个公司都积累了大量用户数据,借助用户画像可以将大数据的价值体现出来,并且运用到各种运营场景里去,实现运营效率的提升,最终获得业务价值。画像平台则可以提高用户画像数据的生产和使用效率,实现用户画像的产品化和功能化。用户画像数据是企业运营的数据基础,而画像平台是企业必备的基础设施,值得每一个公司花时间和精力将其做好。

02

画像平台常见功能

任何业务领域都能找到一些通用的功能,用户画像常见的商用平台如神策数据、GrowingIO、火山引擎、阿里的智能增长平台,它们的画像相关功能都有一些通用的部分,总结起来画像平台常用的功能模块分为标签管理、标签服务、分群功能和画像分析。

1. 标签管理

标签管理就是对标签做一些增删改查,这个模块的重点在于标签生产。常规模式下要加工一个标签,通常需要找数据同学提出加工需求;而在画像平台场景下,可以通过简单的拖拽配置,定义一个标签生产逻辑,然后自动化加工生产这个标签。标签管理也要重视对标签质量的监控。

2. 标签服务

标签生成后可以通过接口的形式对外提供标签查询服务。比如调用方传入 UserId,可以通过接口的形式快速返回该 UserId 对应用户的标签值,例如该用户的性别、兴趣爱好等信息。

3. 分群功能

在标签数据之上可以实现分群功能,分群功能就是通过多种方式找到目标用户。业界最常见的两种分群方式是规则圈选和导入人群。

规则圈选就是基于底层的画像标签,通过交并差的条件组合筛选用户,例如喜欢军事题材、常住地是北京,且性别是男性的用户。导入人群就是将其他数据源的数据,导入到画像平台中构建成一个人群包。

人群圈选的方式还有很多种,要根据业务需求来确定。例如相似人群、人群扩量,还有人群组合。其最终目标就是从不同的数据源里找到想要的 UserId 并构建成一个人群包。

人群构建后就可以对外提供服务,最常见的就是人群判存服务,它用来判断一个UserId 在不在指定人群包中,也叫人群判定。另外,人群包还有一些附加功能,如把一个大人群包等量拆分成小人群包的人群拆分,人群抽样和人群下载等等。

4. 画像分析

借助画像数据,可以对人群包下的群体或单一用户进行分析,比如进行分布分析、趋势分析、价值分析等等。

03

画像平台常见架构及开源实现方案

业界画像平台常采用分层架构,如下图所示:

1. 数据层

底层数据大部分存储在大数据平台中,在该层可以借助大数据组件来生产标签,然后构建宽表。例如在 Hadoop 体系下利用 HDFS 存储数据,Spark、Flink 作为计算引擎,Yarn 进行资源调度,DolphinScheduler 进行任务调度。标签分为离线标签和实时标签,经过清洗整理,汇总到画像宽表中,来提高画像数据的使用效率。

2. 存储层

在各种场景下,通常会借助一些引擎来提高数据的查询和应用效率。例如可以把 Hive 中的数据写到 ClickHouse 引擎中提高画像数据查询效率,还有 Kudu、Doris、Hudi 等其它一些数据存储引擎在业界也有使用。另外为了提高标签数据查询效率,也可以将其写入 Redis、HBase 等。还可以将人群数据进行压缩或者序列化存储到 OSS 这类对象存储中,方便其它业务调用。

3. 服务层

在底层数据之上,可以封装一些基础的服务,比如标签服务、人群服务。在 Java 技术体系下,基于 SpringBoot 和 SpringCloud 来实现。SpringCloud 用于构建微服务,主要用在高并发的服务场景下,例如前面提到的标签查询服务。

4. 应用层

有了这些画像服务和数据,就可以通过可视化平台或者 SDK 形式将这些能力提供出来供业务使用。

04

画像平台工程优化思路

在介绍画像平台常见的优化思路之前,先来梳理一下常规的人群圈选和画像分析流程,如图所示:

在流程的初始阶段,首先将不同数据源的标签整合,形成一张画像宽表,这是数据处理的核心环节。接着,人群圈选引擎将从这张宽表中筛选出符合特定条件的用户,并生成相应的人群圈选结果。借助于人群圈选结果和画像数据,可以通过画像分析引擎进行深入的画像分析。最后,基于人群结果数据可以向外提供多种服务,例如上文提到的人群判存服务。

在上述流程中存在多个可优化的部分,包括画像宽表生成、人群圈选、画像分析,以及人群服务中的判存服务等。以下将详细介绍各部分的优化思路。

1. 画像宽表优化

为什么需要一张画像宽表呢?在传统模式下,如果要查找河北省男性用户,其涉及到的性别和常住省份标签数据可能分布在不同的数据表中。为了找到满足条件的用户,可能需要构建一条复杂的关联查询,将两个表连接在一起,然后筛选出满足条件的用户 ID。如果查询条件变得非常复杂,涉及到更多标签,而这些标签分散在不同的表中,那么整个查询过程将变得冗长低效。将这些分散在不同数据源中的表汇总成一张宽表,就是优化的关键。通过构建这样的宽表,整个查询逻辑变得简单明了,只需在 where 子句中添加相应的条件即可,这种宽表的模式能够显著提高整个圈选逻辑的执行效率。

除了提高效率外,宽表还能够解决一些其他问题,比如权限可以集中管理,在原始方式下,不同部门的数据可能分散在不同的库表中,需要申请多个表权限。而有了宽表,权限管理变得更加集中化,申请一张宽表的权限就能够满足多个条件的查询需求,从而简化了权限管理的过程。

画像宽表也可以实现数据解耦,以往依赖于众多上游标签表的情况下,任何一个上游的变化都可能影响后续执行逻辑。画像宽表将所有上游标签表汇总后,上游数据变动不再影响后续人群圈选执行逻辑。

宽表的生成需要将上游各类标签表进行 Join,这种做法的问题就是执行速度慢,尤其在涉及到大量标签的情况下,可能涉及几十或上百张表进行 Join 运算。为了解决这个问题,可以采用分治思路,将上游大量的数据表进行分组,然后并行处理这些组,最后合并中间表得到最终的宽表。这种分组并行的策略在执行速度和效率上都有显著的提升。标签划分过程并非简单随机,可能会考虑一些策略因素,例如标签的数据量级、产出时间等。

不过这种模式下,仍然存在数据耦合的问题。主要体现在执行逻辑上还是直接依赖于上游标签表,在执行过程中,如果上游标签表发生变化,比如突然阻断、删除或重写数据等,都会对下游执行产生影响。另外,在生成中间宽表的过程中可能对数据进行一些处理,比如对性别进行编码以减少存储空间,或对数组进行截断处理等。在现行模式下,清理逻辑通常写在 SQL 语句中,耦合度会比较高。为了降低耦合度,可以考虑采用分层思路,引入一个数据加载层。首先,通过该层将上游各标签以更细粒度加载到自身的库表中。然后在加载过程中,对数据进行清理,如编码、截断、清洗等。通过引入数据加载层,可以解决上述数据耦合问题。

在这些优化逻辑下,其执行速度尚未达到理想状态,宽表的生成还是依赖大数据框架进行数据表之间的 join 运算,join 运算最耗时的阶段通常出现在后续数据 shuffle 过程中。以 Map 阶段为例,初始的 Map 操作会对所有 UserId 进行分片,然后将相同 UserId 的数据 shuffle 一起后交由 Reduce 来执行,其中最为耗时就是 shuffle 过程。

此时可以考虑在加载数据时进行一些预处理,减少后续的数据 shuffle 操作。此处可以引入 Bucket 表,在数据加载层提前将 UserId 落在相应的 Bucket 中,减少后续的 shuffle 过程,从而提高整个宽表生产的速度。

综上所述,可以通过分治方法,增加并发度,来提高宽表的生产速度;通过引入数据加载层,降低数据耦合问题;在加载阶段进行数据预处理,将 UserId 提前落入相应的 Bucket 表中,最终降低后续 shuffle 过程的耗时。

2. 人群圈选优化

有了画像 Hive 宽表,便可以实现人群圈选,此时可以执行一些 Hive SQL 语句查找满足条件的用户 ID 并插入到人群结果表中。这种方式简单易实现,但速度慢、性能不稳定,对计算资源有明显依赖。在大数据计算资源充裕时,速度相对较快,资源紧张时,计算缓慢。另外人群数据输出效率较低,对于第三方业务,想要拉取人群数据进行投放,只能通过拉取 Hive 表的方式,效率不尽如人意。

为提高人群圈选速度,可以采用缓存思路。此处可以引入 ClickHouse,将 Hive 表中的数据同步到 ClickHouse 中进行缓存。人群圈选引擎可以从 ClickHouse 中直接查询到满足条件的 UserId,并将这些 UserId 写入内存中的 BitMap,之后可以序列化并存储到对象存储引擎中,从而解决圈选速度的问题。同时可以提高人群包对外输出性能,此时不再通过 Hive 表提供人群包,而是可以通过接口秒级拉取到人群 BitMap 数据,相较于之前 Hive 表需要几分钟到十几分钟,性能提升明显。

引入人群包 BitMap 也带来了一些问题,在某些场景下,人群包数据还需要在Hive 中也存储一份用于分析和备份。此时人群包要保存为两种形态,在这种情况下,有一个小技巧可以提高人群 BitMap 和人群 Hive 表之间转换效率,那就是直接操作 HDFS 文件。例如,人群包先在 Hive 中生成数据,想快速生成 BitMap,可以直接读取底层的 HDFS 文件,并发解析分片文件里的数据,然后在内存中构建BitMap。

上面的人群圈选思路仍然是从宽表出发,找到满足条件的用户 ID 并构建成人群包结果。可以尝试换一种思路,提前将北京市的所有用户和男性用户构建成一个 BitMap,然后在内存中基于这两个 BitMap 做交集运算,就能快速得到所有的北京市男性用户。这种方式在实践中证明效率更高,通过空间换时间的思路,提前加工标签值的 BitMap,在人群构建时借助 BitMap 提高计算效率,从而提高人群圈选的速度。

但是,BitMap 并不适用于所有标签,其适用范围主要局限于标签值可枚举的标签,如性别和常驻省份。BitMap 无法表达连续值的标签,如在线时长等。

在实际场景中,可能会面临混合数据的情况,既有宽表的明细数据,又有 BitMap 数据。在这种情况下,关注点主要在于规则圈选引擎的优化。以上图为例,正常用户可能会通过一些组合构建复杂的筛选条件,形成左侧的树状结构。在这个树状结构中存在许多优化空间,可以合并一些 and 和 or 关系。如果 BitMap 能够覆盖大部分标签且计算速度理想,可以优先使用 BitMap,即先计算 BitMap 的部分,然后与明细一起计算,最终自底向上汇总为执行结果。这里要考虑数据量级,在数据量较小的情况下,整个树状结构也可以通过一条 SQL 直接计算出来。

总体而言,优化人群圈选的方法包括利用缓存,在特定场景引入 BitMap,并在复杂模式下对圈选规则引擎进行优化,全面提高效率。

3. 人群画像分析优化

前面提到的优化逻辑也可以应用在人群画像分析中。当有一个人群结果表和一个画像宽表时,如果需要计算这个人群下用户的性别分布,传统的实现模式是对两张Hive 表进行 join,计算出男性和女性的分布。应用之前提到的缓存思路,此时也可以将标签宽表和人群结果表同步到 ClickHouse,这样可以显著提高计算速度。此外,仍然可以运用空间换时间的思路,在画像分析中也可以基于 BitMap 进行计算。例如,想要计算一个人群包下的男女分布,只需将人群的 BitMap 与男性和女性的 BitMap 进行交集运算,即可迅速计算出该人群包下男女用户的数量。

4. 人群判存优化

人群创建成功之后可以对外提供人群服务,其中人群判存是最重要的服务之一。在业务中,常需要快速确定某个 UserId 是否存在于特定人群包内。在传统实现模式下,人群包的数据会从 Hive 同步至 Redis,并借助相应的数据结构来组织这些数据,判存时相当于查找相应的键和数值是否存在。

如果一个人群包每天都是定时更新,那么按照传统逻辑,每次更新都需要全量替换,速度较慢。另一个问题是,新版本人群包在写入过程中,可能在一个时间阶段内与老版本的数据共存,但某些业务可能对此很敏感。

对于以上两个问题,有两个简单的优化思路。第一个是增量更新,即在新版本写入的过程中,与老版本进行对比,确定主要差异的数据,比如哪些数据要删除,哪些数据要新增,间接地减少写入缓存的数据量,提高了整个人群判存服务的效率。对于第二个问题,可以在新版本写入数据的过程中添加版本标识,写入完成后,在业务需要的时间点将版本切换。

上述这两种优化方案还是基于将人群包 Hive 数据写入到 Redis 中,写入过程都需要一定的时间,尤其是在人群包较大的情况下,可能需要几十分钟或者更长时间。在许多场景下我们希望一旦成功创建人群包,就能在短时间内使用判存服务。为了解决这个问题,可以将人群包 BitMap 直接放入内存中来支持判存服务,该方式可以明显提升判存服务的性能和可用性。这种方式下引入新的问题在于需要使用内存,要考虑如何尽量减少对内存的使用。可以进行一些均衡设计来优化内存使用。例如,可以考虑将 UserId 对应的 CrowdId 组成的 BitMap 存在内存中,提高空间利用率。此外,在构建判存服务的过程中,需要注重 BitMap 的压缩率,关注数据的存储格式等。

上面人群判存服务、画像分析优化等,都涉及到了 BitMap 的概念。在画像平台中,BitMap 是一种广泛使用的数据结构。BitMap 通过 0 和 1 来标识数据是否存在,是适合存储数值类型的数据。对于人群包中使用设备 ID、IMEI、IDFA 等非数字类型的 ID,解决方案通常是在底层将非数字类型的 ID 映射成数字类型的 ID。将字符串映射为数字后,上层的架构和业务逻辑都可以通过 BitMap 等方式使用,而用户则无需感知底层是字符串还是数字。最终使用人群包时,例如圈选一个设备 ID 的人群包,需要调用 ID 映射服务获取真实的设备 ID。

在 Java 语言中,常常会使用 RoaringBitMap 这个开源工具。在使用 RoaringBitMap 时,需要注意存储的数据数字越小越好,数字越连贯越好。因为底层数据结构决定了数据越小或者越连贯,整体的压缩效率就会更高。如果 ID 非常随机或者非常大,可能会导致一些内存溢出的问题。

5. 任务模式的使用

在画像平台的业务场景中,业务流程通常较长,比如一个流程中涉及到上游资源是否就绪检查、人群创建、分析、人群包下载、人群推送等。由于业务流程较长,如果想提高某个任务或人群包处理的优先级,或者在某个环节发生失败时重试都不太容易。为了解决这个问题,可以将流程打散,把整个长流程拆分成各个独立的任务。每个任务都被看作是一个独立的单元,放入任务队列中。通过控制任务的优先级和资源使用情况,可以更灵活地进行任务的管理和调度。借助该种模式也可以更容易地对整个系统进行扩容,实现并发控制和优先级控制,整体提高了系统的可用性。

以上就是画像平台建设中的一些工程优化思路,包括分治、解耦、分层以及空间换时间等。这些思路不仅在画像平台的开发中有应用,也在其他技术领域中被广泛使用。希望在大家的业务和开发中能够尝试应用这些思路,提高系统的性能和可用性。

05

业界发展现状

在技术选型方面,没有最好的选择,只有最合适的。在进行技术选型时,需要考虑业务发展现状、实际需求以及公司技术积累等因素,根据实际情况做出合适的选择。

对于画像平台的发展趋势,有以下看法:

1. 实时数据要求增加

画像平台对实时数据的需求越来越高。以前主要依赖离线标签进行分析,可以实现 T+1 的画像服务,但随着运营越来越精细化,对实时性的要求逐渐提高。例如,用户上午进行了某个操作后,下午就要能够针对其进行相应的运营活动。

2. 智能化运营

首先是多维数据建设,即基于用户画像,整合多维数据进行圈人和分析。比如把用户画像、作者画像、作品画像等等更多维的画像融合在一起,共同做圈人和分析,提高人群包的准确率。

其次是智能化投放,现在的投放模式大部分是在画像平台上圈一个人群包,再到其它投放平台把这个人群包投放出去。参考神策实现的流程画布,可以把人群圈选逻辑、触达逻辑、业务目标在一个画布里统一管理,把整个运营流程串连起来。

最后是关于所有投放数据的回收和沉淀,所有的投放都不是做一锤子买卖,而是根据投放结果,反向推动后续如何更精准的圈人,综合提高运营效果。

3. 机器学习和人工智能

在实践过程中发现,通过算法挖掘人群包,相对于基于规则或导入人群的方法,具有更好的效果。但是当前受限于人力和机器资源,每次创建人群都依赖于算法实现还不太可行。但这是一个方向,目前各个平台都在努力将算法更好地融入到整个流程中。

另一方面,人工智能的发展和大型模型技术的进步为我们带来了一些机会。可以尝试将大模型技术应用于圈选和分析中,通过大模型的视角获取更为准确的人群结果或独特的分析,为后续运营行动提供更优质的指导。

以上就是本次分享的内容,谢谢大家。


分享嘉宾

INTRODUCTION


张型龙

快手

画像平台服务端负责人

毕业于中国科学院软件研究所,毕业后入职百度国际化产品部,主要从事服务端研发工作,完成了海外消息服务、图片服务的升级和优化,在服务端架构、分布式与高并发方面积累了一定的经验。之后加入快手,主要从事用户增长与用户画像相关工作,在此期间从 0 到 1 搭建了公司的用户画像平台,并发表专著《用户画像:平台构建与业务实践》。

课程推荐

往期推荐


金融大模型的最优技术决策

腾讯音乐在音质 AIGC 的应用与实践

劳斯莱斯数据科学工程实践

EB 级存储规模 HDFS 在字节的探索与实践

蚂蚁大规模知识图谱构建及其应用

全民K歌音频技术:灵魂歌手的升级神器!

LLM 在马上消费金融的应用实践

字节数据可视化 VTable——不止是高性能表格组件

兼顾降本增效,StarRocks 3.0 关于存算这对CP分离的最佳"姿势"

基于“数据-模型-策略-实验”生态闭环的智能风控实践

B站数据服务中台的建设实践

因果推断在蚂蚁风控场景中的应用

大语言模型在开放世界中的推理能力探索实践

点个在看你最好看


继续滑动看下一个
DataFunSummit
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存