6.3 知识图谱中的推荐算法
在推荐系统中,知识图谱是一种有用的资源,可以帮助我们建立商品之间的关联关系,进而进行推荐。知识图谱是一个结构化的图形数据库,描述了实体之间的关系和属性。在知识图谱中,实体表示为节点,关系表示为边。
6.3.1 基于路径体的推荐算法
在推荐系统中使用知识图谱的一个常见算法是基于路径的推荐算法,该算法利用知识图谱中的路径来推断实体之间的关系,并基于这些关系进行推荐。下面是一个简单的例子,展示了使用知识图谱中的路径来进行推荐的过程。
假设我们有一个电影推荐系统,并且有一个知识图谱,其中包含电影、演员和导演之间的关系。每个电影节点都有一个属性表示电影的类型,每个演员和导演节点都有一个属性表示其参与的电影类型。
源码路径:daima/6/lu.py
import networkx as nx
# 创建知识图谱
graph = nx.Graph()
# 添加电影节点
movies = ["霸王别姬", "大闹天宫", "活着", "阿凡达", "大话西游"]
for movie in movies:
graph.add_node(movie, type="电影")
# 添加演员节点
actors = ["张国荣", "巩俐", "周星驰", "刘德华"]
for actor in actors:
graph.add_node(actor, type="演员")
# 添加导演节点
directors = ["陈凯歌", "万籁鸣", "张艺谋", "詹姆斯·卡梅隆", "刘镇伟"]
for director in directors:
graph.add_node(director, type="导演")
# 添加边,表示关系
graph.add_edge("霸王别姬", "张国荣", relation="主演")
graph.add_edge("霸王别姬", "巩俐", relation="主演")
graph.add_edge("大闹天宫", "周星驰", relation="主演")
graph.add_edge("活着", "巩俐", relation="主演")
graph.add_edge("阿凡达", "詹姆斯·卡梅隆", relation="导演")
graph.add_edge("大话西游", "刘德华", relation="主演")
graph.add_edge("大话西游", "周星驰", relation="导演")
# 基于路径的推荐函数
def recommend_movies_based_on_path(start_node, relation, num_recommendations):
recommendations = []
for neighbor in graph.neighbors(start_node):
if graph.get_edge_data(start_node, neighbor)["relation"] == relation:
recommendations.append(neighbor)
return recommendations[:num_recommendations]
# 示例推荐
start_movie = "霸王别姬"
relation = "主演"
num_recommendations = 2
recommendations = recommend_movies_based_on_path(start_movie, relation, num_recommendations)
print("基于路径的推荐电影:")
for movie in recommendations:
print(movie)
在上面的代码中,首先创建了一个空的知识图谱,然后添加了电影、演员和导演节点,并通过边来表示它们之间的关系。接下来,定义了一个基于路径的推荐函数recommend_movies_based_on_path(),该函数接受起始节点、关系和要推荐的数量作为输入,然后通过遍历邻居节点,找到满足指定关系的节点,并返回推荐结果。在本实例中,我们以电影"霸王别姬"为起始节点,关系为"主演",要推荐2部电影。根据路径推断,我们找到了满足条件的邻居节点(即主演演员),并返回推荐结果。执行后会输出:
基于路径的推荐电影:
张国荣
巩俐
6.3.2 基于实体的推荐算法
基于实体的推荐算法是一种常见的推荐系统算法,它基于用户已有的行为和实体之间的关联来进行推荐。这种算法通过分析用户与实体(如商品、电影、音乐等)的交互行为,识别用户的兴趣和喜好,并向用户推荐与其兴趣相关的实体。
1. 基于实体相似度的推荐算法
基于实体相似度的推荐算法是推荐系统中常用的一种方法,它基于实体之间的相似性来进行推荐。该算法通过计算实体之间的相似度,找到与用户已有喜好相似的实体,并将这些实体推荐给用户。
下面将介绍两种基于实体相似度的推荐算法:基于协同过滤的实体相似度推荐和基于内容的实体相似度推荐。
(1)基于协同过滤的实体相似度推荐
基于协同过滤的实体相似度推荐算法根据用户对实体的行为数据,计算实体之间的相似度,并将相似度高的实体推荐给用户。这种算法可以基于用户行为数据构建用户-实体矩阵,利用矩阵中的相似性来进行推荐。
(2)基于内容的实体相似度推荐
基于内容的实体相似度推荐算法根据实体的属性或特征,计算实体之间的相似度,并将相似度高的实体推荐给用户。这种算法通常使用特征提取和相似度计算的方法来衡量实体之间的相似性。
当涉及到基于实体相似度的推荐算法时,一种常见的方法是使用基于内容的推荐,例如下面是一个基于实体相似度的推荐算法的例子。
源码路径:daima/6/shixiang.py
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import OneHotEncoder
# 自定义中国电影数据集
movies = [
{"id": 1, "title": "霸王别姬", "director": "陈凯歌", "genre": "剧情"},
{"id": 2, "title": "大闹天宫", "director": "万籁鸣", "genre": "动画"},
{"id": 3, "title": "活着", "director": "张艺谋", "genre": "剧情"},
{"id": 4, "title": "阿凡达", "director": "詹姆斯·卡梅隆", "genre": "科幻"},
{"id": 5, "title": "大话西游", "director": "刘镇伟", "genre": "喜剧"},
]
# 提取导演和类型作为特征
directors = [movie["director"] for movie in movies]
genres = [movie["genre"] for movie in movies]
# 使用独热编码将导演和类型转换为数值型特征向量
encoder = OneHotEncoder(sparse=False)
director_features = encoder.fit_transform(np.array(directors).reshape(-1, 1))
genre_features = encoder.fit_transform(np.array(genres).reshape(-1, 1))
# 将导演和类型的特征向量合并为电影-属性矩阵
movie_attributes = np.hstack((director_features, genre_features))
# 计算电影之间的相似度
similarity_matrix = cosine_similarity(movie_attributes)
# 示例推荐函数:基于实体相似度推荐电影
def recommend_similar_movies(movie_id, num_recommendations):
movie_index = movie_id - 1
movie_similarities = similarity_matrix[movie_index]
similar_movie_indices = np.argsort(movie_similarities)[::-1][1:num_recommendations+1]
recommended_movies = [movies[i] for i in similar_movie_indices]
return recommended_movies
# 示例推荐电影
recommendations = recommend_similar_movies(1, 3)
print("基于实体相似度的推荐电影:")
for movie in recommendations:
print(f"电影标题: {movie['title']}, 导演: {movie['director']}, 类型: {movie['genre']}")
对上述代码的具体说明如下:
- 首先,定义了一个包含电影信息的数据集movies,每个电影都有一个唯一的ID、标题、导演和类型等属性。
- 然后,我们使用OneHotEncoder对导演和类型进行独热编码,将其转换为数值型的特征向量。独热编码将每个导演和类型转化为一个二进制向量,其中只有一个元素为1,表示该导演或类型的存在。
- 接下来,将导演和类型的特征向量合并为电影-属性矩阵movie_attributes,其中每一行代表一个电影的属性向量。
- 使用函数cosine_similarity()计算电影之间的相似度,得到一个相似度矩阵similarity_matrix。余弦相似度是衡量两个向量之间的相似度的一种常用度量方法。
- 定义了一个基于实体相似度的推荐函数recommend_similar_movies(),该函数接受一个电影ID和要推荐的数量作为输入,根据该电影与其他电影的相似度,找到相似度高的电影并返回推荐结果。
- 以电影ID为1的电影为例,调用函数recommend_similar_movies()推荐了3部相似的电影,并打印输出它们的标题、导演和类型。 执行后会输出:
基于实体相似度的推荐电影:
电影标题: 活着, 导演: 张艺谋, 类型: 剧情
电影标题: 大话西游, 导演: 刘镇伟, 类型: 喜剧
电影标题: 阿凡达, 导演: 詹姆斯·卡梅隆, 类型: 科幻
2. 基于实体关联度的推荐算法
基于实体关联度的推荐算法是一种常见的推荐方法,它通过分析实体之间的关联关系来进行推荐。在Python中实现基于实体关联度的推荐算法通常需要使用数据处理和分析库(如NumPy、Pandas),机器学习库(如scikit-learn),以及自然语言处理库(如NLTK、Gensim)等。这些库提供了丰富的功能和工具,方便进行实体表示、关联度计算和推荐算法的实现。例如下面是一个使用实体关联度推荐算法实现电影推荐的例子。
源码路径:daima/6/guanlian.py
import numpy as np
# 自定义中国电影数据集
movies = [
{"id": 1, "title": "霸王别姬", "director": "陈凯歌", "genre": "剧情"},
{"id": 2, "title": "大闹天宫", "director": "万籁鸣", "genre": "动画"},
{"id": 3, "title": "活着", "director": "张艺谋", "genre": "剧情"},
{"id": 4, "title": "阿凡达", "director": "詹姆斯·卡梅隆", "genre": "科幻"},
{"id": 5, "title": "大话西游", "director": "刘镇伟", "genre": "喜剧"},
]
# 构建电影-导演关联矩阵
directors = [movie["director"] for movie in movies]
director_matrix = np.zeros((len(movies), len(directors)), dtype=int)
for i, movie in enumerate(movies):
director_index = directors.index(movie["director"])
director_matrix[i, director_index] = 1
# 构建电影-类型关联矩阵
genres = [movie["genre"] for movie in movies]
genre_matrix = np.zeros((len(movies), len(genres)), dtype=int)
for i, movie in enumerate(movies):
genre_index = genres.index(movie["genre"])
genre_matrix[i, genre_index] = 1
# 计算电影之间的关联度
similarity_matrix = np.dot(director_matrix, genre_matrix.T)
# 示例推荐函数:基于实体关联度推荐电影
def recommend_related_movies(movie_id, num_recommendations):
movie_index = movie_id - 1
movie_similarities = similarity_matrix[movie_index]
similar_movie_indices = np.argsort(movie_similarities)[::-1][1:num_recommendations+1]
recommended_movies = [movies[i] for i in similar_movie_indices]
return recommended_movies
# 示例推荐电影
recommendations = recommend_related_movies(1, 3)
print("基于实体关联度的推荐电影:")
for movie in recommendations:
print(f"电影标题: {movie['title']}, 导演: {movie['director']}, 类型: {movie['genre']}")
对上述代码的具体说明如下:
- 首先,定义了一个包含电影信息的数据集movies,其中包括电影的ID、标题、导演和类型等属性。
- 然后,我们构建了电影-导演关联矩阵director_matrix和“电影-类型”关联矩阵genre_matrix。这两个关联矩阵用于表示电影与导演、类型之间的关联关系。
- 接下来计算了电影之间的关联度,通过计算电影-导演关联矩阵和电影-类型关联矩阵的乘积得到关联度矩阵similarity_matrix。
- 最后,定义了一个基于实体关联度的推荐函数recommend_related_movies(),根据指定电影与其他电影的关联度,找到关联度高的电影进行推荐。在实例中,以电影ID为1的电影为例,调用函数recommend_related_movies()推荐了3部相关的电影,并输出它们的标题、导演和类型。执行后会输出:
基于实体关联度的推荐电影:
电影标题: 霸王别姬, 导演: 陈凯歌, 类型: 剧情
电影标题: 大话西游, 导演: 刘镇伟, 类型: 喜剧
电影标题: 阿凡达, 导演: 詹姆斯·卡梅隆, 类型: 科幻
6.3.3 基于关系的推荐算法
基于关系的推荐算法是一种常见的推荐方法,它通过分析实体之间的关系来进行推荐。
1. 基于关系相似度的推荐算法
基于关系相似度的推荐算法是一种常见的推荐方法,它基于实体之间的关系相似度来进行推荐。这种算法通常使用图结构或知识图谱表示实体和关系,并计算实体之间的关系相似度来确定推荐项。例如下面是一个基于关系相似度的推荐算法的例子,使用自定义的音乐数据集实现一个音乐推荐系统。
源码路径:daima/6/guanxixiang.py
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 自定义中国音乐数据集
songs = [
{"id": 1, "title": "晴天", "artist": "周杰伦", "genre": "流行"},
{"id": 2, "title": "稻香", "artist": "周杰伦", "genre": "流行"},
{"id": 3, "title": "七里香", "artist": "周杰伦", "genre": "流行"},
{"id": 4, "title": "大海", "artist": "张雨生", "genre": "摇滚"},
{"id": 5, "title": "成全", "artist": "林宥嘉", "genre": "流行"},
]
# 构建音乐-艺术家关联矩阵
artists = [song["artist"] for song in songs]
artist_matrix = np.zeros((len(songs), len(artists)), dtype=int)
for i, song in enumerate(songs):
artist_index = artists.index(song["artist"])
artist_matrix[i, artist_index] = 1
# 构建音乐-类型关联矩阵
genres = [song["genre"] for song in songs]
genre_matrix = np.zeros((len(songs), len(genres)), dtype=int)
for i, song in enumerate(songs):
genre_index = genres.index(song["genre"])
genre_matrix[i, genre_index] = 1
# 计算音乐之间的关系相似度
similarity_matrix = cosine_similarity(artist_matrix) + cosine_similarity(genre_matrix)
# 示例推荐函数:基于关系相似度推荐音乐
def recommend_related_songs(song_id, num_recommendations):
song_index = song_id - 1
song_similarities = similarity_matrix[song_index]
similar_song_indices = np.argsort(song_similarities)[::-1][1:num_recommendations+1]
recommended_songs = [songs[i] for i in similar_song_indices]
return recommended_songs
# 示例推荐音乐
recommendations = recommend_related_songs(1, 3)
print("基于关系相似度的推荐音乐:")
for song in recommendations:
print(f"音乐标题: {song['title']}, 艺术家: {song['artist']}, 类型: {song['genre']}")
在上述代码中,首先定义了一个包含音乐信息的数据集songs,其中包括音乐的ID、标题、艺术家和类型等属性。然后,构建了音乐-艺术家关联矩阵artist_matrix和“音乐-类型”关联矩阵genre_matrix,这两个关联矩阵用于表示音乐与艺术家、类型之间的关联关系。接下来,计算了音乐之间的关系相似度,通过计算音乐-艺术家关联矩阵和音乐-类型关联矩阵的余弦相似度,并将它们相加得到最终的关系相似度矩阵similarity_matrix。最后,定义了一个基于关系相似度的推荐函数recommend_related_songs(),此函数根据指定音乐与其他音乐的关系相似度,找到关系相似度高的音乐进行推荐。
在本实例中,以音乐ID为1的音乐为例调用推荐函数recommend_related_songs(),推荐了3首相关的音乐,并分别打印输出它们的标题、艺术家和类型。 执行后会输出:
基于关系相似度的推荐音乐:
音乐标题: 稻香, 艺术家: 周杰伦, 类型: 流行
音乐标题: 晴天, 艺术家: 周杰伦, 类型: 流行
音乐标题: 成全, 艺术家: 林宥嘉, 类型: 流行
2. 基于关系路径的推荐算法
基于关系路径的推荐算法是一种基于实体之间的关系路径进行推荐的方法,它利用图结构或知识图谱中的路径信息来发现相关实体之间的关系,并基于这些关系路径进行推荐。基于关系路径的推荐算法可以发现实体之间更加复杂的关系,能够提供更加精准和个性化的推荐结果。在实际应用中,当涉及到基于关系路径的推荐算法时,一个常见的方法是使用图数据库来存储和查询实体之间的关系。在下面提供一个使用Neo4j图数据库和音乐数据集的例子,实现一个简单的音乐推荐系统。
源码路径:daima/6/guanxilu.py
(1)首先使用以下代码创建图数据库并添加中国音乐数据集中的音乐和艺术家作为节点,以及艺术家之间的关系作为边。
from py2neo import Graph, Node, Relationship
# 连接到Neo4j数据库
graph = Graph("neo4j+s://ab3d9ce4.databases.neo4j.io", auth=("neo4j", "密码"))
# 清空数据库
graph.delete_all()
# 自定义中国音乐数据集
songs = [
{"id": 1, "title": "晴天", "artist": "周杰伦", "genre": "流行"},
{"id": 2, "title": "稻香", "artist": "周杰伦", "genre": "流行"},
{"id": 3, "title": "七里香", "artist": "周杰伦", "genre": "流行"},
{"id": 4, "title": "告白气球", "artist": "周杰伦", "genre": "流行"},
{"id": 5, "title": "成全", "artist": "林宥嘉", "genre": "流行"},
{"id": 6, "title": "她说", "artist": "林宥嘉", "genre": "流行"},
{"id": 7, "title": "风继续吹", "artist": "张国荣", "genre": "流行"},
{"id": 8, "title": "在水一方", "artist": "张国荣", "genre": "流行"},
{"id": 9, "title": "大海", "artist": "张雨生", "genre": "摇滚"},
{"id": 10, "title": "摩天大楼", "artist": "林志颖", "genre": "流行"},
]
# 创建节点
for song in songs:
song_node = Node("Song", id=song["id"], title=song["title"], genre=song["genre"])
artist_node = Node("Artist", name=song["artist"])
graph.create(song_node)
graph.create(artist_node)
# 创建关系
for song in songs:
artist_node = graph.nodes.match("Artist", name=song["artist"]).first()
song_node = graph.nodes.match("Song", id=song["id"]).first()
relationship = Relationship(artist_node, "PERFORMS", song_node)
graph.create(relationship)
(2)接下来使用以下代码来执行基于关系路径的推荐算法,并获取与指定音乐相关的推荐音乐。
def recommend_related_songs(song_title, num_recommendations):
query = (
f"MATCH (s1:Song {{title: '{song_title}'}})-[*1..3]-(s2:Song) "
f"RETURN s2.title AS recommended_song "
f"LIMIT {num_recommendations}"
)
result = graph.run(query).data()
recommendations = [record["recommended_song"] for record in result]
return recommendations
# 示例推荐函数:基于关系路径推荐音乐
recommendations = recommend_related_songs("晴天", 3)
if recommendations:
print("基于关系路径的推荐音乐:")
for song in recommendations:
print(song)
else:
print("没有找到相关音乐推荐。")
在上述代码中,将基于关系路径查询与指定音乐相关的推荐音乐,路径长度范围为1到3。大家可以根据需求调整路径长度。在运行本实例前,请确保已经在本地安装并运行了Neo4j图数据库,并将用户名、密码和数据库连接信息适当地修改为您自己的设置。执行后会输出:
基于关系路径的推荐音乐:
稻香
七里香
告白气球
这些推荐音乐与指定的音乐"晴天"具有相关性,通过关系路径在图数据库中找到了与之相连的音乐节点。请注意,推荐结果可能因为我们自定义的数据集和关系路径的设置而有所不同。如果没有找到相关的音乐推荐,输出将显示"没有找到相关音乐推荐。"
6.3.4 基于知识图谱推理的推荐算法
基于知识图谱推理的推荐算法是一种利用知识图谱中的实体、属性和关系进行推理和推荐的方法。知识图谱是一种用于表示和组织知识的图结构,其中实体表示为节点,属性和关系表示为边。推荐算法通过分析知识图谱中的实体之间的关联关系,进行推理和预测,从而为用户提供个性化的推荐。
在实际应用中,经常使用基于规则推理的推荐算法,此算法基于知识图谱的推荐算法之一,它利用预定义的规则来推理出用户可能喜欢的音乐。例如下面是一个使用自定义音乐数据集实现基于规则推理的音乐推荐的例子。
源码路径:daima/6/tu.py
# 定义中国音乐数据集
music_data = {
"张学友": ["李香兰", "吻别", "一路上有你"],
"林忆莲": ["爱情转移", "最近比较烦"],
"邓丽君": ["甜蜜蜜", "但愿人长久", "我只在乎你"],
"王菲": ["传奇", "红豆", "匆匆那年"],
"周杰伦": ["稻香", "晴天", "告白气球"]
}
# 定义推理规则
rules = {
"爱情歌推荐": {
"premise": ["张学友", "邓丽君"],
"conclusion": ["王菲"]
},
"轻快歌曲推荐": {
"premise": ["林忆莲"],
"conclusion": ["周杰伦"]
}
}
# 根据规则推荐音乐
def recommend_music(user_preference):
recommended_music = []
for rule in rules.values():
premise_matched = all(artist in user_preference for artist in rule["premise"])
if premise_matched:
recommended_music.extend(rule["conclusion"])
return recommended_music
# 示例用户偏好
user_preference = ["张学友", "邓丽君"]
recommended_music = recommend_music(user_preference)
# 输出推荐音乐
if recommended_music:
print("基于规则推理的音乐推荐:")
for music in recommended_music:
print(music)
else:
print("没有找到相关音乐推荐。")
在上述代码中,首先定义了中国音乐数据集,其中包含了几位艺术家和他们的歌曲。然后定义了一些推理规则,每个规则都有前提和结论。根据用户的偏好,我们遍历规则并检查前提是否满足,如果满足则推荐相应的音乐。执行后会输出:
基于规则推理的音乐推荐:
王菲
注意:这只是一个简单的例子,在实际应用中可能需要更复杂的规则和数据模型来实现更准确的推荐。同时,为了更好地支持推理,可能需要使用更强大的知识图谱工具或推理引擎,例如基于规则的推理引擎或图数据库。