基于Cypher实现K近邻协同过滤推荐的问题排查
修正后的协同过滤K近邻推荐Cypher查询
原查询的核心问题
- 冗余节点匹配:第一步获取的
rating_u1未被使用,后续重复匹配u1的评分关系,导致逻辑混乱 - 距离计算失真:引入u2的所有评分数据,而非仅与u1的共同评分数据,欧氏距离计算错误
- 分组逻辑缺失:最终计算推荐得分时未正确按书籍分组,求和结果不符合预期
修正后的查询
// 1. 获取目标用户u1及其所有评分记录 MATCH (u1:User {user_id: 11927})-[r1:RATED]->(b:Book) WITH u1, COLLECT({book: b, rating: r1.rating}) AS u1_ratings // 2. 找到与u1共同评分至少5本的用户u2,收集共同评分对 MATCH (u2:User)-[r2:RATED]->(b:Book) WHERE u2 <> u1 AND EXISTS((u1)-[:RATED]->(b)) WITH u1, u2, COLLECT({u1_rating: [x.rating IN u1_ratings WHERE x.book = b][0], u2_rating: r2.rating}) AS common_ratings WHERE size(common_ratings) >= 5 // 3. 计算欧氏距离与相似度,取Top10相似用户 WITH u1, u2, sqrt(sum((cr.u1_rating - cr.u2_rating)^2)) AS euclidean_distance WHERE euclidean_distance > 0 WITH u1, u2, 1 / (1 + euclidean_distance) AS similarity ORDER BY similarity DESC LIMIT 10 // 4. 生成推荐:取相似用户评分过但u1未评分的书籍,计算加权得分 MATCH (u2)-[r:RATED]->(b:Book) WHERE NOT EXISTS((u1)-[:RATED]->(b)) RETURN b.title, SUM(similarity * r.rating) AS recommendation_score ORDER BY recommendation_score DESC LIMIT 25
关键优化点
- 精准收集共同评分:通过匹配u1已评分的书籍,直接获取u2对这些书的评分,确保仅计算共同评分的差异
- 避免冗余计算:提前收集u1的所有评分,后续直接匹配共同书籍,减少重复遍历
- 正确分组求和:最终按书籍分组,将所有相似用户的加权评分累加,得到准确的推荐得分
- 过滤自身用户:添加
u2 <> u1避免将目标用户自身纳入相似用户
内容的提问来源于stack exchange,提问作者Eliza
相关产品推荐
相关产品推荐

