在这里插入图片描述

知识图谱推荐模型: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 启动流程

  1. 初始化数据库:
    py data_process.py
    
  2. 启动服务:
    py app.py
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