数据埋点与采集:用户行为日志设计、埋点规范、数据质量监控
说实话,推荐系统里最让我头疼的,往往不是算法调参,而是数据。数据不对,再牛的模型也是白搭。我见过太多团队,算法工程师天天追着问「这个特征为什么是空的」,结果一查,埋点压根没上报。嗯,今天我们就聊聊数据埋点这件事。
用户行为日志设计
日志设计,说白了就是定义「用户干了什么,我们怎么记下来」。我个人习惯把行为日志分成三类:
- 曝光日志:用户看到了什么
- 交互日志:用户点了什么、滑了什么
- 转化日志:用户最终买了什么、收藏了什么
每一类日志,字段设计上都有讲究。我直接给一个我在项目中用过的通用模板:
{
"event_id": "uuid", // 事件唯一ID
"user_id": "string", // 用户标识
"item_id": "string", // 物品标识
"event_type": "click|expose|collect|purchase",
"timestamp": 1700000000000, // 事件发生时间(毫秒)
"page_id": "homepage|detail|search",
"position": 3, // 物品在列表中的位置
"extra": { // 扩展字段,灵活使用
"source": "recommend",
"duration": 5000 // 停留时长(毫秒)
}
}
你想想看,如果少了 position 字段,你根本不知道用户点的是第几个推荐结果。我在早期项目里就吃过这个亏,后来补数据补到崩溃。
核心原则:日志字段宁可多,不要少。后期加字段的成本,远高于前期多记几个字段。
埋点规范
埋点规范这件事,我建议团队从一开始就定死。为什么?因为前端、后端、客户端、算法,每个角色对「点击」的理解可能都不一样。
我常用的规范框架是这样的:
| 事件类型 | 触发时机 | 上报方式 | 关键字段 |
|---|---|---|---|
| 曝光 | 物品进入屏幕可视区域 | 批量上报(每5秒或每10条) | item_id, position, page_id |
| 点击 | 用户点击物品 | 实时上报 | item_id, position, source |
| 停留 | 用户离开页面时 | 离开时上报 | duration, page_id |
| 转化 | 完成购买/收藏等操作 | 实时上报 | item_id, order_id, price |
这里有个坑,我必须要说。曝光事件如果处理不好,很容易出现「假曝光」——用户根本没看到,但因为页面预加载就上报了。我曾经在某个项目中,曝光量比实际浏览量高了30%,查了半天才发现是埋点时机不对。
避坑指南:曝光事件一定要用 Intersection Observer 或者类似的可见性检测机制,不要用页面加载完成就上报。
数据质量监控
数据质量监控,是我认为整个推荐系统里最容易被忽视、但最重要的环节。没有监控,你根本不知道数据什么时候出了问题。
我一般会从四个维度来监控:
- 完整性:关键字段是否有空值?比如 user_id 为空,这条日志基本废了。
- 准确性:字段值是否符合预期?比如 event_type 只能是那几个枚举值。
- 及时性:日志延迟多久?超过5分钟还没上报,就要报警。
- 一致性:不同来源的数据是否对得上?比如曝光量和点击量,点击率不应该超过100%。
我习惯在数据管道里加一个「质量检查层」,用简单的规则做过滤:
# 伪代码示例
def quality_check(event):
if event.user_id is None:
return False # 丢弃
if event.event_type not in ['click', 'expose', 'collect']:
return False # 丢弃
if event.timestamp > now() + 60000:
return False # 未来时间戳,丢弃
return True
嗯,这里要注意。不要因为数据质量差就直接丢弃,最好把异常数据单独存一份,方便事后排查。我有个习惯,每天上班第一件事就是看数据质量报表,看看昨天的异常率是多少。
个人经验:数据质量监控的报警阈值,建议设置成「连续5分钟异常率超过5%」再报警。太敏感的话,运维同学会疯掉的。
总结一下
数据埋点这件事,说白了就是「先想清楚要什么,再动手做」。日志设计要全面,埋点规范要统一,质量监控要到位。这三步走扎实了,后面的推荐模型才能跑得稳。
我记得有一次,一个新来的同事问我:「为什么我们的推荐效果总是不稳定?」我让他去查数据质量报表,结果发现有一半的日志 timestamp 字段是错的。嗯,从那以后,数据质量监控就成了我们团队的「第一优先级」。