def run(self, dispatcher, tracker, domain): car_body = tracker.get_slot('car_body') energy_type = tracker.get_slot('energy_type') time2market = tracker.get_slot('time2market') listed_items = tracker.get_slot('listed_items') SlotSet("car_body", None) SlotSet("energy_type", None) SlotSet("time2market", None) attribute_dict = {} attribute_dict['body_structure'] = car_body attribute_dict['energy_type'] = energy_type if time2market: attribute_dict['time2market'] = date_transfer(time2market) else: attribute_dict['time2market'] = None graph_database = GraphDatabase() car_model_list = graph_database.query_attribute2entity(attribute_dict) dispatcher.utter_message(template="utter_answer", answer="小通一共找到" + str(len(car_model_list)) + "个车型,由于篇幅限制,为您列出以下几种:") car_model_list_slot = [] for i, e in enumerate(car_model_list): if i >= 10: break answer = str(i + 1) + ": " + e dispatcher.utter_message(template="utter_answer", answer=answer) car_model_list_slot.append(e) slots = [SlotSet("listed_items", car_model_list_slot)] return slots
def run(self, dispatcher, tracker, domain): graph = GraphDatabase() # get entities to compare and their entity type listed_items = tracker.get_slot("listed_items") entity_type = get_entity_type(tracker) if listed_items is None or entity_type is None: dispatcher.utter_message("utter_rephrase", tracker) return [] # get attribute of interest attribute = get_attribute(tracker) if attribute is None: dispatcher.utter_message("utter_rephrase", tracker) return [] # utter response for every entity that shows the value of the attribute for e in listed_items: key_attribute = schema[entity_type]["key"] value = graph.get_attribute_of(entity_type, key_attribute, e, attribute) if value is not None and len(value) == 1: dispatcher.utter_message( f"{e} has the value '{value[0]}' for attribute '{attribute}'." ) return []
def run(self, dispatcher, tracker, domain): graph_database = GraphDatabase() # first need to know the entity type we are looking for entity_type = get_entity_type(tracker) if entity_type is None: dispatcher.utter_template("utter_rephrase", tracker) return [] # check what attributes the NER found for entity type attributes = get_attributes_of_entity(entity_type, tracker) # query knowledge base entities = graph_database.get_entities(entity_type, attributes) # filter out transactions that do not belong the set account (if any) if entity_type == "transaction": account_number = tracker.get_slot("account") entities = self._filter_transaction_entities( entities, account_number) if not entities: dispatcher.utter_template( "I could not find any entities for '{}'.".format(entity_type), tracker) return [] # utter a response that contains all found entities # use the 'representation' attributes to print an entity entity_representation = schema[entity_type]["representation"] dispatcher.utter_message( "Found the following '{}' entities:".format(entity_type)) sorted_entities = sorted( [to_str(e, entity_representation) for e in entities]) for i, e in enumerate(sorted_entities): dispatcher.utter_message(f"{i + 1}: {e}") # set slots # set the entities slot in order to resolve references to one of the found # entites later on entity_key = schema[entity_type]["key"] slots = [ SlotSet("entity_type", entity_type), SlotSet("listed_items", list(map(lambda x: to_str(x, entity_key), entities))), ] # if only one entity was found, that the slot of that entity type to the # found entity if len(entities) == 1: slots.append(SlotSet(entity_type, to_str(entities[0], entity_key))) reset_attribute_slots(slots, entity_type, tracker) return slots
def run(self, dispatcher, tracker, domain): graph_database = GraphDatabase() car_series_list = graph_database.get_entities(entity_type='车系') dispatcher.utter_message(template="utter_answer", answer="小通找到了下列车系:") car_series_list_slot = ['车系'] for i, e in enumerate(car_series_list): answer = str(i + 1) + ": " + e['name'] dispatcher.utter_message(template="utter_answer", answer=answer) car_series_list_slot.append(e['name']) slots = [SlotSet("listed_items", car_series_list_slot)] return slots
def get_attribute(tracker: Tracker) -> Text: """ Get the attribute mentioned by the user. As the user may use a synonym for an attribute, we need to map the mentioned attribute to the attribute name used in the knowledge base. :param tracker: tracker :return: attribute (same type as used in the knowledge base) """ graph_database = GraphDatabase() attribute = tracker.get_slot("attribute") return graph_database.map("attribute-mapping", attribute)
def get_entity_type(tracker: Tracker) -> Text: """ Get the entity type mentioned by the user. As the user may speak of an entity type in plural, we need to map the mentioned entity type to the type used in the knowledge base. :param tracker: tracker :return: entity type (same type as used in the knowledge base) """ graph_database = GraphDatabase() entity_type = tracker.get_slot("entity_type") return graph_database.map("entity-type-mapping", entity_type)
def run(self, dispatcher, tracker, domain): car_series = tracker.get_slot('car_series') if car_series is None: dispatcher.utter_message(template="utter_not_clear") graph_database = GraphDatabase() car_model_list = graph_database.query_relation2entity( entity=car_series, relation='属于') dispatcher.utter_message(template="utter_answer", answer="小通一共找到" + str(len(car_model_list)) + "个车型属于该车系,由于篇幅限制,为您列出以下几种:") car_model_list_slot = ['车型'] for i, e in enumerate(car_model_list): if i >= 10: break answer = str(i + 1) + ": " + e dispatcher.utter_message(template="utter_answer", answer=answer) car_model_list_slot.append(e) slots = [SlotSet("listed_items", car_model_list_slot)] return slots
def run(self, dispatcher, tracker, domain): graph_database = GraphDatabase() print(tracker) # get entity type of entity entity_type = get_entity_type(tracker) print(entity_type) if entity_type is None: dispatcher.utter_message("utter_rephrase", tracker) return [] # get name of entity and attribute of interest name = get_entity_name(tracker, entity_type) print(name) attribute = get_attribute(tracker) if name is None or attribute is None: dispatcher.utter_message("utter_rephrase", tracker) slots = [SlotSet("mention", None)] reset_attribute_slots(slots, entity_type, tracker) return slots # query knowledge base key_attribute = schema[entity_type]["key"] value = graph_database.get_attribute_of( entity_type, key_attribute, name, attribute ) # utter response if value is not None and len(value) == 1: dispatcher.utter_message( f"{name} has the value '{value[0]}' for attribute '{attribute}'." ) else: dispatcher.utter_message( f"Did not found a valid value for attribute {attribute} for entity '{name}'." ) slots = [SlotSet("mention", None), SlotSet(entity_type, name)] reset_attribute_slots(slots, entity_type, tracker) return slots
def resolve_mention(tracker: Tracker) -> Text: """ Resolves a mention of an entity, such as first, to the actual entity. If multiple entities are listed during the conversation, the entities are stored in the slot 'listed_items' as a list. We resolve the mention, such as first, to the list index and retrieve the actual entity. :param tracker: tracker :return: name of the actually entity """ graph_database = GraphDatabase() mention = tracker.get_slot("mention") listed_items = tracker.get_slot("listed_items") if mention is not None and listed_items is not None: idx = int(graph_database.map("mention-mapping", mention)) if type(idx) is int and idx < len(listed_items): return listed_items[idx]
def run(self, dispatcher, tracker, domain): car_series = tracker.get_slot('car_series') attribute = tracker.get_slot('attribute') relationship = tracker.get_slot('relationship') SlotSet("attribute", None) SlotSet("relationship", None) if car_series is None: dispatcher.utter_message(template="utter_not_clear") return [] elif attribute is None and relationship is None: dispatcher.utter_message(template="utter_not_clear") return [] elif attribute: graph_database = GraphDatabase() car_model_dict = graph_database.query_entity2attribute( entity=car_series, relationship=None, c_attribute=attribute) answer = "小通为你查询到" + car_series + "的" for key in car_model_dict.keys(): answer += key + "是" + car_model_dict[key] + " " dispatcher.utter_message(template="utter_answer", answer=answer) return [SlotSet("car_series", car_series)] elif relationship and attribute is None: graph_database = GraphDatabase() car_model_dict = graph_database.query_entity2attribute( entity=car_series, relationship=relationship, c_attribute=None) answer = "小通为你查询到" + car_series + "的 " for key in car_model_dict.keys(): answer += +key + ": " + str(car_model_dict[key]) + " " dispatcher.utter_message(template="utter_answer", answer=answer) return [SlotSet("car_series", car_series)]
def get_entity_name(tracker: Tracker, entity_type: Text): """ Get the name of the entity the user referred to. Either the NER detected the entity and stored its name in the corresponding slot or the user referred to the entity by an ordinal number, such as first or last, or the user refers to an entity by its attributes. :param tracker: Tracker :param entity_type: the entity type :return: the name of the actual entity (value of key attribute in the knowledge base) """ # user referred to an entity by an ordinal number mention = tracker.get_slot("mention") if mention is not None: return resolve_mention(tracker) # user named the entity entity_name = tracker.get_slot(entity_type) if entity_name: return entity_name # user referred to an entity by its attributes listed_items = tracker.get_slot("listed_items") attributes = get_attributes_of_entity(entity_type, tracker) if listed_items and attributes: # filter the listed_items by the set attributes graph_database = GraphDatabase() for entity in listed_items: key_attr = schema[entity_type]["key"] result = graph_database.validate_entity( entity_type, entity, key_attr, attributes ) if result is not None: return to_str(result, key_attr) return None
from graph_database import GraphDatabase from py2neo import Graph, Node, data, Path, Relationship graphDatabase = GraphDatabase() attributes = [{'name': '2021款 精英型'}] result = graphDatabase.get_entities(entity_type='车型', attributes=attributes) print(result) #[{'id': 1, 'label': '车型', 'name': '2021款 精英型'}] attributes = [{'id': 1}] result = graphDatabase.get_entities(entity_type='车型', attributes=attributes) print(result) #[{'id': 1, 'label': '车型', 'name': '2021款 精英型'}] result = graphDatabase.get_entities(entity_type='车系') print(result) #[{'id': 1, 'label': '车型', 'name': '2021款 精英型'}] for i, e in enumerate(result): print(f"{i + 1}: {e['name']}") # # result = graphDatabase.get_entities(entity_type='车型') # print(result) #[{'id': 955, 'label': '车型', 'name': '2021款 精英型'}, {'id': 963, 'label': '车型', 'name': '2019款 2.4L汽油手动四驱高底盘先锋版长厢'}......] # # result = graphDatabase.get_entities(entity_type='车身',limit=2) # print(result) #[{'id': 957, 'label': '车身', '车身结构': '皮卡', '车门数(个)': 4.0, '高度(mm)': 1809.0, '座位数(个)': '5', '后排车门开启方式': '平开门', 'name': '车身节点', '轴距(mm)': 3155.0, '货箱尺寸(mm)': '1485x1510x530'}, {'id': 965, 'label': '车身', '车身结构': '皮卡', '车门数(个)': 4.0, '高度(mm)': 1809.0, '座位数(个)': '5', '后排车门开启方式': '平开门', 'name': '车身节点', '轴距(mm)': 3470.0, '货箱尺寸(mm)': '1800x1510x530'}] # # result = graphDatabase.get_entities(entity_type='发动机',limit=2) # print(result) #[{'id': 961, 'label': '发动机', '最大扭矩(N·m)': '310', '最大功率(kW)': 130.0, 'name': '发动机节点'}, {'id': 968, 'label': '发动机', '每缸气门数(个)': '4', '供油方式': '多点电喷', '排量(L)': '2.4', '进气形式': '自然吸气', '最大扭矩(N·m)': '200', '环保标准': '国V', '最大功率(kW)': 105.0, '最大功率转速(rpm)': '5250', '最大马力(Ps)': 143.0, '最大扭矩转速(rpm)': '2500-3000', '缸体材料': '未知', '气缸数(个)': '4', '气缸排列形式': 'L', '缸盖材料': '铝合金', 'name': '发动机节点', '燃料形式': '汽油', '燃油标号': '92号', '配气机构': '未知'}] # # attributes = [{'供油方式':'直喷','排量(L)':'2.0'}] # result = graphDatabase.get_entities(entity_type='发动机',attributes=attributes,limit=2) # print(result) #[{'id': 1029, 'label': '发动机', '进气形式': '涡轮增压', '每缸气门数(个)': '4', '供油方式': '直喷', '排量(L)': '2.0', '最大扭矩(N·m)': '375', '环保标准': '国VI', '最大功率(kW)': 120.0, '最大马力(Ps)': 163.0, '缸体材料': '未知', '气缸排列形式': 'L', '气缸数(个)': '4', '缸盖材料': '未知', 'name': '发动机节点', '燃料形式': '柴油', '燃油标号': '0号', '配气机构': '未知'}, {'id': 1039, 'label': '发动机', '进气形式': '涡轮增压', '每缸气门数(个)': '4', '供油方式': '直喷', '排量(L)': '2.0', '最大扭矩(N·m)': '350', '环保标准': '国VI', '最大功率(kW)': 160.0, '最大马力(Ps)': 218.0, '缸体材料': '未知', '气缸排列形式': 'L', '气缸数(个)': '4', '缸盖材料': '铝合金', 'name': '发动机节点', '燃料形式': '汽油', '燃油标号': '92号', '配气机构': '未知'}] # # entity_id = 1029 # aimed_attribute = '供油方式'