假设我们有一个包含中文电影信息的数据库表 movies,其中包含以下字段:
- movie_id (电影ID)
- title (电影标题)
- year (上映年份)
- genre (类型)
- director (导演)
- rating (评分)
表中的部分数据如下:
知识抽取步骤
- 数据获取:从数据库中查询所需的数据。例如,我们可以查询所有评分大于8.5的电影。
- 数据清洗:对获取的数据进行清洗,去除重复项、空值等。
- 知识建模:将提取的数据转换为结构化的知识形式,如知识图谱中的节点和边。
- 知识存储:将提取的知识存储到知识图谱或其他知识库中,以便后续使用。
1. 数据获取 使用SQL查询从数据库中提取评分大于8.5的电影:
SELECT * FROM movies WHERE rating > 8.5;
2. 数据清洗 检查并处理数据中的空值、重复项等。假设数据已经比较干净,无需额外清洗。
3. 知识建模 将提取的数据转换为知识图谱中的节点和边。例如:
节点:
- 电影节点:肖申克的救赎、教父、黑暗骑士、低俗小说、阿甘正传
- 导演节点:弗兰克·德拉邦特、弗朗西斯·福特·科波拉、克里斯托弗·诺兰、昆汀·塔伦蒂诺、罗伯特·泽米吉斯
- 类型节点:剧情、犯罪、动作、爱情
边:
- 电影与导演之间的关系:肖申克的救赎 -> 弗兰克·德拉邦特
- 电影与类型之间的关系:肖申克的救赎 -> 剧情,肖申克的救赎 -> 犯罪
- 电影与评分之间的关系:肖申克的救赎 -> 9.3
- 电影与上映年份之间的关系:肖申克的救赎 -> 1994
4. 知识存储 将上述知识存储到知识图谱中
用sqlite模拟实现
-- 创建表
CREATE TABLE movies (
movie_id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
year INTEGER NOT NULL,
genre TEXT NOT NULL,
director TEXT NOT NULL,
rating REAL NOT NULL
);
-- 插入数据
INSERT INTO movies (movie_id, title, year, genre, director, rating) VALUES
(1, '肖申克的救赎', 1994, '剧情, 犯罪', '弗兰克·德拉邦特', 9.3),
(2, '教父', 1972, '犯罪, 剧情', '弗朗西斯·福特·科波拉', 9.2),
(3, '黑暗骑士', 2008, '动作, 犯罪', '克里斯托弗·诺兰', 9.0),
(4, '低俗小说', 1994, '犯罪, 剧情', '昆汀·塔伦蒂诺', 8.9),
(5, '阿甘正传', 1994, '剧情, 爱情', '罗伯特·泽米吉斯', 8.8);
用python实现
import sqlite3
from py2neo import Graph, Node, Relationship
# 连接到SQLite数据库
sqlite_db = sqlite3.connect('movie.db')
cursor = sqlite_db.cursor()
# 查询所有评分大于8.5的电影
cursor.execute("SELECT * FROM movies WHERE rating > 8.5")
rows = cursor.fetchall()
# 连接到Neo4j数据库
neo4j_graph = Graph("bolt://localhost:7687", auth=("neo4j", "swpu@swpu"))
# 清除已有数据(可选)
neo4j_graph.run("MATCH (n) DETACH DELETE n")
# 定义节点和关系标签
MOVIE_LABEL = "Movie"
DIRECTOR_LABEL = "Director"
GENRE_LABEL = "Genre"
# 创建节点和关系
for row in rows:
movie_id, title, year, genre, director, rating = row
# 创建电影节点
movie_node = Node(MOVIE_LABEL, id=movie_id, title=title, year=year, rating=rating)
neo4j_graph.create(movie_node)
# 创建导演节点
director_node = Node(DIRECTOR_LABEL, name=director)
neo4j_graph.merge(director_node, DIRECTOR_LABEL, "name")
# 创建电影与导演的关系
relationship = Relationship(movie_node, "DIRECTED_BY", director_node)
neo4j_graph.create(relationship)
# 处理多个类型
genres = genre.split(", ")
for g in genres:
genre_node = Node(GENRE_LABEL, name=g)
neo4j_graph.merge(genre_node, GENRE_LABEL, "name")
# 创建电影与类型的关系
relationship = Relationship(movie_node, "BELONGS_TO_GENRE", genre_node)
neo4j_graph.create(relationship)
# 关闭数据库连接
cursor.close()
sqlite_db.close()
print("数据已成功导入到Neo4j知识图谱中。")
详细解释
-
连接SQLite数据库:
- 使用
sqlite3.connect
连接到 SQLite 数据库。 - 使用
cursor.execute
执行 SQL 查询,获取所有评分大于8.5的电影。
- 使用
-
连接Neo4j数据库:
- 使用
py2neo.Graph
连接到 Neo4j 数据库。需要提供 Neo4j 的 Bolt 地址和认证信息。
- 使用
-
清除已有数据:
- 可选步骤,用于清除 Neo4j 中已有的数据,以便重新导入。
-
创建节点和关系:
- 遍历查询结果,为每部电影创建一个
Movie
节点。 - 为每个导演创建一个
Director
节点,并与电影节点建立DIRECTED_BY
关系。 - 将电影的类型拆分为多个类型,并为每个类型创建一个
Genre
节点,与电影节点建立BELONGS_TO_GENRE
关系。
- 遍历查询结果,为每部电影创建一个
-
关闭数据库连接:
- 关闭 SQLite 和 Neo4j 的连接。
注意事项
- Neo4j 认证信息:请根据你的 Neo4j 实例配置正确的用户名和密码。
- Bolt 地址:如果你的 Neo4j 实例不在本地运行,请提供正确的 Bolt 地址。
- 数据清理:如果不需要每次都清除已有数据,可以注释掉
neo4j_graph.run("MATCH (n) DETACH DELETE n")
这一行。
通过上述步骤,你可以将 SQLite 中的电影数据成功导入到 Neo4j 知识图谱中。