Spark+ES+ClickHouse 构建DMP用户画像 最新

DMP用户画像介绍

DMP即 Data-Management Platform,数据管理平台,单从名称上来看,这个定义还是非常宽泛的,所以国内很多企业或者个人会将DMP的核心功能理解错。

结合我的理解,DMP其实是一个全面的数据收集,加工,整合的平台,吸收各种数据源的数据,以用户为基本单位,清洗,整理形成结构化的数据表,并进行用户标签的计算,以期能够精准的描述各种用户。

纯碎的DMP平台是指小型的、定制能力极强、中立性好的DMP技术服务商。美国DMP市场是极度细分的,中国市场是高整合的,往往DMP的需求是和DSP、SSP紧密联系在一起的,目前还很难有纯粹的DMP平台。

Spark+ES+ClickHouse实战用户画像签体系构建

第一步是标签系统,标签系统是用来为满足某些特征的人群做标记用的,一个人身上可以有很多标签,我们就是根据这些标签来描绘这个人或人群的用户画像,为业务提供更精准的人群。

搭建标签体系需要从分类开始,标签又可以分为很多种类型,可以分的很细,这里我们只从业务角度出发,简单的分一下类,满足基本的核心需求。

用户标签:这些信息是用户最基本的信息,例如,性别、年龄、地区、学历、注册时间、是否结婚等等。

行为标签:用户的一些可统计的基本行为,例如,7日活跃次数、30日购买次数、90日浏览次数、180日关注次数、90日消费金额等等。

偏好标签:时间偏好、商品偏好、品类偏好、店铺偏好等等,通过统计用户行为后按照规则进行判断分类。

预测标签:通过用户行为数据,运用协同过滤算法、回归算法等等对用户进行行为预测。如果公司业务数据量级不大,这类标签会用的比较少,带来的效果也不一定有明显提升。

TF:

这里我们用 N(P,T)表示一个标签T被用于标签用户P的次数。

TF(P,T)表示这个标记次数在用户P所有标签标记次数中所占的比例。

TF(P,T)= N(P,T)/Σ N(P,Ti)

N(P,T):打在某用户身上某个标签的个数

Σ N(P,Ti):该用户身上全部标签的个数

Ti 该用户全部标签个数

IDF:

IDF(P,T):表示标签T在全部标签中的稀缺程度

如果一个标签出现的几率很小,同时被用户标记某个用户,这就使得该用户与该标签T之间的关系更加紧密。

IDF(P,T)=Σ Σ N(Pi,Ti)/ΣN(Pi,T)

Σ Σ N(Pi,Ti):全部用户的全部标签之和

ΣN(Pi,T) :所有打T标签的用户之和

7)计算方式

举例子:

用户“斑马”,对于标签“语文”的标签权重计算:假设我们之前定义 冷却系数α=0.16。

行为表:




用户“斑马”对标签“语文”的权重:

语文=2*0.1+2*0.2+3*0.6+1*0.5+1*0.9=3.8

语文=3.8 *exp(-α*1)+1*0.1+1*0.2+2*0.6+1*0.5+0=5.067718

2010-08-23:语文= 5.067718*exp(-α*1)= 4.318424

Spark+ES+ClickHouse实战用户画像群体用户画像构建

-- 本地查询代理

CREATE TABLE ch_agent_user

agentname String

ENGINE = MergeTree()

PARTITION BY agentname

ORDER BY (agentname)

SETTINGS index_granularity = 8192;

-- 分布式代理表

CREATE TABLE ch_agent_dist_user AS ch_agent_user

ENGINE = Distributed(‘cluster_test‘, ‘test‘, ‘ch_agent_user‘, cityHash64(agentname))

-- 查询用户数

SELECT sum(user_number) AS user_number

FROM ch_agent_dist_user

RIGHT JOIN

WITH

(

SELECT groupBitmapState(userid) AS users0

FROM ch_label_string

WHERE labelname = ‘T‘

) AS users0

SELECT

‘agent‘ AS agentname,

bitmapCardinality(users0) AS user_number

) USING (agentname) settings enable_scalar_subquery_optimization = 0;

ch_agent_user 表本身不存储数据,当与 with 语句进行 right join 关联查询时,由于是右关联查询,查询结果以 with 语句的结果集为准。

各个节点的查询结果返回给查询节点,查询节点进行汇总计算。参数 enable_scalar_subquery_optimization = 0 表示 with 语句的查询结果不做优化,每个节点都需要执行。

默认情况,在 ClickHouse 中 with 语句的结果作为标量进行缓存,会将查询节点的标量分发到其他服务器,当发现已经存在标量时,就不会在本地节点执行 with 语句。

我们期望 with 语句在每个节点都执行,所以将这个参数设置为 0。

用户画像

用户画像对性能要求比较高,查询平均响应时间不能大于 5 秒。用户在界面上任意圈选人群,然后实时对圈选后的人群进行画像分析。

用户画像技术进行了三次架构重构:

1)V1:大宽表模式

最早的方案是创建一张 userid 为主键的画像表,表的其他字段为画像的特征字段,将圈选的人群与画像表进行 in 操作,然后 group by 操作。

这种设计带来两个比较严重的问题:

当增加或者删除特征字段时,画像表的表结构需要修改;
当圈选的人群数量比较大时,涉及到大记录集的 group by 运算,性能差。
2)V2:Bitmap 模式

将一个特征值下的 userid 集合做为 Bitmap 对象存储到一条记录中,一条记录的内容如下:

用户圈选的人群 Bitmap 对象与画像表的 Bitmap 对象进行与(AND)操作,返回圈选人群的画像信息。

通过这样设计,基本上满足了性能要求,平均时间小于 5 秒,但是一些大的人群包,画像的性能还是差,在 10 秒左右。

画像表的记录数据量不大,但画像表的 Bitmap 字段在计算时需要从磁盘上反序列化出来。有的 Bitmap 对象占用几百兆的空间,导致了性能的下降。

3)V3:Join 表引擎模式

ClickHouse 的 Join 表引擎可以将数据常驻到内存。当插入数据时,数据先写入内存,然后刷到磁盘文件,系统重启时,自动把数据加载回内存。Join 表引擎可以说是常驻内存的带持久化功能的表。

我们把画像表的数据保存到 Join 表引擎,画像表的 Bitmap 字段就常驻内存了,当圈选的人群 Bitmap 对象进行与(AND)操作时,两个内存中已经加载的 Bitmap 对象之间的计算就非常快。

通过这次优化平均查询时间优化到 1 到 2 秒,千万级人群画像分析不超过 5 秒。

作者 \/ 307570512

Spark+ES+ClickHouse 构建DMP用户画像 最新

上一篇:CMMI将能力成熟度分为5个级别


下一篇:使用podman容器部署飞儿云框架