基于知识图谱的电影推荐系统(可提供源码)
·

知识图谱推荐模型:TransH
安装依赖
pip install python-docx openpyxl flask flask_cors py2neo openai pandas ollama flask_sqlalchemy PyJWT pdfminer.six
技术说明文档
1. 项目概述
本系统是一个结合知识图谱存储、可视化展示与自然语言问答功能的综合平台,采用Python技术栈构建。系统通过结构化知识图谱(Neo4j)实现高效数据关联查询,利用自然语言处理(Ollama)解析用户问题,结合RESTful API(Flask)与前端可视化交互,提供直观的知识探索体验。系统核心功能包括:
- 知识图谱可视化:动态展示节点关系与属性。
- 自然语言问答:用户可通过自然语言提问,系统返回结构化答案。
- 用户鉴权:基于JWT实现安全的API访问控制。
2. 技术架构
系统采用分层架构设计,主要分为以下层次:
| 层级 | 技术组件 | 功能描述 |
|---|---|---|
| 数据层 | Neo4j, SQLite | 存储知识图谱数据(Neo4j)与用户元数据(SQLAlchemy) |
| 服务层 | Flask, Flask-SQLAlchemy | 提供RESTful API与业务逻辑处理 |
| NLP层 | Ollama | 大模型问答 |
| 认证层 | PyJWT | 用户身份验证与API权限管理 |
3. 核心模块说明
3.1 后端模块
3.1.1 数据模型
- Neo4j图模型
// 示例:人物-公司-职位关系模型 CREATE (:Person {name: "张三", age: 35})-[:WORK_AT {position: "CTO"}]->(:Company {name: "AI科技", industry: "IT"}) - 关系型模型(SQLAlchemy)
class UserInfo(db.Model):
"""
用户信息表
"""
id = db.Column(db.Integer, primary_key=True)
account = db.Column(db.String(255))
password = db.Column(db.String(255))
name = db.Column(db.String(255))
def to_dict(self):
return {
'id': self.id,
'account': self.account,
'name': self.name
}
3.1.2 API接口
- 用户认证
@app.before_request
def before():
url = request.path # 当前请求的URL
print('url:' + url)
pass_url = ["/", "/api/login", "/api/sign_in"]
if url.startswith("/static") or url in pass_url:
pass
else:
token = request.headers.get('Token')
if not token:
return jsonify({
"code": 403,
"msg": "您还未登录,请先登录"
})
else:
global user_id
user_id = decode(token)['user_id']
- 知识检索
def get_kg_new(self, entity, depth=4):
if entity:
sql = f"""
MATCH p=(n)-[r*1..{depth}]-(m)
WHERE n.name =~ '.*{entity}.*'
RETURN nodes(p) AS nodes, relationships(p) AS rels
"""
else:
sql = f"""
MATCH p=(n)-[r*1..{depth}]-(m)
RETURN nodes(p) AS nodes, relationships(p) AS rels LIMIT 100
"""
result = self.graph.run(sql).data()
nodes = []
lines = []
id_list = []
if result:
for record in result:
for node in record['nodes']:
node_id = node.identity
if node_id not in id_list:
node_data = {
'id': node_id,
'name': node['name'],
'type': list(node.labels)[0] if node.labels else ''
}
for prop in node:
node_data[prop] = node[prop]
id_list.append(node_id)
nodes.append(node_data)
for rel in record['rels']:
lines.append({
'from': rel.start_node.identity,
'to': rel.end_node.identity,
'text': type(rel).__name__
})
json_data = {'nodes': nodes, 'lines': lines}
return json_data
3.2 问答模块
def chat_neo4j(self, entity_list, question):
'''问答流程'''
context = ''
answer = ''
if entity_list:
for entity in entity_list:
# 知识问答
sql = "match p=(n)-[r]->(m) where n.name=~ '.*%s.*' return m.name as name,type(r) as rname" % (entity)
result = self.graph.run(sql).data()
if result:
for lin in result:
if not context:
context = entity + '的' + lin['rname'] + '为' + lin['name'] + '\n'
else:
context = context + ',' + entity + '的' + lin['rname'] + '为' + lin['name'] + '\n'
sql = 'MATCH (n) where n.name="%s" RETURN properties(n) AS nodeProperties' % (entity)
result = self.graph.run(sql).data()
if result:
result_dict = result[0]['nodeProperties']
for lin in result_dict:
if not context:
answer = entity + '的' + lin + '为' + result_dict[lin] + '\n'
else:
answer = context + ',' + entity + '的' + lin + '为' + result_dict[lin] + '\n'
if context:
answer = self.ollama_api_gen(question, context)
return answer
3.3 认证模块
- JWT验证装饰器
import jwt
secret = 'aayujhtsrgabbhdgjccras'
# 编码
def encode(user_id):
return jwt.encode({'user_id': user_id}, secret, algorithm='HS256')
def decode(encoded_jwt):
return jwt.decode(encoded_jwt, secret, algorithms=['HS256'])
5.3 启动流程
- 初始化数据库:
py data_process.py - 启动服务:
py app.py






更多推荐
所有评论(0)