def estimate_bp_hawkes_params(event_dict, node_membership, duration, num_classes, agg_adj=None, return_block_pair_events=False): """ Estimate CHIP Hawkes parameters. :param event_dict: Edge dictionary of events between all node pair. :param node_membership: (list) membership of every node to one of K classes. :param duration: (int) duration of the network :param num_classes: (int) number of blocks / classes :param agg_adj: (optional) np array (num_nodes x num_nodes) Adjacency matrix where element ij denotes the number of events between nodes i an j. If None, this will be calculated. :param return_block_pair_events: (bool) If True, returns the return_block_pair_events :return: parameters of the CHIP model -> mu, alpha, beta, m """ if agg_adj is None: num_nodes = len(node_membership) agg_adj = utils.event_dict_to_aggregated_adjacency( num_nodes, event_dict) bp_mu, bp_alpha_beta_ratio = estimate_utils.estimate_hawkes_from_counts( agg_adj, node_membership, duration, 1e-10 / duration) bp_beta = np.zeros((num_classes, num_classes), dtype=np.float) block_pair_events = utils.event_dict_to_block_pair_events( event_dict, node_membership, num_classes) bp_size = utils.calc_block_pair_size(node_membership, num_classes) for b_i in range(num_classes): for b_j in range(num_classes): bp_beta[b_i, b_j], _ = estimate_utils.estimate_beta_from_events( block_pair_events[b_i][b_j], bp_mu[b_i, b_j], bp_alpha_beta_ratio[b_i, b_j], duration, bp_size[b_i, b_j]) bp_alpha = bp_alpha_beta_ratio * bp_beta if return_block_pair_events: return bp_mu, bp_alpha, bp_beta, bp_alpha_beta_ratio, block_pair_events return bp_mu, bp_alpha, bp_beta, bp_alpha_beta_ratio
def estimate_bp_hawkes_params(event_dict, node_membership, duration, num_classes): """ Estimate CHIP Hawkes parameters. :param event_dict: Edge dictionary of events between all node pair. :param node_membership: (list) membership of every node to one of K classes. :param duration: (int) duration of the network :param num_classes: (int) number of blocks / classes :return: parameters of the CHIP model -> mu, alpha, beta, m """ num_nodes = len(node_membership) agg_adj = utils.event_dict_to_aggregated_adjacency(num_nodes, event_dict) bp_mu, bp_alpha_beta_ratio = estimate_utils.estimate_hawkes_from_counts( agg_adj, node_membership, duration, 1e-10 / duration) bp_beta = np.zeros((num_classes, num_classes), dtype=np.float) block_pair_events = utils.event_dict_to_block_pair_events( event_dict, node_membership, num_classes) for b_i in range(num_classes): for b_j in range(num_classes): bp_size = len(np.where(node_membership == b_i)[0]) * len( np.where(node_membership == b_j)[0]) if b_i == b_j: bp_size -= len(np.where(node_membership == b_i)[0]) bp_beta[b_i, b_j], _ = estimate_utils.estimate_beta_from_events( block_pair_events[b_i][b_j], bp_mu[b_i, b_j], bp_alpha_beta_ratio[b_i, b_j], duration, bp_size) bp_alpha = bp_alpha_beta_ratio * bp_beta return bp_mu, bp_alpha, bp_beta, bp_alpha_beta_ratio
tic = time.time() bp_beta = np.zeros((num_classes, num_classes), dtype=np.float) train_block_pair_events = utils.event_dict_to_block_pair_events( train_event_dict, train_node_membership, num_classes) cnt = 0 for b_i in range(num_classes): for b_j in range(num_classes): bp_size = len(np.where(train_node_membership == b_i)[0]) * len( np.where(train_node_membership == b_j)[0]) if b_i == b_j: bp_size -= len(np.where(train_node_membership == b_i)[0]) bp_beta[b_i, b_j], _ = estimate_utils.estimate_beta_from_events( train_block_pair_events[b_i][b_j], bp_mu[b_i, b_j], bp_alpha_beta_ratio[b_i, b_j], train_duration, bp_size) cnt += 1 print(f"{100 * cnt / num_classes ** 2:0.2f}% Done.", end='\r') bp_alpha = bp_alpha_beta_ratio * bp_beta toc = time.time() toc_tot = time.time() print(f"Beta estimated in {toc - tic:.1f}s") print(f"Total computation time: {toc_tot - tic_tot:.1f}s") if verbose: print("Alpha") print(bp_alpha)
def fit_community_model(event_dict, num_nodes, duration, num_classes, local_search_max_iter, local_search_n_cores, verbose=False): """ Fits CHIP model to a network. :param event_dict: Edge dictionary of events between all node pair. :param num_nodes: (int) Total number of nodes :param duration: (int) duration of the network :param num_classes: (int) number of blocks / classes :param local_search_max_iter: Maximum number of local search to be performed. If 0, no local search is done :param local_search_n_cores: Number of cores to parallelize local search. Only applicable if `local_search_max_iter` > 0 :param verbose: Prints fitted Block Hawkes parameters :return: node_membership, mu, alpha, beta, block_pair_events """ agg_adj = utils.event_dict_to_aggregated_adjacency(num_nodes, event_dict) # adj = utils.event_dict_to_adjacency(num_nodes, event_dict) # Running spectral clustering node_membership = spectral_cluster(agg_adj, num_classes, verbose=False) if local_search_max_iter > 0 and num_classes > 1: node_membership, bp_mu, bp_alpha, bp_beta = cls.chip_local_search( event_dict, num_classes, node_membership, duration, max_iter=local_search_max_iter, n_cores=local_search_n_cores, return_fitted_param=True, verbose=False) block_pair_events = utils.event_dict_to_block_pair_events( event_dict, node_membership, num_classes) else: bp_mu, bp_alpha_beta_ratio = estimate_utils.estimate_hawkes_from_counts( agg_adj, node_membership, duration, 1e-10 / duration) bp_beta = np.zeros((num_classes, num_classes), dtype=np.float) block_pair_events = utils.event_dict_to_block_pair_events( event_dict, node_membership, num_classes) for b_i in range(num_classes): for b_j in range(num_classes): bp_size = len(np.where(node_membership == b_i)[0]) * len( np.where(node_membership == b_j)[0]) if b_i == b_j: bp_size -= len(np.where(node_membership == b_i)[0]) bp_beta[b_i, b_j], _ = estimate_utils.estimate_beta_from_events( block_pair_events[b_i][b_j], bp_mu[b_i, b_j], bp_alpha_beta_ratio[b_i, b_j], duration, bp_size) bp_alpha = bp_alpha_beta_ratio * bp_beta # Printing information about the fit if verbose: _, block_count = np.unique(node_membership, return_counts=True) class_prob = block_count / sum(block_count) print(f"Membership percentage: ", class_prob) print("Mu:") print(bp_mu) print("\nAlpha:") print(bp_alpha) print("\nBeta:") print(bp_beta) return node_membership, bp_mu, bp_alpha, bp_beta, block_pair_events