快速搭建一个基于知识图谱的智能问答系统

article/2025/11/6 17:26:41

点击上方,选择星标置顶,不定期资源大放送

阅读大概需要15分钟

Follow小博主,每天更新前沿干货

作者:张墨一

知乎链接:https://zhuanlan.zhihu.com/p/58248608

本文仅作学术分享,若侵权,请联系后台删文处理

1 任务背景:

本次实验拟设计一个智能问答系统,并应当保证该智能问答系统可以回答5个及其以上的问题。由于本实验室目前正在使用知识图谱搭建问答系统,故而这里将使用知识图谱的方式构建该智能问答系统。这里将构建一个关于歌曲信息的问答系统。以“晴天”为例,本系统应当能够回答晴天的歌词是什么,晴天是哪首专辑的歌曲,该专辑是哪一年发行的,该专辑对应的歌手是谁,该歌手的的基本信息是什么。

本系统的环境配置过程以及全部代码均已上传Github。下面的文章主要介绍的是系统总体结构以及部分代码解析。

  • Github地址:https://github.com/zhangtao-seu/Jay_KG

2 系统总体工作流程图

在搭建系统之前,第一步的任务是准备数据。这里的准备的数据包括周杰伦的姓名,个人简介,出生日期,以及发行的所有专辑名字,《叶惠美》专辑的名字,简介以及发行日期,《以父之名》、《晴天》的歌曲名和歌词。

准备好数据之后,将数据整理成RDF文档的格式。这里采用手工的方式在protégé中构建本体以及知识图谱。本体作为模式层,这里声明了三个类,包括歌手类、专辑类和歌曲类;声明了四种关系,也叫objectProperty,包括include,include_by,release和release_by。其中include和include_by声明为inverseOf关系,表示专辑和歌曲之间的包含和被包含的关系。Release和release_by声明为inverseOf关系表示歌手和专辑之间的发行和被发行的关系;声明了8种数据属性,也叫DataProperty,分别为singer_name,singer_birthday,singer_introduction,album_name,album_introduction,album_release_date,song_name和song_content。将上述准备好的数据以individual和dataProperty的形式写进知识图谱。至此,就准备好了我们的RDF/OWL文件了。

接着,为了使用RDF查询语言SPARQL做后续的查询操作,这里使用Apache Jena的TDB和Fuseki组件。TDB是Jena用于存储RDF的组件,是属于存储层面的技术。Fuseki是Jena提供的SPARQL服务器,也就是SPARQL endpoint。这一步中,首先利用Jena将RDF文件转换为tdb数据。接着对fuseki进行配置并打开SPARQL服务器,就可以通过查询语句完成对知识图谱的查询。

最后,将自然语言问题转换成SPARQL查询语句。首先使用结巴分词将自然语言问题进行分词以及词性标注。这里将专辑名字和歌曲名字作为外部词典以保证正确的分词和词性标注。以“叶惠美”为例,结巴分词将“叶惠美”标注为nr,即人名,这里“叶惠美”作为专辑名字应该标注为nz,即专有名词。对于不同类型的问题,我们将问题匹配给不同的查询语句生成函数从而得到正确的查询语句。将查询语句作为请求参数和Fuseki服务器通信就能得到相应的问题结果。上述工作流程图如图2-1所示。

图2-1 系统工作流程图

3 系统实现

3.1 系统实现工具和环境

使用protégé构建知识库的本体和知识图谱。首先是定义模式层,包括class,objectProperty和dataProperty。以歌曲类为例,其RDF代码为:

<!-- http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#歌曲 -->
<owl:Class rdf:about="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#歌曲"><rdfs:subClassOf><owl:Restriction><owl:onProperty rdf:resource="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#song_content"/><owl:allValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#string"/></owl:Restriction></rdfs:subClassOf><rdfs:subClassOf><owl:Restriction><owl:onProperty rdf:resource="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#song_name"/><owl:allValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#string"/></owl:Restriction></rdfs:subClassOf>
</owl:Class>

可以看出class “歌曲”包含了song_name和song_content两个dataProperty。以include的关系为例,其RDF代码如下:

<!-- http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#include -->
<owl:ObjectProperty rdf:about="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#include">
<owl:inverseOf rdf:resource="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#include_by"/>
<rdfs:domain rdf:resource="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#专辑"/>
<rdfs:range rdf:resource="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#歌曲"/>
</owl:ObjectProperty>

可以看出该关系和include_by是inverseOf的关系,其关系主语是专辑,宾语是歌曲。以singer_introduction的dataProperty为例,其RDF代码如下:

<!-- http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#singer_introduction -->
<owl:DatatypeProperty rdf:about="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#singer_introduction">
<rdfs:domain rdf:resource="http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#歌手"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</owl:DatatypeProperty>

可以看出其主语是歌手类,其宾语是字符串。

接着是数据层。图3-1和图3-2是系统的知识图谱可视化的结果。可以看出,“七里香”是一个专辑,“东风破”是一首歌曲。

图3-1专辑知识图谱可视化

图3-2 歌曲知识图谱可视化

使用Feseki启动SPARQL服务器,可以在localhost:3030中实现数据的查询。以查询“以父之名”的专辑为例,图3-3展示其查询代码和查询结果,可以看出如下语句可以得到查询结果“叶惠美”。

图3-3 Feseki平台的查询情况

3.2 自然语言处理核心代码分析

使用结巴分词将自然语言句子实现分词和词性标注。其核心代码如下:

import jieba
import jieba.posseg as pseg
class Word(object):
def __init__(self, token, pos):self.token = tokenself.pos = pos
class Tagger:
def __init__(self, dict_paths):# TODO 加载外部词典for p in dict_paths:jieba.load_userdict(p)
@staticmethod
def get_word_objects(sentence):# 把自然语言转为Word对象return [Word(word.encode('utf-8'), tag) for word, tag in pseg.cut(sentence)]

这段代码可以将句子作为一个输入,输出句子的分子和词性,以“叶惠美是什么发布的?”为例,可以得到以下结果:

图3-4 结巴分词示意图

将句子作为参数传递给Rule对象,根据关键字匹配相一致的查询语句的生成函数,Rule对象和关键字匹配的代码如下:

from refo import finditer, Predicate, Star, Any, Disjunction
import reclass W(Predicate):def __init__(self, token=".*", pos=".*"):self.token = re.compile(token + "$")self.pos = re.compile(pos + "$")super(W, self).__init__(self.match)def match(self, word):m1 = self.token.match(word.token.decode("utf-8"))m2 = self.pos.match(word.pos)return m1 and m2class Rule(object):def __init__(self, condition_num, condition=None, action=None):assert condition and actionself.condition = conditionself.action = actionself.condition_num = condition_numdef apply(self, sentence):matches = []for m in finditer(self.condition, sentence):i, j = m.span()matches.extend(sentence[i:j])return self.action(matches), self.condition_num
# TODO 定义关键词
pos_person = "nr"
pos_song = "nz"
pos_album = "nz"
person_entity = (W(pos=pos_person))
song_entity = (W(pos=pos_song))
album_entity = (W(pos=pos_album))
singer = (W("歌手") | W("歌唱家") | W("艺术家") | W("艺人") | W("歌星"))
album = (W("专辑") | W("合辑") | W("唱片"))
song = (W("歌") | W("歌曲"))
birth = (W("生日") | W("出生") + W("日期") | W("出生"))
english_name = (W("英文名") | W("英文") + W("名字"))
introduction = (W("介绍") | W("是") + W("谁") | W("简介"))
song_content = (W("歌词") | W("歌") | W("内容"))
release = (W("发行") | W("发布") | W("发表") | W("出"))
when = (W("何时") | W("时候"))
where = (W("哪里") | W("哪儿") | W("何地") | W("何处") | W("在") + W("哪"))# TODO 问题模板/匹配规则
"""
1.周杰伦的专辑都有什么?
2.晴天的歌词是什么?
3.周杰伦的生日是哪天?
4.以父之名是哪个专辑里的歌曲?
5.叶惠美是哪一年发行的?
"""
rules = [Rule(condition_num=2, condition=person_entity + Star(Any(), greedy=False) + album + Star(Any(), greedy=False), action=QuestionSet.has_album),Rule(condition_num=2, condition=song_entity + Star(Any(), greedy=False) + song_content + Star(Any(), greedy=False),action=QuestionSet.has_content),Rule(condition_num=2, condition=person_entity + Star(Any(), greedy=False) + introduction + Star(Any(), greedy=False),action=QuestionSet.person_inroduction),Rule(condition_num=2, condition=song_entity + Star(Any(), greedy=False) + album + Star(Any(), greedy=False),action=QuestionSet.stay_album),Rule(condition_num=2, condition=song_entity + Star(Any(), greedy=False) + release + Star(Any(), greedy=False),action=QuestionSet.release_album),
]

