从零开始学习知识图谱 之 四.电影知识图谱构建 4.基于ElasticSearch的简单语义搜索
本文于1979天之前发表,文中内容可能已经过时。
一. 简介
本次我们基于浙江大学在openKG上提供的基于elasticsearch的KBQA实现及示例,我们将其精简并将应用到自己的知识图谱上。
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。我们将通过提供的接口进行查询,例如查询朱一龙的相关信息,可以通过下列命令进行查询:
1 | curl -XGET 'localhost:9200/demo/baidu_baike/_search?&pretty' -H 'Content-Type:application/json' -d' { "query":{ "bool":{ "filter":{ "term":{"subj":"朱一龙"} } } } } ' |
我们的目的就是在数据导入elasticsearch后,通过将输入的自然语言分解来构建这样的查询模板,从而实现搜索功能。
本教程的项目代码放在github上,下载地址为《从零开始学习知识图谱》项目源代码 。
二. 环境准备
1. 操作系统
支持操作系统:windows、macOS、Linux。为了方便大家搭建开发环境,笔者尽可能在windows下构建,系列篇未特意说明时操作系统都是windows。Linux安装可以参考VirtualBox虚拟机安装Ubuntu或VirtualBox虚拟机安装CentOS8进行安装。
2. jdk
安装参见windows系统安装JDK
3. Python3
安装参见从零开始学习知识图谱 之 一
4. ElasticSearch
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。
安装
elasticsearch 官网下载安装包,软件不需要安装,需要配置相应的Java环境。详细使用可阅读官方教程。
运行 ./bin/elasticsearch.bat
即可开启服务。
在开启服务后,您可以通过 curl 'http://localhost:9200'
来访问 elasticsearch。
1 | { |
三. 数据准备
1. 数据库到JSON
elasticsearch 要求文档的输入格式为 JSON,因此我们需要把数据库中的数据转化为JSON形式。比如:
1 | { |
对应代码为./utils/get_json.py,该程序的工作流程为对数据库进行查表,而后将对应信息保存到字典里。通过 json.dumps()将Python对象转化为JSON格式并写成文件。
运行get_json.py,生成actor.json和movie.json
1 | C:\my\Python\python.exe C:/d/mmm/pycharm/elasticsearch/utils/get_json.py |
可能出现的问题:
python pyahocorasick包安装失败解决方法
2. 属性同义词扩展
为了支持对同一类问题的不同询问方式,我们采用同意属性映射来扩展属性,当遇到同义属性时,我们将其映射到数据集中的属性上,对应于./data/attr_mapping.txt 文件:
1 | actor_chName 中文名 名字 姓名 |
3. 建立属性间映射 get_ac_attr.py
我们通过cpikle 对属性间映射进行打包,其中属性间的映射通过ahocorasic.Automaton()进行处理。对应的输出为./data/attr_ac.pkl.
运行get_ac_attr.py,生成./data/attr_ac.pkl
1 | C:\my\Python\python.exe C:/d/mmm/pycharm/elasticsearch/utils/get_ac_attr.py |
4. 获取属性值和属性间的映射 get_total_val.py
通过对数据库进行查表得到各个实体的属性和属性值,而后将其存储为./data/total_val.txt 文件在搜索时使用。
运行get_total_val.py,生成actor.txt和movie.txt
1 | C:\my\Python\python.exe C:/d/mmm/pycharm/elasticsearch/utils/get_total_val.py |
5. 获取所有实体
我们直接通过MySQL Workbench操作得到所有实体的倒出并存储为一个文件,名为./data/all_entity.txt。
文件格式如下:
1 | 周星驰 |
四. 将数据导入到 elasticsearch
1. 在 elasticsearch 中新建 index 和 type
这里我们遵循教程中的要求,采用下列命令建立 index 和 type:
可以用elasticsearch-head或CURL。
ealsticsearch只是后端提供各种api,那么怎么直观的使用它呢?elasticsearch-head将是一款专门针对于elasticsearch的客户端工具。elasticsearch-head配置包,下载地址:https://github.com/mobz/elasticsearch-head 。安装可以参考文章windows下安装ElasticSearch的Head插件 。
我们这里选择用CURL,去curl官网下载对应版本的包,解压后打开CMD切换到对应目录下运行CURL.exe文件,
如果把该CURL.exe文件复制到C:\Windows\System32目录下,则不需要切换目录,可以直接运行curl命令。
a. 用下列命令建立 index 和 type:
1 | curl -XPUT "localhost:9200/demo?pretty" -H "Content-Type: application/json" -d" { \"mappings\": { \"properties\": { \"subj\": {\"type\": \"keyword\"}, \"po\":{ \"type\": \"nested\", \"properties\":{ \"pred\":{\"type\":\"keyword\"}, \"obj\":{\"type\":\"keyword\"} } } } } } " |
运行结果
1 | C:\Users\mmm>curl -XPUT "localhost:9200/demo?pretty" -H "Content-Type: application/json" -d" { \"mappings\": { \"properties\": { \"subj\": {\"type\": \"keyword\"}, \"po\":{ \"type\": \"nested\", \"properties\":{ \"pred\":{\"type\":\"keyword\"}, \"obj\":{\"type\":\"keyword\"} } } } } } " |
注意:笔者使用的Elasticsearch>7.0,Elasticsearch 7.0及以后版本移除映射类型
b. 可用下列命令查询是否添加成功
1 | curl -XGET localhost:9200/_search?pretty |
运行结果
1 | C:\Users\mmm>curl -XGET localhost:9200/_search?pretty |
c. 如果创建错了,可用下列命令删除索引
1 | curl -XDELETE localhost:9200/demo |
2. 数据导入 insert.py
为了测试简单,把actor.json文件改名为../data/baidu_baike.json。
运行 insert.py
1 | C:\my\Python\python.exe C:/d/mmm/pycharm/elasticsearch/utils/insert.py |
此时已经可以通过curl方式检索知识库了。
五. 检索知识库
DOS默认的是(GB2312),让cmd dos 支持utf-8方法CHCP 65001
,关闭cmd,CHCP又还原成936。
1 | C:\Users\mmm>CHCP 65001 |
curl方式检索知识库,可用下列命令,如检索:周星驰
1 | curl -XGET "localhost:9200/demo/_doc/_search?&pretty" -H "Content-Type:application/json" -d" { \"query\":{ \"bool\":{ \"filter\":{ \"term\":{\"subj\":\"\u5468\u661f\u9a70\"} } } } } |
运行结果
1 | curl -XGET "localhost:9200/demo/_doc/_search?&pretty" -H "Content-Type:application/json" -d" { \"query\":{ \"bool\":{ \"filter\":{ \"term\":{\"subj\":\"\u5468\u661f\u9a70\"} } } } }" |
六. 程序核心 ./utils/views.py
改程序对输入的自然语言问题进行解析,识别出出现在其中的实体名、属性及属性值,并将其转换为对应的logical form。总体流程和浙大的类似,我只是将其从Django 中提取出来方便对于框架不懂的人直接使用。关于views.py的详细解释请看浙大的教程