| @@ -54,9 +54,11 @@ dslist = [ | |||
| # {'name': 'PTC_MR', 'dataset': '../datasets/PTC/Train/MR.ds',}, | |||
| ] | |||
| estimator = untilhpathkernel | |||
| param_grid_precomputed = {'depth': np.linspace(1, 10, 10), # [2], | |||
| 'k_func': ['MinMax'], # ['MinMax', 'tanimoto'], | |||
| 'compute_method': ['trie']} # ['MinMax']} | |||
| param_grid_precomputed = {'depth': np.linspace(3, 10, 8), # [2], | |||
| 'k_func': [None]} # ['MinMax', 'tanimoto'], | |||
| #param_grid_precomputed = {'depth': np.linspace(1, 10, 10), # [2], | |||
| # 'k_func': ['MinMax'], # ['MinMax', 'tanimoto'], | |||
| # 'compute_method': ['trie']} # ['MinMax']} | |||
| param_grid = [{'C': np.logspace(-10, 10, num=41, base=10)}, | |||
| {'alpha': np.logspace(-10, 10, num=41, base=10)}] | |||
| @@ -17,8 +17,11 @@ import multiprocessing | |||
| from tqdm import tqdm | |||
| import networkx as nx | |||
| import matplotlib.pyplot as plt | |||
| import random | |||
| from iam import iam, test_iam_with_more_graphs_as_init, test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations | |||
| import matplotlib.pyplot as plt | |||
| from iam import iam, test_iam_with_more_graphs_as_init, iam_moreGraphsAsInit_tryAllPossibleBestGraphs | |||
| sys.path.insert(0, "../") | |||
| from pygraph.kernels.marginalizedKernel import marginalizedkernel | |||
| from pygraph.kernels.untilHPathKernel import untilhpathkernel | |||
| @@ -67,7 +70,7 @@ def gk_iam(Gn, alpha): | |||
| # Gs_nearest = Gk + gihat_list | |||
| # g_tmp = iam(Gs_nearest) | |||
| # | |||
| # # compute distance between phi and the new generated graph. | |||
| # # compute distance between \psi and the new generated graph. | |||
| # knew = marginalizedkernel([g_tmp, g1, g2], node_label='atom', edge_label=None, | |||
| # p_quit=lmbda, n_iteration=20, remove_totters=False, | |||
| # n_jobs=multiprocessing.cpu_count(), verbose=False) | |||
| @@ -142,7 +145,7 @@ def gk_iam_nearest(Gn, alpha, idx_gi, Kmatrix, k, r_max): | |||
| print(g_tmp.nodes(data=True)) | |||
| print(g_tmp.edges(data=True)) | |||
| # compute distance between phi and the new generated graph. | |||
| # compute distance between \psi and the new generated graph. | |||
| gi_list = [Gn[i] for i in idx_gi] | |||
| knew = compute_kernel([g_tmp] + gi_list, 'untilhpathkernel', False) | |||
| dnew = dis_gstar(0, range(1, len(gi_list) + 1), alpha, knew) | |||
| @@ -236,7 +239,7 @@ def gk_iam_nearest(Gn, alpha, idx_gi, Kmatrix, k, r_max): | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # | |||
| # # compute distance between phi and the new generated graphs. | |||
| # # compute distance between \psi and the new generated graphs. | |||
| # gi_list = [Gn[i] for i in idx_gi] | |||
| # knew = compute_kernel(g_tmp_list + gi_list, 'marginalizedkernel', False) | |||
| # dnew_list = [] | |||
| @@ -278,7 +281,12 @@ def gk_iam_nearest(Gn, alpha, idx_gi, Kmatrix, k, r_max): | |||
| def gk_iam_nearest_multi(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, | |||
| gkernel, c_ei=1, c_er=1, c_es=1, epsilon=0.001): | |||
| gkernel, epsilon=0.001, | |||
| params_iam={'c_ei': 1, 'c_er': 1, 'c_es': 1, | |||
| 'ite_max': 50, 'epsilon': 0.001, | |||
| 'removeNodes': True, 'connected': False}, | |||
| params_ged={'ged_cost': 'CHEM_1', 'ged_method': 'IPFP', | |||
| 'saveGXL': 'benoit'}): | |||
| """This function constructs graph pre-image by the iterative pre-image | |||
| framework in reference [1], algorithm 1, where the step of generating new | |||
| graphs randomly is replaced by the IAM algorithm in reference [2]. | |||
| @@ -310,7 +318,7 @@ def gk_iam_nearest_multi(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, | |||
| g0hat_list = [Gn_init[idx] for idx in sort_idx[0:nb_best]] # the nearest neighbors of phi in DN | |||
| if dis_gs[0] == 0: # the exact pre-image. | |||
| print('The exact pre-image is found from the input dataset.') | |||
| return 0, g0hat_list | |||
| return 0, g0hat_list, 0, 0 | |||
| dhat = dis_gs[0] # the nearest distance | |||
| ghat_list = [g.copy() for g in g0hat_list] | |||
| # for g in ghat_list: | |||
| @@ -320,31 +328,33 @@ def gk_iam_nearest_multi(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| Gk = [Gn_init[ig].copy() for ig in sort_idx[0:k]] # the k nearest neighbors | |||
| # for gi in Gk: | |||
| ## nx.draw_networkx(gi) | |||
| ## plt.show() | |||
| for gi in Gk: | |||
| nx.draw(gi, labels=nx.get_node_attributes(gi, 'atom'), with_labels=True) | |||
| # nx.draw_networkx(gi) | |||
| plt.show() | |||
| # draw_Letter_graph(g) | |||
| # print(gi.nodes(data=True)) | |||
| # print(gi.edges(data=True)) | |||
| Gs_nearest = Gk.copy() | |||
| print(gi.nodes(data=True)) | |||
| print(gi.edges(data=True)) | |||
| Gs_nearest = [g.copy() for g in Gk] | |||
| Gn_nearest_median = [g.copy() for g in Gs_nearest] | |||
| # gihat_list = [] | |||
| # i = 1 | |||
| r = 0 | |||
| itr = 0 | |||
| # cur_sod = dhat | |||
| # old_sod = cur_sod * 2 | |||
| sod_list = [dhat] | |||
| itr_total = 0 | |||
| # cur_dis = dhat | |||
| # old_dis = cur_dis * 2 | |||
| dis_list = [dhat] | |||
| found = False | |||
| nb_updated = 0 | |||
| while r < r_max:# and not found: # @todo: if not found?# and np.abs(old_sod - cur_sod) > epsilon: | |||
| print('\nr =', r) | |||
| print('itr for gk =', itr, '\n') | |||
| while r < r_max:# and not found: # @todo: if not found?# and np.abs(old_dis - cur_dis) > epsilon: | |||
| print('\nCurrent preimage iteration =', r) | |||
| print('Total preimage iteration =', itr_total, '\n') | |||
| found = False | |||
| # Gs_nearest = Gk + gihat_list | |||
| # g_tmp = iam(Gs_nearest) | |||
| g_tmp_list, _ = test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations( | |||
| Gn_median, Gs_nearest, c_ei=c_ei, c_er=c_er, c_es=c_es) | |||
| g_tmp_list, _ = iam_moreGraphsAsInit_tryAllPossibleBestGraphs( | |||
| Gn_nearest_median, Gs_nearest, params_ged=params_ged, **params_iam) | |||
| # for g in g_tmp_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| @@ -352,31 +362,73 @@ def gk_iam_nearest_multi(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # compute distance between phi and the new generated graphs. | |||
| # compute distance between \psi and the new generated graphs. | |||
| knew = compute_kernel(g_tmp_list + Gn_median, gkernel, False) | |||
| dnew_list = [] | |||
| for idx, g_tmp in enumerate(g_tmp_list): | |||
| # @todo: the term3 below could use the one at the beginning of the function. | |||
| dnew_list.append(dis_gstar(idx, range(len(g_tmp_list), | |||
| len(g_tmp_list) + len(Gn_median) + 1), alpha, knew, | |||
| withterm3=False)) | |||
| len(g_tmp_list) + len(Gn_median) + 1), | |||
| alpha, knew, withterm3=False)) | |||
| # dnew = knew[0, 0] - 2 * (alpha[0] * knew[0, 1] + alpha[1] * | |||
| # knew[0, 2]) + (alpha[0] * alpha[0] * k_list[0] + alpha[0] * | |||
| # alpha[1] * k_g2_list[0] + alpha[1] * alpha[0] * | |||
| # k_g1_list[1] + alpha[1] * alpha[1] * k_list[1]) | |||
| # # find the new k nearest graphs. | |||
| # dnew_best = min(dnew_list) | |||
| # dis_gs = dnew_list + dis_gs # add the new nearest distances. | |||
| # Gs_nearest = [g.copy() for g in g_tmp_list] + Gs_nearest # add the corresponding graphs. | |||
| # sort_idx = np.argsort(dis_gs) | |||
| # if len([i for i in sort_idx[0:k] if i < len(dnew_list)]) > 0: | |||
| # print('We got new k nearest neighbors! Hurray!') | |||
| # dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] # the new k nearest distances. | |||
| ## print(dis_gs[-1]) | |||
| # Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| # nb_best = len(np.argwhere(dis_gs == dis_gs[0]).flatten().tolist()) | |||
| # if dnew_best < dhat and np.abs(dnew_best - dhat) > epsilon: | |||
| # print('I have smaller distance!') | |||
| # print(str(dhat) + '->' + str(dis_gs[0])) | |||
| # dhat = dis_gs[0] | |||
| # idx_best_list = np.argwhere(dnew_list == dhat).flatten().tolist() | |||
| # ghat_list = [g_tmp_list[idx].copy() for idx in idx_best_list] | |||
| ## for g in ghat_list: | |||
| ### nx.draw_networkx(g) | |||
| ### plt.show() | |||
| ## draw_Letter_graph(g) | |||
| ## print(g.nodes(data=True)) | |||
| ## print(g.edges(data=True)) | |||
| # r = 0 | |||
| # found = True | |||
| # nb_updated += 1 | |||
| # elif np.abs(dnew_best - dhat) < epsilon: | |||
| # print('I have almost equal distance!') | |||
| # print(str(dhat) + '->' + str(dnew_best)) | |||
| # else: | |||
| # dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] | |||
| # Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| # Gn_nearest_median = [g.copy() for g in Gs_nearest] | |||
| # if not found: | |||
| # r += 1 | |||
| # find the new k nearest graphs. | |||
| dnew_best = min(dnew_list) | |||
| dis_gs = dnew_list + dis_gs # add the new nearest distances. | |||
| Gs_nearest = [g.copy() for g in g_tmp_list] + Gs_nearest # add the corresponding graphs. | |||
| sort_idx = np.argsort(dis_gs) | |||
| if np.abs(dnew_best - dhat) >= epsilon: | |||
| dis_gs = dnew_list + dis_gs # add the new nearest distances. | |||
| Gs_nearest = [g.copy() for g in g_tmp_list] + Gs_nearest # add the corresponding graphs. | |||
| sort_idx = np.argsort(dis_gs) | |||
| else: # if the new distance is equal to the old one. | |||
| # @todo: works if only one graph is generated. | |||
| Gs_nearest[0] = g_tmp_list[0].copy() | |||
| sort_idx = np.argsort(dis_gs) | |||
| if len([i for i in sort_idx[0:k] if i < len(dnew_list)]) > 0: | |||
| print('We got better k nearest neighbors! Hurray!') | |||
| print('We got new k nearest neighbors! Hurray!') | |||
| dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] # the new k nearest distances. | |||
| print(dis_gs[-1]) | |||
| # print(dis_gs[-1]) | |||
| Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| nb_best = len(np.argwhere(dis_gs == dis_gs[0]).flatten().tolist()) | |||
| if dnew_best < dhat and np.abs(dnew_best - dhat) > epsilon: | |||
| if dnew_best < dhat and np.abs(dnew_best - dhat) >= epsilon: | |||
| print('I have smaller distance!') | |||
| print(str(dhat) + '->' + str(dis_gs[0])) | |||
| dhat = dis_gs[0] | |||
| @@ -394,19 +446,269 @@ def gk_iam_nearest_multi(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, | |||
| elif np.abs(dnew_best - dhat) < epsilon: | |||
| print('I have almost equal distance!') | |||
| print(str(dhat) + '->' + str(dnew_best)) | |||
| else: | |||
| dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] | |||
| Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| Gn_nearest_median = [g.copy() for g in Gs_nearest] | |||
| if not found: | |||
| r += 1 | |||
| # old_sod = cur_sod | |||
| # cur_sod = dnew_best | |||
| sod_list.append(dhat) | |||
| itr += 1 | |||
| # old_dis = cur_dis | |||
| # cur_dis = dnew_best | |||
| dis_list.append(dhat) | |||
| itr_total += 1 | |||
| print('\nthe graph is updated', nb_updated, 'times.') | |||
| print('sods in kernel space:', sod_list, '\n') | |||
| print('distances in kernel space:', dis_list, '\n') | |||
| return dhat, ghat_list | |||
| return dhat, ghat_list, dis_list[-1], nb_updated | |||
| def preimage_iam_random_mix(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, | |||
| l_max, gkernel, epsilon=0.001, | |||
| params_iam={'c_ei': 1, 'c_er': 1, 'c_es': 1, | |||
| 'ite_max': 50, 'epsilon': 0.001, | |||
| 'removeNodes': True, 'connected': False}, | |||
| params_ged={'ged_cost': 'CHEM_1', 'ged_method': 'IPFP', | |||
| 'saveGXL': 'benoit'}): | |||
| """This function constructs graph pre-image by the iterative pre-image | |||
| framework in reference [1], algorithm 1, where new graphs are generated | |||
| randomly and by the IAM algorithm in reference [2]. | |||
| notes | |||
| ----- | |||
| Every time a set of n better graphs is acquired, their distances in kernel space are | |||
| compared with the k nearest ones, and the k nearest distances from the k+n | |||
| distances will be used as the new ones. | |||
| """ | |||
| Gn_init = [nx.convert_node_labels_to_integers(g) for g in Gn_init] | |||
| # compute k nearest neighbors of phi in DN. | |||
| dis_list = [] # distance between g_star and each graph. | |||
| term3 = 0 | |||
| for i1, a1 in enumerate(alpha): | |||
| for i2, a2 in enumerate(alpha): | |||
| term3 += a1 * a2 * Kmatrix[idx_gi[i1], idx_gi[i2]] | |||
| for ig, g in tqdm(enumerate(Gn_init), desc='computing distances', file=sys.stdout): | |||
| dtemp = dis_gstar(ig, idx_gi, alpha, Kmatrix, term3=term3) | |||
| dis_list.append(dtemp) | |||
| # sort | |||
| sort_idx = np.argsort(dis_list) | |||
| dis_gs = [dis_list[idis] for idis in sort_idx[0:k]] # the k shortest distances | |||
| nb_best = len(np.argwhere(dis_gs == dis_gs[0]).flatten().tolist()) | |||
| g0hat_list = [Gn_init[idx] for idx in sort_idx[0:nb_best]] # the nearest neighbors of phi in DN | |||
| if dis_gs[0] == 0: # the exact pre-image. | |||
| print('The exact pre-image is found from the input dataset.') | |||
| return 0, g0hat_list, 0, 0 | |||
| dhat = dis_gs[0] # the nearest distance | |||
| ghat_list = [g.copy() for g in g0hat_list] | |||
| # for g in ghat_list: | |||
| # draw_Letter_graph(g) | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| Gk = [Gn_init[ig].copy() for ig in sort_idx[0:k]] # the k nearest neighbors | |||
| for gi in Gk: | |||
| nx.draw(gi, labels=nx.get_node_attributes(gi, 'atom'), with_labels=True) | |||
| # nx.draw_networkx(gi) | |||
| plt.show() | |||
| # draw_Letter_graph(g) | |||
| print(gi.nodes(data=True)) | |||
| print(gi.edges(data=True)) | |||
| Gs_nearest = [g.copy() for g in Gk] | |||
| Gn_nearest_median = [g.copy() for g in Gs_nearest] | |||
| # gihat_list = [] | |||
| # i = 1 | |||
| r = 0 | |||
| itr_total = 0 | |||
| # cur_dis = dhat | |||
| # old_dis = cur_dis * 2 | |||
| dis_list = [dhat] | |||
| found = False | |||
| nb_updated_iam = 0 | |||
| nb_updated_random = 0 | |||
| while r < r_max: # and not found: # @todo: if not found?# and np.abs(old_dis - cur_dis) > epsilon: | |||
| print('\n-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-') | |||
| print('Current preimage iteration =', r) | |||
| print('Total preimage iteration =', itr_total, '\n') | |||
| found = False | |||
| # Gs_nearest = Gk + gihat_list | |||
| # g_tmp = iam(Gs_nearest) | |||
| g_tmp_list, _ = iam_moreGraphsAsInit_tryAllPossibleBestGraphs( | |||
| Gn_nearest_median, Gs_nearest, params_ged=params_ged, **params_iam) | |||
| # for g in g_tmp_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # draw_Letter_graph(g) | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # compute distance between \psi and the new generated graphs. | |||
| knew = compute_kernel(g_tmp_list + Gn_median, gkernel, False) | |||
| dnew_list = [] | |||
| for idx, g_tmp in enumerate(g_tmp_list): | |||
| # @todo: the term3 below could use the one at the beginning of the function. | |||
| dnew_list.append(dis_gstar(idx, range(len(g_tmp_list), | |||
| len(g_tmp_list) + len(Gn_median) + 1), | |||
| alpha, knew, withterm3=False)) | |||
| # find the new k nearest graphs. | |||
| # @todo: for now only consider the situation when only one graph is generated by IAM. | |||
| dnew_best = min(dnew_list) | |||
| gnew_best = g_tmp_list[0].copy() | |||
| # when new distance is equal to the old one, use random generation. | |||
| if np.abs(dnew_best - dhat) < epsilon or dhat < dnew_best: | |||
| # Gs_nearest[0] = g_tmp_list[0].copy() | |||
| # sort_idx = np.argsort(dis_gs) | |||
| print('Distance almost equal or worse, switching to random generation now.') | |||
| print(str(dhat) + '->' + str(dnew_best)) | |||
| if dnew_best > dhat and np.abs(dnew_best - dhat) >= epsilon: | |||
| dnew_best = dhat | |||
| gnew_best = Gs_nearest[0].copy() | |||
| # number of edges to be changed. | |||
| # @todo what if the log is negetive? how to choose alpha (scalar)? seems fdgs is always 1. | |||
| # fdgs = dnew_best | |||
| fdgs = nb_updated_random + 1 | |||
| if fdgs < 1: | |||
| fdgs = 1 | |||
| fdgs = int(np.ceil(np.log(fdgs))) | |||
| if fdgs < 1: | |||
| fdgs += 1 | |||
| # fdgs = nb_updated_random + 1 # @todo: | |||
| # @todo: should we use just half of the adjacency matrix for undirected graphs? | |||
| nb_vpairs = nx.number_of_nodes(gnew_best) * (nx.number_of_nodes(gnew_best) - 1) | |||
| l = 0 | |||
| while l < l_max: | |||
| # add and delete edges. | |||
| gtemp = gnew_best.copy() | |||
| np.random.seed() | |||
| # which edges to change. | |||
| # @todo: what if fdgs is bigger than nb_vpairs? | |||
| idx_change = random.sample(range(nb_vpairs), fdgs if | |||
| fdgs < nb_vpairs else nb_vpairs) | |||
| # idx_change = np.random.randint(0, nx.number_of_nodes(gs) * | |||
| # (nx.number_of_nodes(gs) - 1), fdgs) | |||
| for item in idx_change: | |||
| node1 = int(item / (nx.number_of_nodes(gtemp) - 1)) | |||
| node2 = (item - node1 * (nx.number_of_nodes(gtemp) - 1)) | |||
| if node2 >= node1: # skip the self pair. | |||
| node2 += 1 | |||
| # @todo: is the randomness correct? | |||
| if not gtemp.has_edge(node1, node2): | |||
| gtemp.add_edge(node1, node2) | |||
| # nx.draw_networkx(gs) | |||
| # plt.show() | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| else: | |||
| gtemp.remove_edge(node1, node2) | |||
| # nx.draw_networkx(gs) | |||
| # plt.show() | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| # compute distance between \psi and the new generated graph. | |||
| knew = compute_kernel([gtemp] + Gn_median, gkernel, verbose=False) | |||
| dnew = dis_gstar(0, [1, 2], alpha, knew, withterm3=False) | |||
| # @todo: the new distance is smaller or also equal? | |||
| if dnew < dnew_best or np.abs(dnew_best - dnew) < epsilon: | |||
| if np.abs(dnew_best - dnew) < epsilon: | |||
| print('I am equal!') | |||
| dnew_best = dnew | |||
| gnew_best = gtemp.copy() | |||
| else: | |||
| print('\nI am smaller!') | |||
| print('l =', str(l)) | |||
| print(dnew_best, '->', dnew) | |||
| dis_gs = [dnew] + dis_gs # add the new nearest distances. | |||
| Gs_nearest = [gtemp.copy()] + Gs_nearest # add the corresponding graphs. | |||
| sort_idx = np.argsort(dis_gs) | |||
| dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] # the new k nearest distances. | |||
| Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| Gn_nearest_median = [g.copy() for g in Gs_nearest] | |||
| dhat = dnew | |||
| nb_updated_random += 1 | |||
| found = True # found better graph. | |||
| r = 0 | |||
| print('the graph is updated by random generation', | |||
| nb_updated_random, 'times.') | |||
| nx.draw(gtemp, labels=nx.get_node_attributes(gtemp, 'atom'), | |||
| with_labels=True) | |||
| ## plt.savefig("results/gk_iam/simple_two/xx" + str(i) + ".png", format="PNG") | |||
| plt.show() | |||
| break | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| # print(gtemp.nodes(data=True)) | |||
| # print(gtemp.edges(data=True)) | |||
| l += 1 | |||
| if l == l_max: | |||
| r += 1 | |||
| else: # if the new distance is not equal to the old one. | |||
| dis_gs = dnew_list + dis_gs # add the new nearest distances. | |||
| Gs_nearest = [nx.convert_node_labels_to_integers(g).copy() for g | |||
| in g_tmp_list] + Gs_nearest # add the corresponding graphs. | |||
| sort_idx = np.argsort(dis_gs) | |||
| if len([i for i in sort_idx[0:k] if i < len(dnew_list)]) > 0: | |||
| print('We got new k nearest neighbors! Hurray!') | |||
| dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] # the new k nearest distances. | |||
| # print(dis_gs[-1]) | |||
| Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| nb_best = len(np.argwhere(dis_gs == dis_gs[0]).flatten().tolist()) | |||
| if dnew_best < dhat: | |||
| print('I have smaller distance!') | |||
| print(str(dhat) + '->' + str(dis_gs[0])) | |||
| dhat = dis_gs[0] | |||
| idx_best_list = np.argwhere(dnew_list == dhat).flatten().tolist() | |||
| ghat_list = [g_tmp_list[idx].copy() for idx in idx_best_list] | |||
| # for g in ghat_list: | |||
| ## nx.draw_networkx(g) | |||
| ## plt.show() | |||
| # draw_Letter_graph(g) | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| r = 0 | |||
| found = True | |||
| nb_updated_iam += 1 | |||
| print('the graph is updated by IAM', nb_updated_iam, 'times.') | |||
| nx.draw(ghat_list[0], labels=nx.get_node_attributes(ghat_list[0], 'atom'), | |||
| with_labels=True) | |||
| ## plt.savefig("results/gk_iam/simple_two/xx" + str(i) + ".png", format="PNG") | |||
| plt.show() | |||
| else: | |||
| dis_gs = [dis_gs[idx] for idx in sort_idx[0:k]] | |||
| Gs_nearest = [Gs_nearest[idx] for idx in sort_idx[0:k]] | |||
| Gn_nearest_median = [g.copy() for g in Gs_nearest] | |||
| if not found: | |||
| r += 1 | |||
| # old_dis = cur_dis | |||
| # cur_dis = dnew_best | |||
| dis_list.append(dhat) | |||
| itr_total += 1 | |||
| print('\nthe k shortest distances are', dis_gs) | |||
| print('the shortest distances for previous iterations are', dis_list) | |||
| print('\nthe graph is updated by IAM', nb_updated_iam, 'times, and by random generation', | |||
| nb_updated_random, 'times.') | |||
| print('distances in kernel space:', dis_list, '\n') | |||
| return dhat, ghat_list, dis_list[-1], nb_updated_iam, nb_updated_random | |||
| ############################################################################### | |||
| # useful functions. | |||
| def dis_gstar(idx_g, idx_gi, alpha, Kmatrix, term3=0, withterm3=True): | |||
| term1 = Kmatrix[idx_g, idx_g] | |||
| @@ -424,10 +726,10 @@ def dis_gstar(idx_g, idx_gi, alpha, Kmatrix, term3=0, withterm3=True): | |||
| def compute_kernel(Gn, graph_kernel, verbose): | |||
| if graph_kernel == 'marginalizedkernel': | |||
| Kmatrix, _ = marginalizedkernel(Gn, node_label='atom', edge_label=None, | |||
| p_quit=0.03, n_iteration=20, remove_totters=False, | |||
| p_quit=0.03, n_iteration=10, remove_totters=False, | |||
| n_jobs=multiprocessing.cpu_count(), verbose=verbose) | |||
| elif graph_kernel == 'untilhpathkernel': | |||
| Kmatrix, _ = untilhpathkernel(Gn, node_label='atom', edge_label='bond_type', | |||
| Kmatrix, _ = untilhpathkernel(Gn, node_label='atom', edge_label=None, | |||
| depth=10, k_func='MinMax', compute_method='trie', | |||
| n_jobs=multiprocessing.cpu_count(), verbose=verbose) | |||
| elif graph_kernel == 'spkernel': | |||
| @@ -20,7 +20,424 @@ from pygraph.utils.graphdataset import get_dataset_attributes | |||
| from pygraph.utils.utils import graph_isIdentical, get_node_labels, get_edge_labels | |||
| #from pygraph.utils.utils import graph_deepcopy | |||
| def iam_moreGraphsAsInit_tryAllPossibleBestGraphs(Gn_median, Gn_candidate, | |||
| c_ei=3, c_er=3, c_es=1, ite_max=50, epsilon=0.001, | |||
| node_label='atom', edge_label='bond_type', | |||
| connected=False, removeNodes=True, AllBestInit=True, | |||
| params_ged={'ged_cost': 'CHEM_1', 'ged_method': 'IPFP', 'saveGXL': 'benoit'}): | |||
| """See my name, then you know what I do. | |||
| """ | |||
| from tqdm import tqdm | |||
| # Gn_median = Gn_median[0:10] | |||
| # Gn_median = [nx.convert_node_labels_to_integers(g) for g in Gn_median] | |||
| if removeNodes: | |||
| node_ir = np.inf # corresponding to the node remove and insertion. | |||
| label_r = 'thanksdanny' # the label for node remove. # @todo: make this label unrepeatable. | |||
| ds_attrs = get_dataset_attributes(Gn_median + Gn_candidate, | |||
| attr_names=['edge_labeled', 'node_attr_dim', 'edge_attr_dim'], | |||
| edge_label=edge_label) | |||
| def generate_graph(G, pi_p_forward, label_set): | |||
| G_new_list = [G.copy()] # all "best" graphs generated in this iteration. | |||
| # nx.draw_networkx(G) | |||
| # import matplotlib.pyplot as plt | |||
| # plt.show() | |||
| # print(pi_p_forward) | |||
| # update vertex labels. | |||
| # pre-compute h_i0 for each label. | |||
| # for label in get_node_labels(Gn, node_label): | |||
| # print(label) | |||
| # for nd in G.nodes(data=True): | |||
| # pass | |||
| if not ds_attrs['node_attr_dim']: # labels are symbolic | |||
| for ndi, (nd, _) in enumerate(G.nodes(data=True)): | |||
| h_i0_list = [] | |||
| label_list = [] | |||
| for label in label_set: | |||
| h_i0 = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][ndi] | |||
| if pi_i != node_ir and g.nodes[pi_i][node_label] == label: | |||
| h_i0 += 1 | |||
| h_i0_list.append(h_i0) | |||
| label_list.append(label) | |||
| # case when the node is to be removed. | |||
| if removeNodes: | |||
| h_i0_remove = 0 # @todo: maybe this can be added to the label_set above. | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][ndi] | |||
| if pi_i == node_ir: | |||
| h_i0_remove += 1 | |||
| h_i0_list.append(h_i0_remove) | |||
| label_list.append(label_r) | |||
| # get the best labels. | |||
| idx_max = np.argwhere(h_i0_list == np.max(h_i0_list)).flatten().tolist() | |||
| nlabel_best = [label_list[idx] for idx in idx_max] | |||
| # generate "best" graphs with regard to "best" node labels. | |||
| G_new_list_nd = [] | |||
| for g in G_new_list: # @todo: seems it can be simplified. The G_new_list will only contain 1 graph for now. | |||
| for nl in nlabel_best: | |||
| g_tmp = g.copy() | |||
| if nl == label_r: | |||
| g_tmp.remove_node(nd) | |||
| else: | |||
| g_tmp.nodes[nd][node_label] = nl | |||
| G_new_list_nd.append(g_tmp) | |||
| # nx.draw_networkx(g_tmp) | |||
| # import matplotlib.pyplot as plt | |||
| # plt.show() | |||
| # print(g_tmp.nodes(data=True)) | |||
| # print(g_tmp.edges(data=True)) | |||
| G_new_list = [ggg.copy() for ggg in G_new_list_nd] | |||
| else: # labels are non-symbolic | |||
| for ndi, (nd, _) in enumerate(G.nodes(data=True)): | |||
| Si_norm = 0 | |||
| phi_i_bar = np.array([0.0 for _ in range(ds_attrs['node_attr_dim'])]) | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][ndi] | |||
| if g.has_node(pi_i): #@todo: what if no g has node? phi_i_bar = 0? | |||
| Si_norm += 1 | |||
| phi_i_bar += np.array([float(itm) for itm in g.nodes[pi_i]['attributes']]) | |||
| phi_i_bar /= Si_norm | |||
| G_new_list[0].nodes[nd]['attributes'] = phi_i_bar | |||
| # for g in G_new_list: | |||
| # import matplotlib.pyplot as plt | |||
| # nx.draw(g, labels=nx.get_node_attributes(g, 'atom'), with_labels=True) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # update edge labels and adjacency matrix. | |||
| if ds_attrs['edge_labeled']: | |||
| G_new_list_edge = [] | |||
| for g_new in G_new_list: | |||
| nd_list = [n for n in g_new.nodes()] | |||
| g_tmp_list = [g_new.copy()] | |||
| for nd1i in range(nx.number_of_nodes(g_new)): | |||
| nd1 = nd_list[nd1i]# @todo: not just edges, but all pairs of nodes | |||
| for nd2i in range(nd1i + 1, nx.number_of_nodes(g_new)): | |||
| nd2 = nd_list[nd2i] | |||
| # for nd1, nd2, _ in g_new.edges(data=True): | |||
| h_ij0_list = [] | |||
| label_list = [] | |||
| # @todo: compute edge label set before. | |||
| for label in get_edge_labels(Gn_median, edge_label): | |||
| h_ij0 = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][nd1i] | |||
| pi_j = pi_p_forward[idx][nd2i] | |||
| h_ij0_p = (g.has_node(pi_i) and g.has_node(pi_j) and | |||
| g.has_edge(pi_i, pi_j) and | |||
| g.edges[pi_i, pi_j][edge_label] == label) | |||
| h_ij0 += h_ij0_p | |||
| h_ij0_list.append(h_ij0) | |||
| label_list.append(label) | |||
| # # case when the edge is to be removed. | |||
| # h_ij0_remove = 0 | |||
| # for idx, g in enumerate(Gn_median): | |||
| # pi_i = pi_p_forward[idx][nd1i] | |||
| # pi_j = pi_p_forward[idx][nd2i] | |||
| # if g.has_node(pi_i) and g.has_node(pi_j) and not | |||
| # g.has_edge(pi_i, pi_j): | |||
| # h_ij0_remove += 1 | |||
| # h_ij0_list.append(h_ij0_remove) | |||
| # label_list.append(label_r) | |||
| # get the best labels. | |||
| # choose all best graphs. | |||
| idx_max = np.argwhere(h_ij0_list == np.max(h_ij0_list)).flatten().tolist() | |||
| elabel_best = [label_list[idx] for idx in idx_max] | |||
| h_ij0_max = [h_ij0_list[idx] for idx in idx_max] | |||
| # generate "best" graphs with regard to "best" node labels. | |||
| G_new_list_ed = [] | |||
| for g_tmp in g_tmp_list: # @todo: seems it can be simplified. The G_new_list will only contain 1 graph for now. | |||
| for idxl, el in enumerate(elabel_best): | |||
| g_tmp_copy = g_tmp.copy() | |||
| # check whether a_ij is 0 or 1. | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][nd1i] | |||
| pi_j = pi_p_forward[idx][nd2i] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and \ | |||
| g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if h_ij0_max[idxl] > len(Gn_median) * c_er / c_es + \ | |||
| sij_norm * (1 - (c_er + c_ei) / c_es): | |||
| if not g_tmp_copy.has_edge(nd1, nd2): | |||
| g_tmp_copy.add_edge(nd1, nd2) | |||
| g_tmp_copy.edges[nd1, nd2][edge_label] = elabel_best[idxl] | |||
| else: | |||
| if g_tmp_copy.has_edge(nd1, nd2): | |||
| g_tmp_copy.remove_edge(nd1, nd2) | |||
| G_new_list_ed.append(g_tmp_copy) | |||
| g_tmp_list = [ggg.copy() for ggg in G_new_list_ed] | |||
| G_new_list_edge += g_tmp_list | |||
| G_new_list = [ggg.copy() for ggg in G_new_list_edge] | |||
| # # choose one of the best randomly. | |||
| # idx_max = np.argwhere(h_ij0_list == np.max(h_ij0_list)).flatten().tolist() | |||
| # h_ij0_max = h_ij0_list[idx_max[0]] | |||
| # idx_rdm = random.randint(0, len(idx_max) - 1) | |||
| # best_label = label_list[idx_max[idx_rdm]] | |||
| # | |||
| # # check whether a_ij is 0 or 1. | |||
| # sij_norm = 0 | |||
| # for idx, g in enumerate(Gn_median): | |||
| # pi_i = pi_p_forward[idx][nd1i] | |||
| # pi_j = pi_p_forward[idx][nd2i] | |||
| # if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| # sij_norm += 1 | |||
| # if h_ij0_max > len(Gn_median) * c_er / c_es + sij_norm * (1 - (c_er + c_ei) / c_es): | |||
| # if not g_new.has_edge(nd1, nd2): | |||
| # g_new.add_edge(nd1, nd2) | |||
| # g_new.edges[nd1, nd2][edge_label] = best_label | |||
| # else: | |||
| # if g_new.has_edge(nd1, nd2): | |||
| # g_new.remove_edge(nd1, nd2) | |||
| else: # if edges are unlabeled | |||
| # @todo: is this even right? G or g_tmp? check if the new one is right | |||
| # @todo: works only for undirected graphs. | |||
| for g_tmp in G_new_list: | |||
| nd_list = [n for n in g_tmp.nodes()] | |||
| for nd1i in range(nx.number_of_nodes(g_tmp)): | |||
| nd1 = nd_list[nd1i] | |||
| for nd2i in range(nd1i + 1, nx.number_of_nodes(g_tmp)): | |||
| nd2 = nd_list[nd2i] | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][nd1i] | |||
| pi_j = pi_p_forward[idx][nd2i] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if sij_norm > len(Gn_median) * c_er / (c_er + c_ei): | |||
| # @todo: should we consider if nd1 and nd2 in g_tmp? | |||
| # or just add the edge anyway? | |||
| if g_tmp.has_node(nd1) and g_tmp.has_node(nd2) \ | |||
| and not g_tmp.has_edge(nd1, nd2): | |||
| g_tmp.add_edge(nd1, nd2) | |||
| # else: # @todo: which to use? | |||
| elif sij_norm < len(Gn_median) * c_er / (c_er + c_ei): | |||
| if g_tmp.has_edge(nd1, nd2): | |||
| g_tmp.remove_edge(nd1, nd2) | |||
| # do not change anything when equal. | |||
| # for i, g in enumerate(G_new_list): | |||
| # import matplotlib.pyplot as plt | |||
| # nx.draw(g, labels=nx.get_node_attributes(g, 'atom'), with_labels=True) | |||
| ## plt.savefig("results/gk_iam/simple_two/xx" + str(i) + ".png", format="PNG") | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # # find the best graph generated in this iteration and update pi_p. | |||
| # @todo: should we update all graphs generated or just the best ones? | |||
| dis_list, pi_forward_list = median_distance(G_new_list, Gn_median, | |||
| **params_ged) | |||
| # @todo: should we remove the identical and connectivity check? | |||
| # Don't know which is faster. | |||
| if ds_attrs['node_attr_dim'] == 0 and ds_attrs['edge_attr_dim'] == 0: | |||
| G_new_list, idx_list = remove_duplicates(G_new_list) | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| dis_list = [dis_list[idx] for idx in idx_list] | |||
| # if connected == True: | |||
| # G_new_list, idx_list = remove_disconnected(G_new_list) | |||
| # pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| # idx_min_list = np.argwhere(dis_list == np.min(dis_list)).flatten().tolist() | |||
| # dis_min = dis_list[idx_min_tmp_list[0]] | |||
| # pi_forward_list = [pi_forward_list[idx] for idx in idx_min_list] | |||
| # G_new_list = [G_new_list[idx] for idx in idx_min_list] | |||
| # for g in G_new_list: | |||
| # import matplotlib.pyplot as plt | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| return G_new_list, pi_forward_list, dis_list | |||
| def best_median_graphs(Gn_candidate, pi_all_forward, dis_all): | |||
| idx_min_list = np.argwhere(dis_all == np.min(dis_all)).flatten().tolist() | |||
| dis_min = dis_all[idx_min_list[0]] | |||
| pi_forward_min_list = [pi_all_forward[idx] for idx in idx_min_list] | |||
| G_min_list = [Gn_candidate[idx] for idx in idx_min_list] | |||
| return G_min_list, pi_forward_min_list, dis_min | |||
| def iteration_proc(G, pi_p_forward, cur_sod): | |||
| G_list = [G] | |||
| pi_forward_list = [pi_p_forward] | |||
| old_sod = cur_sod * 2 | |||
| sod_list = [cur_sod] | |||
| dis_list = [cur_sod] | |||
| # iterations. | |||
| itr = 0 | |||
| # @todo: what if difference == 0? | |||
| # while itr < ite_max and (np.abs(old_sod - cur_sod) > epsilon or | |||
| # np.abs(old_sod - cur_sod) == 0): | |||
| while itr < ite_max and np.abs(old_sod - cur_sod) > epsilon: | |||
| # for itr in range(0, 5): # the convergence condition? | |||
| print('itr_iam is', itr) | |||
| G_new_list = [] | |||
| pi_forward_new_list = [] | |||
| dis_new_list = [] | |||
| for idx, g in enumerate(G_list): | |||
| label_set = get_node_labels(Gn_median + [g], node_label) | |||
| G_tmp_list, pi_forward_tmp_list, dis_tmp_list = generate_graph( | |||
| g, pi_forward_list[idx], label_set) | |||
| G_new_list += G_tmp_list | |||
| pi_forward_new_list += pi_forward_tmp_list | |||
| dis_new_list += dis_tmp_list | |||
| # @todo: need to remove duplicates here? | |||
| G_list = [ggg.copy() for ggg in G_new_list] | |||
| pi_forward_list = [pitem.copy() for pitem in pi_forward_new_list] | |||
| dis_list = dis_new_list[:] | |||
| old_sod = cur_sod | |||
| cur_sod = np.min(dis_list) | |||
| sod_list.append(cur_sod) | |||
| itr += 1 | |||
| # @todo: do we return all graphs or the best ones? | |||
| # get the best ones of the generated graphs. | |||
| G_list, pi_forward_list, dis_min = best_median_graphs( | |||
| G_list, pi_forward_list, dis_list) | |||
| if ds_attrs['node_attr_dim'] == 0 and ds_attrs['edge_attr_dim'] == 0: | |||
| G_list, idx_list = remove_duplicates(G_list) | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| # dis_list = [dis_list[idx] for idx in idx_list] | |||
| # import matplotlib.pyplot as plt | |||
| # for g in G_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| print('\nsods:', sod_list, '\n') | |||
| return G_list, pi_forward_list, dis_min | |||
| def remove_duplicates(Gn): | |||
| """Remove duplicate graphs from list. | |||
| """ | |||
| Gn_new = [] | |||
| idx_list = [] | |||
| for idx, g in enumerate(Gn): | |||
| dupl = False | |||
| for g_new in Gn_new: | |||
| if graph_isIdentical(g_new, g): | |||
| dupl = True | |||
| break | |||
| if not dupl: | |||
| Gn_new.append(g) | |||
| idx_list.append(idx) | |||
| return Gn_new, idx_list | |||
| def remove_disconnected(Gn): | |||
| """Remove disconnected graphs from list. | |||
| """ | |||
| Gn_new = [] | |||
| idx_list = [] | |||
| for idx, g in enumerate(Gn): | |||
| if nx.is_connected(g): | |||
| Gn_new.append(g) | |||
| idx_list.append(idx) | |||
| return Gn_new, idx_list | |||
| # phase 1: initilize. | |||
| # compute set-median. | |||
| dis_min = np.inf | |||
| dis_list, pi_forward_all = median_distance(Gn_candidate, Gn_median, | |||
| **params_ged) | |||
| # find all smallest distances. | |||
| if AllBestInit: # try all best init graphs. | |||
| idx_min_list = range(len(dis_list)) | |||
| dis_min = dis_list | |||
| else: | |||
| idx_min_list = np.argwhere(dis_list == np.min(dis_list)).flatten().tolist() | |||
| dis_min = [dis_list[idx_min_list[0]]] * len(idx_min_list) | |||
| # phase 2: iteration. | |||
| G_list = [] | |||
| dis_list = [] | |||
| pi_forward_list = [] | |||
| for idx_tmp, idx_min in enumerate(idx_min_list): | |||
| # print('idx_min is', idx_min) | |||
| G = Gn_candidate[idx_min].copy() | |||
| # list of edit operations. | |||
| pi_p_forward = pi_forward_all[idx_min] | |||
| # pi_p_backward = pi_all_backward[idx_min] | |||
| Gi_list, pi_i_forward_list, dis_i_min = iteration_proc(G, pi_p_forward, dis_min[idx_tmp]) | |||
| G_list += Gi_list | |||
| dis_list += [dis_i_min] * len(Gi_list) | |||
| pi_forward_list += pi_i_forward_list | |||
| if ds_attrs['node_attr_dim'] == 0 and ds_attrs['edge_attr_dim'] == 0: | |||
| G_list, idx_list = remove_duplicates(G_list) | |||
| dis_list = [dis_list[idx] for idx in idx_list] | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| if connected == True: | |||
| G_list_con, idx_list = remove_disconnected(G_list) | |||
| # if there is no connected graphs at all, then remain the disconnected ones. | |||
| if len(G_list_con) > 0: # @todo: ?????????????????????????? | |||
| G_list = G_list_con | |||
| dis_list = [dis_list[idx] for idx in idx_list] | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| # import matplotlib.pyplot as plt | |||
| # for g in G_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # get the best median graphs | |||
| # dis_list, pi_forward_list = median_distance(G_list, Gn_median, | |||
| # **params_ged) | |||
| G_min_list, pi_forward_min_list, dis_min = best_median_graphs( | |||
| G_list, pi_forward_list, dis_list) | |||
| # for g in G_min_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # randomly choose one graph. | |||
| idx_rdm = random.randint(0, len(G_min_list) - 1) | |||
| G_min_list = [G_min_list[idx_rdm]] | |||
| return G_min_list, dis_min | |||
| ############################################################################### | |||
| def iam(Gn, c_ei=3, c_er=3, c_es=1, node_label='atom', edge_label='bond_type', | |||
| connected=True): | |||
| """See my name, then you know what I do. | |||
| @@ -148,27 +565,42 @@ def iam(Gn, c_ei=3, c_er=3, c_es=1, node_label='atom', edge_label='bond_type', | |||
| return G | |||
| def GED(g1, g2, lib='gedlib'): | |||
| def GED(g1, g2, lib='gedlib', cost='CHEM_1', method='IPFP', saveGXL='benoit', | |||
| stabilizer='min'): | |||
| """ | |||
| Compute GED. | |||
| """ | |||
| if lib == 'gedlib': | |||
| # transform dataset to the 'xml' file as the GedLib required. | |||
| saveDataset([g1, g2], [None, None], group='xml', filename='ged_tmp/tmp') | |||
| # script.appel() | |||
| saveDataset([g1, g2], [None, None], group='xml', filename='ged_tmp/tmp', | |||
| xparams={'method': saveGXL}) | |||
| # script.appel() | |||
| script.PyRestartEnv() | |||
| script.PyLoadGXLGraph('ged_tmp/', 'ged_tmp/tmp.xml') | |||
| listID = script.PyGetGraphIds() | |||
| script.PySetEditCost("LETTER") #("CHEM_1") | |||
| script.PySetEditCost(cost) #("CHEM_1") | |||
| script.PyInitEnv() | |||
| script.PySetMethod("IPFP", "") | |||
| script.PySetMethod(method, "") | |||
| script.PyInitMethod() | |||
| g = listID[0] | |||
| h = listID[1] | |||
| script.PyRunMethod(g, h) | |||
| pi_forward, pi_backward = script.PyGetAllMap(g, h) | |||
| upper = script.PyGetUpperBound(g, h) | |||
| lower = script.PyGetLowerBound(g, h) | |||
| if stabilizer == None: | |||
| script.PyRunMethod(g, h) | |||
| pi_forward, pi_backward = script.PyGetAllMap(g, h) | |||
| upper = script.PyGetUpperBound(g, h) | |||
| lower = script.PyGetLowerBound(g, h) | |||
| elif stabilizer == 'min': | |||
| upper = np.inf | |||
| for itr in range(50): | |||
| script.PyRunMethod(g, h) | |||
| upper_tmp = script.PyGetUpperBound(g, h) | |||
| if upper_tmp < upper: | |||
| upper = upper_tmp | |||
| pi_forward, pi_backward = script.PyGetAllMap(g, h) | |||
| lower = script.PyGetLowerBound(g, h) | |||
| if upper == 0: | |||
| break | |||
| dis = upper | |||
| # make the map label correct (label remove map as np.inf) | |||
| @@ -177,12 +609,13 @@ def GED(g1, g2, lib='gedlib'): | |||
| nb1 = nx.number_of_nodes(g1) | |||
| nb2 = nx.number_of_nodes(g2) | |||
| pi_forward = [nodes2[pi] if pi < nb2 else np.inf for pi in pi_forward] | |||
| pi_backward = [nodes1[pi] if pi < nb1 else np.inf for pi in pi_backward] | |||
| pi_backward = [nodes1[pi] if pi < nb1 else np.inf for pi in pi_backward] | |||
| return dis, pi_forward, pi_backward | |||
| def median_distance(Gn, Gn_median, measure='ged', verbose=False): | |||
| def median_distance(Gn, Gn_median, measure='ged', verbose=False, | |||
| ged_cost='CHEM_1', ged_method='IPFP', saveGXL='benoit'): | |||
| dis_list = [] | |||
| pi_forward_list = [] | |||
| for idx, G in tqdm(enumerate(Gn), desc='computing median distances', | |||
| @@ -190,7 +623,8 @@ def median_distance(Gn, Gn_median, measure='ged', verbose=False): | |||
| dis_sum = 0 | |||
| pi_forward_list.append([]) | |||
| for G_p in Gn_median: | |||
| dis_tmp, pi_tmp_forward, pi_tmp_backward = GED(G, G_p) | |||
| dis_tmp, pi_tmp_forward, pi_tmp_backward = GED(G, G_p, | |||
| cost=ged_cost, method=ged_method, saveGXL=saveGXL) | |||
| pi_forward_list[idx].append(pi_tmp_forward) | |||
| dis_sum += dis_tmp | |||
| dis_list.append(dis_sum) | |||
| @@ -228,137 +662,13 @@ def test_iam_with_more_graphs_as_init(Gn, G_candidate, c_ei=3, c_er=3, c_es=1, | |||
| # list of edit operations. | |||
| pi_p_forward = pi_all_forward[idx_min] | |||
| pi_p_backward = pi_all_backward[idx_min] | |||
| # phase 2: iteration. | |||
| ds_attrs = get_dataset_attributes(Gn + [G], attr_names=['edge_labeled', 'node_attr_dim'], | |||
| edge_label=edge_label) | |||
| label_set = get_node_labels(Gn + [G], node_label) | |||
| for itr in range(0, 10): # @todo: the convergence condition? | |||
| G_new = G.copy() | |||
| # update vertex labels. | |||
| # pre-compute h_i0 for each label. | |||
| # for label in get_node_labels(Gn, node_label): | |||
| # print(label) | |||
| # for nd in G.nodes(data=True): | |||
| # pass | |||
| if not ds_attrs['node_attr_dim']: # labels are symbolic | |||
| for nd in G.nodes(): | |||
| h_i0_list = [] | |||
| label_list = [] | |||
| for label in label_set: | |||
| h_i0 = 0 | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd] | |||
| if g.has_node(pi_i) and g.nodes[pi_i][node_label] == label: | |||
| h_i0 += 1 | |||
| h_i0_list.append(h_i0) | |||
| label_list.append(label) | |||
| # choose one of the best randomly. | |||
| idx_max = np.argwhere(h_i0_list == np.max(h_i0_list)).flatten().tolist() | |||
| idx_rdm = random.randint(0, len(idx_max) - 1) | |||
| G_new.nodes[nd][node_label] = label_list[idx_max[idx_rdm]] | |||
| else: # labels are non-symbolic | |||
| for nd in G.nodes(): | |||
| Si_norm = 0 | |||
| phi_i_bar = np.array([0.0 for _ in range(ds_attrs['node_attr_dim'])]) | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd] | |||
| if g.has_node(pi_i): #@todo: what if no g has node? phi_i_bar = 0? | |||
| Si_norm += 1 | |||
| phi_i_bar += np.array([float(itm) for itm in g.nodes[pi_i]['attributes']]) | |||
| phi_i_bar /= Si_norm | |||
| G_new.nodes[nd]['attributes'] = phi_i_bar | |||
| # update edge labels and adjacency matrix. | |||
| if ds_attrs['edge_labeled']: | |||
| for nd1, nd2, _ in G.edges(data=True): | |||
| h_ij0_list = [] | |||
| label_list = [] | |||
| for label in get_edge_labels(Gn, edge_label): | |||
| h_ij0 = 0 | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd1] | |||
| pi_j = pi_p_forward[idx][nd2] | |||
| h_ij0_p = (g.has_node(pi_i) and g.has_node(pi_j) and | |||
| g.has_edge(pi_i, pi_j) and | |||
| g.edges[pi_i, pi_j][edge_label] == label) | |||
| h_ij0 += h_ij0_p | |||
| h_ij0_list.append(h_ij0) | |||
| label_list.append(label) | |||
| # choose one of the best randomly. | |||
| idx_max = np.argwhere(h_ij0_list == np.max(h_ij0_list)).flatten().tolist() | |||
| h_ij0_max = h_ij0_list[idx_max[0]] | |||
| idx_rdm = random.randint(0, len(idx_max) - 1) | |||
| best_label = label_list[idx_max[idx_rdm]] | |||
| # check whether a_ij is 0 or 1. | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd1] | |||
| pi_j = pi_p_forward[idx][nd2] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if h_ij0_max > len(Gn) * c_er / c_es + sij_norm * (1 - (c_er + c_ei) / c_es): | |||
| if not G_new.has_edge(nd1, nd2): | |||
| G_new.add_edge(nd1, nd2) | |||
| G_new.edges[nd1, nd2][edge_label] = best_label | |||
| else: | |||
| if G_new.has_edge(nd1, nd2): | |||
| G_new.remove_edge(nd1, nd2) | |||
| else: # if edges are unlabeled | |||
| # @todo: works only for undirected graphs. | |||
| for nd1 in range(nx.number_of_nodes(G)): | |||
| for nd2 in range(nd1 + 1, nx.number_of_nodes(G)): | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd1] | |||
| pi_j = pi_p_forward[idx][nd2] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if sij_norm > len(Gn) * c_er / (c_er + c_ei): | |||
| if not G_new.has_edge(nd1, nd2): | |||
| G_new.add_edge(nd1, nd2) | |||
| elif sij_norm < len(Gn) * c_er / (c_er + c_ei): | |||
| if G_new.has_edge(nd1, nd2): | |||
| G_new.remove_edge(nd1, nd2) | |||
| # do not change anything when equal. | |||
| G = G_new.copy() | |||
| # update pi_p | |||
| pi_p_forward = [] | |||
| for G_p in Gn: | |||
| dist_tmp, pi_tmp_forward, pi_tmp_backward = GED(G, G_p) | |||
| pi_p_forward.append(pi_tmp_forward) | |||
| return G | |||
| def test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations( | |||
| Gn_median, Gn_candidate, c_ei=3, c_er=3, c_es=1, node_label='atom', | |||
| edge_label='bond_type', connected=False): | |||
| """See my name, then you know what I do. | |||
| """ | |||
| from tqdm import tqdm | |||
| # Gn_median = Gn_median[0:10] | |||
| # Gn_median = [nx.convert_node_labels_to_integers(g) for g in Gn_median] | |||
| node_ir = np.inf # corresponding to the node remove and insertion. | |||
| label_r = 'thanksdanny' # the label for node remove. # @todo: make this label unrepeatable. | |||
| ds_attrs = get_dataset_attributes(Gn_median + Gn_candidate, | |||
| attr_names=['edge_labeled', 'node_attr_dim', 'edge_attr_dim'], | |||
| # phase 2: iteration. | |||
| ds_attrs = get_dataset_attributes(Gn + [G], attr_names=['edge_labeled', 'node_attr_dim'], | |||
| edge_label=edge_label) | |||
| ite_max = 50 | |||
| epsilon = 0.001 | |||
| def generate_graph(G, pi_p_forward, label_set): | |||
| G_new_list = [G.copy()] # all "best" graphs generated in this iteration. | |||
| # nx.draw_networkx(G) | |||
| # import matplotlib.pyplot as plt | |||
| # plt.show() | |||
| # print(pi_p_forward) | |||
| label_set = get_node_labels(Gn + [G], node_label) | |||
| for itr in range(0, 10): # @todo: the convergence condition? | |||
| G_new = G.copy() | |||
| # update vertex labels. | |||
| # pre-compute h_i0 for each label. | |||
| # for label in get_node_labels(Gn, node_label): | |||
| @@ -366,65 +676,41 @@ def test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations( | |||
| # for nd in G.nodes(data=True): | |||
| # pass | |||
| if not ds_attrs['node_attr_dim']: # labels are symbolic | |||
| for ndi, (nd, _) in enumerate(G.nodes(data=True)): | |||
| for nd in G.nodes(): | |||
| h_i0_list = [] | |||
| label_list = [] | |||
| for label in label_set: | |||
| h_i0 = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][ndi] | |||
| if pi_i != node_ir and g.nodes[pi_i][node_label] == label: | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd] | |||
| if g.has_node(pi_i) and g.nodes[pi_i][node_label] == label: | |||
| h_i0 += 1 | |||
| h_i0_list.append(h_i0) | |||
| label_list.append(label) | |||
| # case when the node is to be removed. | |||
| h_i0_remove = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][ndi] | |||
| if pi_i == node_ir: | |||
| h_i0_remove += 1 | |||
| h_i0_list.append(h_i0_remove) | |||
| label_list.append(label_r) | |||
| # get the best labels. | |||
| # choose one of the best randomly. | |||
| idx_max = np.argwhere(h_i0_list == np.max(h_i0_list)).flatten().tolist() | |||
| nlabel_best = [label_list[idx] for idx in idx_max] | |||
| # generate "best" graphs with regard to "best" node labels. | |||
| G_new_list_nd = [] | |||
| for g in G_new_list: # @todo: seems it can be simplified. The G_new_list will only contain 1 graph for now. | |||
| for nl in nlabel_best: | |||
| g_tmp = g.copy() | |||
| if nl == label_r: | |||
| g_tmp.remove_node(nd) | |||
| else: | |||
| g_tmp.nodes[nd][node_label] = nl | |||
| G_new_list_nd.append(g_tmp) | |||
| # nx.draw_networkx(g_tmp) | |||
| # import matplotlib.pyplot as plt | |||
| # plt.show() | |||
| # print(g_tmp.nodes(data=True)) | |||
| # print(g_tmp.edges(data=True)) | |||
| G_new_list = G_new_list_nd[:] | |||
| idx_rdm = random.randint(0, len(idx_max) - 1) | |||
| G_new.nodes[nd][node_label] = label_list[idx_max[idx_rdm]] | |||
| else: # labels are non-symbolic | |||
| for ndi, (nd, _) in enumerate(G.nodes(data=True)): | |||
| for nd in G.nodes(): | |||
| Si_norm = 0 | |||
| phi_i_bar = np.array([0.0 for _ in range(ds_attrs['node_attr_dim'])]) | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][ndi] | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd] | |||
| if g.has_node(pi_i): #@todo: what if no g has node? phi_i_bar = 0? | |||
| Si_norm += 1 | |||
| phi_i_bar += np.array([float(itm) for itm in g.nodes[pi_i]['attributes']]) | |||
| phi_i_bar /= Si_norm | |||
| G_new_list[0].nodes[nd]['attributes'] = phi_i_bar | |||
| G_new.nodes[nd]['attributes'] = phi_i_bar | |||
| # update edge labels and adjacency matrix. | |||
| if ds_attrs['edge_labeled']: | |||
| for nd1, nd2, _ in G.edges(data=True): | |||
| h_ij0_list = [] | |||
| label_list = [] | |||
| for label in get_edge_labels(Gn_median, edge_label): | |||
| for label in get_edge_labels(Gn, edge_label): | |||
| h_ij0 = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd1] | |||
| pi_j = pi_p_forward[idx][nd2] | |||
| h_ij0_p = (g.has_node(pi_i) and g.has_node(pi_j) and | |||
| @@ -441,12 +727,12 @@ def test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations( | |||
| # check whether a_ij is 0 or 1. | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd1] | |||
| pi_j = pi_p_forward[idx][nd2] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if h_ij0_max > len(Gn_median) * c_er / c_es + sij_norm * (1 - (c_er + c_ei) / c_es): | |||
| if h_ij0_max > len(Gn) * c_er / c_es + sij_norm * (1 - (c_er + c_ei) / c_es): | |||
| if not G_new.has_edge(nd1, nd2): | |||
| G_new.add_edge(nd1, nd2) | |||
| G_new.edges[nd1, nd2][edge_label] = best_label | |||
| @@ -455,197 +741,36 @@ def test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations( | |||
| G_new.remove_edge(nd1, nd2) | |||
| else: # if edges are unlabeled | |||
| # @todo: works only for undirected graphs. | |||
| nd_list = [n for n in G.nodes()] | |||
| for g_tmp in G_new_list: | |||
| for nd1i in range(nx.number_of_nodes(G)): | |||
| nd1 = nd_list[nd1i] | |||
| for nd2i in range(nd1i + 1, nx.number_of_nodes(G)): | |||
| nd2 = nd_list[nd2i] | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn_median): | |||
| pi_i = pi_p_forward[idx][nd1i] | |||
| pi_j = pi_p_forward[idx][nd2i] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if sij_norm > len(Gn_median) * c_er / (c_er + c_ei): | |||
| # @todo: should we consider if nd1 and nd2 in g_tmp? | |||
| # or just add the edge anyway? | |||
| if g_tmp.has_node(nd1) and g_tmp.has_node(nd2) \ | |||
| and not g_tmp.has_edge(nd1, nd2): | |||
| g_tmp.add_edge(nd1, nd2) | |||
| elif sij_norm < len(Gn_median) * c_er / (c_er + c_ei): | |||
| if g_tmp.has_edge(nd1, nd2): | |||
| g_tmp.remove_edge(nd1, nd2) | |||
| # do not change anything when equal. | |||
| # # find the best graph generated in this iteration and update pi_p. | |||
| # @todo: should we update all graphs generated or just the best ones? | |||
| dis_list, pi_forward_list = median_distance(G_new_list, Gn_median) | |||
| # @todo: should we remove the identical and connectivity check? | |||
| # Don't know which is faster. | |||
| if ds_attrs['node_attr_dim'] == 0 and ds_attrs['edge_attr_dim'] == 0: | |||
| G_new_list, idx_list = remove_duplicates(G_new_list) | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| dis_list = [dis_list[idx] for idx in idx_list] | |||
| # if connected == True: | |||
| # G_new_list, idx_list = remove_disconnected(G_new_list) | |||
| # pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| # idx_min_list = np.argwhere(dis_list == np.min(dis_list)).flatten().tolist() | |||
| # dis_min = dis_list[idx_min_tmp_list[0]] | |||
| # pi_forward_list = [pi_forward_list[idx] for idx in idx_min_list] | |||
| # G_new_list = [G_new_list[idx] for idx in idx_min_list] | |||
| # for g in G_new_list: | |||
| # import matplotlib.pyplot as plt | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| return G_new_list, pi_forward_list, dis_list | |||
| def best_median_graphs(Gn_candidate, pi_all_forward, dis_all): | |||
| idx_min_list = np.argwhere(dis_all == np.min(dis_all)).flatten().tolist() | |||
| dis_min = dis_all[idx_min_list[0]] | |||
| pi_forward_min_list = [pi_all_forward[idx] for idx in idx_min_list] | |||
| G_min_list = [Gn_candidate[idx] for idx in idx_min_list] | |||
| return G_min_list, pi_forward_min_list, dis_min | |||
| def iteration_proc(G, pi_p_forward, cur_sod): | |||
| G_list = [G] | |||
| pi_forward_list = [pi_p_forward] | |||
| old_sod = cur_sod * 2 | |||
| sod_list = [cur_sod] | |||
| # iterations. | |||
| itr = 0 | |||
| while itr < ite_max and np.abs(old_sod - cur_sod) > epsilon: | |||
| # for itr in range(0, 5): # the convergence condition? | |||
| print('itr is', itr) | |||
| G_new_list = [] | |||
| pi_forward_new_list = [] | |||
| dis_new_list = [] | |||
| for idx, G in enumerate(G_list): | |||
| label_set = get_node_labels(Gn_median + [G], node_label) | |||
| G_tmp_list, pi_forward_tmp_list, dis_tmp_list = generate_graph( | |||
| G, pi_forward_list[idx], label_set) | |||
| G_new_list += G_tmp_list | |||
| pi_forward_new_list += pi_forward_tmp_list | |||
| dis_new_list += dis_tmp_list | |||
| G_list = G_new_list[:] | |||
| pi_forward_list = pi_forward_new_list[:] | |||
| dis_list = dis_new_list[:] | |||
| old_sod = cur_sod | |||
| cur_sod = np.min(dis_list) | |||
| sod_list.append(cur_sod) | |||
| itr += 1 | |||
| # @todo: do we return all graphs or the best ones? | |||
| # get the best ones of the generated graphs. | |||
| G_list, pi_forward_list, dis_min = best_median_graphs( | |||
| G_list, pi_forward_list, dis_list) | |||
| for nd1 in range(nx.number_of_nodes(G)): | |||
| for nd2 in range(nd1 + 1, nx.number_of_nodes(G)): | |||
| sij_norm = 0 | |||
| for idx, g in enumerate(Gn): | |||
| pi_i = pi_p_forward[idx][nd1] | |||
| pi_j = pi_p_forward[idx][nd2] | |||
| if g.has_node(pi_i) and g.has_node(pi_j) and g.has_edge(pi_i, pi_j): | |||
| sij_norm += 1 | |||
| if sij_norm > len(Gn) * c_er / (c_er + c_ei): | |||
| if not G_new.has_edge(nd1, nd2): | |||
| G_new.add_edge(nd1, nd2) | |||
| elif sij_norm < len(Gn) * c_er / (c_er + c_ei): | |||
| if G_new.has_edge(nd1, nd2): | |||
| G_new.remove_edge(nd1, nd2) | |||
| # do not change anything when equal. | |||
| G = G_new.copy() | |||
| if ds_attrs['node_attr_dim'] == 0 and ds_attrs['edge_attr_dim'] == 0: | |||
| G_list, idx_list = remove_duplicates(G_list) | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| # dis_list = [dis_list[idx] for idx in idx_list] | |||
| # import matplotlib.pyplot as plt | |||
| # for g in G_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| print('\nsods:', sod_list, '\n') | |||
| return G_list, pi_forward_list, dis_min | |||
| def remove_duplicates(Gn): | |||
| """Remove duplicate graphs from list. | |||
| """ | |||
| Gn_new = [] | |||
| idx_list = [] | |||
| for idx, g in enumerate(Gn): | |||
| dupl = False | |||
| for g_new in Gn_new: | |||
| if graph_isIdentical(g_new, g): | |||
| dupl = True | |||
| break | |||
| if not dupl: | |||
| Gn_new.append(g) | |||
| idx_list.append(idx) | |||
| return Gn_new, idx_list | |||
| # update pi_p | |||
| pi_p_forward = [] | |||
| for G_p in Gn: | |||
| dist_tmp, pi_tmp_forward, pi_tmp_backward = GED(G, G_p) | |||
| pi_p_forward.append(pi_tmp_forward) | |||
| def remove_disconnected(Gn): | |||
| """Remove disconnected graphs from list. | |||
| """ | |||
| Gn_new = [] | |||
| idx_list = [] | |||
| for idx, g in enumerate(Gn): | |||
| if nx.is_connected(g): | |||
| Gn_new.append(g) | |||
| idx_list.append(idx) | |||
| return Gn_new, idx_list | |||
| return G | |||
| ############################################################################### | |||
| # phase 1: initilize. | |||
| # compute set-median. | |||
| dis_min = np.inf | |||
| dis_list, pi_forward_all = median_distance(Gn_candidate, Gn_median) | |||
| # find all smallest distances. | |||
| idx_min_list = np.argwhere(dis_list == np.min(dis_list)).flatten().tolist() | |||
| dis_min = dis_list[idx_min_list[0]] | |||
| # phase 2: iteration. | |||
| G_list = [] | |||
| dis_list = [] | |||
| pi_forward_list = [] | |||
| for idx_min in idx_min_list: | |||
| # print('idx_min is', idx_min) | |||
| G = Gn_candidate[idx_min].copy() | |||
| # list of edit operations. | |||
| pi_p_forward = pi_forward_all[idx_min] | |||
| # pi_p_backward = pi_all_backward[idx_min] | |||
| Gi_list, pi_i_forward_list, dis_i_min = iteration_proc(G, pi_p_forward, dis_min) | |||
| G_list += Gi_list | |||
| dis_list.append(dis_i_min) | |||
| pi_forward_list += pi_i_forward_list | |||
| if ds_attrs['node_attr_dim'] == 0 and ds_attrs['edge_attr_dim'] == 0: | |||
| G_list, idx_list = remove_duplicates(G_list) | |||
| dis_list = [dis_list[idx] for idx in idx_list] | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| if connected == True: | |||
| G_list_con, idx_list = remove_disconnected(G_list) | |||
| # if there is no connected graphs at all, then remain the disconnected ones. | |||
| if len(G_list_con) > 0: # @todo: ?????????????????????????? | |||
| G_list = G_list_con | |||
| dis_list = [dis_list[idx] for idx in idx_list] | |||
| pi_forward_list = [pi_forward_list[idx] for idx in idx_list] | |||
| # import matplotlib.pyplot as plt | |||
| # for g in G_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # get the best median graphs | |||
| # dis_list, pi_forward_list = median_distance(G_list, Gn_median) | |||
| G_min_list, pi_forward_min_list, dis_min = best_median_graphs( | |||
| G_list, pi_forward_list, dis_list) | |||
| # for g in G_min_list: | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| return G_min_list, dis_min | |||
| if __name__ == '__main__': | |||
| @@ -5,10 +5,10 @@ import numpy as np | |||
| import networkx as nx | |||
| import time | |||
| #import librariesImport | |||
| #import script | |||
| #sys.path.insert(0, "/home/bgauzere/dev/optim-graphes/") | |||
| #import pygraph | |||
| import librariesImport | |||
| import script | |||
| sys.path.insert(0, "/home/bgauzere/dev/optim-graphes/") | |||
| import pygraph | |||
| from pygraph.utils.graphfiles import loadDataset | |||
| def replace_graph_in_env(script, graph, old_id, label='median'): | |||
| @@ -191,28 +191,28 @@ def compute_median_set(script,listID): | |||
| return median_set_index, sod | |||
| #if __name__ == "__main__": | |||
| # #Chargement du dataset | |||
| # script.PyLoadGXLGraph('/home/bgauzere/dev/gedlib/data/datasets/Letter/HIGH/', '/home/bgauzere/dev/gedlib/data/collections/Letter_Z.xml') | |||
| # script.PySetEditCost("LETTER") | |||
| # script.PyInitEnv() | |||
| # script.PySetMethod("IPFP", "") | |||
| # script.PyInitMethod() | |||
| # | |||
| # dataset,my_y = pygraph.utils.graphfiles.loadDataset("/home/bgauzere/dev/gedlib/data/datasets/Letter/HIGH/Letter_Z.cxl") | |||
| # | |||
| # listID = script.PyGetAllGraphIds() | |||
| # median, sod = compute_median(script,listID,dataset,verbose=True) | |||
| # | |||
| # print(sod) | |||
| # draw_Letter_graph(median) | |||
| if __name__ == '__main__': | |||
| # test draw_Letter_graph | |||
| ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| 'extra_params': {}} # node nsymb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| print(y_all) | |||
| for g in Gn: | |||
| draw_Letter_graph(g) | |||
| if __name__ == "__main__": | |||
| #Chargement du dataset | |||
| script.PyLoadGXLGraph('/home/bgauzere/dev/gedlib/data/datasets/Letter/HIGH/', '/home/bgauzere/dev/gedlib/data/collections/Letter_Z.xml') | |||
| script.PySetEditCost("LETTER") | |||
| script.PyInitEnv() | |||
| script.PySetMethod("IPFP", "") | |||
| script.PyInitMethod() | |||
| dataset,my_y = pygraph.utils.graphfiles.loadDataset("/home/bgauzere/dev/gedlib/data/datasets/Letter/HIGH/Letter_Z.cxl") | |||
| listID = script.PyGetAllGraphIds() | |||
| median, sod = compute_median(script,listID,dataset,verbose=True) | |||
| print(sod) | |||
| draw_Letter_graph(median) | |||
| #if __name__ == '__main__': | |||
| # # test draw_Letter_graph | |||
| # ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| # 'extra_params': {}} # node nsymb | |||
| # Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # print(y_all) | |||
| # for g in Gn: | |||
| # draw_Letter_graph(g) | |||
| @@ -25,14 +25,16 @@ import functools | |||
| from pygraph.utils.kernels import deltakernel, gaussiankernel, kernelproduct | |||
| from pygraph.kernels.structuralspKernel import structuralspkernel | |||
| from gk_iam import dis_gstar | |||
| def compute_kernel(Gn, graph_kernel, verbose): | |||
| if graph_kernel == 'marginalizedkernel': | |||
| Kmatrix, _ = marginalizedkernel(Gn, node_label='atom', edge_label=None, | |||
| p_quit=0.03, n_iteration=20, remove_totters=False, | |||
| p_quit=0.03, n_iteration=10, remove_totters=False, | |||
| n_jobs=multiprocessing.cpu_count(), verbose=verbose) | |||
| elif graph_kernel == 'untilhpathkernel': | |||
| Kmatrix, _ = untilhpathkernel(Gn, node_label='atom', edge_label='bond_type', | |||
| Kmatrix, _ = untilhpathkernel(Gn, node_label='atom', edge_label=None, | |||
| depth=10, k_func='MinMax', compute_method='trie', | |||
| n_jobs=multiprocessing.cpu_count(), verbose=verbose) | |||
| elif graph_kernel == 'spkernel': | |||
| @@ -47,34 +49,167 @@ def compute_kernel(Gn, graph_kernel, verbose): | |||
| n_jobs=multiprocessing.cpu_count(), verbose=verbose) | |||
| # normalization | |||
| # Kmatrix_diag = Kmatrix.diagonal().copy() | |||
| # for i in range(len(Kmatrix)): | |||
| # for j in range(i, len(Kmatrix)): | |||
| # Kmatrix[i][j] /= np.sqrt(Kmatrix_diag[i] * Kmatrix_diag[j]) | |||
| # Kmatrix[j][i] = Kmatrix[i][j] | |||
| Kmatrix_diag = Kmatrix.diagonal().copy() | |||
| for i in range(len(Kmatrix)): | |||
| for j in range(i, len(Kmatrix)): | |||
| Kmatrix[i][j] /= np.sqrt(Kmatrix_diag[i] * Kmatrix_diag[j]) | |||
| Kmatrix[j][i] = Kmatrix[i][j] | |||
| return Kmatrix | |||
| def random_preimage(Gn_init, Gn_median, alpha, idx_gi, Kmatrix, k, r_max, l, gkernel): | |||
| Gn_init = [nx.convert_node_labels_to_integers(g) for g in Gn_init] | |||
| # compute k nearest neighbors of phi in DN. | |||
| dis_list = [] # distance between g_star and each graph. | |||
| term3 = 0 | |||
| for i1, a1 in enumerate(alpha): | |||
| for i2, a2 in enumerate(alpha): | |||
| term3 += a1 * a2 * Kmatrix[idx_gi[i1], idx_gi[i2]] | |||
| for ig, g in tqdm(enumerate(Gn_init), desc='computing distances', file=sys.stdout): | |||
| dtemp = dis_gstar(ig, idx_gi, alpha, Kmatrix, term3=term3) | |||
| dis_list.append(dtemp) | |||
| # print(np.max(dis_list)) | |||
| # print(np.min(dis_list)) | |||
| # print(np.min([item for item in dis_list if item != 0])) | |||
| # print(np.mean(dis_list)) | |||
| # sort | |||
| sort_idx = np.argsort(dis_list) | |||
| dis_gs = [dis_list[idis] for idis in sort_idx[0:k]] # the k shortest distances | |||
| nb_best = len(np.argwhere(dis_gs == dis_gs[0]).flatten().tolist()) | |||
| g0hat_list = [Gn_init[idx] for idx in sort_idx[0:nb_best]] # the nearest neighbors of phi in DN | |||
| if dis_gs[0] == 0: # the exact pre-image. | |||
| print('The exact pre-image is found from the input dataset.') | |||
| return 0, g0hat_list[0], 0 | |||
| dhat = dis_gs[0] # the nearest distance | |||
| # ghat_list = [g.copy() for g in g0hat_list] | |||
| # for g in ghat_list: | |||
| # draw_Letter_graph(g) | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| Gk = [Gn_init[ig].copy() for ig in sort_idx[0:k]] # the k nearest neighbors | |||
| # for gi in Gk: | |||
| ## nx.draw_networkx(gi) | |||
| ## plt.show() | |||
| # draw_Letter_graph(g) | |||
| # print(gi.nodes(data=True)) | |||
| # print(gi.edges(data=True)) | |||
| Gs_nearest = [g.copy() for g in Gk] | |||
| gihat_list = [] | |||
| dihat_list = [] | |||
| # i = 1 | |||
| r = 0 | |||
| # sod_list = [dhat] | |||
| # found = False | |||
| nb_updated = 0 | |||
| g_best = [] | |||
| while r < r_max: | |||
| print('\nr =', r) | |||
| print('itr for gk =', nb_updated, '\n') | |||
| found = False | |||
| dis_bests = dis_gs + dihat_list | |||
| # @todo what if the log is negetive? how to choose alpha (scalar)? | |||
| fdgs_list = np.array(dis_bests) | |||
| if np.min(fdgs_list) < 1: | |||
| fdgs_list /= np.min(dis_bests) | |||
| fdgs_list = [int(item) for item in np.ceil(np.log(fdgs_list))] | |||
| if np.min(fdgs_list) < 1: | |||
| fdgs_list = np.array(fdgs_list) + 1 | |||
| for ig, gs in enumerate(Gs_nearest + gihat_list): | |||
| # nx.draw_networkx(gs) | |||
| # plt.show() | |||
| for trail in range(0, l): | |||
| # for trail in tqdm(range(0, l), desc='l loops', file=sys.stdout): | |||
| # add and delete edges. | |||
| gtemp = gs.copy() | |||
| np.random.seed() | |||
| # which edges to change. | |||
| # @todo: should we use just half of the adjacency matrix for undirected graphs? | |||
| nb_vpairs = nx.number_of_nodes(gs) * (nx.number_of_nodes(gs) - 1) | |||
| # @todo: what if fdgs is bigger than nb_vpairs? | |||
| idx_change = random.sample(range(nb_vpairs), fdgs_list[ig] if | |||
| fdgs_list[ig] < nb_vpairs else nb_vpairs) | |||
| # idx_change = np.random.randint(0, nx.number_of_nodes(gs) * | |||
| # (nx.number_of_nodes(gs) - 1), fdgs) | |||
| for item in idx_change: | |||
| node1 = int(item / (nx.number_of_nodes(gs) - 1)) | |||
| node2 = (item - node1 * (nx.number_of_nodes(gs) - 1)) | |||
| if node2 >= node1: # skip the self pair. | |||
| node2 += 1 | |||
| # @todo: is the randomness correct? | |||
| if not gtemp.has_edge(node1, node2): | |||
| gtemp.add_edge(node1, node2) | |||
| # nx.draw_networkx(gs) | |||
| # plt.show() | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| else: | |||
| gtemp.remove_edge(node1, node2) | |||
| # nx.draw_networkx(gs) | |||
| # plt.show() | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| # compute distance between \psi and the new generated graph. | |||
| # knew = marginalizedkernel([gtemp, g1, g2], node_label='atom', edge_label=None, | |||
| # p_quit=lmbda, n_iteration=20, remove_totters=False, | |||
| # n_jobs=multiprocessing.cpu_count(), verbose=False) | |||
| knew = compute_kernel([gtemp] + Gn_median, gkernel, verbose=False) | |||
| dnew = dis_gstar(0, [1, 2], alpha, knew, withterm3=False) | |||
| if dnew <= dhat: # @todo: the new distance is smaller or also equal? | |||
| if dnew < dhat: | |||
| print('\nI am smaller!') | |||
| print('ig =', str(ig), ', l =', str(trail)) | |||
| print(dhat, '->', dnew) | |||
| nb_updated += 1 | |||
| elif dnew == dhat: | |||
| print('I am equal!') | |||
| # nx.draw_networkx(gtemp) | |||
| # plt.show() | |||
| # print(gtemp.nodes(data=True)) | |||
| # print(gtemp.edges(data=True)) | |||
| dhat = dnew | |||
| gnew = gtemp.copy() | |||
| found = True # found better graph. | |||
| if found: | |||
| r = 0 | |||
| gihat_list = [gnew] | |||
| dihat_list = [dhat] | |||
| else: | |||
| r += 1 | |||
| # dis_best.append(dhat) | |||
| g_best = (g0hat_list[0] if len(gihat_list) == 0 else gihat_list[0]) | |||
| return dhat, g_best, nb_updated | |||
| # return 0, 0, 0 | |||
| if __name__ == '__main__': | |||
| # ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| # 'extra_params': {}} # node/edge symb | |||
| # ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| # 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/monoterpenoides/trainset_9.ds', | |||
| # 'extra_params': {}} | |||
| ds = {'name': 'Acyclic', 'dataset': '../datasets/acyclic/dataset_bps.ds', | |||
| 'extra_params': {}} # node symb | |||
| # ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| # 'extra_params': {}} # node/edge symb | |||
| ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/monoterpenoides/trainset_9.ds', | |||
| # 'extra_params': {}} | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/acyclic/dataset_bps.ds', | |||
| # 'extra_params': {}} # node symb | |||
| DN, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| #DN = DN[0:10] | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 10 # recursions | |||
| r_max = 3 # 10 # iteration limit. | |||
| l = 500 | |||
| alpha_range = np.linspace(0.5, 0.5, 1) | |||
| #alpha_range = np.linspace(0.1, 0.9, 9) | |||
| k = 5 # k nearest neighbors | |||
| k = 10 # 5 # k nearest neighbors | |||
| # randomly select two molecules | |||
| #np.random.seed(1) | |||
| @@ -245,6 +245,9 @@ def test_remove_bests(Gn, gkernel): | |||
| print(g.edges(data=True)) | |||
| ############################################################################### | |||
| # Tests on dataset Letter-H. | |||
| def test_gkiam_letter_h(): | |||
| from gk_iam import gk_iam_nearest_multi, compute_kernel | |||
| from iam import median_distance | |||
| @@ -263,8 +266,10 @@ def test_gkiam_letter_h(): | |||
| # classify graphs according to letters. | |||
| idx_dict = get_same_item_indices(y_all) | |||
| time_list = [] | |||
| sod_list = [] | |||
| sod_min_list = [] | |||
| sod_ks_min_list = [] | |||
| sod_gs_list = [] | |||
| sod_gs_min_list = [] | |||
| nb_updated_list = [] | |||
| for letter in idx_dict: | |||
| print('\n-------------------------------------------------------\n') | |||
| Gn_let = [Gn[i].copy() for i in idx_dict[letter]] | |||
| @@ -280,10 +285,10 @@ def test_gkiam_letter_h(): | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('alpha =', alpha) | |||
| dhat, ghat_list = gk_iam_nearest_multi(Gn_let, Gn_let, [alpha] * len(Gn_let), | |||
| range(len(Gn_let), len(Gn_mix)), km, | |||
| k, r_max, gkernel, c_ei=1.7, | |||
| c_er=1.7, c_es=1.7) | |||
| dhat, ghat_list, sod_ks, nb_updated = gk_iam_nearest_multi(Gn_let, | |||
| Gn_let, [alpha] * len(Gn_let), range(len(Gn_let), len(Gn_mix)), | |||
| km, k, r_max, gkernel, c_ei=1.7, c_er=1.7, c_es=1.7, | |||
| ged_cost='LETTER', ged_method='IPFP', saveGXL='gedlib-letter') | |||
| dis_best.append(dhat) | |||
| g_best.append(ghat_list) | |||
| time_list.append(time.time() - time0) | |||
| @@ -300,13 +305,18 @@ def test_gkiam_letter_h(): | |||
| print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. (alpha range not considered.) | |||
| sod_tmp, _ = median_distance(g_best[0], Gn_let) | |||
| sod_list.append(sod_tmp) | |||
| sod_min_list.append(np.min(sod_tmp)) | |||
| sod_tmp, _ = median_distance(g_best[0], Gn_let, ged_cost='LETTER', | |||
| ged_method='IPFP', saveGXL='gedlib-letter') | |||
| sod_gs_list.append(sod_tmp) | |||
| sod_gs_min_list.append(np.min(sod_tmp)) | |||
| sod_ks_min_list.append(sod_ks) | |||
| nb_updated_list.append(nb_updated) | |||
| print('\nsods in graph space: ', sod_list) | |||
| print('\nsmallest sod in graph space for each letter: ', sod_min_list) | |||
| print('\nsods in graph space: ', sod_gs_list) | |||
| print('\nsmallest sod in graph space for each letter: ', sod_gs_min_list) | |||
| print('\nsmallest sod in kernel space for each letter: ', sod_ks_min_list) | |||
| print('\nnumber of updates for each letter: ', nb_updated_list) | |||
| print('\ntimes:', time_list) | |||
| @@ -356,7 +366,8 @@ def test_iam_letter_h(): | |||
| for alpha in alpha_range: | |||
| print('alpha =', alpha) | |||
| ghat_list, dhat = test_iam_moreGraphsAsInit_tryAllPossibleBestGraphs_deleteNodesInIterations( | |||
| Gn_let, Gn_let, c_ei=1.7, c_er=1.7, c_es=1.7) | |||
| Gn_let, Gn_let, c_ei=1.7, c_er=1.7, c_es=1.7, | |||
| ged_cost='LETTER', ged_method='IPFP', saveGXL='gedlib-letter') | |||
| dis_best.append(dhat) | |||
| g_best.append(ghat_list) | |||
| time_list.append(time.time() - time0) | |||
| @@ -388,18 +399,283 @@ def test_iam_letter_h(): | |||
| print('\nsods in kernel space: ', sod_list) | |||
| print('\nsmallest sod in kernel space for each letter: ', sod_min_list) | |||
| print('\ntimes:', time_list) | |||
| def test_random_preimage_letter_h(): | |||
| from preimage import random_preimage, compute_kernel | |||
| ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'Letter-med', 'dataset': '../datasets/Letter-med/Letter-med_A.txt', | |||
| # 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| # 'extra_params': {}} # node/edge symb | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/monoterpenoides/trainset_9.ds', | |||
| # 'extra_params': {}} | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/acyclic/dataset_bps.ds', | |||
| # 'extra_params': {}} # node symb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| gkernel = 'structuralspkernel' | |||
| # lmbda = 0.03 # termination probalility | |||
| r_max = 3 # 10 # recursions | |||
| l = 500 | |||
| # alpha_range = np.linspace(0.5, 0.5, 1) | |||
| #alpha_range = np.linspace(0.1, 0.9, 9) | |||
| k = 10 # 5 # k nearest neighbors | |||
| # classify graphs according to letters. | |||
| idx_dict = get_same_item_indices(y_all) | |||
| time_list = [] | |||
| sod_list = [] | |||
| sod_min_list = [] | |||
| for letter in idx_dict: | |||
| print('\n-------------------------------------------------------\n') | |||
| Gn_let = [Gn[i].copy() for i in idx_dict[letter]] | |||
| Gn_mix = Gn_let + [g.copy() for g in Gn_let] | |||
| alpha_range = np.linspace(1 / len(Gn_let), 1 / len(Gn_let), 1) | |||
| # compute | |||
| time0 = time.time() | |||
| km = compute_kernel(Gn_mix, gkernel, True) | |||
| g_best = [] | |||
| dis_best = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('alpha =', alpha) | |||
| dhat, ghat_list = random_preimage(Gn_let, Gn_let, [alpha] * len(Gn_let), | |||
| range(len(Gn_let), len(Gn_mix)), km, | |||
| k, r_max, gkernel, c_ei=1.7, | |||
| c_er=1.7, c_es=1.7) | |||
| dis_best.append(dhat) | |||
| g_best.append(ghat_list) | |||
| time_list.append(time.time() - time0) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', dis_best[idx]) | |||
| print('the corresponding pre-images are') | |||
| for g in g_best[idx]: | |||
| draw_Letter_graph(g, savepath='results/gk_iam/') | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| print(g.nodes(data=True)) | |||
| print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. (alpha range not considered.) | |||
| sod_tmp, _ = median_distance(g_best[0], Gn_let) | |||
| sod_list.append(sod_tmp) | |||
| sod_min_list.append(np.min(sod_tmp)) | |||
| print('\nsods in graph space: ', sod_list) | |||
| print('\nsmallest sod in graph space for each letter: ', sod_min_list) | |||
| print('\ntimes:', time_list) | |||
| def test_gkiam_mutag(): | |||
| from gk_iam import gk_iam_nearest_multi, compute_kernel | |||
| from iam import median_distance | |||
| ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'Letter-med', 'dataset': '../datasets/Letter-med/Letter-med_A.txt', | |||
| # 'extra_params': {}} # node nsymb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| gkernel = 'structuralspkernel' | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 3 # recursions | |||
| # alpha_range = np.linspace(0.5, 0.5, 1) | |||
| k = 20 # k nearest neighbors | |||
| # classify graphs according to letters. | |||
| idx_dict = get_same_item_indices(y_all) | |||
| time_list = [] | |||
| sod_ks_min_list = [] | |||
| sod_gs_list = [] | |||
| sod_gs_min_list = [] | |||
| nb_updated_list = [] | |||
| for letter in idx_dict: | |||
| print('\n-------------------------------------------------------\n') | |||
| Gn_let = [Gn[i].copy() for i in idx_dict[letter]] | |||
| Gn_mix = Gn_let + [g.copy() for g in Gn_let] | |||
| alpha_range = np.linspace(1 / len(Gn_let), 1 / len(Gn_let), 1) | |||
| # compute | |||
| time0 = time.time() | |||
| km = compute_kernel(Gn_mix, gkernel, True) | |||
| g_best = [] | |||
| dis_best = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('alpha =', alpha) | |||
| dhat, ghat_list, sod_ks, nb_updated = gk_iam_nearest_multi(Gn_let, Gn_let, [alpha] * len(Gn_let), | |||
| range(len(Gn_let), len(Gn_mix)), km, | |||
| k, r_max, gkernel, c_ei=1.7, | |||
| c_er=1.7, c_es=1.7) | |||
| dis_best.append(dhat) | |||
| g_best.append(ghat_list) | |||
| time_list.append(time.time() - time0) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', dis_best[idx]) | |||
| print('the corresponding pre-images are') | |||
| for g in g_best[idx]: | |||
| draw_Letter_graph(g, savepath='results/gk_iam/') | |||
| # nx.draw_networkx(g) | |||
| # plt.show() | |||
| print(g.nodes(data=True)) | |||
| print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. (alpha range not considered.) | |||
| sod_tmp, _ = median_distance(g_best[0], Gn_let) | |||
| sod_gs_list.append(sod_tmp) | |||
| sod_gs_min_list.append(np.min(sod_tmp)) | |||
| sod_ks_min_list.append(sod_ks) | |||
| nb_updated_list.append(nb_updated) | |||
| print('\nsods in graph space: ', sod_gs_list) | |||
| print('\nsmallest sod in graph space for each letter: ', sod_gs_min_list) | |||
| print('\nsmallest sod in kernel space for each letter: ', sod_ks_min_list) | |||
| print('\nnumber of updates for each letter: ', nb_updated_list) | |||
| print('\ntimes:', time_list) | |||
| ############################################################################### | |||
| # Re-test. | |||
| def retest_the_simple_two(): | |||
| from gk_iam import gk_iam_nearest_multi, compute_kernel | |||
| from iam import median_distance | |||
| from test_random_mutag import remove_edges | |||
| # The two simple graphs. | |||
| # g1 = nx.Graph(name='haha') | |||
| # g1.add_nodes_from([(0, {'atom': 'C'}), (1, {'atom': 'O'}), (2, {'atom': 'C'})]) | |||
| # g1.add_edges_from([(0, 1, {'bond_type': '1'}), (1, 2, {'bond_type': '1'})]) | |||
| # g2 = nx.Graph(name='hahaha') | |||
| # g2.add_nodes_from([(0, {'atom': 'C'}), (1, {'atom': 'O'}), (2, {'atom': 'C'}), | |||
| # (3, {'atom': 'O'}), (4, {'atom': 'C'})]) | |||
| # g2.add_edges_from([(0, 1, {'bond_type': '1'}), (1, 2, {'bond_type': '1'}), | |||
| # (2, 3, {'bond_type': '1'}), (3, 4, {'bond_type': '1'})]) | |||
| g1 = nx.Graph(name='haha') | |||
| g1.add_nodes_from([(0, {'atom': 'C'}), (1, {'atom': 'C'}), (2, {'atom': 'C'}), | |||
| (3, {'atom': 'S'}), (4, {'atom': 'S'})]) | |||
| g1.add_edges_from([(0, 1, {'bond_type': '1'}), (1, 2, {'bond_type': '1'}), | |||
| (2, 3, {'bond_type': '1'}), (2, 4, {'bond_type': '1'})]) | |||
| g2 = nx.Graph(name='hahaha') | |||
| g2.add_nodes_from([(0, {'atom': 'C'}), (1, {'atom': 'C'}), (2, {'atom': 'C'}), | |||
| (3, {'atom': 'O'}), (4, {'atom': 'O'})]) | |||
| g2.add_edges_from([(0, 1, {'bond_type': '1'}), (1, 2, {'bond_type': '1'}), | |||
| (2, 3, {'bond_type': '1'}), (2, 4, {'bond_type': '1'})]) | |||
| # # randomly select two molecules | |||
| # np.random.seed(1) | |||
| # idx_gi = [0, 6] # np.random.randint(0, len(Gn), 2) | |||
| # g1 = Gn[idx_gi[0]] | |||
| # g2 = Gn[idx_gi[1]] | |||
| # Gn_mix = [g.copy() for g in Gn] | |||
| # Gn_mix.append(g1.copy()) | |||
| # Gn_mix.append(g2.copy()) | |||
| Gn = [g1.copy(), g2.copy()] | |||
| remove_edges(Gn) | |||
| gkernel = 'marginalizedkernel' | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 10 # recursions | |||
| # l = 500 | |||
| alpha_range = np.linspace(0.5, 0.5, 1) | |||
| k = 2 # k nearest neighbors | |||
| epsilon = 1e-6 | |||
| ged_cost='CHEM_1' | |||
| ged_method='IPFP' | |||
| saveGXL='gedlib' | |||
| c_ei=1 | |||
| c_er=1 | |||
| c_es=1 | |||
| Gn_mix = Gn + [g1.copy(), g2.copy()] | |||
| # compute | |||
| time0 = time.time() | |||
| km = compute_kernel(Gn_mix, gkernel, True) | |||
| time_km = time.time() - time0 | |||
| time_list = [] | |||
| sod_ks_min_list = [] | |||
| sod_gs_list = [] | |||
| sod_gs_min_list = [] | |||
| nb_updated_list = [] | |||
| g_best = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('\n-------------------------------------------------------\n') | |||
| print('alpha =', alpha) | |||
| time0 = time.time() | |||
| dhat, ghat_list, sod_ks, nb_updated = gk_iam_nearest_multi(Gn, [g1, g2], | |||
| [alpha, 1 - alpha], range(len(Gn), len(Gn) + 2), km, k, r_max, | |||
| gkernel, c_ei=c_ei, c_er=c_er, c_es=c_es, epsilon=epsilon, | |||
| ged_cost=ged_cost, ged_method=ged_method, saveGXL=saveGXL) | |||
| time_total = time.time() - time0 + time_km | |||
| print('time: ', time_total) | |||
| time_list.append(time_total) | |||
| sod_ks_min_list.append(dhat) | |||
| g_best.append(ghat_list) | |||
| nb_updated_list.append(nb_updated) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', sod_ks_min_list[idx]) | |||
| print('one of the possible corresponding pre-images is') | |||
| nx.draw(g_best[idx][0], labels=nx.get_node_attributes(g_best[idx][0], 'atom'), | |||
| with_labels=True) | |||
| plt.savefig('results/gk_iam/mutag_alpha' + str(item) + '.png', format="PNG") | |||
| plt.show() | |||
| print(g_best[idx][0].nodes(data=True)) | |||
| print(g_best[idx][0].edges(data=True)) | |||
| # for g in g_best[idx]: | |||
| # draw_Letter_graph(g, savepath='results/gk_iam/') | |||
| ## nx.draw_networkx(g) | |||
| ## plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. | |||
| for idx, item in enumerate(alpha_range): | |||
| sod_tmp, _ = median_distance(g_best[0], [g1, g2], ged_cost=ged_cost, | |||
| ged_method=ged_method, saveGXL=saveGXL) | |||
| sod_gs_list.append(sod_tmp) | |||
| sod_gs_min_list.append(np.min(sod_tmp)) | |||
| print('\nsods in graph space: ', sod_gs_list) | |||
| print('\nsmallest sod in graph space for each alpha: ', sod_gs_min_list) | |||
| print('\nsmallest sod in kernel space for each alpha: ', sod_ks_min_list) | |||
| print('\nnumber of updates for each alpha: ', nb_updated_list) | |||
| print('\ntimes:', time_list) | |||
| if __name__ == '__main__': | |||
| # ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| # 'extra_params': {}} # node/edge symb | |||
| ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'Letter-high', 'dataset': '../datasets/Letter-high/Letter-high_A.txt', | |||
| # 'extra_params': {}} # node nsymb | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/monoterpenoides/trainset_9.ds', | |||
| # 'extra_params': {}} | |||
| # ds = {'name': 'Acyclic', 'dataset': '../datasets/acyclic/dataset_bps.ds', | |||
| # 'extra_params': {}} # node symb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # Gn = Gn[0:20] | |||
| # import networkx.algorithms.isomorphism as iso | |||
| @@ -419,5 +695,10 @@ if __name__ == '__main__': | |||
| # test_the_simple_two(Gn, 'untilhpathkernel') | |||
| # test_remove_bests(Gn, 'untilhpathkernel') | |||
| test_gkiam_letter_h() | |||
| # test_iam_letter_h() | |||
| # test_gkiam_letter_h() | |||
| # test_iam_letter_h() | |||
| # test_random_preimage_letter_h | |||
| ############################################################################### | |||
| # retests. | |||
| retest_the_simple_two() | |||
| @@ -18,17 +18,17 @@ def test() : | |||
| script.PyRestartEnv() | |||
| # print("Here is the Python function !") | |||
| # | |||
| # print("List of Edit Cost Options : ") | |||
| # for i in script.listOfEditCostOptions : | |||
| # print (i) | |||
| # print("") | |||
| # | |||
| # print("List of Method Options : ") | |||
| # for j in script.listOfMethodOptions : | |||
| # print (j) | |||
| # print("") | |||
| print("Here is the Python function !") | |||
| print("List of Edit Cost Options : ") | |||
| for i in script.listOfEditCostOptions : | |||
| print (i) | |||
| print("") | |||
| print("List of Method Options : ") | |||
| for j in script.listOfMethodOptions : | |||
| print (j) | |||
| print("") | |||
| script.PyLoadGXLGraph('include/gedlib-master/data/datasets/Mutagenicity/data/', 'collections/MUTA_10.xml') | |||
| listID = script.PyGetGraphIds() | |||
| @@ -0,0 +1,599 @@ | |||
| #!/usr/bin/env python3 | |||
| # -*- coding: utf-8 -*- | |||
| """ | |||
| Created on Thu Sep 5 15:59:00 2019 | |||
| @author: ljia | |||
| """ | |||
| import numpy as np | |||
| import networkx as nx | |||
| import matplotlib.pyplot as plt | |||
| import time | |||
| from tqdm import tqdm | |||
| import os | |||
| import sys | |||
| sys.path.insert(0, "../") | |||
| from pygraph.utils.graphfiles import loadDataset | |||
| ############################################################################### | |||
| # test on the combination of the two randomly chosen graphs. (the same as in the | |||
| # random pre-image paper.) | |||
| def test_preimage_mix_2combination_all_pairs(): | |||
| from gk_iam import preimage_iam_random_mix, compute_kernel | |||
| from iam import median_distance | |||
| ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| 'extra_params': {}} # node/edge symb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # Gn = Gn[0:50] | |||
| remove_edges(Gn) | |||
| gkernel = 'marginalizedkernel' | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 10 # iteration limit for pre-image. | |||
| l_max = 500 # update limit for random generation | |||
| alpha_range = np.linspace(0.7, 1, 4) | |||
| k = 5 # k nearest neighbors | |||
| epsilon = 1e-6 | |||
| # parameters for GED function | |||
| ged_cost='CHEM_1' | |||
| ged_method='IPFP' | |||
| saveGXL='gedlib' | |||
| # parameters for IAM function | |||
| c_ei=1 | |||
| c_er=1 | |||
| c_es=1 | |||
| ite_max_iam = 50 | |||
| epsilon_iam = 0.001 | |||
| removeNodes = True | |||
| connected_iam = False | |||
| nb_update_mat_iam = np.full((len(Gn), len(Gn)), np.inf) | |||
| nb_update_mat_random = np.full((len(Gn), len(Gn)), np.inf) | |||
| # test on each pair of graphs. | |||
| # for idx1 in range(len(Gn) - 1, -1, -1): | |||
| # for idx2 in range(idx1, -1, -1): | |||
| for idx1 in range(187, 188): | |||
| for idx2 in range(167, 168): | |||
| g1 = Gn[idx1].copy() | |||
| g2 = Gn[idx2].copy() | |||
| # Gn[10] = [] | |||
| # Gn[10] = [] | |||
| nx.draw(g1, labels=nx.get_node_attributes(g1, 'atom'), with_labels=True) | |||
| plt.savefig("results/preimage_mix/mutag187.png", format="PNG") | |||
| plt.show() | |||
| plt.clf() | |||
| nx.draw(g2, labels=nx.get_node_attributes(g2, 'atom'), with_labels=True) | |||
| plt.savefig("results/preimage_mix/mutag167.png", format="PNG") | |||
| plt.show() | |||
| plt.clf() | |||
| ################################################################### | |||
| # Gn_mix = [g.copy() for g in Gn] | |||
| # Gn_mix.append(g1.copy()) | |||
| # Gn_mix.append(g2.copy()) | |||
| # | |||
| # # compute | |||
| # time0 = time.time() | |||
| # km = compute_kernel(Gn_mix, gkernel, True) | |||
| # time_km = time.time() - time0 | |||
| # | |||
| # # write Gram matrix to file and read it. | |||
| # np.savez('results/gram_matrix_uhpath_itr7_pq0.8.gm', gm=km, gmtime=time_km) | |||
| ################################################################### | |||
| gmfile = np.load('results/gram_matrix_marg_itr10_pq0.03.gm.npz') | |||
| km = gmfile['gm'] | |||
| time_km = gmfile['gmtime'] | |||
| # modify mixed gram matrix. | |||
| for i in range(len(Gn)): | |||
| km[i, len(Gn)] = km[i, idx1] | |||
| km[i, len(Gn) + 1] = km[i, idx2] | |||
| km[len(Gn), i] = km[i, idx1] | |||
| km[len(Gn) + 1, i] = km[i, idx2] | |||
| km[len(Gn), len(Gn)] = km[idx1, idx1] | |||
| km[len(Gn), len(Gn) + 1] = km[idx1, idx2] | |||
| km[len(Gn) + 1, len(Gn)] = km[idx2, idx1] | |||
| km[len(Gn) + 1, len(Gn) + 1] = km[idx2, idx2] | |||
| ################################################################### | |||
| # # use only the two graphs in median set as candidates. | |||
| # Gn = [g1.copy(), g2.copy()] | |||
| # Gn_mix = Gn + [g1.copy(), g2.copy()] | |||
| # # compute | |||
| # time0 = time.time() | |||
| # km = compute_kernel(Gn_mix, gkernel, True) | |||
| # time_km = time.time() - time0 | |||
| time_list = [] | |||
| dis_ks_min_list = [] | |||
| sod_gs_list = [] | |||
| sod_gs_min_list = [] | |||
| nb_updated_list_iam = [] | |||
| nb_updated_list_random = [] | |||
| g_best = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('\n-------------------------------------------------------\n') | |||
| print('alpha =', alpha) | |||
| time0 = time.time() | |||
| dhat, ghat_list, sod_ks, nb_updated_iam, nb_updated_random = \ | |||
| preimage_iam_random_mix(Gn, [g1, g2], | |||
| [alpha, 1 - alpha], range(len(Gn), len(Gn) + 2), km, k, r_max, | |||
| l_max, gkernel, epsilon=epsilon, | |||
| params_iam={'c_ei': c_ei, 'c_er': c_er, 'c_es': c_es, | |||
| 'ite_max': ite_max_iam, 'epsilon': epsilon_iam, | |||
| 'removeNodes': removeNodes, 'connected': connected_iam}, | |||
| params_ged={'ged_cost': ged_cost, 'ged_method': ged_method, | |||
| 'saveGXL': saveGXL}) | |||
| time_total = time.time() - time0 + time_km | |||
| print('time: ', time_total) | |||
| time_list.append(time_total) | |||
| dis_ks_min_list.append(dhat) | |||
| g_best.append(ghat_list) | |||
| nb_updated_list_iam.append(nb_updated_iam) | |||
| nb_updated_list_random.append(nb_updated_random) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', dis_ks_min_list[idx]) | |||
| print('one of the possible corresponding pre-images is') | |||
| nx.draw(g_best[idx][0], labels=nx.get_node_attributes(g_best[idx][0], 'atom'), | |||
| with_labels=True) | |||
| plt.savefig('results/preimage_mix/mutag' + str(idx1) + '_' + str(idx2) | |||
| + '_alpha' + str(item) + '.png', format="PNG") | |||
| # plt.show() | |||
| plt.clf() | |||
| # print(g_best[idx][0].nodes(data=True)) | |||
| # print(g_best[idx][0].edges(data=True)) | |||
| # for g in g_best[idx]: | |||
| # draw_Letter_graph(g, savepath='results/gk_iam/') | |||
| ## nx.draw_networkx(g) | |||
| ## plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. | |||
| for idx, item in enumerate(alpha_range): | |||
| sod_tmp, _ = median_distance(g_best[0], [g1, g2], ged_cost=ged_cost, | |||
| ged_method=ged_method, saveGXL=saveGXL) | |||
| sod_gs_list.append(sod_tmp) | |||
| sod_gs_min_list.append(np.min(sod_tmp)) | |||
| print('\nsods in graph space: ', sod_gs_list) | |||
| print('\nsmallest sod in graph space for each alpha: ', sod_gs_min_list) | |||
| print('\nsmallest distance in kernel space for each alpha: ', dis_ks_min_list) | |||
| print('\nnumber of updates for each alpha by IAM: ', nb_updated_list_iam) | |||
| print('\nnumber of updates for each alpha by random generation: ', | |||
| nb_updated_list_random) | |||
| print('\ntimes:', time_list) | |||
| nb_update_mat_iam[idx1, idx2] = nb_updated_list_iam[0] | |||
| nb_update_mat_random[idx1, idx2] = nb_updated_list_random[0] | |||
| str_fw = 'graphs %d and %d: %d times by IAM, %d times by random generation.\n' \ | |||
| % (idx1, idx2, nb_updated_list_iam[0], nb_updated_list_random[0]) | |||
| with open('results/preimage_mix/nb_updates.txt', 'r+') as file: | |||
| content = file.read() | |||
| file.seek(0, 0) | |||
| file.write(str_fw + content) | |||
| def test_gkiam_2combination_all_pairs(): | |||
| from gk_iam import gk_iam_nearest_multi, compute_kernel | |||
| from iam import median_distance | |||
| ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| 'extra_params': {}} # node/edge symb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # Gn = Gn[0:50] | |||
| remove_edges(Gn) | |||
| gkernel = 'marginalizedkernel' | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 10 # iteration limit for pre-image. | |||
| alpha_range = np.linspace(1, 1, 1) | |||
| k = 5 # k nearest neighbors | |||
| epsilon = 1e-6 | |||
| # parameters for GED function | |||
| ged_cost='CHEM_1' | |||
| ged_method='IPFP' | |||
| saveGXL='gedlib' | |||
| # parameters for IAM function | |||
| c_ei=1 | |||
| c_er=1 | |||
| c_es=1 | |||
| ite_max_iam = 50 | |||
| epsilon_iam = 0.001 | |||
| removeNodes = True | |||
| connected_iam = False | |||
| nb_update_mat = np.full((len(Gn), len(Gn)), np.inf) | |||
| # test on each pair of graphs. | |||
| # for idx1 in range(len(Gn) - 1, -1, -1): | |||
| # for idx2 in range(idx1, -1, -1): | |||
| for idx1 in range(187, 188): | |||
| for idx2 in range(167, 168): | |||
| g1 = Gn[idx1].copy() | |||
| g2 = Gn[idx2].copy() | |||
| # Gn[10] = [] | |||
| # Gn[10] = [] | |||
| nx.draw(g1, labels=nx.get_node_attributes(g1, 'atom'), with_labels=True) | |||
| plt.savefig("results/gk_iam/all_pairs/mutag187.png", format="PNG") | |||
| plt.show() | |||
| plt.clf() | |||
| nx.draw(g2, labels=nx.get_node_attributes(g2, 'atom'), with_labels=True) | |||
| plt.savefig("results/gk_iam/all_pairs/mutag167.png", format="PNG") | |||
| plt.show() | |||
| plt.clf() | |||
| ################################################################### | |||
| # Gn_mix = [g.copy() for g in Gn] | |||
| # Gn_mix.append(g1.copy()) | |||
| # Gn_mix.append(g2.copy()) | |||
| # | |||
| # # compute | |||
| # time0 = time.time() | |||
| # km = compute_kernel(Gn_mix, gkernel, True) | |||
| # time_km = time.time() - time0 | |||
| # | |||
| # # write Gram matrix to file and read it. | |||
| # np.savez('results/gram_matrix_uhpath_itr7_pq0.8.gm', gm=km, gmtime=time_km) | |||
| ################################################################### | |||
| gmfile = np.load('results/gram_matrix_marg_itr10_pq0.03.gm.npz') | |||
| km = gmfile['gm'] | |||
| time_km = gmfile['gmtime'] | |||
| # modify mixed gram matrix. | |||
| for i in range(len(Gn)): | |||
| km[i, len(Gn)] = km[i, idx1] | |||
| km[i, len(Gn) + 1] = km[i, idx2] | |||
| km[len(Gn), i] = km[i, idx1] | |||
| km[len(Gn) + 1, i] = km[i, idx2] | |||
| km[len(Gn), len(Gn)] = km[idx1, idx1] | |||
| km[len(Gn), len(Gn) + 1] = km[idx1, idx2] | |||
| km[len(Gn) + 1, len(Gn)] = km[idx2, idx1] | |||
| km[len(Gn) + 1, len(Gn) + 1] = km[idx2, idx2] | |||
| ################################################################### | |||
| # # use only the two graphs in median set as candidates. | |||
| # Gn = [g1.copy(), g2.copy()] | |||
| # Gn_mix = Gn + [g1.copy(), g2.copy()] | |||
| # # compute | |||
| # time0 = time.time() | |||
| # km = compute_kernel(Gn_mix, gkernel, True) | |||
| # time_km = time.time() - time0 | |||
| time_list = [] | |||
| dis_ks_min_list = [] | |||
| sod_gs_list = [] | |||
| sod_gs_min_list = [] | |||
| nb_updated_list = [] | |||
| g_best = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('\n-------------------------------------------------------\n') | |||
| print('alpha =', alpha) | |||
| time0 = time.time() | |||
| dhat, ghat_list, sod_ks, nb_updated = gk_iam_nearest_multi(Gn, [g1, g2], | |||
| [alpha, 1 - alpha], range(len(Gn), len(Gn) + 2), km, k, r_max, | |||
| gkernel, epsilon=epsilon, | |||
| params_iam={'c_ei': c_ei, 'c_er': c_er, 'c_es': c_es, | |||
| 'ite_max': ite_max_iam, 'epsilon': epsilon_iam, | |||
| 'removeNodes': removeNodes, 'connected': connected_iam}, | |||
| params_ged={'ged_cost': ged_cost, 'ged_method': ged_method, | |||
| 'saveGXL': saveGXL}) | |||
| time_total = time.time() - time0 + time_km | |||
| print('time: ', time_total) | |||
| time_list.append(time_total) | |||
| dis_ks_min_list.append(dhat) | |||
| g_best.append(ghat_list) | |||
| nb_updated_list.append(nb_updated) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', dis_ks_min_list[idx]) | |||
| print('one of the possible corresponding pre-images is') | |||
| nx.draw(g_best[idx][0], labels=nx.get_node_attributes(g_best[idx][0], 'atom'), | |||
| with_labels=True) | |||
| plt.savefig('results/gk_iam/mutag' + str(idx1) + '_' + str(idx2) | |||
| + '_alpha' + str(item) + '.png', format="PNG") | |||
| # plt.show() | |||
| plt.clf() | |||
| # print(g_best[idx][0].nodes(data=True)) | |||
| # print(g_best[idx][0].edges(data=True)) | |||
| # for g in g_best[idx]: | |||
| # draw_Letter_graph(g, savepath='results/gk_iam/') | |||
| ## nx.draw_networkx(g) | |||
| ## plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. | |||
| for idx, item in enumerate(alpha_range): | |||
| sod_tmp, _ = median_distance(g_best[0], [g1, g2], ged_cost=ged_cost, | |||
| ged_method=ged_method, saveGXL=saveGXL) | |||
| sod_gs_list.append(sod_tmp) | |||
| sod_gs_min_list.append(np.min(sod_tmp)) | |||
| print('\nsods in graph space: ', sod_gs_list) | |||
| print('\nsmallest sod in graph space for each alpha: ', sod_gs_min_list) | |||
| print('\nsmallest distance in kernel space for each alpha: ', dis_ks_min_list) | |||
| print('\nnumber of updates for each alpha: ', nb_updated_list) | |||
| print('\ntimes:', time_list) | |||
| nb_update_mat[idx1, idx2] = nb_updated_list[0] | |||
| str_fw = 'graphs %d and %d: %d.\n' % (idx1, idx2, nb_updated_list[0]) | |||
| with open('results/gk_iam/all_pairs/nb_updates.txt', 'r+') as file: | |||
| content = file.read() | |||
| file.seek(0, 0) | |||
| file.write(str_fw + content) | |||
| def test_gkiam_2combination(): | |||
| from gk_iam import gk_iam_nearest_multi, compute_kernel | |||
| from iam import median_distance | |||
| ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| 'extra_params': {}} # node/edge symb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # Gn = Gn[0:50] | |||
| remove_edges(Gn) | |||
| gkernel = 'marginalizedkernel' | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 10 # iteration limit for pre-image. | |||
| alpha_range = np.linspace(0.5, 0.5, 1) | |||
| k = 20 # k nearest neighbors | |||
| epsilon = 1e-6 | |||
| ged_cost='CHEM_1' | |||
| ged_method='IPFP' | |||
| saveGXL='gedlib' | |||
| c_ei=1 | |||
| c_er=1 | |||
| c_es=1 | |||
| # randomly select two molecules | |||
| np.random.seed(1) | |||
| idx_gi = [10, 11] # np.random.randint(0, len(Gn), 2) | |||
| g1 = Gn[idx_gi[0]].copy() | |||
| g2 = Gn[idx_gi[1]].copy() | |||
| # Gn[10] = [] | |||
| # Gn[10] = [] | |||
| # nx.draw(g1, labels=nx.get_node_attributes(g1, 'atom'), with_labels=True) | |||
| # plt.savefig("results/random_preimage/mutag10.png", format="PNG") | |||
| # plt.show() | |||
| # nx.draw(g2, labels=nx.get_node_attributes(g2, 'atom'), with_labels=True) | |||
| # plt.savefig("results/random_preimage/mutag11.png", format="PNG") | |||
| # plt.show() | |||
| Gn_mix = [g.copy() for g in Gn] | |||
| Gn_mix.append(g1.copy()) | |||
| Gn_mix.append(g2.copy()) | |||
| # compute | |||
| # time0 = time.time() | |||
| # km = compute_kernel(Gn_mix, gkernel, True) | |||
| # time_km = time.time() - time0 | |||
| # write Gram matrix to file and read it. | |||
| # np.savez('results/gram_matrix.gm', gm=km, gmtime=time_km) | |||
| gmfile = np.load('results/gram_matrix.gm.npz') | |||
| km = gmfile['gm'] | |||
| time_km = gmfile['gmtime'] | |||
| time_list = [] | |||
| dis_ks_min_list = [] | |||
| sod_gs_list = [] | |||
| sod_gs_min_list = [] | |||
| nb_updated_list = [] | |||
| g_best = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('\n-------------------------------------------------------\n') | |||
| print('alpha =', alpha) | |||
| time0 = time.time() | |||
| dhat, ghat_list, sod_ks, nb_updated = gk_iam_nearest_multi(Gn, [g1, g2], | |||
| [alpha, 1 - alpha], range(len(Gn), len(Gn) + 2), km, k, r_max, | |||
| gkernel, c_ei=c_ei, c_er=c_er, c_es=c_es, epsilon=epsilon, | |||
| ged_cost=ged_cost, ged_method=ged_method, saveGXL=saveGXL) | |||
| time_total = time.time() - time0 + time_km | |||
| print('time: ', time_total) | |||
| time_list.append(time_total) | |||
| dis_ks_min_list.append(dhat) | |||
| g_best.append(ghat_list) | |||
| nb_updated_list.append(nb_updated) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', dis_ks_min_list[idx]) | |||
| print('one of the possible corresponding pre-images is') | |||
| nx.draw(g_best[idx][0], labels=nx.get_node_attributes(g_best[idx][0], 'atom'), | |||
| with_labels=True) | |||
| plt.savefig('results/gk_iam/mutag_alpha' + str(item) + '.png', format="PNG") | |||
| plt.show() | |||
| print(g_best[idx][0].nodes(data=True)) | |||
| print(g_best[idx][0].edges(data=True)) | |||
| # for g in g_best[idx]: | |||
| # draw_Letter_graph(g, savepath='results/gk_iam/') | |||
| ## nx.draw_networkx(g) | |||
| ## plt.show() | |||
| # print(g.nodes(data=True)) | |||
| # print(g.edges(data=True)) | |||
| # compute the corresponding sod in graph space. | |||
| for idx, item in enumerate(alpha_range): | |||
| sod_tmp, _ = median_distance(g_best[0], [g1, g2], ged_cost=ged_cost, | |||
| ged_method=ged_method, saveGXL=saveGXL) | |||
| sod_gs_list.append(sod_tmp) | |||
| sod_gs_min_list.append(np.min(sod_tmp)) | |||
| print('\nsods in graph space: ', sod_gs_list) | |||
| print('\nsmallest sod in graph space for each alpha: ', sod_gs_min_list) | |||
| print('\nsmallest distance in kernel space for each alpha: ', dis_ks_min_list) | |||
| print('\nnumber of updates for each alpha: ', nb_updated_list) | |||
| print('\ntimes:', time_list) | |||
| def test_random_preimage_2combination(): | |||
| # from gk_iam import compute_kernel | |||
| from preimage import random_preimage | |||
| ds = {'name': 'MUTAG', 'dataset': '../datasets/MUTAG/MUTAG_A.txt', | |||
| 'extra_params': {}} # node/edge symb | |||
| Gn, y_all = loadDataset(ds['dataset'], extra_params=ds['extra_params']) | |||
| # Gn = Gn[0:12] | |||
| remove_edges(Gn) | |||
| gkernel = 'marginalizedkernel' | |||
| # dis_mat, dis_max, dis_min, dis_mean = kernel_distance_matrix(Gn, gkernel=gkernel) | |||
| # print(dis_max, dis_min, dis_mean) | |||
| lmbda = 0.03 # termination probalility | |||
| r_max = 10 # iteration limit for pre-image. | |||
| l = 500 | |||
| alpha_range = np.linspace(0, 1, 11) | |||
| k = 5 # k nearest neighbors | |||
| # randomly select two molecules | |||
| np.random.seed(1) | |||
| idx_gi = [187, 167] # np.random.randint(0, len(Gn), 2) | |||
| g1 = Gn[idx_gi[0]].copy() | |||
| g2 = Gn[idx_gi[1]].copy() | |||
| # nx.draw(g1, labels=nx.get_node_attributes(g1, 'atom'), with_labels=True) | |||
| # plt.savefig("results/random_preimage/mutag10.png", format="PNG") | |||
| # plt.show() | |||
| # nx.draw(g2, labels=nx.get_node_attributes(g2, 'atom'), with_labels=True) | |||
| # plt.savefig("results/random_preimage/mutag11.png", format="PNG") | |||
| # plt.show() | |||
| ###################################################################### | |||
| # Gn_mix = [g.copy() for g in Gn] | |||
| # Gn_mix.append(g1.copy()) | |||
| # Gn_mix.append(g2.copy()) | |||
| # | |||
| ## g_tmp = iam([g1, g2]) | |||
| ## nx.draw_networkx(g_tmp) | |||
| ## plt.show() | |||
| # | |||
| # # compute | |||
| # time0 = time.time() | |||
| # km = compute_kernel(Gn_mix, gkernel, True) | |||
| # time_km = time.time() - time0 | |||
| ################################################################### | |||
| idx1 = idx_gi[0] | |||
| idx2 = idx_gi[1] | |||
| gmfile = np.load('results/gram_matrix_marg_itr10_pq0.03.gm.npz') | |||
| km = gmfile['gm'] | |||
| time_km = gmfile['gmtime'] | |||
| # modify mixed gram matrix. | |||
| for i in range(len(Gn)): | |||
| km[i, len(Gn)] = km[i, idx1] | |||
| km[i, len(Gn) + 1] = km[i, idx2] | |||
| km[len(Gn), i] = km[i, idx1] | |||
| km[len(Gn) + 1, i] = km[i, idx2] | |||
| km[len(Gn), len(Gn)] = km[idx1, idx1] | |||
| km[len(Gn), len(Gn) + 1] = km[idx1, idx2] | |||
| km[len(Gn) + 1, len(Gn)] = km[idx2, idx1] | |||
| km[len(Gn) + 1, len(Gn) + 1] = km[idx2, idx2] | |||
| ################################################################### | |||
| time_list = [] | |||
| nb_updated_list = [] | |||
| g_best = [] | |||
| dis_ks_min_list = [] | |||
| # for each alpha | |||
| for alpha in alpha_range: | |||
| print('\n-------------------------------------------------------\n') | |||
| print('alpha =', alpha) | |||
| time0 = time.time() | |||
| dhat, ghat, nb_updated = random_preimage(Gn, [g1, g2], [alpha, 1 - alpha], | |||
| range(len(Gn), len(Gn) + 2), km, | |||
| k, r_max, l, gkernel) | |||
| time_total = time.time() - time0 + time_km | |||
| print('time: ', time_total) | |||
| time_list.append(time_total) | |||
| dis_ks_min_list.append(dhat) | |||
| g_best.append(ghat) | |||
| nb_updated_list.append(nb_updated) | |||
| # show best graphs and save them to file. | |||
| for idx, item in enumerate(alpha_range): | |||
| print('when alpha is', item, 'the shortest distance is', dis_ks_min_list[idx]) | |||
| print('one of the possible corresponding pre-images is') | |||
| nx.draw(g_best[idx], labels=nx.get_node_attributes(g_best[idx], 'atom'), | |||
| with_labels=True) | |||
| plt.savefig('results/random_preimage/mutag_alpha' + str(item) + '.png', format="PNG") | |||
| plt.show() | |||
| plt.clf() | |||
| print(g_best[idx].nodes(data=True)) | |||
| print(g_best[idx].edges(data=True)) | |||
| # # compute the corresponding sod in graph space. (alpha range not considered.) | |||
| # sod_tmp, _ = median_distance(g_best[0], Gn_let) | |||
| # sod_gs_list.append(sod_tmp) | |||
| # sod_gs_min_list.append(np.min(sod_tmp)) | |||
| # sod_ks_min_list.append(sod_ks) | |||
| # nb_updated_list.append(nb_updated) | |||
| # print('\nsmallest sod in graph space for each alpha: ', sod_gs_min_list) | |||
| print('\nsmallest distance in kernel space for each alpha: ', dis_ks_min_list) | |||
| print('\nnumber of updates for each alpha: ', nb_updated_list) | |||
| print('\ntimes:', time_list) | |||
| ############################################################################### | |||
| # help functions | |||
| def remove_edges(Gn): | |||
| for G in Gn: | |||
| for _, _, attrs in G.edges(data=True): | |||
| attrs.clear() | |||
| def kernel_distance_matrix(Gn, Kmatrix=None, gkernel=None): | |||
| from gk_iam import compute_kernel | |||
| dis_mat = np.empty((len(Gn), len(Gn))) | |||
| if Kmatrix == None: | |||
| Kmatrix = compute_kernel(Gn, gkernel, True) | |||
| for i in range(len(Gn)): | |||
| for j in range(i, len(Gn)): | |||
| dis = Kmatrix[i, i] + Kmatrix[j, j] - 2 * Kmatrix[i, j] | |||
| if dis < 0: | |||
| if dis > -1e-10: | |||
| dis = 0 | |||
| else: | |||
| raise ValueError('The distance is negative.') | |||
| dis_mat[i, j] = np.sqrt(dis) | |||
| dis_mat[j, i] = dis_mat[i, j] | |||
| dis_max = np.max(np.max(dis_mat)) | |||
| dis_min = np.min(np.min(dis_mat[dis_mat != 0])) | |||
| dis_mean = np.mean(np.mean(dis_mat)) | |||
| return dis_mat, dis_max, dis_min, dis_mean | |||
| ############################################################################### | |||
| if __name__ == '__main__': | |||
| ############################################################################### | |||
| # test on the combination of the two randomly chosen graphs. (the same as in the | |||
| # random pre-image paper.) | |||
| # test_random_preimage_2combination() | |||
| # test_gkiam_2combination() | |||
| # test_gkiam_2combination_all_pairs() | |||
| test_preimage_mix_2combination_all_pairs() | |||
| @@ -51,6 +51,7 @@ def untilhpathkernel(*args, | |||
| applied for the graph kernel. The Following choices are available: | |||
| 'MinMax': use the MiniMax kernel and counting feature map. | |||
| 'tanimoto': use the Tanimoto kernel and binary feature map. | |||
| None: no sub-kernel is used, the kernel is computed directly. | |||
| compute_method : string | |||
| Computation method to store paths and compute the graph kernel. The | |||
| Following choices are available: | |||
| @@ -72,14 +73,16 @@ def untilhpathkernel(*args, | |||
| Kmatrix = np.zeros((len(Gn), len(Gn))) | |||
| ds_attrs = get_dataset_attributes( | |||
| Gn, | |||
| attr_names=['node_labeled', 'edge_labeled', 'is_directed'], | |||
| attr_names=['node_labeled', 'node_attr_dim', 'edge_labeled', | |||
| 'edge_attr_dim', 'is_directed'], | |||
| node_label=node_label, edge_label=edge_label) | |||
| if not ds_attrs['node_labeled']: | |||
| for G in Gn: | |||
| nx.set_node_attributes(G, '0', 'atom') | |||
| if not ds_attrs['edge_labeled']: | |||
| for G in Gn: | |||
| nx.set_edge_attributes(G, '0', 'bond_type') | |||
| if k_func != None: | |||
| if not ds_attrs['node_labeled']: | |||
| for G in Gn: | |||
| nx.set_node_attributes(G, '0', 'atom') | |||
| if not ds_attrs['edge_labeled']: | |||
| for G in Gn: | |||
| nx.set_edge_attributes(G, '0', 'bond_type') | |||
| start_time = time.time() | |||
| @@ -93,12 +96,15 @@ def untilhpathkernel(*args, | |||
| else: | |||
| chunksize = 100 | |||
| all_paths = [[] for _ in range(len(Gn))] | |||
| if compute_method == 'trie': | |||
| if compute_method == 'trie' and k_func != None: | |||
| getps_partial = partial(wrapper_find_all_path_as_trie, depth, | |||
| ds_attrs, node_label, edge_label) | |||
| else: | |||
| elif compute_method != 'trie' and k_func != None: | |||
| getps_partial = partial(wrapper_find_all_paths_until_length, depth, | |||
| ds_attrs, node_label, edge_label) | |||
| ds_attrs, node_label, edge_label, True) | |||
| else: | |||
| getps_partial = partial(wrapper_find_all_paths_until_length, depth, | |||
| ds_attrs, node_label, edge_label, False) | |||
| if verbose: | |||
| iterator = tqdm(pool.imap_unordered(getps_partial, itr, chunksize), | |||
| desc='getting paths', file=sys.stdout) | |||
| @@ -110,10 +116,12 @@ def untilhpathkernel(*args, | |||
| pool.join() | |||
| # for g in Gn: | |||
| # if compute_method == 'trie': | |||
| # if compute_method == 'trie' and k_func != None: | |||
| # find_all_path_as_trie(g, depth, ds_attrs, node_label, edge_label) | |||
| # else: | |||
| # elif compute_method != 'trie' and k_func != None: | |||
| # find_all_paths_until_length(g, depth, ds_attrs, node_label, edge_label) | |||
| # else: | |||
| # find_all_paths_until_length(g, depth, ds_attrs, node_label, edge_label, False) | |||
| ## size = sys.getsizeof(all_paths) | |||
| ## for item in all_paths: | |||
| @@ -130,20 +138,27 @@ def untilhpathkernel(*args, | |||
| ## all_paths[i] = ps | |||
| ## print(time.time() - ttt) | |||
| if compute_method == 'trie': | |||
| if compute_method == 'trie' and k_func != None: | |||
| def init_worker(trie_toshare): | |||
| global G_trie | |||
| G_trie = trie_toshare | |||
| do_partial = partial(wrapper_uhpath_do_trie, k_func) | |||
| parallel_gm(do_partial, Kmatrix, Gn, init_worker=init_worker, | |||
| glbv=(all_paths,), n_jobs=n_jobs, verbose=verbose) | |||
| else: | |||
| elif compute_method != 'trie' and k_func != None: | |||
| def init_worker(plist_toshare): | |||
| global G_plist | |||
| G_plist = plist_toshare | |||
| do_partial = partial(wrapper_uhpath_do_naive, k_func) | |||
| parallel_gm(do_partial, Kmatrix, Gn, init_worker=init_worker, | |||
| glbv=(all_paths,), n_jobs=n_jobs, verbose=verbose) | |||
| else: | |||
| def init_worker(plist_toshare): | |||
| global G_plist | |||
| G_plist = plist_toshare | |||
| do_partial = partial(wrapper_uhpath_do_kernelless, ds_attrs, edge_kernels) | |||
| parallel_gm(do_partial, Kmatrix, Gn, init_worker=init_worker, | |||
| glbv=(all_paths,), n_jobs=n_jobs, verbose=verbose) | |||
| # # ---- direct running, normally use single CPU core. ---- | |||
| @@ -353,12 +368,62 @@ def wrapper_uhpath_do_naive(k_func, itr): | |||
| return i, j, _untilhpathkernel_do_naive(G_plist[i], G_plist[j], k_func) | |||
| def _untilhpathkernel_do_kernelless(paths1, paths2, k_func): | |||
| """Calculate path graph kernels up to depth d between 2 graphs naively. | |||
| Parameters | |||
| ---------- | |||
| paths_list : list of list | |||
| List of list of paths in all graphs, where for unlabeled graphs, each | |||
| path is represented by a list of nodes; while for labeled graphs, each | |||
| path is represented by a string consists of labels of nodes and/or | |||
| edges on that path. | |||
| k_func : function | |||
| A kernel function applied using different notions of fingerprint | |||
| similarity. | |||
| Return | |||
| ------ | |||
| kernel : float | |||
| Path kernel up to h between 2 graphs. | |||
| """ | |||
| all_paths = list(set(paths1 + paths2)) | |||
| if k_func == 'tanimoto': | |||
| length_union = len(set(paths1 + paths2)) | |||
| kernel = (len(set(paths1)) + len(set(paths2)) - | |||
| length_union) / length_union | |||
| # vector1 = [(1 if path in paths1 else 0) for path in all_paths] | |||
| # vector2 = [(1 if path in paths2 else 0) for path in all_paths] | |||
| # kernel_uv = np.dot(vector1, vector2) | |||
| # kernel = kernel_uv / (len(set(paths1)) + len(set(paths2)) - kernel_uv) | |||
| else: # MinMax kernel | |||
| path_count1 = Counter(paths1) | |||
| path_count2 = Counter(paths2) | |||
| vector1 = [(path_count1[key] if (key in path_count1.keys()) else 0) | |||
| for key in all_paths] | |||
| vector2 = [(path_count2[key] if (key in path_count2.keys()) else 0) | |||
| for key in all_paths] | |||
| kernel = np.sum(np.minimum(vector1, vector2)) / \ | |||
| np.sum(np.maximum(vector1, vector2)) | |||
| return kernel | |||
| def wrapper_uhpath_do_kernelless(k_func, itr): | |||
| i = itr[0] | |||
| j = itr[1] | |||
| return i, j, _untilhpathkernel_do_kernelless(G_plist[i], G_plist[j], k_func) | |||
| # @todo: (can be removed maybe) this method find paths repetively, it could be faster. | |||
| def find_all_paths_until_length(G, | |||
| length, | |||
| ds_attrs, | |||
| node_label='atom', | |||
| edge_label='bond_type'): | |||
| edge_label='bond_type', | |||
| tolabelseqs=True): | |||
| """Find all paths no longer than a certain maximum length in a graph. A | |||
| recursive depth first search is applied. | |||
| @@ -398,7 +463,7 @@ def find_all_paths_until_length(G, | |||
| # path_l = path_l_new[:] | |||
| path_l = [[n] for n in G.nodes] # paths of length l | |||
| all_paths = path_l[:] | |||
| all_paths = [p.copy() for p in path_l] | |||
| for l in range(1, length + 1): | |||
| path_lplus1 = [] | |||
| for path in path_l: | |||
| @@ -409,7 +474,7 @@ def find_all_paths_until_length(G, | |||
| path_lplus1.append(tmp) | |||
| all_paths += path_lplus1 | |||
| path_l = path_lplus1[:] | |||
| path_l = [p.copy() for p in path_lplus1] | |||
| # for i in range(0, length + 1): | |||
| # new_paths = find_all_paths(G, i) | |||
| @@ -419,15 +484,18 @@ def find_all_paths_until_length(G, | |||
| # consider labels | |||
| # print(paths2labelseqs(all_paths, G, ds_attrs, node_label, edge_label)) | |||
| return paths2labelseqs(all_paths, G, ds_attrs, node_label, edge_label) | |||
| print() | |||
| return (paths2labelseqs(all_paths, G, ds_attrs, node_label, edge_label) | |||
| if tolabelseqs else all_paths) | |||
| def wrapper_find_all_paths_until_length(length, ds_attrs, node_label, | |||
| edge_label, itr_item): | |||
| edge_label, tolabelseqs, itr_item): | |||
| g = itr_item[0] | |||
| i = itr_item[1] | |||
| return i, find_all_paths_until_length(g, length, ds_attrs, | |||
| node_label=node_label, edge_label=edge_label) | |||
| node_label=node_label, edge_label=edge_label, | |||
| tolabelseqs=tolabelseqs) | |||
| def find_all_path_as_trie(G, | |||
| @@ -84,7 +84,7 @@ def loadGXL(filename): | |||
| return g | |||
| def saveGXL(graph, filename, method='gedlib-letter'): | |||
| def saveGXL(graph, filename, method='benoit'): | |||
| if method == 'benoit': | |||
| import xml.etree.ElementTree as ET | |||
| root_node = ET.Element('gxl') | |||
| @@ -131,13 +131,13 @@ def saveGXL(graph, filename, method='gedlib-letter'): | |||
| gxl_file.write("<gxl>\n") | |||
| gxl_file.write("<graph id=\"" + str(graph.graph['name']) + "\" edgeids=\"true\" edgemode=\"undirected\">\n") | |||
| for v, attrs in graph.nodes(data=True): | |||
| gxl_file.write("<node id=\"_" + str(v) + "\">\n") | |||
| gxl_file.write("<attr name=\"" + "chem" + "\"><int>" + str(attrs['atom']) + "</int></attr>\n") | |||
| gxl_file.write("<node id=\"_" + str(v) + "\">") | |||
| gxl_file.write("<attr name=\"" + "chem" + "\"><int>" + str(attrs['atom']) + "</int></attr>") | |||
| gxl_file.write("</node>\n") | |||
| for v1, v2, attrs in graph.edges(data=True): | |||
| gxl_file.write("<edge from=\"_" + str(v1) + "\" to=\"_" + str(v2) + "\">\n") | |||
| # gxl_file.write("<attr name=\"valence\"><int>" + str(attrs['bond_type']) + "</int></attr>\n") | |||
| gxl_file.write("<attr name=\"valence\"><int>" + "1" + "</int></attr>\n") | |||
| gxl_file.write("<edge from=\"_" + str(v1) + "\" to=\"_" + str(v2) + "\">") | |||
| # gxl_file.write("<attr name=\"valence\"><int>" + str(attrs['bond_type']) + "</int></attr>") | |||
| gxl_file.write("<attr name=\"valence\"><int>" + "1" + "</int></attr>") | |||
| gxl_file.write("</edge>\n") | |||
| gxl_file.write("</graph>\n") | |||
| gxl_file.write("</gxl>\n") | |||
| @@ -485,7 +485,7 @@ def loadDataset(filename, filename_y=None, extra_params=None): | |||
| return data, y | |||
| def saveDataset(Gn, y, gformat='gxl', group=None, filename='gfile'): | |||
| def saveDataset(Gn, y, gformat='gxl', group=None, filename='gfile', xparams=None): | |||
| """Save list of graphs. | |||
| """ | |||
| import os | |||
| @@ -502,7 +502,7 @@ def saveDataset(Gn, y, gformat='gxl', group=None, filename='gfile'): | |||
| fgroup.write("\n<GraphCollection>") | |||
| for idx, g in enumerate(Gn): | |||
| fname_tmp = "graph" + str(idx) + ".gxl" | |||
| saveGXL(g, dirname_ds + fname_tmp) | |||
| saveGXL(g, dirname_ds + fname_tmp, method=xparams['method']) | |||
| fgroup.write("\n\t<graph file=\"" + fname_tmp + "\" class=\"" + str(y[idx]) + "\"/>") | |||
| fgroup.write("\n</GraphCollection>") | |||
| fgroup.close() | |||