import networkx as nx import numpy as np import matplotlib.pyplot as plt from stochasticBlockModel import SBM x = range(5,150,25) y_sparse = [] y_dense = [] for i in x: # sparse graph n_vertices = i # number of vertices n_communities = 2 # number of communities cin = 15 cout = 5 probability_matrix = (1.0/n_vertices)*(np.full((n_communities,n_communities), cout) + np.diag([cin-cout]*n_communities)) sbm = SBM(n_vertices, n_communities, probability_matrix) y_sparse.append(sbm.average_degree) for i in x: # dense graph n_vertices = i # number of vertices n_communities = 2 # number of communities cin = 0.7 cout = 0.3 probability_matrix = np.full((n_communities,n_communities), cout) + np.diag([cin-cout]*n_communities) sbm = SBM(n_vertices, n_communities, probability_matrix) y_dense.append(sbm.average_degree) plt.xlim(0,x[-1]) plt.xlabel("Number of vertices") plt.ylabel("Average degree") plt.plot(x,y_sparse, 'r', label="sparse")
def main(): #---------------------------------------------------------------------- # Stochastic block model parameters #---------------------------------------------------------------------- n_vertices = 100 # number of vertices n_communities = 2 # number of communities # cin > cout is referred to as the assortative case # cout > cin is called the disassortative case cin = 15 cout = 5 probability_matrix = (1.0/n_vertices)*(np.full((n_communities,n_communities), cout) + np.diag([cin-cout]*n_communities)) # matrix of edge probabilities (to generate a sparse graph) sbm = SBM(n_vertices, n_communities, probability_matrix) print("Average degree: {}, abs(cin - cout): {}, n_commuties*sqrt(c): {}".format(sbm.average_degree, abs(cin-cout), n_communities*np.sqrt(sbm.average_degree))) #---------------------------------------------------------------------- # Draw generated graph and print communities #---------------------------------------------------------------------- color_map = np.array(['cyan', 'red', 'yellow', 'magenta', 'blue', 'green', 'white']) for i in xrange(n_communities): indices = [j+1 for j, x in enumerate(sbm.community_labels) if x == i] print("Community C{}, n{} = {} vertices, color: {}, E[di] = {}".format(i, i, sbm.n_per_community[i], color_map[i], sbm.expected_degrees[i])) if n_vertices > PLOT_MAX_NODES: print("Can't draw graph if number of vertices is too big") else: G = nx.from_numpy_matrix(sbm.adjacency_matrix) # generate networkx graph labels = {key: key+1 for key in xrange(n_vertices)} # vertices numbers node_color = color_map[sbm.community_labels] plt.title("Generated graph using Stochastic block model\n{} nodes and {} communities".format(n_vertices, n_communities)) nx.draw(G, labels=labels, node_color=node_color, font_size=10) plt.figure() #---------------------------------------------------------------------- # Spectral clustering #---------------------------------------------------------------------- n_clusters = 2 if n_clusters != n_communities: print("Number of clusters ({}) is not equal to number of communities generated by the SBM ({})!".format(n_clusters, n_communities)) spectral_labels, eigvals, eigvects, W = SpectralClustering(n_clusters, BetheHessian(sbm.adjacency_matrix), "BetheHessian") # spectral clustering well_placed_vertices = pg.permutation_calculator(sbm.community_labels, spectral_labels, n_clusters) print("Spectral clustering accuracy: " + str(100*well_placed_vertices/n_vertices) + "%") print("Normalized Mutual Information: " + str(normalized_mutual_info_score(sbm.community_labels, spectral_labels))) # Eigenvalues and eigenvectors plt.title("Histogram of matrix eigenvalues") plt.hist(eigvals, bins=100) # plot histogram of the eigenvalues if n_clusters <= 2: plt.figure() plt.title("Eigenvectors corresponding to the {} smallest eigenvalues".format(n_clusters)) plt.plot(W[:,0], W[:,1], 'o', markersize=5) # plot eigenvectors corresponding to the 'n_clusters' smallest eigenvalues plt.figure() plt.title("Kmeans, n_vertices = {}".format(n_vertices)) for i in xrange(n_clusters): ds = W[np.where(spectral_labels == i)] plt.plot(ds[:,0], ds[:,1], color=color_map[i], marker='o', markersize=5, ls='') if n_vertices <= PLOT_MAX_NODES: plt.figure() plt.title("Detected communities") nx.draw(G, labels=labels, node_color=color_map[spectral_labels], font_size=10) plt.show() pass