def test_tensor_input(): X = np.random.normal(size=(100, 5, 5)) mds = ClassicalMDS(n_components=3, dissimilarity="euclidean") mds.fit(X) assert_equal(mds.dissimilarity_matrix_.shape, (100, 100)) X_transformed = mds.fit_transform(X) assert_equal(X_transformed.shape, (100, 3))
def use_fit_transform(): A = np.ones((4, 4)) - np.identity(4) mds = ClassicalMDS(n_components=3, dissimilarity="precomputed") B = mds.fit_transform(A) Ahat = _compute_dissimilarity(B) # Checks up to 7 decimal points assert_almost_equal(A, Ahat)
def use_fit(): A = np.ones((4, 4)) - np.identity(4) mds = ClassicalMDS(n_components=3, dissimilarity="precomputed") mds.fit(A) B = np.dot(mds.components_, np.diag(mds.singular_values_)) Ahat = _compute_dissimilarity(B) # Checks up to 7 decimal points assert_almost_equal(A, Ahat)
def use_euclidean(): A = np.array([ [-7.62291243e-17, 6.12372436e-01, 4.95031815e-16], [-4.97243701e-01, -2.04124145e-01, -2.93397401e-01], [5.02711453e-01, -2.04124145e-01, -2.83926977e-01], [-5.46775198e-03, -2.04124145e-01, 5.77324378e-01], ]) mds = ClassicalMDS(dissimilarity="euclidean") B = mds.fit_transform(A) target = np.ones((4, 4)) - np.identity(4) assert_almost_equal(mds.dissimilarity_matrix_, target)
def _omni_embed(pop_array, atlas, graph_path_list, ID, subgraph_name="all_nodes", n_components=None, norm=1): """ Omnibus embedding of arbitrary number of input graphs with matched vertex sets. Given :math:`A_1, A_2, ..., A_m` a collection of (possibly weighted) adjacency matrices of a collection :math:`m` undirected graphs with matched vertices. Then the :math:`(mn \times mn)` omnibus matrix, :math:`M`, has the subgraph where :math:`M_{ij} = \frac{1}{2}(A_i + A_j)`. The omnibus matrix is then embedded using adjacency spectral embedding. Parameters ---------- pop_array : list of nx.Graph or ndarray, or ndarray If list of nx.Graph, each Graph must contain same number of nodes. If list of ndarray, each array must have shape (n_vertices, n_vertices). If ndarray, then array must have shape (n_graphs, n_vertices, n_vertices). atlas : str The name of an atlas (indicating the node definition). graph_pathlist : list List of file paths to graphs in pop_array. ID : str An arbitrary subject identifier. subgraph_name : str Returns ------- out_path : str File path to .npy file containing omni embedding tensor. References ---------- .. [1] Levin, K., Athreya, A., Tang, M., Lyzinski, V., & Priebe, C. E. (2017, November). A central limit theorem for an omnibus embedding of multiple random dot product graphs. In Data Mining Workshops (ICDMW), 2017 IEEE International Conference on (pp. 964-967). IEEE. .. [2] Chung, J., Pedigo, B. D., Bridgeford, E. W., Varjavand, B. K., Helm, H. S., & Vogelstein, J. T. (2019). Graspy: Graph statistics in python. Journal of Machine Learning Research. """ import os import networkx as nx import numpy as np from pynets.core.utils import flatten from graspologic.embed.omni import OmnibusEmbed from graspologic.embed.mds import ClassicalMDS from joblib import dump from pynets.stats.netstats import CleanGraphs dir_path = str(Path(os.path.dirname(graph_path_list[0])).parent) namer_dir = f"{dir_path}/embeddings" if os.path.isdir(namer_dir) is False: os.makedirs(namer_dir, exist_ok=True) clean_mats = [] i = 0 for graph_path in graph_path_list: cg = CleanGraphs(None, None, graph_path, 0, norm) if float(norm) >= 1: G = cg.normalize_graph() mat_clean = nx.to_numpy_array(G) else: mat_clean = pop_array[i] mat_clean[np.where(np.isnan(mat_clean) | np.isinf(mat_clean))] = 0 if np.isnan(np.sum(mat_clean)) == False: clean_mats.append(mat_clean) i += 1 clean_mats = [i for i in clean_mats if np.isfinite(i).all()] if len(clean_mats) > 0: # Omnibus embedding print( f"{'Embedding unimodal omnetome for atlas: '}{atlas} and " f"{subgraph_name}{'...'}" ) omni = OmnibusEmbed(n_components=n_components, check_lcc=False) mds = ClassicalMDS(n_components=n_components) omni_fit = omni.fit_transform(clean_mats) # Transform omnibus tensor into dissimilarity feature mds_fit = mds.fit_transform(omni_fit.reshape(omni_fit.shape[1], omni_fit.shape[2], omni_fit.shape[0])) out_path = ( f"{namer_dir}/gradient-OMNI_{atlas}_{subgraph_name}_" f"{os.path.basename(graph_path_list[0]).split('_thrtype')[0]}.npy" ) # out_path_est_omni = f"{namer_dir}/gradient-OMNI_{atlas}_" \ # f"{subgraph_name}_" \ # f"{os.path.basename(graph_path).split( # '_thrtype')[0]}" \ # f"_MDS.joblib" # out_path_est_mds = f"{namer_dir}/gradient-OMNI_{atlas}_" \ # f"{subgraph_name}_" \ # f"{os.path.basename(graph_path).split( # '_thrtype')[0]}" \ # f"_MDS.joblib" # dump(omni, out_path_est_omni) # dump(omni, out_path_est_mds) print("Saving...") np.save(out_path, mds_fit) del mds, mds_fit, omni, omni_fit else: # Add a null tmp file to prevent pool from breaking out_path = f"{namer_dir}/gradient-OMNI" \ f"_{atlas}_{subgraph_name}_" \ f"{os.path.basename(graph_path_list[0])}_NULL" if not os.path.exists(out_path): os.mknod(out_path) return out_path
def test_input(): X = np.random.normal(0, 1, size=(10, 3)) # X cannot be tensor when precomputed dissimilarity with pytest.raises(ValueError): tensor = np.random.normal(0, 1, size=(10, 3, 3)) mds = ClassicalMDS(n_components=3, dissimilarity="precomputed") mds.fit(tensor) with pytest.raises(ValueError): one_dimensional = np.random.normal(size=10) mds = ClassicalMDS(n_components=2, dissimilarity="euclidean") mds.fit(one_dimensional) # n_components > n_samples with pytest.raises(ValueError): mds = ClassicalMDS(n_components=100) mds.fit(X) # Invalid n_components with pytest.raises(ValueError): mds = ClassicalMDS(n_components=-2) with pytest.raises(TypeError): mds = ClassicalMDS(n_components="1") # Invalid dissimilarity with pytest.raises(ValueError): mds = ClassicalMDS(dissimilarity="abc") # Invalid input for fit function with pytest.raises(ValueError): mds = ClassicalMDS(n_components=3, dissimilarity="precomputed") mds.fit(X="bad_input") # Must be square and symmetric matrix if precomputed dissimilarity with pytest.raises(ValueError): mds = ClassicalMDS(n_components=3, dissimilarity="precomputed") mds.fit(X)
def test_sklearn_conventions(self): check_estimator(ClassicalMDS())