近期,由于项目需求,需要构建一套消费者的用户画像。这是一套偏大数据处理和实时数仓领域的解决方案,因为之前对这个领域并不熟悉,因此做了下前期的方案调研和初步的解决方案设计,本文将这个过程做个记录总结,希望能够对同样第一次接触这个领域,需要入门的同学有所帮助。
一. 用户画像构建方法调研
在方案调研前期,主要是调研业界现有的主流用户画像构建方案。通过网上的搜索和学习,发现用户画像的构建方案大都大同小异,其中,《用户画像:方法论与工程化解决方案》 一书对用户画像做了较为全面的整理和概括,因此,笔者前期主要是快速学习本书的知识,本章也是对这本书的知识总结。
1.1 用户画像基础
1.1.1 用户画像是什么
用户画像,即用户信息标签化,通过收集用户的基础属性、社会属性、消费习惯 、偏好特征等各个维度的数据,进而对用户或产品特征数据进行刻画,并对这些特征进行分析、统计,挖掘潜在价值信息,从而抽象出用户的信息全貌。
用户画像建模,其实就是对用户“打标签”,从对用户打标签的方式来看,一般分为(1)统计类标签(2)规则类标签 (3)机器学习挖掘类标签
1. 统计类标签
统计类标签是最为常见的标签类型,如用户的性别、年龄、星座、近7日活跃时长等等,该类标签构成了用户画像的基础。
2. 规则类标签
规则类标签是基于用户行为及确定性规则产生的,如对平台活跃用户的定义口径为“近30天交易次数>=2”,实际开发画像的过程中,由于运营人员对业务更熟悉, 而数据人员对数据的结构、分布、特征更为熟悉,因此规则类标签的规则由运营人员和数据人员共同协商决定。
3. 机器学习挖掘类标签
算法类标签是通过机器学习挖掘产生,对用户的属性或者行为进行预测和判断。例如根据用户的行为习惯判断该用户是男性还是女性。
在实际实践中,一般统计类标签和规则类标签即可满足应用需求,在开发中占有较大比例。一般机器学习类标签开发周期较长,开发成本较高,因此其开发所占比例较小。
1.1.2 数据架构
上图是用户画像的数仓架构图,下方虚线框中为常见的数据仓库ETL加工流程,也就是将每日的业务数据、日志数据、埋点数据等经过ETL过程,加工到数据仓库对应的ODS层,DW层,DM层。
中间的虚线框即为用户画像建模的主要环节,用户画像不是产生数据的源头,而是对基于数据仓库ODS层,DW层,DM层中与用户相关数据的二次建模加工。在ETL过程中将用户标签计算结果写入Hive,由于不同数据库有不同的应用场景,后续需要进一步将数据同步到MySQL、HBase、ElasticSearch等数据库中。
1.1.3 主要覆盖模块和开发流程
搭建一套用户画像方案整体来说需要考虑8个模块的建设,包括:用户画像基础,画像标签的数据指标体系、标签数据存储、标签数据开发、开发性能调优、作业流程调度、用户画像产品化、用户画像应用。如下图所示:
而用户画像的开发流程如下图所示,可以分为7个阶段:
第一阶段:目标解读
在建立用户画像前,首先需要明确用户画像服务于企业的对象,再根据业务方需求,明确未来产品建设目标和用户画像分析之后的预期效果。
第二阶段:任务分解与需求调研
经过第一阶段的需求调研和目标解读,我们已经明确了用户画像的服务对象和应用场景,接下来需要针对服务对象的需求侧重点,结合产品现有业务体系和“数据字典”规约实体和标签之间的关联关系,明确分析维度。
第三阶段:需求场景讨论与明确
在本阶段,数据运营人员需要根据与需求方的沟通结果,输出产品用户画像需求文档,在该文档中明确画像应用场景、最终开发出的标签内容与应用方式,并就该文档与需求方反复沟通并确认无误。
第四阶段:应用场景与数据口径确认
经过第三个阶段明确了需求场景与最终实现的标签维度、标签类型后,数据运营人员需要结合业务与数据仓库中已有的相关表,明确与各业务场景相关的数据口径。
第五阶段:特征选取与模型数据落表
本阶段中数据分析挖掘人员需要根据前面明确的需求场景进行业务建模,写好HQL逻辑,将相应的模型逻辑写入临时表中,并抽取数据校验是否符合业务场景需求。
第六阶段:线下模型数据验收与测试
数据仓库团队的人员将相关数据落表后,设置定时调度任务,定期增量更新数据。数据运营人员需要验收数仓加工的HQL逻辑是否符合需求,根据业务需求抽取表中数据查看其是否在合理范围内,如果发现问题要及时反馈给数据仓库人员调整代码逻辑和行为权重的数值。
第七阶段:线上模型发布与效果追踪
上线后通过持续追踪标签应用效果及业务方反馈,调整优化模型及相关权重配置。
1.2 数据指标体系
数据指标体系是建立用户画像的关键环节,也是在标签开发前要进行的工作,具体来说就是需求结合企业的业务情况设定相关的指标。互联网企业在建立用户画像时一般除了基于用户(userid)建立一套用户标签体系外,还会基于cookieid、设备id等建立相应的标签体系。
按标签维度,可以分为用户属性类、用户行为类、用户消费类和风险控制类等常见类型。
1.3 标签数据存储
在用户画像系统搭建过程中,数据存储的技术选型是非常重要的一项内容,不同的存储方式适用于不同的应用场景。外部基于开源体系主要的存储方式有Hive,MySQL,HBase,Elasticsearch等。
1.3.1 Hive存储
建立用户画像首先需要建立数据仓库,用于存储用户标签数据。Hive是基于Hadoop的数据仓库工具,依赖于HDFS存储数据,提供的SQL语言可以查询存储在HDFS中的数据。开发时一般使用Hive作为数据仓库,存储标签和用户特征库等相关数据。
如果将用户标签开发成一张大的宽表,在这张宽表下放几十种类型标签,那么每天该画像宽表的ETL作业将会花费很长时间,而且不便于向这张宽表中新增标签类型。
要解决这种ETL花费较长时间的问题,可以从以下几个方面着手:
- 将数据分区存储,分别执行作业。
- 标签脚本性能调优。
- 基于一些标签的共同的数据源开发中间表。
例如,可以根据标签指标体系的人口属性、行为属性、用户消费、风险控制、社交属性等维度分别建立对应的标签表进行分表存储对应的标签数据。
最后,将用户身上的标签做聚合处理,方便分析和查询。
ID-Mapping
在用户画像标签的开发过程中,一个重点工作是进行不同数据源之间数据的关联,即ID-Mapping,把用户不同来源的身份标识通过数据手段识别为一个主体,消除数据孤岛,达到扩展用户标签维度的最终目的。
例如上图所示,在包裹签收表里只有收件人的手机号,但是为了获得他的性别,常用手机品牌,过去的交易订单等信息,就需要使用手机号去关联他的淘宝账号id,然后用淘宝账号id去关联他过去的订单等信息,这样才能尽可能多的获得用户多维标签。
但是用户是会换手机的,手机和会员帐号的对应关系会随着时间而缓慢变化,为了记录这种变化,可以设计如下的缓慢变化拉链维表:
user_id | mobile | start_date | end_date |
---|---|---|---|
zhangsan | 123456 | 2020-10-11 | 9999-12-31 |
zhangsan | 789012 | 2009-10-10 | 2020-10-10 |
lisi | 125467 | 2009-10-10 | 9999-12-31 |
如上表例子所示,如果zhangsan这个用户换手机了,为了获得他在2020-10-10以前的物流签收信息,可以通过ID-MAPPING获取他在那之前的手机号,再用手机号获取他的物流签收信息。
1.3.2 MySQL存储
MySQL作为关系型数据库,在用户画像中可用于元数据管理、监控预警数据、结果集存储等,下面介绍下元数据的管理。
标签元数据用来对标签的名称,属性,来源等进行描述。如下图所示:
可以定义如下数据结构的标签元数据:
id | 标签label | 标签名称 | 一级属性 | 二级属性 | 三级属性 | 创建时间 | 修改时间 | 标签来源 | 标签备注 |
---|---|---|---|---|---|---|---|---|---|
1 | pre_gender | 预测性别 | 个人基础信息 | 身份信息 | 2020-11-03 12:00:01 | 2020-11-03 12:00:01 | demo_table | 0代表女,1代表男,2代表未知 |
1.3.3 HBase存储
HBase是一个高性能、列存储、可伸缩、实时读写的分布式存储系统,同样运行在HDFS上。与Hive不同的是,HBase能够在数据库上实时运行,而不是跑MapReduce任务,适合进行大数据的实时查询。
画像系统每天在Hive里跑出的结果集数据可同步到HBase数据库,用于线上实时应用的场景。
1.3.4 ES存储
ES是一个开源的分布式全文检索引擎,可以近乎实时地存储、检索数据。而且扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。对于用户标签查询,用户人群计算,用户群多维透视分析这类对响应时间要求较高的场景,可以考虑使用ES进行存储。
1.4 标签数据开发
标签数据开发是用户画像体系搭建中最重要的环节,主要包括离线标签开发、实时类标签开发、用户特征库开发、人群计算、打通数据服务层等开发内容。
离线标签开发主要围绕统计类、规则类及算法类等三类标签展开;实时类标签主要针对用户展现实时性较强的场景开发相关数据,如首页新人弹窗、新人红包场景;用户特征库围绕用户的每次行为明细记录相关数据,如用户搜索、点击、浏览、加购、收藏、下单等行为明细,一般该特征库按日做时间分区,但为了进行用户的实时个性化,也会有实时数据的计算流程;人群计算应用在数据服务层之前,业务方需求组合用户的标签来筛选出对应人群,通过人群计算功能组合标签划分出对应的人群;打通数据服务层将业务方根据业务规则圈定出来的用户人群推送到不同的业务系统中去。
具体的统计类标签开发,规则类标签开发和算法类标签开发细节可以参考《用户画像:方法论与工程化解决方案》
1.5 性能调优
为了以最快的速度更新数据并通过服务层提供服务,画像基础设施需要持续针对ETL调度时间进行优化,主要有以下优化点:
• 数据倾斜优化。数据倾斜是开发画像过程常常遇到的问题,当任务运行一直卡在map 100%、reduce 99%,最后的1%花了几个小时都没有执行完时,这时一般是遇到了数据倾斜。
• 小文件合并优化。分布式文件系统按块Block存放,文件大小比块大小小的文件,称之为小文件。小文件过多会影响整体的执行性能和空间的有效利用率。
• 中间表优化。在用户画像的迭代开发过程中,初期开发完标签后,通过对标签加工作业的血缘图整理,可以找到使用相同数据源的标签,对这部分标签,可以通过加工中间表缩减每日画像调度作用时间。
二. 初步方案设计
通过对《用户画像:方法论与工程化解决方案》 的快速学习,了解了构建用户画像的通用解决方案。结合我们的应用场景和公司的基础设施,我们设计了如下的用户画像整体解决方案。
2.1 整体架构设计
物流画像的整体架构如下图所示,系统可以分为接入层,存储层,服务层和应用层。
2.2 接入层设计
用户画像的数据来源多种多样,可以从物流数据,订单数据,app交易数据,工单信息表等数据来源获得。此外,除了已有的表数据,还可以通过日志分析等数据源获取数据。
所有这些数据源,从实时性区分,可以分为离线数据和实时数据。实时数据可以通过kafka等进行接入,最后通过flink进行分析计算;离线数据可以通过HIVE进行训练分析,得到画像标签。
在这里我们采用了将实时流式计算和离线批量分析拆分成2种不同的独立架构的传统架构方案,是基于以下考虑:
- 我们的离线标签和实时标签的数据来源不同。现有的流批一体大数据分析架构,不管是lambda架构还是kappa架构,都是为了应对历史数据和实时数据来源相同,历史模型和实时模型的事实表基本相同的场景而设计的。但在用户标签的具体应用中,我们的离线数据来源于各种明细数据表,实时数据来源于日志表流,来源并不相同,处理逻辑也并不一样,因此使用流批一体架构并没有显示的好处。
- 我们的数据大部分来源于离线数据。类似kappa的流批一体架构,会将批处理转化为流处理,而流数据天生的数据质量不可控,尽管缩短了数据处理时间,但可能牺牲数据的正确性和完整性;在大部分数据来源是离线数据的情况下,这种牺牲是不值得的。
- 在项目前期不需要流处理数据的时候,这种架构能够支持我们项目快速迭代,验证数据的准确性,快速满足业务需求。
当然,这种架构也存在分别维护实时分析与离线分析两套不同架构的服务,对于系统运行的稳定性,后续应用升级,故障处理等都会比较复杂和繁琐的缺点;这个可以通过前期定义好接入标准,ETL标准流程等在一定程度上得以解决。
2.2.1 离线接入层
离线接入层主要对从离线数据源得到的数据进行离线分析,统计和训练,得到统计类,规则类和机器学习挖掘类标签。这里使用集团的HIVE进行离线分析处理。
1 标签表结构设计:
标签表数据分为全量数据和增量数据,下面介绍这几种表结构的设计。
标签全量表在当天的分区中插入截止到当前为止的全量数据,全量表的表结构设计如下:
create table if not exists user_profile_label_all(
user_id string comment '用户id',
label_value string comment '标签值')
comment '标签全量表'
partitioned by
(ds string comment '数据日期', label_id string comment '标签id')
lifecycle 7;
标签增量表在当天的分区中插入当天业务运行产生的数据,用于查找在特定时间内被打上特定标签的用户,或者作为用户行为标签明细。增量表的表结构设计如下:
create table if not exists user_profile_label_delta(
user_id string comment '用户id',
label_value string comment '标签值',
label_id string comment '标签id')
comment '标签增量表'
partitioned by
(ds string comment '数据日期')
lifecycle 365;
2 ETL流程:
(1)最开始,没有全量表,则此时可以使用一份较全的数据作为基准表数据,构建一份基础全量数据。例如可以使用过去一年的站点签收数据作为基准数据,构建一份包含过去一年物流消费者用户的基础画像数据。
(2)有了全量表之后,再从每天的增量数据中提取出增量表,例如提取过去7天的签收数据:
insert overwrite table use_profile_logistics_delta partition(ds="bizdate")
selelct
"sign_num" as label_id,
count(*) as label_value,
user_id as user_id,
from
dncdm.dwd_csn_dn_lgt_sms_pkg_di where ds="bizdate"
group by mobile;
(3)有了增量表后,用全量表和增量表做全联接,去更新全量表:
-- 使用全量表和增量表做全连接,更新全量表
insert overwrite table use_profile_logistics_all
partition(ds="bizdate",label_id="sign_num")
select
coalesce(t1.label_id, t2.label_id) as label_id,
coalesce(t1.label_value, t2.label_value) as label_value,
coalesce(t1.user_id, t2.user_id) as user_id
from
(select * from use_profile_logistics_all where ds="bizdate-1"
and label_id="sign_num") t1
full outer join
(select * from use_profile_logistics_delta where ds="bizdate"
and label_id="sign_num") t2
on t1.user_id = t2.user_id and t1.label_id=t2.label_id;
综上所述,标签表的更新流程如下图所示:
2.2. 实时接入层
实时接入层的模型定义和离线层的类似,不过都是增量数据。数据处理后,直接导入存储层进行存储。同时,实时接入层的每个标签,也需要增加元数据,进行管理。
2.3 存储层设计
2.3.1 存储选型
用户画像数据有如下特点:
- 数据量大:物流消费者拥有者海量的用户,以众配宝物流签收表dncdm.dwd_csn_dn_lgt_sms_pkg_di为例,去过去一年不同收件号码的用户,就有1.4亿的用户。海量的用户意味着会产生海量的行为数据,基于海量明细数据,通过离线模型训练产出最终的用户画像,最终的用户画像数据往往也是数以亿计的高维(数百,数千甚至万计的字段数量)数据。
- 高并发读写:海量用户数据需要实时写入到后台的存储系统中,因此数据写入的并发度往往会达到每秒数万,数十万甚至数百万或更高。同时,用户画像数据的在线应用场景,如校园件,按需上门,用户分析等,要求高并发低延迟的查询。
- 有动态列需求:用户画像的数据维度往往处于不断变化不断丰富当中,因此表结构也会处于不断变化当中。
- 查询种类多而且复杂:面向不同的业务需求,对用户画像数据的查询需求也会有差异。比如:获取用户的画像数据,只需要根据key做单条记录的查询;对用户行为数据的分析,可能是按照用户ID批量获取其数据;也可能是运营人员根据需要查询某个维度的统计数据。
基于以上用户画像数据特点,我们选用阿里云的Lindorm作为我们的实时存储,理由如下:
- Mysql作为SQL类型数据库,对动态列的支持较弱,此外,MySQL是行式存储的,不适合按照某个维度统计和查询数据的场景,特别当满足条件数据可能达到百万,千万级别的时候。
- Lindorm支持高吞吐的qps和tps,价格低廉,支持动态列,是最适合用户画像场景的数据库。
此外,选用Lindorm具有以下优势:
- 低成本。Lindorm的低成本能力体现在:(1)多样化存储类型支持,性能型存储、标准型存储、容量型存储,总有一款适合业务场景;(2)深度压缩优化;(3)冷热分离。
- 高性能吞吐。根据实测同样规格,相同数据量的情况下,Lindorm不管是在单行读、范围读还是单行写及批量写场景下,其吞吐量和P99延迟相比社区版本HBase2.0都有数倍提升。
- 动态列。Lindorm的宽表模型支持多列簇、动态列、TTL、多版本等特性,可以很好的适合用户画像这样表结构不稳定,经常需要进行变更的业务场景。
- 多维度&复杂查询。对于基于rowkey的单key或基于rowkey前缀的scan,Lindorm自身就可以很好的满足业务的需求。当遇到多维度、少量组合列,而且有固定查询模式的场景来说,Lindorm内置的高性能全局二级索引功能也可以满足业务需求,同时仍保持强大的吞吐与性能。当面对更加复杂的查询,比如模糊查找、随机条件组合查询等等,二级索引方案会显得力不从心,这时候Lindorm搜索引擎LSearch就有其用武之地。
总之,Lindorm单表可支持PB级数据量、万亿条记录数以及千万级的TPS,它具有多样化存储类型支持,深度压缩优化,冷热分离等特点,更多Lindorm的特性可以参考Lindorm产品简介。
三. 总结
用户画像的构建方案大同小异,开发者可以根据自己的具体场景,所在公司的基础设施等,对设计方案进行小调。真正的难度在于数据的清理,开发性能的调优,特征质量的评估,以及模型效果的调优等,这是需要在具体的应用场景里进行大量实践和调整的。前方坑位漫漫,与诸君共勉。