教程:构建 Cypher 推荐引擎
图无处不在。通过追踪人与电影之间有意义的关系,你可以确定演员合作的情况、演员之间合作的频率,以及他们在图中共同拥有的电影。这是我们向用户推荐电影的一种方式,基于他们过去喜欢的内容以及他们最喜欢的演员。我们将带您逐步完成使用 AuraDB 和 Cypher® 入门所需的一切,以解决实际问题。
设置
创建 AuraDB 帐户后,点击“创建数据库 (Create a Database)”并选择一个免费数据库
然后,填写名称,为您的数据库选择一个云区域,然后点击“创建数据库 (Create Database)”。请确保选中“通过电影数据集了解图 (Learn about graphs with a movie dataset)”,这样您就可以从一个现成的数据集开始。
当 AuraDB 设置您的新实例时,会提示您显示密码。请务必保存此密码以备后续步骤使用。
一旦数据库运行,按下图所示打开浏览器。
现在您已进入 Neo4j Browser。使用您的用户名和密码(您上面保存的那个)登录。您会立即注意到左侧有一个指南,您可以切换查看,以开始进行一些实验性查询。点击小“播放”按钮,您看到的任何查询都可以自动放入查询执行框并在屏幕右侧运行。
第一个查询仅显示数据库中的几部电影,以证明其中已有数据。恭喜,您的新数据库中已经有了一些数据,我们准备开始了。
下一节将向您展示如何编写一些查询来探索您刚刚创建的数据。
基础查询
在开始推荐之前,我们需要找出数据中哪些是有趣的,看看我们可以并且想要推荐什么样的内容。首先,让我们运行如下查询来查找像 汤姆·汉克斯 (Tom Hanks) 这样的单个演员。
MATCH (tom:Person {name: 'Tom Hanks'})
RETURN tom
现在我们找到了感兴趣的演员,可以通过从 Tom Hanks 节点出发并跟随 ACTED_IN(参演)关系来检索他所有的电影。您的结果应该看起来像一个图。
MATCH (tom:Person {name: 'Tom Hanks'})-[r:ACTED_IN]->(movie:Movie)
RETURN tom, r, movie
当然,汤姆有与他共同出演电影的同事。查找汤姆的合作演员的语句如下
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coActor:Person)
RETURN coActor.name
基于协同过滤的推荐
现在,我们可以将上述合作演员查询转换为推荐查询。方法是沿着这些关系再往外延伸一步,找到“合作者的合作者”,即汤姆网络中的二级演员。这将向我们展示汤姆尚未合作过的所有演员,我们还可以指定标准,以确保他没有直接与该人合作过。
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movie1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(movie2:Movie)<-[:ACTED_IN]-(coCoActor:Person)
WHERE tom <> coCoActor
AND NOT (tom)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coCoActor)
RETURN coCoActor.name
您可能已经注意到有些名字出现了多次。这是因为从 汤姆·汉克斯 (Tom Hanks) 到这些演员有多条路径可循。
为了查看哪些“合作者的合作者”在汤姆的网络中出现频率最高,我们可以将出现频率考虑在内,方法是计算 汤姆·汉克斯 (Tom Hanks) 与每个合作者之间的路径数量,并按从高到低的值对它们进行排序。
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movie1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(movie2:Movie)<-[:ACTED_IN]-(coCoActor:Person)
WHERE tom <> coCoActor
AND NOT (tom)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coCoActor)
RETURN coCoActor.name, count(coCoActor) as frequency
ORDER BY frequency DESC
LIMIT 5
其中一位“合作者的合作者”是 汤姆·克鲁斯 (Tom Cruise)。现在让我们看看两个汤姆之间有哪些电影和演员,这样我们就可以找出谁能为他们做介绍。
探索路径
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movie1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(movie2:Movie)<-[:ACTED_IN]-(cruise:Person {name: 'Tom Cruise'})
WHERE NOT (tom)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(cruise)
RETURN tom, movie1, coActor, movie2, cruise
正如您所见,这将返回多条路径。如果您玩过 凯文·贝肯的六度分隔 (six degrees of Kevin Bacon) 游戏,那么这种查看人与人之间存在多少跳的概念正是图所描绘的。您会注意到,我们的结果甚至返回了一条包含 凯文·贝肯 (Kevin Bacon) 本人的路径。
通过这两个简单的 Cypher 语句,我们已经创建了两个推荐算法 —— 下一步与谁见面/合作 以及 如何与他们建立联系。
其他推荐
您可以将此处学到的相同想法应用于推荐产品和服务、寻找您可能喜欢的餐厅或活动,或与拥有相似技能兴趣的同事建立联系等多种用途。我们在这里特别提几个资源,您可以使用它们找到更多信息。
餐厅推荐
我们有一个包含几个朋友及其最喜欢的餐厅、菜系和位置的图。
这里有一个实际问题,将其表述为 图搜索,即
What Sushi restaurants are in New York that my friends like?
如何将其转换为适当的 Cypher 语句?
MATCH (person:Person {name: 'Philip'})-[:IS_FRIEND_OF]->(friend)-[:LIKES]->(restaurant:Restaurant)-[:LOCATED_IN]->(loc:Location {location: 'New York'}),
(restaurant)-[:SERVES]->(type:Cuisine {type: 'Sushi'})
RETURN restaurant.name, count(*) AS occurrence
ORDER BY occurrence DESC
LIMIT 5
其他可以轻松集成到此查询中的因素包括喜好、过敏原、评分以及距当前位置的距离。