匹配成功后,通过action动作出发相对应的函数能够生成相对应的查询语句。以查询“以父之名是哪个专辑的歌曲?”为例,其生成查询语句的代码如下:

# TODO SPARQL前缀和模板
SPARQL_PREXIX = u"""
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX : <http://www.semanticweb.org/张涛/ontologies/2019/1/untitled-ontology-32#>
"""
SPARQL_SELECT_TEM = u"{prefix}\n" + \u"SELECT {select} WHERE {{\n" + \u"{expression}\n" + \u"}}\n"
class QuestionSet:
@staticmethoddef stay_album(word_object):# 以父之名是哪个专辑的歌曲select = u"?x"sparql = Nonefor w in word_object:if w.pos == pos_song:e = u" :{song} :include_by ?o."\u" ?o :album_name ?x.".format(song=w.token.decode('utf-8'))sparql = SPARQL_SELECT_TEM.format(prefix=SPARQL_PREXIX,select=select,expression=e)breakreturn sparql
最后,将得到的查询语句作为请求参数和SPARQL服务器进行通信并对得到的结果进行解析就能得到我们想要的答案,其核心代码如下:
from SPARQLWrapper import SPARQLWrapper, JSON
from collections import OrderedDictclass JenaFuseki:def __init__(self, endpoint_url='http://localhost:3030/jay_kbqa/sparql'):self.sparql_conn = SPARQLWrapper(endpoint_url)def get_sparql_result(self, query):self.sparql_conn.setQuery(query)self.sparql_conn.setReturnFormat(JSON)return self.sparql_conn.query().convert()@staticmethoddef parse_result(query_result):"""解析返回的结果:param query_result::return:"""try:query_head = query_result['head']['vars']query_results = list()for r in query_result['results']['bindings']:temp_dict = OrderedDict()for h in query_head:temp_dict[h] = r[h]['value']query_results.append(temp_dict)return query_head, query_resultsexcept KeyError:return None, query_result['boolean']

以上就是将自然语言转换成SPARQL查询语言并与Feseki进行通信的核心代码。

3.3 代码运行结果

这里分别从歌手的简介,专辑的发行时间,歌手的所有专辑,歌曲属于哪个专辑以及歌曲的歌词等5类问题做问答,均能达到良好的表现效果。其问答情况如图3-5所示。

图3-5 问答系统运行结果实例

最后:

代码部分参考了:https://zhuanlan.zhihu.com/knowledgegraph

配置部分参考了:https://blog.csdn.net/keyue123/article/details/85266355

重磅!自然语言处理技术交流群已成立!

欢迎各位NLPer加入自然语言处理技术交流群,目前群内已有上百人!本群旨在交流文本分类、知识图谱、语音识别、阅读理解、机器翻译、情感分析、信息检索、问答系统自然语言处理领域内容。自然语言处理领域前沿信息将会第一时间在群里发布!欢迎大家进群一起交流学习!

