<jupyter_start><jupyter_text>Stochastic Block Model (SBM)<jupyter_code>import graspy

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Unlike [Erdos-Renyi (ER) models](./erdos_renyi.ipynb), SBM tends to produce graphs containing communities, subsets characterized by being connected with one another with particular edge densities. For example, edges may be more common within communities than between communities [1](https://en.wikipedia.org/wiki/Stochastic_block_model).SBM is parametrized by $n$, which specifies the number of vertices in each community, and a block probability matrix, $P$, where each element specifies the probability of an edge in a particular block and has size that is number of communites by number of communities. One can think of SBM as a collection of ER graphs where each block corresponds to an ER graph.Below, we sample a two-block SBM (undirected, no self-loops) with following parameters:\begin{align*}n &= [50, 50]\\P &= \begin{bmatrix} 0.5 & 0.2\\0.2 & 0.05\end{bmatrix}\end{align*}The diagonals correspond to probability of an edge within blocks and the off-diagonals correspond to probability of an edge across blocks.<jupyter_code>from graspy.simulations import sbm

n = [50, 50]
p = [[0.5, 0.2],
     [0.2, 0.05]]

np.random.seed(1)
G = sbm(n=n, p=p)<jupyter_output><empty_output><jupyter_text>Visualize the graph using heatmap<jupyter_code>from graspy.plot import heatmap

heatmap(G, title ='SBM Simulation')<jupyter_output><empty_output><jupyter_text>Weighted SBM GraphsSimilar to ER simulations, *sbm* functions provide ways to sample weights for all edges that were sampled via a probability distribution function. In order to sample with weights, you can either:1. Provide *single* probability distribution function with corresponding keyword arguments for the distribution function. All weights will be sampled using the same function.2. Provide a probability distribution function with corresponding keyword arguments for each block.Below we sample a SBM (undirected, no self-loops) with the following parameters:\begin{align*}n &= [50, 50]\\P &= \begin{bmatrix}0.5 & 0.2\\0.2 & 0.05\end{bmatrix}\end{align*}and the weights are sampled from the following probability functions:\begin{align*}PDFs &= \begin{bmatrix}Normal & Poisson\\Poisson & Normal\end{bmatrix}\\Parameters   &= \begin{bmatrix}{\mu=3, \sigma^2=1} & {\lambda=5}\\{\lambda=5} & {\mu=3, \sigma^2=1}\end{bmatrix}\end{align*}<jupyter_code>from numpy.random import normal, poisson

n = [50, 50]
p = [[0.5, 0.2],
     [0.2, 0.05]]
wt = [[normal, poisson],
      [poisson, normal]]
wtargs = [[dict(loc=3, scale=1), dict(lam=5)],
          [dict(lam=5), dict(loc=3, scale=1)]]

G = sbm(n=n, p=p, wt=wt, wtargs=wtargs)<jupyter_output><empty_output><jupyter_text>Visualize the graph using heatmap<jupyter_code>heatmap(G, title='Weighted SBM Simulation')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11457627118644068, 'fraction_numerical': 0.023728813559322035, 'mean_word_length': 5.587053571428571, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '52739', 'license': 'Apache-2.0', 'n_tokens_mistral': 966, 'n_tokens_neox': 906, 'n_words': 311, 'path': 'docs/tutorials/simulations/sbm.ipynb', 'repo_name': 'idc9/graspy', 'size': '2950'}