OneID实战笔记,汽车行业图算法设计与五个避坑要点
上篇写了主数据治理,这篇展开讲其中最核心的模块,OneID。这是C企CDP项目里我花时间最多、踩坑最深的一块,今天把完整设计方案和经验记录下来。
OneID到底是什么
DAMA体系里没有OneID这个词,对应的学术术语是Entity Resolution(实体识别),把分散在不同数据源中指向同一实体的多条记录,通过标识符匹配关联到统一ID。OneID做完后生成Golden Record(黄金记录),即合并后最完整最准确的那份客户档案。
简单说,OneID就是搞清楚这几条记录是不是同一个人,Golden Record是合并后最好的一份。先识别,后合并。
汽车行业的数据源有多复杂
很多人以为OneID就是把CRM和DMS的数据拼一下,实际上远不止。
C企CDP项目里,接入OneID计算的数据源最终覆盖了十几个系统,40多张表。厂家层面有单点登录系统(SSO)、CRM、DCS(几条业务线各自一套,每套都有线索表、订单表、实销表、维修工单表)。还有DMP广告投放平台、统一埋点平台、全媒体系统、车联网平台、官方App、商城、企微、直营线索平台,甚至某区域分公司的独立DMS系统。
涉及的用户ID类型有12种,GlobalID、手机号、证件号、邮箱、UnionID、OpenID、ExternalUserID、IMEI、AndroidID、OAID、IDFA、IDFV。每个系统的数据格式、标识逻辑、数据质量都不一样。不做OneID的话,你在系统里看到的就是几十条互不关联的记录,但现实里可能就是同一个人。
人和车的关系更复杂,一个人可能名下多辆车,一辆车可能被多人使用。OneID不仅合并人,还要建人-车关系图谱,比电商的纯客户合并多了一个维度。
不是四级匹配,是图算法
之前我写过一版文章说「四级关联规则逐级匹配」,不够准确,实际项目用的是图算法。
第一步,用Snowflake雪花算法给每一个「用户ID + ID类型」的组合生成一个全局唯一编号,作为图计算的节点。
第二步,构建关系对,就是图里的边。同一条记录里既有手机号又有GlobalID,两个ID之间就有一条边。
第三步,用Spark GraphX跑连通图算法。所有ID作为节点,所有关系对作为边,互相能连通的ID会被分到同一个图中,一个图代表一个潜在用户。
第四步,选OneID。在每个连通图里找优先级最高的ID类型,用它的Snowflake编号作为OneID。优先级排序,GlobalID第一,手机号第二,证件号第三,后面依次是各种设备ID。
关键问题,一个图里出现多个最高优先级ID怎么办。比如两个GlobalID在同一个连通图里,说明可能是两个不同的人被某个低优先级ID错误地连在了一起。这时候用Dijkstra最短路径算法,计算路径权重,权重最大的路径获胜,另一个被拆分出去。这个过程叫「压制」,反向操作叫「增益」。
置信度A和B,不是所有关系对都一样可信
关系对分两类。A类高置信度,权重1.0,比如单点登录系统的账户表和DCS实销客户表,用户自注册验证或实名认证过的。B类低置信度,权重0.8,CRM线索表、全媒体、埋点平台数据、广告设备ID,这些可能代填或未验证。
冲突的时候优先采信A类。比如一个手机号在CRM线索表里关联了GlobalID_A,在实销客户表里关联了GlobalID_B,算法会把手机号归到A类的GlobalID_B下面。
数据清洗,比匹配算法更花时间
物理ID清洗主要是格式校验。手机号去除非数字字符后正则校验,号段13到19开头,11位。证件号更复杂,身份证分15位和18位,军官证、护照、驾照、港澳台身份证各有各的校验规则。
关系对清洗是OneID计算前最关键的一步。同系统内一对多或多对多,只保留最新关系对。跨系统冲突按优先级处理,SSO > A类 > 时间最新。一个手机号关联超过20个身份证号,判定公共电话直接移除。
v_global_id,解决手机号单独出现的稳定性问题
OneID的原则是「相对稳定,匹配大多数业务场景」。但大量线索数据里只有手机号没有GlobalID,直接用手机号做OneID的话,后来客户注册了App有了GlobalID,OneID变了就要迁移所有历史数据。
解决方案是引入v_global_id(虚拟GlobalID)。手机号没有跟任何GlobalID同时出现时,用Snowflake生成一个虚拟ID做OneID。将来手机号跟真实GlobalID关联上了,虚拟ID和真实GlobalID会被归到同一个连通图里,OneID编号不变。这叫「OneID不变性」。
手机号换绑的归并和解绑逻辑
归并有四种场景。手机号单独出现以手机号为OneID。GlobalID跟新手机号同时出现但手机号之前没记录,以GlobalID为OneID。手机号之前已有记录,以手机号已有的OneID为准。GlobalID重新绑新手机号,沿用GlobalID当前的OneID。
解绑逻辑处理会员解绑手机号,旧手机号废弃不再纳入OneID计算。如果后来被新客户办理,重新走归并逻辑。
踩过的坑,一对多关系对清洗时直接删关系对,某个会员解绑手机号后旧手机号在OneID里彻底消失了,历史数据断链。解决方案是清洗前先判断被丢弃的ID是否还有其他关系对,没有的话生成v_global_id保留。这个优化让覆盖率提升了大概5个百分点。
离线加实时,两条腿走路
离线方案T+1跑批,每天凌晨跑Spark任务。但线索数据有时效性要求,客户上午留资下午销售就要看到完整画像,不能等第二天。
实时这条线,源系统数据变更通过CDC推到Kafka,Flink SQL做实时清洗提取关系对,object-modeling服务实时计算OneID映射关系,结果写入PostgreSQL。目前先接了线索汇聚和会员注册两个场景。
离线和实时是互补关系。离线T+1全量跑保证完整性,每天凌晨跑完后同步覆盖实时结果做数据对齐。
三级客户质量分类
认证会员,有验证过的GlobalID同时有手机号和证件号。
普通会员,有GlobalID和手机号但没有证件号。
非会员,没有GlobalID只有手机号或纯设备ID。
三级互斥,可以自动升级。
四个验证指标
ID归属唯一性,每个原始ID只能查到一个OneID,这是红线。
重心稳定性,OneID上关联的可认证ID不应频繁变更。
增益率,算法把原本不连通的ID连通起来的效果。
压制率,算法把不合理的ID关联打散的效果。
五个避坑要点
第一个坑,源系统主数据不规范就上OneID。最常见也最致命。先做Data Profiling(数据探查),评估覆盖率、唯一性和规范度,达标了再进匹配流程。
第二个坑,关系对清洗太暴力导致物理ID消失。一对多清洗时直接删关系对,某些物理ID在OneID里消失。加了「保留孤岛ID」逻辑后大概5%的数据被救回来。
第三个坑,没有区分置信度等级。所有关系对一视同仁,低质量数据污染高质量数据。分A/B两类,A类权重1.0,B类权重0.8,图算法路径计算中自动体现差异。
第四个坑,忽略了人-车关系。汽车行业必须同时建人-车关系图谱。定义了24个融合对象,每个对象有自己的归并规则。
第五个坑最隐蔽,不可逆操作没有审计。合并操作不可逆,必须有审计日志。脏数据表不是垃圾箱,是审计依据,记录每一条被清洗掉的关系对的来源系统、置信度等级、脏数据原因。
小结
OneID看着是技术模块,说到底是一套数据治理体系。前置工作占整个项目精力的70%,真正的匹配算法大概只占30%。很多人问我要OneID的技术方案,我一般先反问,你们源系统的手机号规范率是多少?回答不上来,那现在不是做OneID的时候。
作者,凌波,18年汽车行业数字化老兵,CDGP数据治理专家。
下篇预告,CDGP到底值不值得考?我的两次考试实录

浙公网安备 33010602011771号