def fit( self, adjacency: Union[sparse.csr_matrix, np.ndarray]) -> 'LaplacianEmbedding': """Compute the graph embedding. Parameters ---------- adjacency : Adjacency matrix of the graph (symmetric matrix). Returns ------- self: :class:`LaplacianEmbedding` """ adjacency = check_format(adjacency).asfptype() check_square(adjacency) check_symmetry(adjacency) n = adjacency.shape[0] regularize: bool = not (self.regularization is None or self.regularization == 0.) check_scaling(self.scaling, adjacency, regularize) if regularize: solver: EigSolver = LanczosEig() else: solver = set_solver(self.solver, adjacency) n_components = 1 + check_n_components(self.n_components, n - 2) weights = adjacency.dot(np.ones(n)) regularization = self.regularization if regularization: if self.relative_regularization: regularization = regularization * weights.sum() / n**2 weights += regularization * n laplacian = LaplacianOperator(adjacency, regularization) else: weight_diag = sparse.diags(weights, format='csr') laplacian = weight_diag - adjacency solver.which = 'SM' solver.fit(matrix=laplacian, n_components=n_components) eigenvalues = solver.eigenvalues_[1:] eigenvectors = solver.eigenvectors_[:, 1:] embedding = eigenvectors.copy() if self.scaling: eigenvalues_inv_diag = diag_pinv(eigenvalues**self.scaling) embedding = eigenvalues_inv_diag.dot(embedding.T).T if self.normalized: embedding = normalize(embedding, p=2) self.embedding_ = embedding self.eigenvalues_ = eigenvalues self.eigenvectors_ = eigenvectors self.regularization_ = regularization return self
def fit(self, adjacency: Union[sparse.csr_matrix, np.ndarray]) -> 'Spectral': """Compute the graph embedding. Parameters ---------- adjacency : Adjacency matrix of the graph (symmetric matrix). Returns ------- self: :class:`Spectral` """ adjacency = check_format(adjacency).asfptype() check_square(adjacency) check_symmetry(adjacency) n = adjacency.shape[0] solver = set_solver(self.solver, adjacency) n_components = 1 + check_n_components(self.n_components, n - 2) regularize: bool = not (self.regularization is None or self.regularization == 0.) check_scaling(self.scaling, adjacency, regularize) weights = adjacency.dot(np.ones(n)) regularization = self.regularization if regularization: if self.relative_regularization: regularization = regularization * weights.sum() / n**2 weights += regularization * n # Spectral decomposition of the normalized adjacency matrix weights_inv_sqrt_diag = diag_pinv(np.sqrt(weights)) if regularization: norm_adjacency = NormalizedAdjacencyOperator( adjacency, regularization) else: norm_adjacency = weights_inv_sqrt_diag.dot( adjacency.dot(weights_inv_sqrt_diag)) solver.which = 'LA' solver.fit(matrix=norm_adjacency, n_components=n_components) eigenvalues = solver.eigenvalues_ index = np.argsort(-eigenvalues)[1:] # skip first eigenvalue eigenvalues = eigenvalues[index] eigenvectors = weights_inv_sqrt_diag.dot(solver.eigenvectors_[:, index]) embedding = eigenvectors.copy() if self.scaling: eigenvalues_inv_diag = diag_pinv((1 - eigenvalues)**self.scaling) embedding = eigenvalues_inv_diag.dot(embedding.T).T if self.normalized: embedding = normalize(embedding, p=2) self.embedding_ = embedding self.eigenvalues_ = eigenvalues self.eigenvectors_ = eigenvectors self.regularization_ = regularization return self
def fit(self, adjacency: Union[sparse.csr_matrix, np.ndarray]) -> 'Spectral': """Compute the graph embedding. Parameters ---------- adjacency : Adjacency matrix of the graph (symmetric matrix). Returns ------- self: :class:`Spectral` """ adjacency = check_format(adjacency).asfptype() check_square(adjacency) check_symmetry(adjacency) n = adjacency.shape[0] if self.solver == 'auto': solver = auto_solver(adjacency.nnz) if solver == 'lanczos': self.solver: EigSolver = LanczosEig() else: # pragma: no cover self.solver: EigSolver = HalkoEig() n_components = check_n_components(self.n_components, n - 2) n_components += 1 if self.equalize and (self.regularization is None or self.regularization == 0.) and not is_connected(adjacency): raise ValueError( "The option 'equalize' is valid only if the graph is connected or with regularization." "Call 'fit' either with 'equalize' = False or positive 'regularization'." ) weights = adjacency.dot(np.ones(n)) regularization = self.regularization if regularization: if self.relative_regularization: regularization = regularization * weights.sum() / n**2 weights += regularization * n if self.normalized_laplacian: # Finding the largest eigenvalues of the normalized adjacency is easier for the solver than finding the # smallest eigenvalues of the normalized laplacian. weights_inv_sqrt_diag = diag_pinv(np.sqrt(weights)) if regularization: norm_adjacency = NormalizedAdjacencyOperator( adjacency, regularization) else: norm_adjacency = weights_inv_sqrt_diag.dot( adjacency.dot(weights_inv_sqrt_diag)) self.solver.which = 'LA' self.solver.fit(matrix=norm_adjacency, n_components=n_components) eigenvalues = 1 - self.solver.eigenvalues_ # eigenvalues of the Laplacian in increasing order index = np.argsort(eigenvalues)[1:] # skip first eigenvalue eigenvalues = eigenvalues[index] # eigenvectors of the Laplacian, skip first eigenvector eigenvectors = np.array( weights_inv_sqrt_diag.dot(self.solver.eigenvectors_[:, index])) else: if regularization: laplacian = LaplacianOperator(adjacency, regularization) else: weight_diag = sparse.diags(weights, format='csr') laplacian = weight_diag - adjacency self.solver.which = 'SM' self.solver.fit(matrix=laplacian, n_components=n_components) eigenvalues = self.solver.eigenvalues_[1:] eigenvectors = self.solver.eigenvectors_[:, 1:] embedding = eigenvectors.copy() if self.equalize: eigenvalues_sqrt_inv_diag = diag_pinv(np.sqrt(eigenvalues)) embedding = eigenvalues_sqrt_inv_diag.dot(embedding.T).T if self.barycenter: eigenvalues_diag = sparse.diags(eigenvalues) subtract = eigenvalues_diag.dot(embedding.T).T if not self.normalized_laplacian: weights_inv_diag = diag_pinv(weights) subtract = weights_inv_diag.dot(subtract) embedding -= subtract if self.normalized: embedding = normalize(embedding, p=2) self.embedding_ = embedding self.eigenvalues_ = eigenvalues self.eigenvectors_ = eigenvectors self.regularization_ = regularization return self