麻烦大家进群后请备注:研究方向+学校/公司+昵称(如文本分类+浙大+小民)

广告商、博主请绕道!

???? 长按识别添加,邀请您入群!


http://chatgpt.dhexx.cn/article/SekcOqP7.shtml

相关文章

自然语言处理之智能问答系统

目录 一、问答系统简介 二、搭建基于检索的问答系统 三、其他相似度计算 相关参考&#xff1a; 一、问答系统简介 问答系统通常分为任务型机器人、闲聊机器人和解决型机器人&#xff08;客服机器人&#xff09;&#xff0c;三者的设计分别针对不同的应用场景。A&#xff0…

智能问答产品与技术

封面上放上凯的图片是因为&#xff0c;火影里面的凯有几个特点&#xff1a; 1、无忍术、血继界限、主角光环、显赫背景&#xff0c;完全靠自己努力修炼体术成为上忍 2、代表一种平凡的人做不平凡的事情的精神 3、对后辈也极其关注&#xff0c;所谓木叶飞舞之处 &#xff0c;…

你知道该如何搭建 AI 智能问答系统吗?

作者 | 李秋键 责编 | 刘静 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 今天我们将利用分词处理以及搜索引擎搭建一个智能问答系统&#xff0c;具体的效果如下所示&#xff1a; 下面简单了解下智能问答系统和自然语言处理的概念&#xff0c;智能问答系统是自然…

NLP: 基于文本语义的智能问答系统

向AI转型的程序员都关注了这个号???????????? 人工智能大数据与深度学习 公众号&#xff1a;datayx 问答系统是自然语言处理领域一个很经典的问题&#xff0c;它用于回答人们以自然语言形式提出的问题&#xff0c;有着广泛的应用。 经典应用场景包括&#xff1a;智…

浅谈基于知识图谱构建智能问答系统

“人才引进落户政策”“企业法人变更登记”“如何办理公积金贷款”……在智慧政务业务中&#xff0c;智能客服能够7*24小时响应群众、企业关于日常事务办理、民生政策、企业经营法规等咨询&#xff0c;大力提升了信息获取的便利性。 智能问答系统涉及自然语言处理、语音技术、…

从0到1构建一个基于知识图谱的智能问答系统

目录 一、前言二、知识图谱2.1 数据入库2.1.1 Nebula Graph搭建2.1.2数据导入 三、后端3.1 搭建Flask框架&#xff0c;处理http请求3.2 处理请求(核心)3.2.1 实体提取和意图分类建立AC树实体提取建立意图特征库意图模板匹配 3.2.2 转换成ngql语句 3.3 连接nebula查询结果返回 一…

智能问答系统产品设计详解

问答系统的概述 我想大家肯定看过很多关于自然语言处理&#xff08;简称&#xff1a;NLP&#xff09;技术方面的书籍或者论文&#xff0c;但在这里我不会详细叙述NLP技术方面的知识&#xff0c;而是想通过产品化思路结合NLP相关技术来搭建一个基础版的问答系统。本文通过基于问…

基于Bert的知识库智能问答系统

项目完整地址&#xff1a;https://github.com/1105425455/Bert/tree/master 有训练好的模型 可以先看一下Bert的介绍。 Bert简单介绍 一.系统流程介绍。 知识库是指存储大量有组织、有结构的知识和信息的仓库。这些知识和信息被存储为实体和实体关系的形式&#xff0c;通常用于…

智能问答系统实践——答案选择

问题描述 这个问题来自于SemEval-2015Task3: Answer Selection in Community Question Answering. 简单的说就是从一堆问题和答案中找出他们之间的相关性。 这个Task包含两个Subtasks: 1.给定一个问题和一些答案,将答案进行为3类:good/potential/bad。 2.给定一个判定问题…

