目录
一、部署本地大语言模型Ollama
下载Ollama
安装Ollama到本地
安装完毕,打开命令行输入`ollama --help`检查是否安装成功。
选择合适的模型,并使用命令行指令`ollama run llama3.2:3b`进行本地安装(由于设备受限,我选择了参数大小为3b的llama3.2模型,本地存储占用2GB.)
安装完成后即可在本地进行对话
对话时只要输入运行相应模型的指令"ollama run 模型名称"即可。
二、安装Neo4j数据库
参考以下教程:
neo4j入门到精通------1、安装部署_neo4j需要jdk在系统环境中吗?-CSDN博客
NEO4J指定JDK路径_elasticsearch_K歌、之王-华为开发者空间
Neo4j启动指令:`neo4j.bat console`,停止指令:`neo4j stop`
默认用户名:`neo4j`,密码:`neo4j`
可视化网址:http://localhost:7474/
图数据库用户名:neo4j,密码:your_password
注意:项目中的代码需要适配neo4j最新版,并配置相应的apoch包。
安装过程容易发生的错误:
Neo.ClientError.Statement.SyntaxError Unknown function 'apoc.version' (line 1, column 8 (offset: 7)) "RETURN apoc.version()"
-
检查 APOC 插件是否已安装
如果您已经安装了 Neo4j 5.x,并且遇到这个错误,可能是因为 APOC 插件未安装或未启用。在 Neo4j 5.x 版本中,APOC 插件需要手动安装。
您可以执行以下步骤来安装和配置 APOC 插件:
a. 安装 APOC 插件
- 访问 APOC Releases 页面,下载与您的 Neo4j 版本相匹配的 APOC 插件
.jar
文件。 - 将下载的
.jar
文件放置到 Neo4j 的plugins
目录中:- 如果您是手动安装的 Neo4j,
plugins
目录通常位于 Neo4j 安装路径下。 - 如果您使用 Docker 部署 Neo4j,请将
.jar
文件挂载到 Docker 容器中的/var/lib/neo4j/plugins
目录。
- 如果您是手动安装的 Neo4j,
b. 配置
neo4j.conf
文件在 Neo4j 的配置文件
neo4j.conf
中,确保以下设置项存在并已启用(没有就自己添加): - 访问 APOC Releases 页面,下载与您的 Neo4j 版本相匹配的 APOC 插件
-
dbms.security.procedures.unrestricted=apoc.* dbms.security.procedures.allowlist=apoc.*
dbms.security.procedures.unrestricted
允许使用 APOC 中的所有过程。dbms.security.procedures.allowlist
列出了允许的 APOC 过程。
修改配置文件后,重启 Neo4j 服务以使设置生效。
-
确认 APOC 是否有效
重新启动 Neo4j 后,您可以再次尝试查询 APOC 版本:
在cypher输入指令:
RETURN apoc.version()
如果成功返回版本信息,说明 APOC 插件已安装并正确配置。
-
查看日志
如果安装和配置后仍然无法使用 APOC,您可以查看 Neo4j 日志文件,通常位于
logs
目录下的debug.log
或neo4j.log
文件,查看是否有错误或警告信息,帮助进一步排查问题。
完成这些步骤后,应该能够成功调用 APOC 函数。如果问题仍然存在,请提供更多详细的日志信息。
三、应用本地大语言模型搭建知识图谱
1、导入依赖库
python
from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
from langchain_core.output_parsers import StrOutputParser
from langchain_community.graphs import Neo4jGraph
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.chat_models import ChatOllama
from langchain_experimental.graph_transformers import LLMGraphTransformer
from neo4j import GraphDatabase
from yfiles_jupyter_graphs import GraphWidget
from langchain_community.vectorstores import Neo4jVector
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores.neo4j_vector import remove_lucene_chars
from langchain_ollama import OllamaEmbeddings
import os
from langchain_experimental.llms.ollama_functions import OllamaFunctions
from neo4j import Driver
from dotenv import load_dotenv
load_dotenv()
load_dotenv()函数用来加载本地环境,在项目文件夹中创建.env文件,写入相关代码,此函数能将文件内容链入程序中。
python
NEO4J_URI=neo4j://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=12345678
python
import langchain
print(langchain.__version__)
0.3.7
2、连接数据库
python
# graph = Neo4jGraph()
graph = Neo4jGraph(
url="neo4j://localhost:7687", # 替换为您的 Neo4j 地址
username="neo4j", # 替换为您的用户名
password="12345678", # 替换为您的密码
#database="my_database" # 替换为您希望连接的数据库(默认是neo4j)
)
3、加载CSV文档
python
from langchain_community.document_loaders import CSVLoader
from langchain_core.documents import Document
# 加载 CSV 文档
loader = CSVLoader(
file_path="./data/douban_movies.csv",
encoding='utf-8', # 如果有中文,确保使用正确的编码
csv_args={
'delimiter': ',', # CSV 分隔符,默认为逗号
}
)
rows = loader.load()
# 将每行数据作为一个文档
documents = [Document(page_content=row.page_content) for row in rows]
# 检查文档数量
print(f"文档数量: {len(documents)}")
for i, doc in enumerate(documents[:5]): # 打印前5个文档内容
print(f"文档 {i+1}:")
print(doc.page_content)
print("---")
4、初始化(载入)大模型
python
llm = OllamaFunctions(
model="llama3.1:8b",
temperature=0,
base_url="http://localhost:11434",
format="json"
)
llm_transformer = LLMGraphTransformer(llm=llm)
5、编写实体关系识别函数
python
from tqdm.auto import tqdm
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
from typing import List
import json
# 定义关系模式
class MovieRelation(BaseModel):
movie_name: str = Field(description="电影名称")
director: List[str] = Field(description="导演列表")
screenwriter: List[str] = Field(description="编剧列表")
actors: List[str] = Field(description="主演列表")
relationships: List[dict] = Field(description="实体之间的关系列表")
# 创建提示模板
prompt_template = """
请分析以下电影信息,识别出电影、导演、编剧和演员之间的关系:
{text}
请以JSON格式输出以下信息:
1. 电影名称
2. 导演列表
3. 编剧列表
4. 主演列表(仅包含前5名主演)
5. 实体之间的关系(如:导演-执导->电影,演员-主演->电影,编剧-编写->电影)
请确保输出格式符合以下结构:
{
{
"movie_name": "电影名",
"director": ["导演1", "导演2"],
"screenwriter": ["编剧1", "编剧2"],
"actors": ["演员1", "演员2"],
"relationships": [
{
{"source": "导演名", "relation": "执导", "target": "电影名"}},
{
{"source": "编剧名", "relation": "编写", "target": "电影名"}},
{
{"source": "演员名", "relation": "主演", "target": "电影名"}}
]
}}
"""
# 创建提示对象
prompt = ChatPromptTemplate.from_template(prompt_template)
6、处理文档生成知识图谱
python
# 处理文档并生成知识图谱
def process_movie_relations(doc, llm):
response = None # 初始化response变量
try:
# 构建完整的提示
chain = prompt | llm
# 获取模型响应
response = chain.invoke({"text": doc.page_content})
# 添加调试信息
print("原始响应类型:", type(response))
print("原始响应内容:", response)
# 尝试解析JSON响应
if isinstance(response, str):
try:
parsed_response = json.loads(response)
except json.JSONDecodeError as e:
print(f"JSON解析错误: {str(e)}")
print(f"问题响应: {response}")
return None
elif hasattr(response, 'content'):
try:
parsed_response = json.loads(response.content)
except json.JSONDecodeError as e:
print(f"JSON解析错误: {str(e)}")
print(f"问题响应: {response.content}")
return None
elif isinstance(response, dict):
parsed_response = response
else:
raise ValueError(f"无法处理的响应类型: {type(response)}")
# 验证必要的字段
required_fields = ['movie_name', 'director', 'screenwriter', 'actors', 'relationships']
if all(field in parsed_response for field in required_fields):
return parsed_response
else:
missing_fields = [field for field in required_fields if field not in parsed_response]
raise ValueError(f"响应缺少必要字段: {missing_fields}")
except Exception as e:
print(f"处理错误: {str(e)}")
if response:
print(f"问题响应: {response}")
return None
打印输出
处理全部文档内容
python
# 处理所有文档并显示进度
results = []
failed_docs = []
print(f"\n开始处理 {len(documents)} 部电影数据...")
with tqdm(total=len(documents), desc="处理电影数据", unit="部") as pbar:
for i, doc in enumerate(documents):
try:
result = process_movie_relations(doc, llm)
if result:
results.append(result)
movie_name = result.get('movie_name', 'Unknown')
tqdm.write(f"[{i+1}/{len(documents)}] ✓ 成功: {movie_name}")
else:
failed_docs.append(doc)
tqdm.write(f"[{i+1}/{len(documents)}] ✗ 失败: 解析错误")
except Exception as e:
failed_docs.append(doc)
tqdm.write(f"[{i+1}/{len(documents)}] ✗ 失败: {str(e)}")
finally:
pbar.update(1)
# 打印详细统计
print("\n处理统计:")
print(f"总数据量: {len(documents)} 部电影")
print(f"成功处理: {len(results)} 部电影")
print(f"处理失败: {len(failed_docs)} 部电影")
print(f"成功率: {len(results)/len(documents)*100:.2f}%")
# 保存成功的结果
with open('movie_relations.json', 'w', encoding='utf-8') as f:
json.dump(results, f, ensure_ascii=False, indent=2)
print("\n成功的结果已保存到 movie_relations.json")
# 保存失败的文档信息供后续分析
if failed_docs:
with open('failed_movies.txt', 'w', encoding='utf-8') as f:
for doc in failed_docs:
f.write(f"---\n{doc.page_content}\n")
print("失败的文档已保存到 failed_movies.txt")
成功率达到51.20%,正确转化成知识图谱的电影条数为128条,说明该模型转换能力还有待提高。
模型选取方面:
qwen2.5-coder:7b------直解析错误
llama3.1:8b ------正确处理51.20%
可见,不同的模型对这种数据的解析能力是不同的,如果采用参数更大更适合实体关系抽取的模型效果会更好!由于本地电脑内存限制,我将继续使用已成功转化的128条数据进行图谱构建,以便给读者留下改进空间。
7、将大模型识别出的关系写入数据库
插入数据的时候,实体之间的关系是否符合:导演-执导->电影,演员-主演->电影,编剧-编写->电影
python
from langchain_community.graphs import Neo4jGraph
import json
from tqdm import tqdm
def import_to_neo4j(graph: Neo4jGraph, json_file: str):
"""
从JSON文件逐条导入电影关系数据到Neo4j数据库
"""
# 读取JSON文件
print(f"正在读取文件: {json_file}")
with open(json_file, 'r', encoding='utf-8') as f:
movie_data = json.load(f)
print(f"成功读取 {len(movie_data)} 条电影数据")
try:
# 清空数据库
print("清空数据库...")
graph.query("""
MATCH (n)
DETACH DELETE n
""")
# 创建索引
print("创建索引...")
graph.query("""
CREATE INDEX IF NOT EXISTS FOR (m:Movie) ON (m.name)
""")
graph.query("""
CREATE INDEX IF NOT EXISTS FOR (p:Person) ON (p.name)
""")
# 逐条处理数据
print(f"\n开始导入数据,共 {len(movie_data)} 条记录...")
success_count = 0
error_count = 0
with tqdm(total=len(movie_data), desc="导入进度") as pbar:
for movie in movie_data:
try:
# 创建电影节点
graph.query("""
MERGE (m:Movie {name: $movie_name})
""", {"movie_name": movie["movie_name"]})
# 处理每个关系
for rel in movie["relationships"]:
# 创建人物节点
graph.query("""
MERGE (p:Person {name: $person_name})
""", {"person_name": rel["source"]})
# 根据关系类型创建关系
if rel["relation"] == "执导":
graph.query("""
MATCH (p:Person {name: $person_name})
MATCH (m:Movie {name: $movie_name})
MERGE (p)-[:DIRECTED]->(m)
""", {
"person_name": rel["source"],
"movie_name": movie["movie_name"]
})
elif rel["relation"] == "编写":
graph.query("""
MATCH (p:Person {name: $person_name})
MATCH (m:Movie {name: $movie_name})
MERGE (p)-[:WROTE]->(m)
""", {
"person_name": rel["source"],
"movie_name": movie["movie_name"]
})
elif rel["relation"] == "主演":
graph.query("""
MATCH (p:Person {name: $person_name})
MATCH (m:Movie {name: $movie_name})
MERGE (p)-[:ACTED_IN]->(m)
""", {
"person_name": rel["source"],
"movie_name": movie["movie_name"]
})
success_count += 1
pbar.update(1)
pbar.set_description(f"成功: {success_count}, 失败: {error_count}")
except Exception as e:
error_count += 1
print(f"\n导入电影 {movie.get('movie_name', 'Unknown')} 失败: {str(e)}")
pbar.update(1)
pbar.set_description(f"成功: {success_count}, 失败: {error_count}")
continue
# 打印统计信息
print("\n导入完成!")
print(f"成功导入: {success_count}")
print(f"导入失败: {error_count}")
# 打印详细统计
stats_result = graph.query("""
MATCH (m:Movie)
WITH COUNT(m) as movies
MATCH (p:Person)
WITH movies, COUNT(p) as persons
MATCH ()-[r]->()
WITH movies, persons, COUNT(r) as relations
RETURN movies, persons, relations
""")
if stats_result and len(stats_result) > 0:
stats = stats_result[0]
print("\n数据库统计:")
print(f"电影节点数: {stats['movies']}")
print(f"人物节点数: {stats['persons']}")
print(f"关系数: {stats['relations']}")
# 打印各类关系的统计
relation_stats = graph.query("""
MATCH ()-[r]->()
WITH type(r) as relation_type, COUNT(*) as count
RETURN relation_type, count
ORDER BY count DESC
""")
print("\n关系类型统计:")
for rel in relation_stats:
print(f"{rel['relation_type']}: {rel['count']} 条")
except Exception as e:
print(f"导入过程中出错: {str(e)}")
raise e
# 使用示例
try:
# 连接到Neo4j数据库
graph = Neo4jGraph(
url="neo4j://localhost:7687",
username="neo4j",
password="12345678" # 替换为您的实际密码
)
# 导入数据
import_to_neo4j(graph, 'movie_relations.json')
except Exception as e:
print(f"导入失败: {str(e)}")
8、设置QA链实现关于电影的问答功能
python
# 导入必要的依赖
from langchain_core.prompts import PromptTemplate
from langchain.chains import GraphCypherQAChain
# 修改Cypher查询模板
CYPHER_GENERATION_TEMPLATE = """任务: 生成查询图数据库的Cypher语句。
说明:
数据库中的关系模式如下:
- (Person)-[:DIRECTED]->(Movie) 表示导演关系
- (Person)-[:ACTED_IN]->(Movie) 表示演员关系
- (Person)-[:WROTE]->(Movie) 表示编剧关系
所有节点和关系的属性:
- Person节点有name属性
- Movie节点有name属性
注意:
- 不要使用未定义的关系类型或属性
- 返回完整的节点信息
问题是:
{question}"""
# 创建Cypher生成提示
CYPHER_GENERATION_PROMPT = PromptTemplate(
input_variables=["schema", "question"],
template=CYPHER_GENERATION_TEMPLATE
)
# 创建新的QA链
chain = GraphCypherQAChain.from_llm(
llm,
graph=graph,
verbose=True,
allow_dangerous_requests=True, # 添加这个参数
cypher_prompt=PromptTemplate(
input_variables=["question"],
template=CYPHER_GENERATION_TEMPLATE
)
)
这样设置的QA链可以:
将自然语言问题转换为Cypher查询在Neo4j数据库中执行查询将结果转换回自然语言回答您可以尝试各种问题,比如:某个导演导演了哪些电影、某个演员参演了哪些电影、某类型的电影推荐等。
python
# 测试查询
response = chain.run("宫崎骏执导了哪些电影?")
print(response)
python
# 测试查询
response = chain.run("评分最高的前5部电影是什么?")
print(response)
python
# 测试查询
response = chain.run("我想看一部战争与爱情相关的评分较高的电影有什么推荐?")
print(response)
9、实现电影推荐
通过修改查询模板,添加相关的说明。
python
# 修改Cypher查询模板,添加推荐相关的说明
CYPHER_GENERATION_TEMPLATE = """任务: 生成查询图数据库的Cypher语句。
说明:
数据库中的关系模式如下:
- (Person)-[:DIRECTED]->(Movie) 表示导演关系
- (Person)-[:ACTED_IN]->(Movie) 表示演员关系
- (Person)-[:WROTE]->(Movie) 表示编剧关系
Movie节点的属性包括:
- name: 电影名称
- type: 电影类型
- rating: 豆瓣评分
- plot: 剧情简介
请根据用户的偏好生成合适的推荐查询。
问题是:
{question}"""
# 创建新的QA链
chain = GraphCypherQAChain.from_llm(
llm,
graph=graph,
verbose=True,
allow_dangerous_requests=True,
cypher_prompt=PromptTemplate(
input_variables=["question"],
template=CYPHER_GENERATION_TEMPLATE
)
)
# 测试各种推荐场景
recommendation_questions = [
# 基于类型推荐
"请推荐一些好看的爱情片",
"我想看评分高的动作片",
# 基于导演推荐
"我喜欢宫崎骏的作品风格,请推荐类似的动画电影",
"我看过张艺谋的《英雄》很喜欢,有类似风格的电影推荐吗",
# 基于演员推荐
"我很喜欢周星驰的喜剧电影,请推荐类似的",
"我是汤姆·汉克斯的粉丝,想看他的经典作品",
# 基于评分推荐
"请推荐一些豆瓣评分9分以上的经典电影",
"最近有什么好评的新电影推荐吗",
# 组合条件推荐
"想看一部评分高的爱情片,最好是90年代的经典",
"请推荐一些适合全家观看的动画电影"
]
# 测试推荐
for question in recommendation_questions[:3]: # 测试前3个问题
print(f"\n问题:{question}")
try:
response = chain.run(question)
print(f"推荐:{response}")
except Exception as e:
print(f"查询出错:{str(e)}")
print("-" * 50)
改进与反思:
解决方法:
python
import re
def normalize_movie_name(name):
"""标准化电影名称,处理各种特殊情况"""
# 常见的电影名称映射
name_mapping = {
"Coco": "寻梦环游记",
"小森林 夏秋篇 リトル・フォレスト 夏・秋": "小森林 夏秋篇",
"城王之李 City Lights": "城市之光",
"Rain Man": "雨人",
"The Notebook": "恋恋笔记本",
"Lord of War": "战争之王",
"Waterloo Bridge": "魂断蓝桥",
"黄崋小口橡小窗杀": "黄金三镖客",
"芦苇镇": "芦苇镇"
}
if name in name_mapping:
return name_mapping[name]
return name
def parse_movie_attributes(doc):
"""从文档中解析电影属性"""
movie = {}
# 使用正则表达式提取各个属性
patterns = {
'name': r'电影名称:\s*(.*?)(?=\n|$)',
'director': r'导演:\s*(.*?)(?=\n|$)',
'writer': r'编剧:\s*(.*?)(?=\n|$)',
'actors': r'主演:\s*(.*?)(?=\n|$)',
'genres': r'类型:\s*(.*?)(?=\n|$)',
'country': r'制片国家/地区:\s*(.*?)(?=\n|$)',
'language': r'语言:\s*(.*?)(?=\n|$)',
'release_date': r'上映日期:\s*(.*?)(?=\n|$)',
'duration': r'片长:\s*(\d+).*?(?=\n|$)',
'rating': r'豆瓣评分:\s*([\d.]+)(?=\n|$)',
'plot': r'剧情简介:\s*(.*?)(?=\n\n|$)'
}
for key, pattern in patterns.items():
match = re.search(pattern, doc, re.DOTALL)
if match:
value = match.group(1).strip()
if key in ['director', 'writer', 'actors', 'genres']:
# 处理列表类型的属性
value = [v.strip() for v in value.split('/')]
elif key == 'duration':
# 转换为整数
value = int(value)
elif key == 'rating':
# 转换为浮点数
value = float(value)
elif key == 'release_date':
# 提取年份
year_match = re.search(r'(\d{4})', value)
if year_match:
value = int(year_match.group(1))
else:
value = None
movie[key] = value
return movie
def update_movie_attributes(documents, graph):
"""更新数据库中电影的属性"""
success_count = 0
error_count = 0
skipped_count = 0
# 获取数据库中现有的电影名称
existing_movies = graph.query("""
MATCH (m:Movie)
RETURN m.name as name
""")
existing_names = {record['name'] for record in existing_movies}
print(f"数据库中现有电影数量:{len(existing_names)}")
with tqdm(total=len(documents), desc="更新电影属性") as pbar:
for doc in documents:
try:
# 确保从doc对象中正确获取文本内容
content = doc.page_content if hasattr(doc, 'page_content') else str(doc)
# 解析文档中的电影信息
movie = parse_movie_attributes(content)
if not movie or 'name' not in movie:
skipped_count += 1
pbar.update(1)
continue
# 标准化电影名称
movie_name = movie['name'].split()[0] # 只取中文名部分
db_name = None
# 尝试直接匹配
if movie_name in existing_names:
db_name = movie_name
else:
# 尝试标准化后匹配
normalized_name = normalize_movie_name(movie_name)
if normalized_name in existing_names:
db_name = normalized_name
# 只处理找到匹配的电影
if db_name:
# 处理类型列表
genres = movie.get('genres', [])
if isinstance(genres, str):
genres = [g.strip() for g in genres.split('/')]
# 更新电影属性
update_query = """
MATCH (m:Movie {name: $db_name})
SET
m.rating = toFloat($rating),
m.year = toInteger($year),
m.duration = toInteger($duration),
m.country = $country,
m.language = $language,
m.genres = $genres,
m.plot = $plot
"""
params = {
'db_name': db_name,
'rating': movie.get('rating'),
'year': movie.get('release_date'),
'duration': movie.get('duration'),
'country': movie.get('country'),
'language': movie.get('language'),
'genres': genres,
'plot': movie.get('plot', '')
}
# 打印调试信息
print(f"\n正在更新电影: {db_name}")
print(f"评分: {params['rating']}")
print(f"类型: {params['genres']}")
graph.query(update_query, params)
success_count += 1
else:
skipped_count += 1
except Exception as e:
print(f"处理电影时出错: {str(e)}")
error_count += 1
pbar.update(1)
print(f"\n更新完成!")
print(f"成功更新: {success_count}")
print(f"更新失败: {error_count}")
print(f"跳过处理: {skipped_count}")
最终结果:
设置QA链,根据电影内容进行推荐。
python
# 修改Cypher查询模板,添加更多维度的推荐说明
CYPHER_GENERATION_TEMPLATE = """任务: 根据用户需求生成Neo4j查询语句,实现电影推荐。
数据库模式说明:
1. 节点类型:
- Movie: 电影节点
- Person: 人物节点(导演/演员/编剧)
2. 关系类型:
- (Person)-[:DIRECTED]->(Movie): 导演关系
- (Person)-[:ACTED_IN]->(Movie): 演员关系
- (Person)-[:WROTE]->(Movie): 编剧关系
3. Movie节点属性:
- name: 电影名称
- rating: 豆瓣评分(float)
- year: 上映年份(int)
- duration: 片长(int,分钟)
- country: 制片国家
- language: 语言
- genres: 电影类型(list)
- plot: 剧情简介
推荐维度说明:
1. 基于类型推荐: 使用genres属性匹配
2. 基于评分推荐: 使用rating属性筛选
3. 基于年代推荐: 使用year属性筛选
4. 基于导演/演员推荐: 通过关系查询
5. 基于国家/语言推荐: 使用country/language属性
6. 多维度组合推荐: 结合多个属性
用户问题:
{question}
请生成合适的Cypher查询语句,注意:
1. 优先按评分降序排序
2. 建议返回电影名称、评分、年份、类型等关键信息
3. 适当限制返回结果数量(如LIMIT 5)
4. 确保ORDER BY在LIMIT之前
"""
# 创建新的QA链
chain = GraphCypherQAChain.from_llm(
llm,
graph=graph,
verbose=True,
allow_dangerous_requests=True, # 添加这个参数来确认安全风险
cypher_prompt=PromptTemplate(
input_variables=["question"],
template=CYPHER_GENERATION_TEMPLATE
)
)
# # 测试各种推荐场景
# test_questions = [
# # 单维度推荐
# "请推荐一些评分超过9分的经典电影",
# "有什么好看的动作片推荐?",
# "90年代的经典电影有哪些?",
# "宫崎骏导演的动画电影推荐",
# # 多维度组合推荐
# "想看一部评分高的爱情片,最好是90年代的",
# "有什么适合全家一起看的、评分不错的动画电影?",
# "请推荐几部张艺谋导演的、评分高于8分的电影",
# "想看一部评分高的日本电影,最好是剧情片"
# ]
# # 测试推荐效果
# for question in test_questions:
# print(f"\n问题: {question}")
# print("-" * 50)
# try:
# response = chain.run(question)
# print(f"推荐结果:\n{response}")
# except Exception as e:
# print(f"查询出错: {str(e)}")
# print("=" * 50)
python
chain.run("请推荐一些评分超过9分的经典电影")
python
test_queries = [
"请推荐一些评分超过9分的经典电影",
"有什么好看的动作片推荐?",
"90年代的经典电影有哪些?",
"宫崎骏导演的动画电影推荐"
]
for query in test_queries:
print(f"\n问题: {query}")
try:
response = chain.run(query)
print(f"回答:\n{response}")
except Exception as e:
print(f"错误: {str(e)}")
还是有一些不足,但是回答的正确率已经达到60%以上。
程序文件链接:
通过网盘分享的文件:豆瓣电影知识图谱构建.rar
链接: https://pan.baidu.com/s/1aKIHXtZXCi-FjFLrfW8z6A 提取码: 6bkp
--来自百度网盘超级会员v5的分享