Package: lightNLU
lightNLU一个小巧简单的基于模板匹配的自然语言理解框架。简介一个基于Python实现的小巧简单的基于模板匹配的自然语言理解框架。
这里的自然语言理解仅指意图识别和词槽提取。安装pipinstalllightnlu特性特别轻量模板文件使用yml格式支持多源数据导入模板语法简明易懂使用示例step1:定制词表规则如编写words.yml文件如下：-name:personaliases:-人物type:jsonconfig:path:data/person.json-name:placealiases:-地点-位置-城市-区域type:csvconfig:path:data/place.csv-name:relationaliases:[]type:ymlconfig:path:data/relation.yml-name:predicatealiases:[]type:ymlconfig:path:data/predicate.yml其中对应的各yml、json、csv文件内容如下：person.json中内容如下：{"name":"曹操","id":"1"}{"name":"刘备","id":"2"}{"name":"诸葛亮","id":"3"}{"name":"曹丕","id":"4"}{"name":"曹植","id":"5"}place.csv中内容如下：name,id
洛阳,1
长安,2
新野,3
赤壁,4
宛城,5relation.yml中内容如下：son:-儿子father:-父亲-爸爸predicatel.yml中内容如下：is:-是-为isnot:-不是-不为step2:定制模板规则如编写pattern.yml文件如下：-name:father_son_relationpatterns:--[person,~,son]# 规则为 [类型, id值, 词槽名称]-[relation,father,~]-[predicate,is,null]-[person,~,father]--[person,~,father]-[predicate,is,null]-[person,~,son]-[relation,father,~]-name:testpatterns:--[person,~,person]-[predicate,is,null]-['@person',~,ttt]在以上的模板规则中，对于每一个模板规则，需要指定其名字（name）及相应的模板（patterns）。
由于存在多个相近但不相同的模板对应同一种意图及词槽，所以这里的patterns是一个列表。
在以上的pattern.yml文件中，包含一个'@person'，这里可以映射到person这个类别所对应的所有别名，具体来说，可以对应到["人物"]列表中的所有词汇。step3:编写源代码及触发函数示例如下：# -*- coding: utf-8 -*-importosimportsysproject_path=os.path.abspath(os.path.join(__file__,"../.."))sys.path.insert(0,project_path)fromlightnlu.coreimportNER,Ruleif__name__=='__main__':path=os.path.join(project_path,'data/words.yml')ner=NER()ner.build_from_yml(path,base_dir=project_path)print(ner.entities)path=os.path.join(project_path,'data/pattern.yml')rule=Rule()rule.build_from_yml(path)@rule.bind(rule_name="father_son_relation",domain="relation")deftest(slots:dict,text:str):return{"slots":slots,"text":text}@rule.bind(rule_name="test",domain="hello_world")defppp(slots:dict,text:str):return"slots:{}, text:{}".format(slots,text)print(rule.actors)text="刘备和诸葛亮在新野旅游，途中遇上了曹操"domain="relation"slots=ner.extract(text)print(slots)print(rule.match(slots,domain=domain))text="曹丕的父亲是曹操"domain="relation"slots=ner.extract(text)print(rule.match(slots,domain=domain))print(rule.match_and_act(slots,domain=domain,text=text))text="曹操是曹丕的父亲"domain="relation"slots=ner.extract(text)print(rule.match(slots,domain=domain))print(rule.match_and_act(slots,domain=domain,text=text))text="曹操是个人物"domain="hello_world"slots=ner.extract(text)print(rule.match(slots,domain=domain))print(rule.match_and_act(slots,domain=domain,text=text))执行结果如下：defaultdict(<function default_type at 0x7fbba1df5670>, {'曹操': [{'type': 'person', 'id': '1'}], '刘备': [{'type': 'person', 'id': '2'}], '诸葛亮': [{'type': 'person', 'id': '3'}], '曹丕': [{'type': 'person', 'id': '4'}], '曹植': [{'type': 'person', 'id': '5'}], '人物': [{'type': '@person', 'id': None}], '洛阳': [{'type': 'place', 'id': '1'}], '长安': [{'type': 'place', 'id': '2'}], '新野': [{'type': 'place', 'id': '3'}], '赤壁': [{'type': 'place', 'id': '4'}], '宛城': [{'type': 'place', 'id': '5'}], '地点': [{'type': '@place', 'id': None}], '位置': [{'type': '@place', 'id': None}], '城市': [{'type': '@place', 'id': None}], '区域': [{'type': '@place', 'id': None}], '电站': [{'type': 'ban_words', 'id': ''}], '正在站': [{'type': 'ban_words', 'id': ''}], '引流线': [{'type': 'ban_words', 'id': ''}], '子导线': [{'type': 'ban_words', 'id': ''}], '甲母线': [{'type': 'ban_words', 'id': ''}], '规则': [{'type': '@ban_words', 'id': None}], '所属厂站': [{'type': 'attr', 'id': 'attr_ST_ID'}], '所属电厂': [{'type': 'attr', 'id': 'attr_ST_ID'}], '属于哪个厂站': [{'type': 'attr', 'id': 'attr_ST_ID'}], '属于哪个电厂': [{'type': 'attr', 'id': 'attr_ST_ID'}], '电压等级': [{'type': 'attr', 'id': 'attr_VOLTAGE_TYPE'}], '儿子': [{'type': 'relation', 'id': 'son'}], '父亲': [{'type': 'relation', 'id': 'father'}], '爸爸': [{'type': 'relation', 'id': 'father'}], '是': [{'type': 'predicate', 'id': 'is'}], '为': [{'type': 'predicate', 'id': 'is'}], '不是': [{'type': 'predicate', 'id': 'isnot'}], '不为': [{'type': 'predicate', 'id': 'isnot'}]})
defaultdict(<function _helper_func at 0x7fbba247d280>, {'relation': defaultdict(<class 'dict'>, {'father_son_relation': {'test': <function test at 0x7fbba1db5d30>}}), 'hello_world': defaultdict(<class 'dict'>, {'test': {'ppp': <function ppp at 0x7fbba1d7f040>}})})
[('刘备', {'type': 'person', 'id': '2'}, 0, 2), ('诸葛亮', {'type': 'person', 'id': '3'}, 3, 6), ('新野', {'type': 'place', 'id': '3'}, 7, 9), ('曹操', {'type': 'person', 'id': '1'}, 17, 19)]
[]
[{'name': 'father_son_relation', 'slots': {'son': {'word': '曹丕', 'type': 'person', 'id': '4', 'left': 0, 'right': 2}, 'father': {'word': '曹操', 'type': 'person', 'id': '1', 'left': 6, 'right': 8}}}]
{'father_son_relation': {'test': {'slots': {'son': {'word': '曹丕', 'type': 'person', 'id': '4', 'left': 0, 'right': 2}, 'father': {'word': '曹操', 'type': 'person', 'id': '1', 'left': 6, 'right': 8}}, 'text': '曹丕的父亲是曹操'}}}
[{'name': 'father_son_relation', 'slots': {'father': {'word': '曹操', 'type': 'person', 'id': '1', 'left': 0, 'right': 2}, 'son': {'word': '曹丕', 'type': 'person', 'id': '4', 'left': 3, 'right': 5}}}]
{'father_son_relation': {'test': {'slots': {'father': {'word': '曹操', 'type': 'person', 'id': '1', 'left': 0, 'right': 2}, 'son': {'word': '曹丕', 'type': 'person', 'id': '4', 'left': 3, 'right': 5}}, 'text': '曹操是曹丕的父亲'}}}
[{'name': 'test', 'slots': {'person': {'word': '曹操', 'type': 'person', 'id': '1', 'left': 0, 'right': 2}, 'ttt': {'word': '人物', 'type': '@person', 'id': None, 'left': 4, 'right': 6}}}]
{'test': {'ppp': "slots: {'person': {'word': '曹操', 'type': 'person', 'id': '1', 'left': 0, 'right': 2}, 'ttt': {'word': '人物', 'type': '@person', 'id': None, 'left': 4, 'right': 6}}, text: 曹操是个人物"}}注意事项csv文件和json文件中必须包含name和id两个属性或列。更新日志v0.1.1 初始版本v0.2.0 增加域（domain）这一概念参考keyue123/poemElasticDemo: 基于Elasticsearch的KBQAliuhuanyong/QAonMilitaryKG: QAonMilitaryKG，QaSystem based on military knowledge graph that stores in mongodb which is different from the previous one, 基于mongodb存储的军事领域知识图谱问答项目，包括飞行器、太空装备等8大类，100余小类，共计5800项的军事武器知识库，该项目不使用图数据库进行存储，通过jieba进行问句解析，问句实体项识别，基于查询模板完成多类问题的查询，主要是提供一种工业界的问答思想demo。