基于开源WQ装备知识图谱的智能问答优化

基于笔者之前写的博客基础上:https://blog.csdn.net/zhanghan11366/article/details/142139488【基于开源WQ装备知识图谱的智能问答全流程构建】进行优化。

优化一、

解决你提出的多武器、多关系解析问题,并确保每个武器只匹配其对应的关系,结合分句功能

  1. 改进点:
  • 分句功能:将问题分成多个句子,每个句子分别处理。
  • 关系和武器的精确匹配:确保每个武器只匹配其对应的关系。
  • 灵活解析:可以识别并处理句子中多个武器、多个关系。
  1. 改进点说明:
  • 分句处理:问题会被切分为多个句子,使用 split_sents 函数根据常见的标点符号(如句号、问号、感叹号)进行分割。每个句子会独立处理。
  • 多武器和多关系匹配:在每个句子中,分别提取出相关的武器和关系,并进行相应的查询。确保不会混淆多个武器和它们的对应关系。
  • 缓存武器节点:程序启动时会从 Neo4j 缓存所有武器节点,避免重复查询,提高效率。

主要代码如下:

import re
from neo4j import GraphDatabase


# 全局缓存武器节点
cached_weapons = []

# 查询Neo4j数据库
def query_neo4j(query, parameters=None):
    with driver.session() as session:
        result = session.run(query, parameters)
        return [record for record in result]

# 分句功能
def split_sents(content):
    return [sentence.strip() for sentence in re.split(r'[??!!。;;\n\r]', content) if sentence.strip()]

# 生成回答模块
def generate_answer(sentence):
    # 解析问题,提取武器和关系类型
    parsed_sentence = parse_question(sentence)
    weapons = parsed_sentence.get('weapons')
    relations = parsed_sentence.get('relations')

    if not weapons or not relations:
        return f"无法识别句子中的武器或关系类型: {sentence}"

    answers = []
    for weapon in weapons:
        for relation in relations:
            # 构建查询语句
            query = (
                f"MATCH (w:Weapon {{name: $weapon}})-[r:`{relation}`]->(e) "
                "RETURN e.name AS entity"
            )
            result = query_neo4j(query, parameters={"weapon": weapon})

            # 生成单个武器-关系的回答
            if result:
                entity_list = [record["entity"] for record in result]
                answers.append(f"{weapon}的{relation}是: {', '.join(entity_list)}")
            else:
                answers.append(f"没有找到{weapon}的{relation}信息。")

    return "\n".join(answers)

结果
在这里插入图片描述

优化二

查寻两个武器之间的关系:“PZL P.6战斗机"和"PZL P.1战斗机”。为了解决两两配对查询中可能存在重复结果的问题,可以对配对后的武器查询进行优化。

  1. 主要思路是:
  • 去重处理:在查询之前,使用集合来存储查询对,以避免重复查询同一对武器(无论顺序如何)。
  • 只查询唯一的武器组合:即 (‘weapon1’, ‘weapon2’) 和 (‘weapon2’, ‘weapon1’) 应该视为同一对武器,不必重复查询。
  1. 关键优化点
  • 使用 set():queried_pairs 集合用于存储已经查询过的武器对,确保每个组合只查询一次。这里使用 tuple(sorted([node1, node2])) 来生成无序的组合,即 (‘A’, ‘B’) 和 (‘B’, ‘A’) 会被视为同一个组合。
  • 避免重复查询:每次进行查询前,检查该武器组合是否已经存在于 queried_pairs 中。如果不存在,则进行查询,并将其添加到 queried_pairs 中。
  1. 优化后的效果
  • 同一对武器(如 PZL P.6战斗机 和 PZL P.1战斗机)无论顺序如何,只会查询一次,避免了重复结果。
    提升了查询效率,尤其是在输入包含多个武器节点时,系统不会因重复查询浪费时间。

主要代码:

def generate_answer(sentence):
    # 解析问题,提取武器和关系类型
    parsed_sentence = parse_question(sentence)
    weapons = parsed_sentence.get('weapons')
    print(weapons)
    relations = parsed_sentence.get('relations')

    # 处理两个武器节点之间的关系查询
    if len(weapons) == 2 and not relations:
        node1, node2 = weapons[0], weapons[1]
        return query_relation_between_weapons(node1, node2)

    if not weapons or not relations:
        return f"无法识别句子中的武器或关系类型: {sentence}"

    answers = []
    for weapon in weapons:
        for relation in relations:
            # 构建查询语句
            query = (
                f"MATCH (w:Weapon {{name: $weapon}})-[r:`{relation}`]->(e) "
                "RETURN e.name AS entity"
            )
            result = query_neo4j(query, parameters={"weapon": weapon})

            # 生成单个武器-关系的回答
            if result:
                entity_list = [record["entity"] for record in result]
                answers.append(f"{weapon}的{relation}是: {', '.join(entity_list)}")
            else:
                answers.append(f"没有找到{weapon}的{relation}信息。")

    return "\n".join(answers)

结果如下:
在这里插入图片描述

优化三

查找任意两个节点之间的关系。并在生成每个回答时,仅保留那些有实际关系的答案,避免输出那些无效的“没有找到关系”的信息。可以通过简单的条件检查实现这一点。

主要代码如下:

def generate_answer(sentence):
    # 解析问题,提取节点和关系类型
    parsed_sentence = parse_question(sentence)
    nodes = parsed_sentence.get('nodes')
    relations = parsed_sentence.get('relations')

    # 处理多个节点之间的两两关系查询
    if len(nodes) > 1 and not relations:
        answers = []
        # 使用集合存储查询对,避免重复查询
        queried_pairs = set()

        # 两两配对查询,避免重复的节点组合
        for i in range(len(nodes)):
            for j in range(i + 1, len(nodes)):
                node1, node1_type = nodes[i]
                node2, node2_type = nodes[j]
                # 生成无序的节点对,用于去重
                pair = tuple(sorted([(node1, node1_type), (node2, node2_type)]))


                # 仅当这个配对未被查询过时才进行查询
                if pair not in queried_pairs:
                    queried_pairs.add(pair)  # 记录这个节点配对
                    answer = query_relation_between_nodes(node1, node1_type, node2, node2_type)
                    if answer:  # 仅添加有关系的答案
                        answers.append(answer)

        # 过滤掉没有关系的答案
        return "\n".join(answers) if answers else "没有找到相关的关系。"

    if not nodes or not relations:
        return f"无法识别句子中的节点或关系类型: {sentence}"

    # 单节点与关系类型的查询
    answers = []
    for node, node_type in nodes:
        for relation in relations:
            # 构建查询语句
            query = (
                f"MATCH (n:{node_type} {{name: $node}})-[r:`{relation}`]->(e) "
                "RETURN e.name AS entity"
            )
            result = query_neo4j(query, parameters={"node": node})

            # 生成单个节点-关系的回答
            if result:
                entity_list = [record["entity"] for record in result]
                answers.append(f"{node}的{relation}是: {', '.join(entity_list)}")
            else:
                answers.append(f"没有找到{node}的{relation}信息。")

    return "\n".join(answers)

结果展示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值