def __init__(self, query_data, dependency=None): logger.info('Query Parsing...') self.relation = query_data.setdefault('relation', list()) self.entity = query_data.setdefault('entity', list()) self.intent = query_data['intent'] self.dependency = dependency self.relation_component_list = list() self.entity_component_list = list() # 获取实体和关系对应的子图组件 self.init_relation_component() self.init_entity_component() # 若有依存分析,根据依存分析来获取组件图 if self.dependency and len(self.dependency) > 0: logger.info('dependency exist.') print('dependency exist.') dm = DepMap(query_data['dependency'], self.relation_component_list, self.entity_component_list) if dm.check_dep(): # 使用依存分析,获取self.component_graph if nx.algorithms.is_weakly_connected(dm.dep_graph): self.query_graph = dm.dep_graph self.determine_intention() return else: logger.info('dependency wrong!') # 得到子图组件构成的集合,用图表示 self.component_graph = nx.disjoint_union_all( self.relation_component_list + self.entity_component_list) self.query_graph = copy.deepcopy(self.component_graph) self.query_graph = Graph(self.query_graph) self.old_query_graph = copy.deepcopy(self.component_graph) self.node_type_dict = self.query_graph.node_type_statistic() self.component_assemble() while len(self.query_graph.nodes) != len(self.old_query_graph.nodes) \ and not nx.algorithms.is_weakly_connected(self.query_graph): # 节点一样多说明上一轮没有合并 # 图已连通也不用合并 self.old_query_graph = copy.deepcopy(self.query_graph) self.node_type_dict = self.query_graph.node_type_statistic() self.component_assemble() while not nx.algorithms.is_weakly_connected(self.query_graph): # 若不连通则在联通分量之间添加默认边 flag = self.add_default_edge() if not flag: logger.info('default edge missing!') # 未添加上说明缺少默认边 break # 经过上面两个循环,得到连通的图,下面确定意图 self.determine_intention()
def add_default_edge(self): flag = False components_set = self.query_graph.get_connected_components_subgraph() d0 = Graph(components_set[0]).node_type_statistic() d1 = Graph(components_set[1]).node_type_statistic() candidates = itertools.product(d0.keys(), d1.keys()) candidates = list(candidates) for key, edge in DEFAULT_EDGE.items(): for c in candidates: if c[0] == edge['domain'] and c[1] == edge['range']: node_0 = d0[edge['domain']][0] node_1 = d1[edge['range']][0] self.query_graph.add_edge(node_0, node_1, key) flag = True return flag elif c[1] == edge['domain'] and c[0] == edge['range']: node_0 = d1[edge['domain']][0] node_1 = d0[edge['range']][0] self.query_graph.add_edge(node_0, node_1, key) flag = True return flag return flag
def add_default_edge_between_components(self, components_set, c1, c2): """ 在两个连通分量之间添加默认边 :param components_set: :param c1: :param c2: :return: """ flag = False d0 = Graph(components_set[c1]).node_type_statistic() d1 = Graph(components_set[c2]).node_type_statistic() candidates = itertools.product(d0.keys(), d1.keys()) candidates = list(candidates) trick_index = 0 for key, edge in DEFAULT_EDGE.items(): for c in candidates: if c[0] == edge['domain'] and c[1] == edge['range']: node_0 = d0[edge['domain']][trick_index] node_1 = d1[edge['range']][trick_index] self.query_graph.add_edge(node_0, node_1, key, type=key, value=edge['value']) flag = True return flag elif c[1] == edge['domain'] and c[0] == edge['range']: node_0 = d1[edge['domain']][trick_index] node_1 = d0[edge['range']][trick_index] self.query_graph.add_edge(node_0, node_1, key, type=key, value=edge['value']) flag = True return flag return flag
def init_dep_graph(self): for item in self.dependency: f = item['from'] t = item['to'] if f['type'] == 'entity' and t['type'] == 'relation': temp_graph = self.from_ent_to_rel(f['value'], t['value']) self.dep_graph_list.append(temp_graph) elif f['type'] == 'relation' and t['type'] == 'entity': temp_graph = self.from_rel_to_ent(f['value'], t['value']) self.dep_graph_list.append(temp_graph) self.dep_graph = nx.disjoint_union_all(self.dep_graph_list) mapping = dict() for i, n in enumerate(self.dep_graph.nodes): mapping[n] = i nx.relabel_nodes(self.dep_graph, mapping, copy=False) self.dep_graph = Graph(self.dep_graph)
def __init__(self, graph, query): self.graph = nx.convert_node_labels_to_integers(graph) self.graph = Graph(self.graph) self.query = query # 用于指出查询意图为某归属属性的情况 self.intention_tail = '' self.entities = dict() self.init_entities() self.rels = list() self.init_rels() self.intentions = list() self.init_intention() self.query_dict = dict() self.serial_process() self.add_rels_to_entities() self.final_delete() self.init_query_dict()
def __init__(self, query_data, dependency=None): logger.info('Query Graph Parsing...') self.error_info = None # print('Query Graph Parsing...') self.relation = query_data.setdefault('relation', list()) self.entity = query_data.setdefault('entity', list()) self.pre_process() self.intent = query_data['intent'] self.dependency = dependency self.relation_component_list = list() self.entity_component_list = list() # 获取实体和关系对应的子图组件 self.init_relation_component() self.init_entity_component() # 若有依存分析,根据依存分析来获取组件图 if self.dependency and len(self.dependency) > 0: logger.info('dependency exist.') # print('dependency exist.') dm = DepMap(self.dependency, self.relation_component_list, self.entity_component_list) if dm.check_dep( ) and dm.dep_graph and nx.algorithms.is_weakly_connected( dm.dep_graph): self.query_graph = dm.dep_graph self.query_graph = None # 得到子图组件构成的集合,用图表示 # self.component_graph = nx.disjoint_union_all(self.relation_component_list + self.entity_component_list) # self.component_graph的顺序决定了节点合并顺序,对最终构建的图有很大影响 self.component_graph = my_disjoint_union_all( self.entity_component_list + self.relation_component_list) self.query_graph = copy.deepcopy(self.component_graph) self.query_graph = Graph(self.query_graph) self.old_query_graph = copy.deepcopy(self.component_graph) self.node_type_dict = self.query_graph.node_type_statistic() self.component_assemble() while len(self.query_graph.nodes) != len(self.old_query_graph.nodes) \ and not nx.algorithms.is_weakly_connected(self.query_graph): # 节点一样多说明上一轮没有合并 # 图已连通也不用合并 self.old_query_graph = copy.deepcopy(self.query_graph) self.node_type_dict = self.query_graph.node_type_statistic() self.component_assemble() if not self.query_graph: self.error_info = '问句缺失必要实体' return while not nx.algorithms.is_weakly_connected(self.query_graph): # 若不连通则在联通分量之间添加默认边 flag = self.add_default_edge() if not flag: logger.info('default edge missing!') logger.info('graph is not connected!') self.error_info = 'graph is not connected!' # 未添加上说明缺少默认边 return # 经过上面两个循环,得到连通的图,下面确定意图 logger.info('connected graph is already') self.query_graph = nx.convert_node_labels_to_integers(self.query_graph) self.query_graph = Graph(self.query_graph) self.query_graph.show_log() logger.info('next is determine intention') self.determine_intention()