基于apache-jena的知识问答

前言
这篇文章主要写如何使用Python对apache-jena进行交互查询。具体三元组数据建立、转换、导入内容请看:知识问答三元组数据准备阶段 。本文在知识问答三元组数据准备阶段的基础上,接着往下写。
注:本文案例代码使用 https://github.com/zhangtao-seu/Jay_KG 中的代码

目录

一、代码目录结构

二、知识问答实现

2.1、三元组数据获取

2.1、定义实体

2.2、定义问题模板

三、运行代码进行问答

一、代码目录结构

下图为Jay_KG项目的代码目录结构。其中重要的是query_main.py和question_temp.py文件,其中前者为程序主入口,后者为知识问答模板的定义。

基于apache-jena的知识问答

二、知识问答实现

2.1、三元组数据获取

本文案例使用potege软件建模,最后导出owl文件,后继续根据知识问答三元组数据准备阶段 文中的2.2小节内容一步一步做。本案例使用potege建模后如下图所示

基于apache-jena的知识问答

2.1、定义实体

在Jay_KG/KB_query/external_dict中有一个sanguo.txt,这就是博主定义的实体文件,内容如下图所示

基于apache-jena的知识问答

2.2、定义问题模板

打开 question_temp.py文件,定义模板,如下代码所示,QuestionSet类下的o_name、rides函数定义了关羽字(别名、小名)是什么?被、和关羽的坐骑(骑、战马)是什么?两个模板。

encoding=utf-8

"""
@desc:
设置问题模板,为每个模板设置对应的SPARQL语句。demo提供如下模板:

"""
from refo import finditer, Predicate, Star, Any, Disjunction
import re

# TODO SPARQL前缀和模板
SPARQL_PREXIX = u"""
PREFIX owl:
PREFIX rdfs:
PREFIX xsd:
PREFIX :
"""

SPARQL_PREXIX = u"""
PREFIX owl:
PREFIX rdfs:
PREFIX xsd:
PREFIX :
"""

SPARQL_SELECT_TEM = u"{prefix}\n" + \
             u"SELECT {select} WHERE {{\n" + \
             u"{expression}\n" + \
             u"}}\n"

class 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 m2

class Rule(object):
    def __init__(self, condition_num, condition=None, action=None):
        assert condition and action
        self.condition = condition
        self.action = action
        self.condition_num = condition_num
    #                 word_object  :   [词,词性]
    def apply1(self, sentence):
        matches = []
        #                      【person_entity】
        for m in finditer(self.condition, sentence):
            i, j = m.span()
            matches.extend(sentence[i:j])

        return self.action(matches), self.condition_num

class QuestionSet:
    def __init__(self):
        pass

    @staticmethod
    def o_name(word_object):
        #关羽字什么?

        select = u"?o"
        sparql = None

        for w in word_object:
            if w.pos == pos_person:
                e = u" :{person} :字 ?o.".format(person=w.token.decode('utf-8'))
            sparql = SPARQL_SELECT_TEM.format(prefix=SPARQL_PREXIX,
                                              select=select,
                                              expression=e)
            print(sparql)
            break
        return sparql

    @staticmethod
    def rides(word_object):
        #关羽战马是什么?

        select = u"?o"
        sparql = None

        for w in word_object:
            if w.pos == pos_person:
                e = u" :{person} :骑 ?o.".format(person=w.token.decode('utf-8'))
            sparql = SPARQL_SELECT_TEM.format(prefix=SPARQL_PREXIX,
                                              select=select,
                                              expression=e)
            print(sparql)
            break
        return sparql

TODO 定义关键词
pos_person = "nr"
person_entity = (W(pos=pos_person))

other_name = (W("字") | W("别名") | W("小名"))
ride = (W("骑") | W("坐骑") | W("战马"))

TODO 问题模板/匹配规则
"""

关羽字什么?
关羽的战马是什么?

"""

rules = [
    # 关羽字什么?
    Rule(condition_num=0, condition=person_entity + Star(Any(), greedy=False) + other_name + Star(Any(), greedy=False), action=QuestionSet.o_name),
    Rule(condition_num=0, condition=person_entity + Star(Any(), greedy=False) + ride + Star(Any(), greedy=False), action=QuestionSet.rides),

]

三、运行代码进行问答

进入query_main文件运行,后在控制台输入之前定义好的模板,即可收到返回。

Original: https://blog.csdn.net/zkkkkkkkkkkkkk/article/details/123801304
Author: zkkkkkkkkkkkkk
Title: 基于apache-jena的知识问答

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/554975/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球