def get_PR_AUC(causality_truth, causality_value, neglect_idx=None): from sklearn.metrics import precision_recall_curve, auc causality_truth = to_np_array(causality_truth) causality_value = to_np_array(causality_value) assert not np.isinf(causality_value).any() and not np.isnan( causality_value).any() precision_curve, recall_curve, _ = precision_recall_curve( flatten_matrix(causality_truth, neglect_idx), flatten_matrix(causality_value, neglect_idx)) PR_AUC = auc(recall_curve, precision_curve) PR_AUC_list = [] for i in range(len(causality_truth)): try: if neglect_idx is not None: precision_curve_ele, recall_curve_ele, _ = precision_recall_curve( flatten_matrix(causality_truth[i], neglect_idx=i), flatten_matrix(causality_value[i], neglect_idx=i)) else: precision_curve_ele, recall_curve_ele, _ = precision_recall_curve( flatten_matrix(causality_truth[i]), flatten_matrix(causality_value[i])) PR_AUC_ele = auc(recall_curve_ele, precision_curve_ele) except: PR_AUC_ele = np.NaN PR_AUC_list.append(PR_AUC_ele) PR_AUC_mean = np.nanmean(PR_AUC_list) return PR_AUC, PR_AUC_mean, PR_AUC_list
def get_prfs(causality_truth, causality_pred): assert causality_pred.shape == causality_truth.shape assert len(causality_pred.shape) == 2 from sklearn.metrics import precision_recall_fscore_support as prfs precision, recall, F1, _ = prfs( to_np_array(causality_truth).flatten(), to_np_array(causality_pred).flatten()) return precision[1], recall[1], F1[1]
def plot_examples(X_ele, y_ele, title=None, isplot=True): if isplot: assert len(X_ele.shape) == len(y_ele.shape) == 3 N = X_ele.size(-1) fig = plt.figure(figsize=(N * 6, 5)) for j in range(N): plt.subplot(1, N, j + 1) plt.plot( np.concatenate((to_np_array(X_ele)[:, :, j].T, to_np_array(y_ele)[:, :, j].T), 0)) if title is not None: plt.title(title) plt.show()
def get_ROC_AUC(causality_truth, causality_value, neglect_idx=None): from sklearn.metrics import roc_auc_score causality_truth = to_np_array(causality_truth) causality_value = to_np_array(causality_value) assert not np.isinf(causality_value).any() and not np.isnan( causality_value).any() ROC_AUC = roc_auc_score(flatten_matrix(causality_truth, neglect_idx), flatten_matrix(causality_value, neglect_idx)) ROC_AUC_list = [] for i in range(len(causality_truth)): try: if neglect_idx is not None: ROC_AUC_ele = roc_auc_score( flatten_matrix(causality_truth[i], neglect_idx=i), flatten_matrix(causality_value[i], neglect_idx=i)) else: ROC_AUC_ele = roc_auc_score(flatten_matrix(causality_truth[i]), flatten_matrix(causality_value[i])) except: ROC_AUC_ele = np.NaN ROC_AUC_list.append(ROC_AUC_ele) ROC_AUC_mean = np.nanmean(ROC_AUC_list) return ROC_AUC, ROC_AUC_mean, ROC_AUC_list
def train(self, input_list, num_steps=10): for k in range(num_steps): loss_list = [] for i, X in enumerate(input_list): getattr(self, "optimizer_{0}".format(i)).zero_grad() loss = getattr(self, "model_{0}".format(i)).get_loss( flatten(X).detach()) loss_list.append(loss) loss.backward() getattr(self, "optimizer_{0}".format(i)).step() loss_list = torch.stack(loss_list) print("{0}: losses: {1}".format( k, to_string(to_np_array(loss_list), connect=" ", num_digits=4, num_strings=None)))
def get_synthetic_data( N, K, K2=1, p_N=0.5, p_K=0.5, time_length=10, num_examples=3000, A_whole=None, dist_type="uniform", mode="linear", indi_activation=None, noise_multiplicative_matrix=None, noise_variance=None, observational_model=None, isplot=False, velocity_type="pos", normalize=0, is_cuda=False, ): # Configure causal factor A: if A_whole is None: A_whole = np.zeros((N, K, N)) for n in range(N): A_whole[n] = get_A_matrix(N, K, p_N=p_N, p_K=p_K, dist_type=dist_type, isTorch=False) else: assert A_whole.shape[0] == A_whole.shape[ 2], "A_whole must have the shape of (N, K, N)!" if isplot: plot_matrices(A_whole) # Configure individual scaling factor B: if indi_activation is not None: B_whole = np.random.choice( [1, -1], size=(N, K, N)) * (np.random.rand(N, K, N) + 1) else: B_whole = None # configure noise_multiplicative_matrix if noise_multiplicative_matrix is not None: if isinstance(noise_multiplicative_matrix, str) and noise_multiplicative_matrix == "random": noise_multiplicative_matrix = torch.zeros(N, K, N) for n in range(N): noise_multiplicative_matrix[n] = get_A_matrix( N, K, p_N=p_N, p_K=p_K, dist_type=dist_type, isTorch=True).abs() else: noise_multiplicative_matrix = to_Variable( noise_multiplicative_matrix).abs() shape = noise_multiplicative_matrix.shape if len(shape) == 2: assert shape[0] == shape[1] noise_multiplicative_matrix = noise_multiplicative_matrix.unsqueeze( 1).repeat(1, K, 1) if isplot: print("noise_multiplicative_matrix:") plot_matrices(to_np_array(noise_multiplicative_matrix)) # Begin time-series generation: time_series_all = [] for i in range(int(num_examples / time_length)): x = torch.randn(K, N) time_series = [x] for j in range(time_length): if noise_variance is not None: if isinstance(noise_variance, np.ndarray) or isinstance( noise_variance, list): noise_to_add = np.random.multivariate_normal( np.zeros(N), noise_variance, size=time_length) else: noise_to_add = np.random.randn(time_length, N) * np.sqrt(noise_variance) x_t = torch.zeros(1, N) for n in range(N): if indi_activation is not None: x_core = get_activation(indi_activation)( torch.FloatTensor(B_whole[n]) * x) else: x_core = x if noise_multiplicative_matrix is None: x_t[0, n] = get_activation(mode)( (torch.FloatTensor(A_whole[n]) * x_core).sum()) else: x_t[0, n] = get_activation(mode)( (torch.FloatTensor(A_whole[n]) * noise_multiplicative_matrix[n] * torch.randn(K, N) * x_core + torch.FloatTensor(A_whole[n]) * (noise_multiplicative_matrix[n] < 1e-9).float() * x_core).sum()) if noise_variance is not None: x_t[0, n] += noise_to_add[j, n] time_series.append(x_t) x = torch.cat([x[1:], x_t], 0) time_series = torch.cat(time_series, 0) time_series_all.append(time_series) time_series_all = torch.stack(time_series_all) if isplot: for kk in range(4): plt.figure(figsize=(20, 8)) plt.plot(time_series_all[kk].numpy()) plt.legend(list(range(time_series_all.size(-1)))) # Apply observational model if given: if observational_model is not None: if isinstance(observational_model, list): shape = time_series_all.shape time_series_all_new = [] for i, model in enumerate(observational_model): time_series = model(time_series_all[..., i:i + 1].contiguous().view( -1, 1)) time_series_all_new.append(time_series) time_series_all = torch.cat(time_series_all_new, -1).view(shape[0], shape[1], -1) else: time_series_all = observational_model(time_series_all) time_series_all = to_Variable(time_series_all, requires_grad=False) X, y = process_time_series(time_series_all, K=K, K2=K2, velocity_type=velocity_type, normalize=normalize, is_cuda=is_cuda) if is_cuda: time_series_all = time_series_all.cuda() return (X, y), A_whole, B_whole, time_series_all
def get_MIs( X, y, noise_amp_all, group_sizes, mode="xn-y", noise_type="uniform-series", estimate_method="k-nearest", ): assert len(X.shape) == len(y.shape) == 3 _, K, N = X.shape if isinstance(group_sizes, int): num_models = int(N / group_sizes) else: num_models = len(group_sizes) num = noise_amp_all.size(0) if noise_type == "uniform-series": MI = np.zeros((num, num_models)) elif noise_type == "fully-random": MI = np.zeros((num, K, num_models)) else: raise X_std = X.std(0) is_cuda = X.is_cuda device = torch.device("cuda" if is_cuda else "cpu") if noise_type == "uniform-series": for i in range(num): noise_amp_core = X_std * expand_tensor(noise_amp_all[i].to(device), -1, group_sizes) X_tilde = X + torch.randn(X.size()).to(device) * noise_amp_core if mode == "xn-y": arg1 = y arg2 = X_tilde elif mode == "x-y": arg1 = y arg2 = X elif mode == "xn-x": arg1 = X_tilde arg2 = X else: raise for j in range(num_models): if mode == "xn-x": if estimate_method == "k-nearest": MI[i, j] = ee.mi( to_np_array(arg1[:, :, j * group_sizes:(j + 1) * group_sizes].contiguous().view( arg1.size(0), -1)), to_np_array(arg2[:, :, j * group_sizes:(j + 1) * group_sizes].contiguous().view( arg2.size(0), -1))) elif estimate_method == "Gaussian": entropy_X_tilde = get_entropy_Gaussian( arg1[:, :, j * group_sizes:(j + 1) * group_sizes].contiguous().view( arg1.size(0), -1), is_diagonal=False) KM = group_sizes * K entropy_noise = ( KM / float(2) * np.log2(2 * np.pi * np.e) + torch.log2(noise_amp_core[:, j]).sum()) MI[i, j] = entropy_X_tilde - entropy_noise else: raise else: if estimate_method == "k-nearest": MI[i, j] = ee.mi( to_np_array(arg1[:, :, i * group_sizes:(i + 1) * group_sizes].contiguous().view( arg1.size(0), -1)), to_np_array(arg2[:, :, j * group_sizes:(j + 1) * group_sizes].contiguous().view( arg2.size(0), -1))) elif estimate_method == "Gaussian": MI[i, j] = get_entropy_Gaussian( arg1[:, :, i * group_sizes:(i + 1) * group_sizes].contiguous().view( arg1.size(0), -1), arg2[:, :, j * group_sizes:(j + 1) * group_sizes].contiguous().view( arg2.size(0), -1)) else: raise elif noise_type == "fully-random": for i in range(num): noise_amp_core = X_std * noise_amp_all[i].to(device) X_tilde = X + torch.randn(X.size()).to(device) * noise_amp_core if mode == "xn-y": arg1 = y arg2 = X_tilde elif mode == "x-y": arg1 = y arg2 = X elif mode == "xn-x": arg1 = X_tilde arg2 = X else: raise for k in range(K): for j in range(num_models): if mode == "xn-x": MI[i, k, j] = ee.mi( to_np_array(arg1[:, k, j * group_sizes:(j + 1) * group_sizes]), to_np_array(arg2[:, k, j * group_sizes:(j + 1) * group_sizes])) else: MI[i, k, j] = ee.mi( to_np_array(arg1[:, :, i * group_sizes:(i + 1) * group_sizes].contiguous().view( arg1.size(0), -1)), to_np_array(arg2[:, k, j * group_sizes:(j + 1) * group_sizes])) else: raise return MI