Skip to content

图算法

基于neo4j

PageRank 算法原理

PageRank 的核心思想是基于网页之间的链接关系来评估网页的重要性,即一个网页被其他重要网页链接得越多,它的重要性就越高。

PageRank 算法的基本原理可以概括为以下几点: 1. 链接投票:每个网页(节点)将其重要性的一部分传递给它所链接的其他网页(节点)。 2. 随机跳转:为了避免某些节点因为缺乏链接而变得不重要,算法引入了一个随机跳转的机制,即用户有一定概率随机跳转到任意一个网页。 3. 迭代计算:PageRank 值通过多次迭代计算得出,每次迭代中,每个节点的 PageRank 值会根据其链接节点的 PageRank 值进行更新。

PageRank 公式

PageRank 的计算公式如下: [ PR(A) = (1 - d) + d \left( \sum_{i=1}^{n} \frac{PR(T_i)}{C(T_i)} \right) ]

其中: - ( PR(A) ) 是网页 A 的 PageRank 值。 - ( d ) 是阻尼系数(通常取值为 0.85),表示用户随机跳转的概率。 - ( PR(T_i) ) 是链接到网页 A 的网页 ( T_i ) 的 PageRank 值。 - ( C(T_i) ) 是网页 ( T_i ) 的出链数量。

数据

CREATE (a:Page {name: 'A'})
CREATE (b:Page {name: 'B'})
CREATE (c:Page {name: 'C'})
CREATE (d:Page {name: 'D'})
CREATE (a)-[:LINKS_TO]->(b)
CREATE (a)-[:LINKS_TO]->(c)
CREATE (b)-[:LINKS_TO]->(c)
CREATE (c)-[:LINKS_TO]->(a)
CREATE (d)-[:LINKS_TO]->(c)

分析

推荐某一类别受欢迎的产品

CALL gds.graph.project(
  'myGraph',
  'Page',
  'LINKS_TO'
)

CALL gds.pageRank.stream('myGraph')
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS page, score
ORDER BY score DESC

电影推荐

from py2neo import Graph, Node, Relationship

# 连接到Neo4j数据库
graph = Graph("bolt://localhost:7687", auth=("neo4j", "password"))

# 清空数据库
graph.delete_all()

# 创建用户节点
users = ["Alice", "Bob", "Charlie"]
for user in users:
    graph.create(Node("User", name=user))

# 创建电影节点
movies = {
    "Inception": ["Action", "Sci-Fi"],
    "The Matrix": ["Action", "Sci-Fi"],
    "Forrest Gump": ["Drama", "Romance"],
    "The Shawshank Redemption": ["Drama"]
}
for movie, genres in movies.items():
    movie_node = Node("Movie", title=movie)
    graph.create(movie_node)
    for genre in genres:
        genre_node = Node("Genre", name=genre)
        graph.merge(genre_node, "Genre", "name")
        graph.create(Relationship(movie_node, "IS_OF_GENRE", genre_node))

# 创建用户和电影之间的关系
ratings = [
    ("Alice", "Inception", 5),
    ("Alice", "The Matrix", 4),
    ("Bob", "Forrest Gump", 5),
    ("Bob", "The Shawshank Redemption", 5),
    ("Charlie", "Inception", 4),
    ("Charlie", "The Matrix", 5)
]
for user, movie, rating in ratings:
    user_node = graph.nodes.match("User", name=user).first()
    movie_node = graph.nodes.match("Movie", title=movie).first()
    graph.create(Relationship(user_node, "RATED", movie_node, rating=rating))



# 为Alice推荐电影
query = """
MATCH (u:User {name: 'Alice'})-[:RATED]->(m1:Movie)<-[:RATED]-(u2:User)-[:RATED]->(m2:Movie)
WHERE NOT (u)-[:RATED]->(m2)
RETURN m2.title AS Recommendation, COUNT(*) AS Frequency
ORDER BY Frequency DESC
LIMIT 5
"""
recommendations = graph.run(query).data()
print("Recommendations for Alice:")
for rec in recommendations:
    print(f"{rec['Recommendation']} (Frequency: {rec['Frequency']})")