基于医疗知识图谱的问答实践中遇到的问题

医药领域知识图谱和问答系统的搭建是参考中科院软件所刘焕勇老师在github上的开源项目,项目地址:https://github.com/liuhuanyong/QASystemOnMedicalKG ,感谢刘老师,这个项目是我能找到的最好最全最易上手的KBQA实践项目。
搭建过程中踩了一下坑,记录如下。

问题1:ahocorasick安装失败

pip安装报错:error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
解决:下载visualcppbuildtools_full.exe工具,安装Visual C++,第一次显示安装未完全成功且pip安装后依然出错,重新又装了一次后重新pip,成功。

问题2:gbk编码报错

for data in open(self.data_path): UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 124: illegal multibyte sequence for data in open(self.data_path,encoding='utf-8'):
解决:定位到错误代码question_classifier.py里,在open函数中加上,encoding='utf-8'即可:

self.disease_wds= [i.strip() for i in open(self.disease_path,encoding='utf-8') if i.strip()]
        self.department_wds= [i.strip() for i in open(self.department_path,encoding='utf-8') if i.strip()]
        self.check_wds= [i.strip() for i in open(self.check_path,encoding='utf-8') if i.strip()]
        self.drug_wds= [i.strip() for i in open(self.drug_path,encoding='utf-8') if i.strip()]
        self.food_wds= [i.strip() for i in open(self.food_path,encoding='utf-8') if i.strip()]
        self.producer_wds= [i.strip() for i in open(self.producer_path,encoding='utf-8') if i.strip()]
        self.symptom_wds= [i.strip() for i in open(self.symptom_path,encoding='utf-8') if i.strip()]
        self.region_words = set(self.department_wds + self.disease_wds + self.check_wds + self.drug_wds + self.food_wds + self.producer_wds + self.symptom_wds)
        self.deny_words = [i.strip() for i in open(self.deny_path,encoding='utf-8') if i.strip()]

问题3:配置问题

根据neo4j 安装时的端口、账户、密码配置设置设置项目配置文件:answer_search.py & build_medicalgraph.py
注意:不同的py2neo版本调用方法不一样。

    def __init__(self):
        self.g = Graph(
            # "http://localhost:7474/db/data"  # py2neo 2.0.8写法
            host="127.0.0.1",  # py2neo 3写法
            user="neo4j",
            password="leilu"
        )

问题4:构建知识图谱时的问题

GitHub上原版本的build_medicalgraph.py中main函数只有handler = MedicalGraph()一行,需要添加两个建立节点和实体关系边的函数的调用。
build_medicalgraph.py的main函数修改为:

if __name__ == '__main__':
    handler = MedicalGraph()
    handler.create_graphnodes()
    handler.create_graphrels()

    # handler.export_data()

问题5:问答时的查询问题

在问答输入问题后进行查询的时候报错。
py2neo v3版本报错如下:

Traceback (most recent call last):
  File "F:/IBM/QASystemOnMedicalKG/chatbot_graph.py", line 34, in <module>
    answer = handler.chat_main(question)
  File "F:/IBM/QASystemOnMedicalKG/chatbot_graph.py", line 24, in chat_main
    final_answers = self.searcher.search_main(res_sql)
  File "F:\IBM\QASystemOnMedicalKG\answer_search.py", line 26, in search_main
    ress = self.g.run(query).data()
AttributeError: 'Cursor' object has no attribute 'data'

py2neo v2.0.8版本报错如下:

AttributeError: 'Graph' object has no attribute 'run'

检查出错位置所在源码C:\Python37\Lib\site-packages\py2neo\database.py,发现run函数返回一个Cursor对象。

Cursors
py2neo的函数运行结果,通常会以Cursors类的实例形式返回,Cursors实例是一种迭代器,通过遍历它可以获得所有返回结果。需要注意的是,Cursors.data()只能运行一次,运行一次之后,这个Cursors中的数据就被释放了。如果要多次使用Cursors.data()的数据,应该用一个变量将Cursors.data()的结果记住。

但在C:\Python37\Lib\site-packages\py2neo\database.py源码中进入class Cursor,发现确实没有data函数。
于是感觉是版本问题,升级到v4.2版本,遂解决。
(但是v3的用户手册中class Cursor有def data,而我的v3版本py2neo源码中却没有,不知道为什么)
另外在v4版本中测试了一下:

g = Graph(
            host="127.0.0.1",  # py2neo 3写法
            http_port=7474,
            user="neo4j",
            password="leilu"
        )
test_node_1 = Node(label = "Person",name = "test_node_1")
g.create(test_node_1)  # 注意一定要调用create方法否则无法入库
find_code_1 = g.find_one(
  label="Person",
  property_key="name",
  property_value="test_node_1"
)
print(find_code_1['name'])

报错:AttributeError: 'Graph' object has no attribute 'find_one'
原因:py2neo的v2和v3版本有两个很简便的查找节点的函数find_one()和find(),但是在v4版本里面不见了。在v4中用match查找。

问题6:import问题

在buil_data里from max_cut import *会出现下划红线,报错Unresolved reference 'max_cut'

文件树部分结构如下:

QASystemOnMedicalKG/prepare_data
			├── build_data.py
			├── data_spider.py
			├── max_cut.py

感觉这种import方式是OK的,不知道为什么会出现红色下划波浪线,而且运行也是OK的。
修改为from prepare_data.max_cut import *就没有报错了,也能运行。。。很奇怪。

总结

被run.data()查询困扰了很多天,最后是版本问题。在翻查py2neo用户手册和源码的过程中发现不同py2neo版本的差别还挺大的。Graph类和Cursor类中很多函数有的版本有有的版本没有。所以以后学习过程中遇到不熟悉的库需要多查源码。

上一篇:Day02:快捷键


下一篇:#1 爬虫:豆瓣图书TOP250 「requests、BeautifulSoup」