构建一个完整的中文智能问答系统

向AI转型的程序员都关注了这个号&#x1f447;&#x1f447;&#x1f447; 机器学习AI算法工程 公众号&#xff1a;datayx 简略概述要求&#xff1a; 构建一个完整的QA系统整个系统由三部分构成&#xff1a;前台&#xff0c;后台&#xff0c;知识库前台&#xff1a;请设计一个…

智能问答

问答系统是信息检索的一种高级形式&#xff0c;它能用准确、简洁的自然语言回答用户用自然语言提出的问题。其研究兴起的主要原因是人们对快速、准确地获取信息的需求。其中问答系统是目前人工智能和自然语 言处理领域中倍受关注并具有广泛发展前景的研究方向。不同类型的问答系…

智能答疑系统

问答系统是目前自然语言处理领域中的研宄热点&#xff0c;它既能让用户通过自然语言直接发问&#xff0c;又能直接向用户返回精确、简洁的答案&#xff0c;而不是一系列相关网页。 从算法与模型上来说&#xff0c;问答系统主要分成两个流派&#xff0c;一派是搜索式问答&#x…

人工智能AI系列 - 问答系统

目录&#xff1a; http://aias.top/ 问答系统 问答系统(Question Answering System, QA)是信息检索系统的一种高级形式&#xff0c;它能用准确、简洁的自然语言回答用户用自然语言提出的问题。其研究兴起的主要原因是人们对快速、准确地获取信息的需求。问答系统是人工智能和…

智能问答系统:问句预处理、检索和深度语义匹配技术

更多干货内容敬请关注「平安寿险PAI」(公众号ID:PAL-AI),文末有本期分享内容资料获取方式。 智能问答系统是人机交互的核心技术之一,常见的应用场景主要是智慧客服。通过构建该系统,机器人可以快速找到与用户问题相匹配的答案并自动回答,从而大大减少企业的人力成本;除…

自然语音处理(NLP)系列(五)——详解智能问答系统

为方便客户进行网上登记&#xff0c;提升各大官网系统的智能化水平&#xff0c;很多官网已上线“智能小客服”。“智能小客服”支持语音引导、机器人24小时智能问答、文字提问、上传图片咨询、关联问题推荐、远程人工客服等多种便利化的贴心咨询服务。这些服务中运用到了自然语…

FAQ智能问答系统设计与实现

一、项目介绍 FAQ&#xff08;FAQ&#xff0c;frequently-asked questions&#xff09;问答系统表示常见问题问答系统&#xff0c;常用于一些特定领域的智能客服&#xff0c;将用户经常问到的高频问答对索引起来&#xff0c;当新的提问命中时可以快速回答&#xff0c;准确而高…

react全家桶实战

整个目录结构如下&#xff1a; package.json代码如下&#xff1a; {"name": "active","version": "0.1.0","private": true,"dependencies": {"react": "^16.4.1","react-dom"…

React全家桶学习

来源&#xff1a;尚硅谷视频教程 - 张天禹 一、React简介 1 react特点 React&#xff1a;用于构建用户界面的javascript库。是一个将数据渲染为HTML视图的开源JavaScript库。 react的特点&#xff1a; 1.采用组件化模式、声明式编码&#xff0c;提高开发效率及组件复用率。…

react全家桶实战(千峰教育)

说明&#xff1a;本笔记为本人基于千锋教育2022版React全家桶教程_react零基础入门到项目实战完整版的学习笔记&#xff0c;知识点不清或不全&#xff0c;可以到视频教程中学习 文章目录 一、安装create-react-app&#xff0c;新建react项目1、安装脚手架create-react-app<s…

搭建react全家桶

1.安装react项目 ①使用webpack安装 npx create-react-app my-app cd my-app npm start ②使用vite安装 创建Vite项目 npm create vitelatest my-vue-app --template react cd my-app npm run dev 配置vite.config.js import { defineConfig } from vite import react from vit…