Giter Club home page Giter Club logo

Comments (4)

alexpghayes avatar alexpghayes commented on September 12, 2024

We reorder pi_in and pi_out so that there blocks are arranged from smallest to largest, at https://github.com/RoheLab/fastRG/blob/main/R/directed_dcsbm.R#L440.

It sounds like you may also want the undirected version of the sbm, in which case you should use dcsbm() rather than directed_dcsbm().

If you would like to combine the latent information in your sbm object with the sample graph in net, you should be able to do that as follows.

set.seed(32)

bm <- as.matrix(cbind(
  c(.3, .005, .005, .005, .005),
  c(.002, .3, .005, .005, .005),
  c(.002, .01, .3, .005, .005),
  c(.002, .01, .005, .2, .005),
  c(.002, .005, .005, .005, .2)
))

pi <- c(5, 50, 20, 25, 100)

sbm <- fastRG::directed_dcsbm(
  n = 200,
  B = bm,
  pi_in = pi,
  pi_out = pi,
  expected_out_degree = 3,
  allow_self_loops = FALSE,
  sort_nodes = TRUE
)
#> Generating random degree heterogeneity parameters `theta_in` and `theta_out` from LogNormal(2, 1) distributions. This distribution may change in the future. Explicitly set `theta_in` and `theta_out` for reproducible results.

net <- fastRG::sample_igraph(sbm)

## the order of the blocks as given for the block probabilities don't align with the order of the block memberships in the factor model:
pi
#> [1]   5  50  20  25 100
table(sbm$z_in)
#> 
#>   1   2   3   4   5 
#>   3  25  24  47 101

net |>
  igraph::set_vertex_attr("in_block", value = sbm$z_in)
#> Error in i_set_vertex_attr(graph = graph, name = name, value = value, : Length of new attribute value must be 1 or 156, the number of target vertices, not 200

Created on 2023-08-14 with reprex v2.0.2

However, it looks like there is an issue creating the igraph object here. I'll fix this and ping again here once things are working as expected.

from fastrg.

alexpghayes avatar alexpghayes commented on September 12, 2024

Fixed. You'll need to update to the dev version with

remotes::install_github("RoheLab/fastRG")

Then I think you'll want something like the following

set.seed(32)

bm <- as.matrix(cbind(
  c(.3, .005, .005, .005, .005),
  c(.002, .3, .005, .005, .005),
  c(.002, .01, .3, .005, .005),
  c(.002, .01, .005, .2, .005),
  c(.002, .005, .005, .005, .2)
))

pi <- c(5, 50, 20, 25, 100)

latent <- fastRG::dcsbm(
  n = 200,
  B = bm,
  pi = pi,
  expected_degree = 3,
  allow_self_loops = FALSE,
  sort_nodes = TRUE,
  poisson_edges = FALSE     # my guess is that you want this! would read the documentation about this carefully!
)
#> Generating random degree heterogeneity parameters `theta` from a LogNormal(2, 1) distribution. This distribution may change in the future. Explicitly set `theta` for reproducible results.


ig <- fastRG::sample_igraph(latent)

# node orders between `latent` and `ig` object will match up :)
ig_with_block <- ig |>
  igraph::set_vertex_attr("block", value = latent$z)

igraph::V(ig_with_block)$block
#>   [1] block1 block1 block1 block1 block1 block1 block1 block1 block2 block2
#>  [11] block2 block2 block2 block2 block2 block2 block2 block2 block2 block2
#>  [21] block2 block2 block2 block2 block2 block2 block2 block2 block2 block2
#>  [31] block2 block2 block3 block3 block3 block3 block3 block3 block3 block3
#>  [41] block3 block3 block3 block3 block3 block3 block3 block3 block3 block3
#>  [51] block3 block3 block4 block4 block4 block4 block4 block4 block4 block4
#>  [61] block4 block4 block4 block4 block4 block4 block4 block4 block4 block4
#>  [71] block4 block4 block4 block4 block4 block4 block4 block4 block4 block4
#>  [81] block4 block4 block4 block4 block4 block4 block4 block4 block4 block4
#>  [91] block4 block4 block4 block4 block4 block4 block4 block4 block4 block4
#> [101] block4 block4 block4 block4 block4 block4 block4 block4 block4 block4
#> [111] block4 block4 block4 block5 block5 block5 block5 block5 block5 block5
#> [121] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [131] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [141] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [151] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [161] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [171] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [181] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> [191] block5 block5 block5 block5 block5 block5 block5 block5 block5 block5
#> Levels: block1 block2 block3 block4 block5

Again note that the blocks are ordered by block size

Created on 2023-08-14 with reprex v2.0.2

from fastrg.

eapower avatar eapower commented on September 12, 2024

Thanks for the quick and helpful reply! Just to be clear: imagine you have two blocks of the same size, but very different entries in the block matrix: how could you be sure that you're associating the right block with the right entries in the block matrix? e.g., if you run the above with set.seed(34), you get block 2 and 3 differing by one node (see with table(latent$z)) -- I can't be sure which block matrix entries those really align with, given the sorting of blocks by size.

Also, with set.seed(32) as original, table(latent$z) implies that blocks aren't quite sorted by size?

(Finally, I do actually want a directed network to result (and the block matrix given wasn't symmetric), so is there any chance of setting z_in == z_out?)

from fastrg.

alexpghayes avatar alexpghayes commented on September 12, 2024

imagine you have two blocks of the same size, but very different entries in the block matrix: how could you be sure that you're associating the right block with the right entries in the block matrix?

When we sort pi vectors, we also reorder the rows and columns of B to align with sorted pi. See https://github.com/RoheLab/fastRG/blob/main/R/directed_dcsbm.R#L433, for example. I will add some documentation about this.

Also, with set.seed(32) as original, table(latent$z) implies that blocks aren't quite sorted by size?

Right, they're sorted by expected size.

(Finally, I do actually want a directed network to result (and the block matrix given wasn't symmetric), so is there any chance of setting z_in == z_out?)

Yes, although it's a little hacky.

set.seed(32)

bm <- as.matrix(cbind(
  c(.3, .005, .005, .005, .005),
  c(.002, .3, .005, .005, .005),
  c(.002, .01, .3, .005, .005),
  c(.002, .01, .005, .2, .005),
  c(.002, .005, .005, .005, .2)
))

pi <- c(5, 50, 20, 25, 100)

# note: this is a Poisson DCSBM, rather than a Bernoulli DCSBM
latent <- fastRG::directed_dcsbm(
  n = 200,
  B = bm,
  pi_in = pi,
  pi_out = pi,
  expected_out_degree = 3,
  allow_self_loops = FALSE,
  sort_nodes = TRUE
)
#> Generating random degree heterogeneity parameters `theta_in` and `theta_out` from LogNormal(2, 1) distributions. This distribution may change in the future. Explicitly set `theta_in` and `theta_out` for reproducible results.

# for sampling to work as expected, all you need is this, which forces
# blocks and degree-correction parameters to match across incoming and
# outgoing blocks
latent$Y <- latent$X

# fix meta-data
latent$theta_out <- latent$theta_in
latent$z_out <- latent$z_in
latent$pi_out <- latent$pi_in

ig <- fastRG::sample_igraph(latent)

# node orders between `latent` and `ig` object will match up :)
ig_with_block <- ig |>
  igraph::set_vertex_attr("block", value = latent$z_in)

igraph::V(ig_with_block)$block
#>   [1] 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3
#>  [38] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
#>  [75] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5
#> [112] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
#> [149] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
#> [186] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
#> Levels: 1 2 3 4 5

Created on 2023-08-15 with reprex v2.0.2

from fastrg.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.