7.1 推荐系统与社交网络:把共同行为变成信号


文档摘要

7.1 推荐系统与社交网络:把共同行为变成信号 本节摘要:推荐的本质是"和你相似的人还喜欢什么",社交发现的本职是"朋友的朋友"。两者在图上是同一类问题:以共同行为为边、以邻居为候选。本节完整走一遍信号建模、离线相似度计算与在线查询服务的双层架构,并处理冷启动这个经典难题。 前六章的技能第一次整体上场。这道题的输入是行为数据(浏览、购买、点赞),输出是"你可能感兴趣"——中间全部过程都在图里发生。 一、信号建模:行为即边 推荐的图信号有三层,由弱到强: 权重 w 是信号强度,后续所有计算都按它加权。把行为建为边而非事件节点是这里的关键取舍:如果行为本身会被评论、被退款、被追踪生命周期,才升级为事件节点(2.1 的建模判据);纯推荐场景里,加权边足够且遍历更快。

7.1 推荐系统与社交网络:把共同行为变成信号

本节摘要:推荐的本质是"和你相似的人还喜欢什么",社交发现的本职是"朋友的朋友"。两者在图上是同一类问题:以共同行为为边、以邻居为候选。本节完整走一遍信号建模、离线相似度计算与在线查询服务的双层架构,并处理冷启动这个经典难题。

前六章的技能第一次整体上场。这道题的输入是行为数据(浏览、购买、点赞),输出是"你可能感兴趣"——中间全部过程都在图里发生。

一、信号建模:行为即边

推荐的图信号有三层,由弱到强:

// 三层信号:浏览(弱)→ 购买(中)→ 好评(强) CREATE (u:User {userId: 'u-1001', name: '林晓'}) CREATE (i1:Item {itemId: 'i-201', title: '机械键盘'}) CREATE (i2:Item {itemId: 'i-202', title: '键帽套装'}) CREATE (u)-[:VIEWED {ts: datetime(), w: 1}]->(i1) CREATE (u)-[:BOUGHT {ts: datetime(), w: 3}]->(i1) CREATE (u)-[:RATED {stars: 5, w: 5}]->(i2)

权重 w 是信号强度,后续所有计算都按它加权。把行为建为边而非事件节点是这里的关键取舍:如果行为本身会被评论、被退款、被追踪生命周期,才升级为事件节点(2.1 的建模判据);纯推荐场景里,加权边足够且遍历更快。

二、在线查询:朋友的朋友与共同偏好

轻量推荐直接用 Cypher 现算——图小(单用户邻域)时毫秒级:

// 协同信号:买过 A 商品的人还买了什么 MATCH (me:User {userId: 'u-1001'})-[b1:BOUGHT]->(a:Item) <-[:BOUGHT]-(other:User)-[b2:BOUGHT]->(rec:Item) WHERE NOT (me)-[:BOUGHT|VIEWED]->(rec) WITH rec, count(DISTINCT other) AS 支持人数, sum(b2.w) AS 信号强度 RETURN rec.title, 支持人数, 信号强度 ORDER BY 信号强度 DESC LIMIT 5
rec.title | 支持人数 | 信号强度 -------------|---------|--------- "键帽套装" | 4 | 11 "腕托" | 2 | 5

社交发现的同构写法——朋友的朋友里找出"共同好友最多的人":

// 两个人之间共同好友数 = 关系强度 MATCH (me:User {userId: 'u-1001'})-[:FRIENDS_WITH]-(f)-[:FRIENDS_WITH]-(fof) WHERE NOT (me)-[:FRIENDS_WITH]-(fof) AND fof <> me RETURN fof.name, count(DISTINCT f) AS 共同好友数 ORDER BY 共同好友数 DESC LIMIT 3
fof.name | 共同好友数 ---------|----------- "周然" | 5 "李洱" | 3

三、离线计算:相似度写回,在线直查

候选集一大,在线现算就不合算了。按 5.3 的三步走:投影、算法、写回——在线查询退化成读一个属性:

// 离线:物品相似度(基于共同购买者)写回 CALL gds.nodeSimilarity.write('item-graph', { writeProperty: 'simScore', // 相似度写成 Item 节点间关系的属性 relationshipTypes: ['BOUGHT_BY'] }) YIELD relationshipsWritten
// 在线:直接查已算好的相似关系,毫秒级 MATCH (me:User {userId: 'u-1001'})-[:BOUGHT]->(i:Item) -[s:SIMILAR_TO]->(rec:Item) WHERE NOT (me)-[:BOUGHT|VIEWED]->(rec) RETURN rec.title, s.simScore ORDER BY s.simScore DESC LIMIT 5

图:推荐的离线与在线双层架构

图:推荐的离线与在线双层架构

四、冷启动:图式解法

新用户没有行为边,协同信号失效。图的解法是换起点——从属性与内容出发找相似人群:

// 新用户 u-2002 只填了兴趣标签:从内容相似性借信号 MATCH (me:User {userId: 'u-2002'})-[:INTERESTED_IN]->(t:Topic) <-[:INTERESTED_IN]-(peer:User)-[:BOUGHT]->(rec:Item) WHERE peer.activityScore > 0.5 RETURN rec.title, count(DISTINCT peer) AS 同好人数 ORDER BY 同好人数 DESC LIMIT 5
思路:兴趣标签是天然的中介节点, 新人 → 标签 → 活跃同好 → 热门商品 三程漫游给出"编辑精选式"的初始推荐, 行为积累后再无缝切换到协同信号

社交网络侧的冷启动同理:导入通讯录建立第一批 FRIENDS_WITH 边,社交信号先于行为信号上岗。

五、推荐结果的业务口径

工程之外的提醒:推荐系统的指标在业务侧不在算法侧。图给出的候选集最终要看三个口径:

覆盖率:候选集是否长尾也能被推到(图的连通性红利) 多样性:同类候选是否扎堆(用社区或类别约束打散) 可解释性:沿路径输出推荐理由("你的好友 A 也买过")

第三条是图方案的独门优势——推荐路径本身就是理由,MATCH 出来的每一程都能翻译成人话。协同矩阵类方案给不出"为什么",图方案顺手就有,这在推荐合规审查越来越严的环境里越来越值钱。

本节要点回顾

  • 行为即边:VIEWED/BOUGHT/RATED 分级加权,行为本身被追踪才升级为事件节点;
  • 轻量协同查询用 Cypher 现算,规模化后转"离线相似度写回 + 在线直查";
  • 社交发现与推荐同构:共同好友数就是关系强度;
  • 冷启动的图式解法:换信号起点——兴趣标签与社交关系先顶上;
  • 双层架构是 5.3 与 2.4 两条原则在业务侧的合流。

推荐是"顺水推舟",下一节的欺诈检测是"顺藤摸瓜"——图把伪装撕开的地方。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U