Commit 15ebaf46 authored by lishen's avatar lishen

[add] exercise QA

parent c75d1f7f
......@@ -36,7 +36,22 @@ class AnswerSearcher:
final_answer = []
if not answers:
return ''
if question_type == question_type_enum.DISEASE_SYMPTOM:
if question_type == question_type_enum.DISEASE_ONLY:
final_answer = answers[0]['m.desc']
elif question_type == question_type_enum.FOODMATERIAL_ONLY or question_type == question_type_enum.FOODPACKAGE_ONLY or question_type == question_type_enum.FOODPROCESS_ONLY:
subject = answers[0]['m.name']
desc = answers[0]['m.description']
if len(desc) != 0:
final_answer = f'{subject}{desc}'
else:
final_answer = f'{subject}暂无具体描述'
elif question_type == question_type_enum.EXERCISE_ONLY:
final_answer = answers[0]['m.description']
elif question_type == question_type_enum.DISEASE_SYMPTOM:
desc = [i['n.name'] for i in answers]
subject = answers[0]['m.name']
final_answer = '{0}的症状包括:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
......@@ -89,10 +104,15 @@ class AnswerSearcher:
desc = [i for i in desc1 + desc2 if i != subject]
final_answer = '{0}的症状包括:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.DISEASE_NOT_FOOD:
elif question_type == question_type_enum.DISEASE_BELONG:
desc = [i['n.name'] for i in answers]
subject = answers[0]['m.name']
final_answer = '{0}忌食的食物包括有:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
final_answer = '{0}所属医院的科室是:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.DEPARTMENT_DISEASE:
desc = [i['m.name'] for i in answers]
subject = answers[0]['n.name']
final_answer = '{0}科室治疗范围内的疾病有:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.DISEASE_DO_FOOD:
do_desc = [i['n.name'] for i in answers if i['r.name'] == '宜吃']
......@@ -237,10 +257,35 @@ class AnswerSearcher:
subject = answers[0]['n.name']
final_answer = '含低量{0}的食物有:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.FOODPROCESS_ALIAS:
elif question_type == question_type_enum.FOODPROCESS_NATURE:
desc = [i['n.name'] for i in answers]
subject = answers[0]['m.name']
final_answer = '{0}的性质是:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.COOKINGSTYLE_FOODPROCESS:
desc = [i['m.name'] for i in answers]
subject = answers[0]['n.name']
final_answer = '“{0}”这种做法的菜品有:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.EXERCISE_TYPE:
desc = [i['n.name'] for i in answers]
subject = answers[0]['m.name']
final_answer = '{0}是一种{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.TYPE_EXERCISE:
desc = [i['m.name'] for i in answers]
subject = answers[0]['n.name']
final_answer = '{0}包括:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.EXERCISE_DIFFICULTY:
desc = [i['n.name'] for i in answers]
subject = answers[0]['m.name']
final_answer = '{0}的动作困难度为:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
elif question_type == question_type_enum.EXERCISE_FEATURE:
desc = [i['n.name'] for i in answers]
subject = answers[0]['m.name']
final_answer = '{0}的别名还有:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
final_answer = '{0}的动作特点有:{1}'.format(subject, ';'.join(list(set(desc))[:self.num_limit]))
return final_answer
......
......@@ -16,7 +16,7 @@ from answer_search import *
class ChatBotGraph:
def __init__(self):
self.g = Graph(
'http://127.0.0.1:7476',
'http://127.0.0.1:7474',
user="neo4j",
password="neo4j")
self.classifier = QuestionClassifier(self.g)
......@@ -36,18 +36,18 @@ class ChatBotGraph:
return '\n'.join(final_answers)
# if __name__ == '__main__':
# handler = ChatBotGraph()
# while 1:
# question = input('用户:')
# answer = handler.chat_main(question)
# print('小益:', answer)
if __name__ == '__main__':
handler = ChatBotGraph()
# 接口创建函数
# fn设置处理函数,inputs设置输入接口组件,outputs设置输出接口组件
# fn,inputs,outputs都是必填函数
demo = gr.Interface(fn=handler.chat_main, inputs="text", outputs="text")
while 1:
question = input('用户:')
answer = handler.chat_main(question)
print('小益:', answer)
demo.launch(share=True, server_name="0.0.0.0", server_port=7860)
# if __name__ == '__main__':
# handler = ChatBotGraph()
# # 接口创建函数
# # fn设置处理函数,inputs设置输入接口组件,outputs设置输出接口组件
# # fn,inputs,outputs都是必填函数
# demo = gr.Interface(fn=handler.chat_main, inputs="text", outputs="text")
#
# demo.launch(share=True, server_name="0.0.0.0")
......@@ -36,6 +36,7 @@ class QuestionClassifier:
# 3、运动
self.exercise_wds = self.init_name_by_node('Exercise')
self.exercise_type_wds = self.init_name_by_node('ExerciseType')
# 4、药品
self.drug_wds = self.init_name_by_node('Drug')
......@@ -43,7 +44,7 @@ class QuestionClassifier:
self.region_words = set(self.department_wds + self.disease_wds + self.check_wds + self.producer_wds + self.symptom_wds
+ self.food_wds + self.food_material_wds + self.food_package_wds + self.food_process_wds
+ self.cooking_style_wds + self.index_level_wds + self.province_wds + self.nutrient_wds
+ self.exercise_wds
+ self.exercise_wds + self.exercise_type_wds
+ self.drug_wds)
self.deny_words = [i.strip() for i in open(self.deny_path) if i.strip()]
# 构造领域actree
......@@ -81,11 +82,16 @@ class QuestionClassifier:
self.content_qwds = ['含有', '有', '包含', '含', '包括', '营养', '元素', '成分']
self.alias_qwds = ['别名', '化名', '别称', '叫什么', '称为', '近似', '类似', '差不多', '称呼', '菜名', '叫法', '其他']
self.nature_qwds = ['性质']
self.cooking_style_qwds = ['哪些菜', '什么菜']
self.cooking_style_qwds = ['哪些', '什么', '罗列', '列举', '给']
self.index_level_high_qwds = ['高', '多', '富']
self.index_level_mid_qwds = ['中']
self.index_level_low_qwds = ['低', '少']
# 3、运动
self.exercise_type_qwds = ['类型', '类', '种', '种类']
self.action_difficulty_qwds = ['难', '简单', '容易', '困难', '程度', '难度']
self.action_feature_qwds = ['特点']
print('model init finished ......')
return
......@@ -110,6 +116,27 @@ class QuestionClassifier:
question_types = []
# 当提问单纯名词时
if question.strip() in self.disease_wds:
question_type = question_type_enum.DISEASE_ONLY
question_types.append(question_type)
if question.strip() in self.food_material_wds:
question_type = question_type_enum.FOODMATERIAL_ONLY
question_types.append(question_type)
if question.strip() in self.food_package_wds:
question_type = question_type_enum.FOODPACKAGE_ONLY
question_types.append(question_type)
if question.strip() in self.food_process_wds:
question_type = question_type_enum.FOODPROCESS_ONLY
question_types.append(question_type)
if question.strip() in self.exercise_wds:
question_type = question_type_enum.EXERCISE_ONLY
question_types.append(question_type)
# 症状
if self.check_words(self.symptom_qwds, question) and (word_type_enum.DISEASE in types):
question_type = question_type_enum.DISEASE_SYMPTOM
......@@ -191,6 +218,16 @@ class QuestionClassifier:
question_type = question_type_enum.DISEASE_EASYGET
question_types.append(question_type)
# 已知疾病查科室
if self.check_words(self.belong_qwds, question) and word_type_enum.DISEASE in types:
question_type = question_type_enum.DISEASE_BELONG
question_types.append(question_type)
# 已知科室查疾病
if word_type_enum.DEPARTMENT in types:
question_type = question_type_enum.DEPARTMENT_DISEASE
question_types.append(question_type)
# 若没有查到相关的外部查询信息,那么则将该疾病的描述信息返回
if question_types == [] and word_type_enum.DISEASE in types:
question_types = [question_type_enum.DISEASE_DESC]
......@@ -340,6 +377,36 @@ class QuestionClassifier:
question_type = question_type_enum.FOODPROCESS_ALIAS
question_types.append(question_type)
# 已知菜品查性质
if self.check_words(self.nature_qwds, question) and word_type_enum.FOOD_PROCESS in types:
question_type = question_type_enum.FOODPROCESS_NATURE
question_types.append(question_type)
# 已知做法查菜品
if self.check_words(self.cooking_style_qwds, question) and word_type_enum.COOKING_STYLE in types:
question_type = question_type_enum.COOKINGSTYLE_FOODPROCESS
question_types.append(question_type)
# 已知运动查类型
if self.check_words(self.exercise_type_qwds, question) and word_type_enum.EXERCISE in types:
question_type = question_type_enum.EXERCISE_TYPE
question_types.append(question_type)
# 已知运动类型查运动
if word_type_enum.EXERCISE_TYPE in types:
question_type = question_type_enum.TYPE_EXERCISE
question_types.append(question_type)
# 已知运动查难度
if self.check_words(self.action_difficulty_qwds, question) and word_type_enum.EXERCISE in types:
question_type = question_type_enum.EXERCISE_DIFFICULTY
question_types.append(question_type)
# 已知运动查特点
if self.check_words(self.action_feature_qwds, question) and word_type_enum.EXERCISE in types:
question_type = question_type_enum.EXERCISE_FEATURE
question_types.append(question_type)
# 将多个分类结果进行合并处理,组装成一个字典
data['question_types'] = question_types
......@@ -379,6 +446,8 @@ class QuestionClassifier:
wd_dict[wd].append(word_type_enum.NUTRIENT)
if wd in self.exercise_wds:
wd_dict[wd].append(word_type_enum.EXERCISE)
if wd in self.exercise_type_wds:
wd_dict[wd].append(word_type_enum.EXERCISE_TYPE)
if wd in self.drug_wds:
wd_dict[wd].append(word_type_enum.DRUG)
return wd_dict
......
......@@ -34,6 +34,22 @@ class QuestionPaser:
sql_['question_type'] = question_type
sql = []
# 当提问单纯名词时
if question_type == question_type_enum.DISEASE_ONLY:
sql = ["MATCH (m:Disease) where m.name = '{0}' return m.desc".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
if question_type == question_type_enum.FOODMATERIAL_ONLY:
sql = ["MATCH (m:FoodMaterial) where m.name = '{0}' return m.name, m.description".format(i) for i in entity_dict.get(word_type_enum.FOOD_MATERIAL)]
if question_type == question_type_enum.FOODPACKAGE_ONLY:
sql = ["MATCH (m:FoodPackage) where m.name = '{0}' return m.name, m.description".format(i) for i in entity_dict.get(word_type_enum.FOOD_PACKAGE)]
if question_type == question_type_enum.FOODPROCESS_ONLY:
sql = ["MATCH (m:FoodProcess) where m.name = '{0}' return m.name, m.description".format(i) for i in entity_dict.get(word_type_enum.FOOD_PROCESS)]
if question_type == question_type_enum.EXERCISE_ONLY:
sql = ["MATCH (m:Exercise) where m.name = '{0}' return m.description".format(i) for i in entity_dict.get(word_type_enum.EXERCISE)]
# 查询疾病有哪些症状
if question_type == question_type_enum.DISEASE_SYMPTOM:
sql = ["MATCH (m:Disease)-[r:has_symptom]->(n:Symptom) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
......@@ -48,8 +64,8 @@ class QuestionPaser:
# 查询疾病的并发症
elif question_type == question_type_enum.DISEASE_ACOMPANY:
sql1 = ["MATCH (m:Disease)-[r:acompany_with]->(n:Disease) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
sql2 = ["MATCH (m:Disease)-[r:acompany_with]->(n:Disease) where n.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
sql1 = ["MATCH (m:Disease)-[r:accompany_with]->(n:Disease) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
sql2 = ["MATCH (m:Disease)-[r:accompany_with]->(n:Disease) where n.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
sql = sql1 + sql2
# 查询疾病的忌口
......@@ -116,6 +132,14 @@ class QuestionPaser:
elif question_type == question_type_enum.DISEASE_DESC:
sql = ["MATCH (m:Disease) where m.name = '{0}' return m.name, m.desc".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
# 已知疾病查科室
elif question_type == question_type_enum.DISEASE_BELONG:
sql = ["MATCH (m:Disease)-[r:belongs_to]->(n:Department) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DISEASE)]
# 已知科室查疾病
elif question_type == question_type_enum.DEPARTMENT_DISEASE:
sql = ["MATCH (m:Disease)-[r:belongs_to]->(n:Department) where n.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.DEPARTMENT)]
# 已知忌口查人群
elif question_type == question_type_enum.FOODMATERIAL_NOT_CROWD:
sql = ["MATCH (m:FoodMaterial)-[r:taboo_crowd]->(n:Crowd) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_MATERIAL)]
......@@ -175,17 +199,20 @@ class QuestionPaser:
# 已知食物找烹饪特点
elif question_type == question_type_enum.FOODPROCESS_COOKING_SPECIALTY:
sql = ["MATCH (m:FoodProcess)-[r:cooking_specialty]->(n:CookingSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_PROCESS)]
sql = ["MATCH (m:FoodProcess)-[r:cooking_specialty]->(n:CookingSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in
entity_dict.get(word_type_enum.FOOD_PROCESS)]
elif question_type == question_type_enum.FOODMATERIAL_COOKING_SPECIALTY:
sql = ["MATCH (m:FoodMaterial)-[r:cooking_specialty]->(n:CookingSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_MATERIAL)]
sql = ["MATCH (m:FoodMaterial)-[r:cooking_specialty]->(n:CookingSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in
entity_dict.get(word_type_enum.FOOD_MATERIAL)]
# 已知食物找膳食特点
elif question_type == question_type_enum.FOODPROCESS_FOOD_SPECIALTY:
sql = ["MATCH (m:FoodProcess)-[r:food_specialty]->(n:FoodSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_PROCESS)]
elif question_type == question_type_enum.FOODMATERIAL_FOOD_SPECIALTY:
sql = ["MATCH (m:FoodMaterial)-[r:food_specialty]->(n:FoodSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_MATERIAL)]
sql = ["MATCH (m:FoodMaterial)-[r:food_specialty]->(n:FoodSpecialty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in
entity_dict.get(word_type_enum.FOOD_MATERIAL)]
# 已知食物找地域
elif question_type == question_type_enum.FOODPROCESS_PROVINCE:
......@@ -201,10 +228,12 @@ class QuestionPaser:
# 已知食物查单位
elif question_type == question_type_enum.FOODPROCESS_UNIT:
sql = ["MATCH (m:FoodProcess)-[r:extension_unit]->(n:ExtensionUnits) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_PROCESS)]
sql = ["MATCH (m:FoodProcess)-[r:extension_unit]->(n:ExtensionUnits) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in
entity_dict.get(word_type_enum.FOOD_PROCESS)]
elif question_type == question_type_enum.FOODMATERIAL_UNIT:
sql = ["MATCH (m:FoodMaterial)-[r:extension_unit]->(n:ExtensionUnits) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_MATERIAL)]
sql = ["MATCH (m:FoodMaterial)-[r:extension_unit]->(n:ExtensionUnits) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in
entity_dict.get(word_type_enum.FOOD_MATERIAL)]
# 已知食物查富含的元素
elif question_type == question_type_enum.FOODPROCESS_HIGH_CONT:
......@@ -234,6 +263,30 @@ class QuestionPaser:
elif question_type == question_type_enum.FOODPROCESS_ALIAS:
sql = ["MATCH (m:FoodProcess)-[r:alias_of]->(n:Alias) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_PROCESS)]
# 已知菜品查性质
elif question_type == question_type_enum.FOODPROCESS_NATURE:
sql = ["MATCH (m:FoodProcess)-[r:nature_of]->(n:Nature) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.FOOD_PROCESS)]
# 已知做法查菜品
elif question_type == question_type_enum.COOKINGSTYLE_FOODPROCESS:
sql = ["MATCH (m:FoodProcess)-[r:cooking_style]->(n:CookingStyle) where n.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.COOKING_STYLE)]
# 已知运动查类型
elif question_type == question_type_enum.EXERCISE_TYPE:
sql = ["MATCH (m:Exercise)-[r:exercise_type]->(n:ExerciseType) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.EXERCISE)]
# 已知运动类型查运动
elif question_type == question_type_enum.TYPE_EXERCISE:
sql = ["MATCH (m:Exercise)-[r:exercise_type]->(n:ExerciseType) where n.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.EXERCISE_TYPE)]
# 已知运动查动作困难度
elif question_type == question_type_enum.EXERCISE_DIFFICULTY:
sql = ["MATCH (m:Exercise)-[r:action_difficulty]->(n:ActionDifficulty) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.EXERCISE)]
# 已知运动查动作特点
elif question_type == question_type_enum.EXERCISE_FEATURE:
sql = ["MATCH (m:Exercise)-[r:action_feature]->(n:ActionFeatures) where m.name = '{0}' return m.name, r.name, n.name".format(i) for i in entity_dict.get(word_type_enum.EXERCISE)]
if sql:
sql_['sql'] = sql
......
......@@ -16,11 +16,19 @@ class word_type_enum(Enum):
PROVINCE = 'province'
NUTRIENT = 'nutrient'
EXERCISE = 'exercise'
EXERCISE_TYPE = 'exercise_type'
DRUG = 'drug'
class question_type_enum(Enum):
OTHERS = 'others'
DISEASE_ONLY = 'disease_only'
FOODMATERIAL_ONLY = 'foodMaterial_only'
FOODPACKAGE_ONLY = 'foodPackage_only'
FOODPROCESS_ONLY = 'foodProcess_only'
EXERCISE_ONLY = 'exercise_only'
DISEASE_SYMPTOM = 'disease_symptom'
SYMPTOM_DISEASE = 'symptom_disease'
DISEASE_CAUSE = 'disease_cause'
......@@ -39,6 +47,9 @@ class question_type_enum(Enum):
DISEASE_CUREPROB = 'disease_cureprob'
DISEASE_EASYGET = 'disease_easyget'
DISEASE_DESC = 'disease_desc'
DISEASE_BELONG = 'disease_belong'
DEPARTMENT_DISEASE = 'department_disease'
FOODMATERIAL_NOT_CROWD = 'foodMaterial_not_crowd'
FOODMATERIAL_DO_CROWD = 'foodMaterial_do_crowd'
FOODPROCESS_NOT_CROWD = 'foodProcess_not_crowd'
......@@ -70,3 +81,10 @@ class question_type_enum(Enum):
FOODMATERIAL_LOW_CONT = 'foodMaterial_low_cont'
NUTRIENT_LOW_CONT = 'nutrient_low_cont'
FOODPROCESS_ALIAS = 'foodProcess_alias'
FOODPROCESS_NATURE = 'foodProcess_nature'
COOKINGSTYLE_FOODPROCESS = 'cookingStyle_foodProcess'
EXERCISE_TYPE = 'EXERCISE_TYPE'
TYPE_EXERCISE = 'TYPE_EXERCISE'
EXERCISE_DIFFICULTY = 'EXERCISE_DIFFICULTY'
EXERCISE_FEATURE = 'EXERCISE_FEATURE'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment