如何在对话中引入知识一直是备受关注的问题,这里的知识常常分为两类:
- 非结构化知识
- 结构化知识
包括知识库、知识图谱、类别属性知识。
在使用知识时,我们常常采用两种方式:
- 生成式
把知识转为向量形式丢到模型里面一起训练 - 检索式
匹配到相关实体就可以输出预先设定好的回复语句
我采用的是检索知识图谱的形式。
知识图谱一般采用Neo4j
图数据库存储,存储形式为<头实体,关系,尾实体>。让知识图谱辅助多轮对话需要实现以下步骤:
(以下部分都是我自学的,不保证是最简单的操作,也不保证普适性。)
1 熟悉知识图谱的增删查改操作
1.1 Neo4j界面操作
增加节点
CREATE(n:标签{name:'内容'})
增加关系(节点已存在)
MATCH(a:标签{name:"内容"}),(b:标签{name:"内容"}) with a,b CREATE(a)-[:关系名]->(b)
删除关系
MATCH(n)-[r]-() where id(r)=id号 DELETE r
删除节点和与节点相连的所有关系:
MATCH(n)-[r]-() where id(n)=id号 DELETE n,r
修改节点属性
MATCH(n:标签名{name:"内容"}) SET n.name="新内容"
1.2 python操作知识图谱
这一部分暂时略,我有代码,但是没怎么用过,基本都是手动输入CQL
操作Neo4j
2 检索知识图谱
先看这篇博客,都是我遇到的雷:https://blog.csdn.net/qq_45520647/article/details/123457168?spm=1001.2014.3001.5502
我是想通过头实体,关系,检索出尾实体,但是网上居然没有一个帖子是写这个的。
我和我同学翻了下官方文档,摸索的方法如下,以<Movie, DIRECT, Director>这个为例。(图谱里是<Iron_Man, DIRECT, Jon_Favreau>)
2.1 定义两个类
这两个类的作用就是声明了Movie
和Director
这两个标签的主键,以及两个是怎么联系的(通过DIRECT
),如果要修改的话应该很好照猫画虎。
class Movie(Model):
__primarykey__ = "name"
name = Property()
DIRECT = RelatedTo("Director")
class Director(Model):
__primarykey__ = "name"
name = Property()
DIRECT = RelatedFrom("Movie")
2.2 检索
这段代码就是先检索出来第一个名字是noun
的Movie
类型的节点,通过DIRECT
关系找到的第一个尾节点,并提取出内容。
# noun = ...
keanu = repo.match(Movie).where(name=noun).first()
if keanu: # 如果该名词在知识图谱内
s = list(keanu.DIRECT.triples())[0][2]
s = str(s).split("'")[1].replace("_", " ")
print("Let me see...The director of {m} is {d}".format(m=noun, d=s))
break
else:
print("none")
就是这两步了,把需要替换的改成你建立的图谱里的内容即可。
感觉没说明白,但是说不明白了,尽力了…