在字节跳动,推荐系统不仅靠“最近点过什么”,更依赖**“用户兴趣图谱”进行推理:如果你喜欢《孤独摇滚》,也可能喜欢《轻音少女》。这不是简单的协同过滤,而是实体关系图 + 多跳兴趣传导**。本篇我们将从业务价值出发,构建一个简化版兴趣图谱系统原型,并用 Python + NetworkX 实现基本查询和兴趣预测能力。
🧠 一、为什么要构建兴趣图谱?
问题 | 图谱的价值 |
---|---|
用户数据稀疏 | 弥补冷启动、新用户的行为空缺 |
推荐内容单一 | 打通用户偏好内容的潜在连接 |
分类不精准 | 用关系图建“兴趣簇”,比靠标签更真实 |
AB标签失效 | 基于实体关系推理比静态打标签更持久 |
图谱推荐不是代替 CTR 模型,而是作为“召回增强器 + 推理助手”存在
🏗️ 二、字节跳动兴趣图谱系统结构(简化)
[用户节点] —— 喜欢 ——> [视频节点] ↓ 属于 [标签节点] ↓ 相关 [知识节点/实体节点]
- 每个节点都有属性(热度、类型、时间)每条边有关系(喜好、相似、包含、属于)可通过图算法实现兴趣扩展、相似召回
⚙️ 三、代码实战:用 Python + NetworkX 构建兴趣图谱原型
1. 安装依赖
pip install networkx
2. 构建兴趣图
import networkx as nxG = nx.Graph()# 添加用户和内容节点G.add_node("user_001", type="user")G.add_node("video_001", type="video", title="孤独摇滚")G.add_node("video_002", type="video", title="轻音少女")G.add_node("video_003", type="video", title="新世纪福音战士")G.add_node("tag_rock", type="tag")G.add_node("tag_anime", type="tag")# 用户行为G.add_edge("user_001", "video_001", relation="like")# 视频标签关系G.add_edge("video_001", "tag_rock")G.add_edge("video_002", "tag_rock")G.add_edge("video_002", "tag_anime")G.add_edge("video_003", "tag_anime")
3. 查询“用户可能喜欢”的视频
def predict_interests(user_id): neighbors = list(G.neighbors(user_id)) candidate_tags = set() for n in neighbors: if G.nodes[n]['type'] == 'video': tags = G.neighbors(n) candidate_tags.update(tags) related_videos = set() for tag in candidate_tags: for v in G.neighbors(tag): if G.nodes[v]['type'] == 'video' and v not in neighbors: related_videos.add(v) return related_videosprint("推荐给用户的内容:", predict_interests("user_001"))
✅ 输出:{'video_002', 'video_003'}
→ 即通过 tag 找到相似兴趣内容
🔍 四、图谱系统在推荐中的用法
模块 | 用法 |
---|---|
召回增强 | user → tag → video → 精排 |
标签补全 | 内容 → 图嵌入 → 相似 tag |
新内容启动 | video → tag → 相似用户 → 强插推荐 |
用户兴趣推理 | 多跳扩展兴趣簇,进行离散转连续的特征构造 |
✍️ 五、总结与思考
- 兴趣图谱 ≠ 复杂的知识图谱,而是结构化“兴趣关系”的图字节跳动用兴趣图谱作为推荐召回的补丁、冷启动的热身、兴趣的延展小团队可以用 NetworkX 构建离线图谱,用 Neo4j 作为生产图查询系统真正价值在于“多跳推理 + 关系语义”,而不仅仅是“图”
🎁 拓展推荐
- 《推荐系统中的图神经网络实践》阿里PPTNeo4j 入门图谱系统教程(支持 Cypher 查询)字节跳动技术博客《构建亿级兴趣图谱的落地方案》