Tutorial 2: Terms and model specification

Goal. Learn how a model is written in nwergm and how to read the coefficient of each kind of term: covariate terms (nodematch, nodefactor, nodemix, nodeicov), structural terms (mutual) and triad terms (gwesp, with its decay parameter).

  • This is Tutorial 2. It builds on Tutorial 1: A first ERGM, which fits a first model and explains edges, MPLE and MCMLE.
  • You need the core nwcommands and the package nwergm (see Install).

Data. Two networks that ship with nwcommands and are loaded with nwwebuse: mesa, the friendship network of 205 students in a US high school (undirected, with the attributes grade, race and sex), and lazega, the friendship network among 71 lawyers of a law firm (directed, with practice, seniority and others). The commands below were run with nwergm 1.3.1 and the core 3.10.0; the complete script and log are in example.do and example.log. Every model uses only terms that are in the released version 1.3.1. Models fitted by Monte Carlo involve simulation, so a repetition with another seed() gives slightly different numbers. Output is shortened to the coefficient table and the log-likelihood line; ... marks what is left out.

How a model is written

nwergm netname, edges term1 term2(...) ... [options]

edges is required (it is the intercept). Every other term is an option named after the term of R’s ergm. Each coefficient is the change in the log-odds of a tie when the statistic of the term grows by one, given everything else in the model. One restriction: nodal attributes must be numeric, so a string variable has to be encoded first.

Covariate terms on the mesa network

. nwwebuse mesa, nwclear
. encode race, generate(race_n)
. encode sex, generate(sex_n)

With only edges the coefficient is the log-odds of the density of the network:

. nwergm mesa, edges

Exponential-family random graph model

Network:               =  mesa
Nodes:                 =  205
Ties:                  =  203
Directed:              =  No
Estimation:            =  MPLE

------------------------------------------------------------------------------
        mesa | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
       edges |  -4.625021   .0705294   -65.58   0.000    -4.763256   -4.486786
------------------------------------------------------------------------------

Maximum pseudolikelihood estimate (not full ERGM maximum likelihood unless the model is dyad-independent).

             Null Deviance:   28987.4  on 20910 degrees of freedom
         Residual Deviance:    2285.7  on 20909 degrees of freedom

Log-likelihood: -1142.8711 (df = 1)   AIC:    2287.7   BIC:    2295.7   (MC std. err. =       0)

nodematch(grade) adds one statistic: the number of ties between students of the same grade.

. nwergm mesa, edges nodematch(grade)
...
---------------------------------------------------------------------------------
           mesa | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
----------------+----------------------------------------------------------------
          edges |  -6.034045   .1583032   -38.12   0.000    -6.344314   -5.723776
nodematch_grade |   2.830999   .1773251    15.97   0.000     2.483449     3.17855
---------------------------------------------------------------------------------
...
Log-likelihood:  -969.7742 (df = 2)   AIC:    1943.5   BIC:    1959.4   (MC std. err. =       0)

The coefficient 2.83 is large: the odds of a tie between two students of the same grade are exp(2.83), about 17 times the odds for students of different grades, holding the other terms fixed. Adding race and sex works the same way, one coefficient per variable:

. nwergm mesa, edges nodematch(grade race_n sex_n)
...
----------------------------------------------------------------------------------
            mesa | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-----------------+----------------------------------------------------------------
           edges |  -6.600575   .1998753   -33.02   0.000    -6.992324   -6.208827
 nodematch_grade |   2.830693    .177456    15.95   0.000     2.482886    3.178501
nodematch_race_n |   .4331562   .1429951     3.03   0.002     .1528911    .7134214
 nodematch_sex_n |   .6447389    .149475     4.31   0.000     .3517733    .9377045
----------------------------------------------------------------------------------
...
Log-likelihood:  -955.5870 (df = 4)   AIC:    1919.2   BIC:    1951.0   (MC std. err. =       0)

All three kinds of homophily are positive, and grade is by far the strongest. Every term so far depends only on the attributes of the two students, so the model is dyad-independent: nwergm reports the maximum pseudolikelihood estimate (MPLE), which for such a model is the maximum likelihood estimate, and no simulation is needed.

Pooled or differential homophily

nodematch pools all levels of an attribute into one coefficient. nodematchdiff() gives one coefficient per level, so you can see whether homophily is equally strong for girls and for boys:

. nwergm mesa, edges nodematch(grade) nodematchdiff(sex_n)
...
-----------------------------------------------------------------------------------
             mesa | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
------------------+----------------------------------------------------------------
            edges |  -6.392904   .1856467   -34.44   0.000    -6.756765   -6.029043
  nodematch_grade |   2.820284   .1774895    15.89   0.000     2.472411    3.168157
nodematch_sex_n_1 |   .8880277   .1651607     5.38   0.000     .5643186    1.211737
nodematch_sex_n_2 |    .333064   .1871779     1.78   0.075     -.033798     .699926
-----------------------------------------------------------------------------------
...
Log-likelihood:  -955.4147 (df = 4)   AIC:    1918.8   BIC:    1950.6   (MC std. err. =       0)

(The levels of sex_n are 1 for F and 2 for M.) The preference for the same sex is clearer among girls (0.89, p < 0.001) than among boys (0.33, p = 0.075).

Activity by group and mixing between groups

nodefactor() asks whether members of a group have more ties overall: one coefficient per level, the first level being the reference, as in R. nodemix() gives one coefficient per cell of the mixing matrix, again with the first cell as the reference:

. nwergm mesa, edges nodematch(grade) nodefactor(race_n) nodemix(sex_n)
...
-------------------------------------------------------------------------------------
               mesa | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
--------------------+----------------------------------------------------------------
              edges |  -3.303633   .4342755    -7.61   0.000    -4.154797   -2.452468
    nodematch_grade |   2.874633   .1785757    16.10   0.000     2.524631    3.224635
nodefactor_race_n_2 |  -1.335929   .2233276    -5.98   0.000    -1.773643   -.8982147
nodefactor_race_n_3 |   -.924473   .2260387    -4.09   0.000    -1.367501   -.4814453
nodefactor_race_n_4 |  -3.214314   1.025584    -3.13   0.002    -5.224422   -1.204206
nodefactor_race_n_5 |  -.8606332   .2582152    -3.33   0.001    -1.366726   -.3545407
  nodemix_sex_n_1_2 |  -.9352662   .1663521    -5.62   0.000     -1.26131   -.6092221
  nodemix_sex_n_2_2 |  -.6284435   .1849762    -3.40   0.001    -.9909901   -.2658968
-------------------------------------------------------------------------------------
...
Log-likelihood:  -931.6931 (df = 8)   AIC:    1879.4   BIC:    1943.0   (MC std. err. =       0)

The levels of race_n are sorted alphabetically (Black, Hisp, NatAm, Other, White), so the reference is the small group of 6 Black students. Each nodefactor_race_n_k compares group k with it: all four are negative, so students of the other groups have fewer ties on average. This is a statement about how many ties people have, not about with whom they tie. The two nodemix_sex_n cells (girl-boy and boy-boy) are measured against girl-girl ties, the reference cell: both are negative, so, given the other terms, girl-girl is the most frequent kind of tie in these data.

Dyad-dependent terms on the Lazega network

A term such as mutual (the number of reciprocated pairs) depends on more than one dyad at a time, so the model is dyad-dependent. nwergm then switches to Monte Carlo maximum likelihood on its own, and seed() makes the simulation repeatable. As in R’s ergm, the number of simulated networks adapts to the model (the iteration counts below differ between models for this reason). nodeicov() is the effect of a numeric attribute on receiving ties.

. nwwebuse lazega, nwclear
. encode practice, generate(prac)
. nwergm lazega_fr, edges mutual nodematch(prac) nodeicov(seniority)
...
------------------------------------------------------------------------------------
         lazega_fr | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------------+----------------------------------------------------------------
             edges |  -2.514152   .1074062   -23.41   0.000    -2.724665    -2.30364
            mutual |   .9874129   .1527646     6.46   0.000     .6879997    1.286826
    nodematch_prac |   .9147415   .0937094     9.76   0.000     .7310745    1.098409
nodeicov_seniority |   -.006675   .0022217    -3.00   0.003    -.0110295   -.0023205
------------------------------------------------------------------------------------

MCMLE converged after 1 iteration(s).
...
Log-likelihood: -1697.6808 (df = 4)   AIC:    3403.4   BIC:    3429.4   (MC std. err. =  .14486)

mutual is 0.99: friendships are strongly reciprocal. Lawyers of the same practice are more likely to be friends, and the negative nodeicov_seniority says that lawyers with a higher value of seniority receive slightly fewer friendship nominations.

The decay of gwesp

Friends of friends tend to become friends. gwesp(decay) counts tied pairs that have shared partners, with diminishing weight for each additional partner; decay sets how fast the weight diminishes (a small decay means that the second and third shared partner add little, a large decay that each shared partner counts nearly fully). The right value is an empirical question. Here are two values:

. nwergm lazega_fr, edges mutual nodematch(prac) nodeicov(seniority) gwesp(0.5) seed(1)
...
------------------------------------------------------------------------------------
         lazega_fr | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------------+----------------------------------------------------------------
             edges |   -3.32184    .131386   -25.28   0.000    -3.579352   -3.064328
            mutual |   .7969492   .1553399     5.13   0.000     .4924887     1.10141
    nodematch_prac |   .7214706    .080024     9.02   0.000     .5646264    .8783149
nodeicov_seniority |  -.0046162   .0018014    -2.56   0.010    -.0081468   -.0010856
         gwesp_0.5 |   .4935235    .061269     8.06   0.000     .3734384    .6136085
------------------------------------------------------------------------------------

MCMLE converged after 2 iteration(s).
...
Log-likelihood: -1667.4731 (df = 5)   AIC:    3344.9   BIC:    3377.5   (MC std. err. =  .15171)
. nwergm lazega_fr, edges mutual nodematch(prac) nodeicov(seniority) gwesp(1) seed(1)
...
------------------------------------------------------------------------------------
         lazega_fr | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------------+----------------------------------------------------------------
             edges |  -3.167451   .1101029   -28.77   0.000    -3.383249   -2.951653
            mutual |      .8028   .1607891     4.99   0.000     .4876591    1.117941
    nodematch_prac |   .6901202   .0781094     8.84   0.000     .5370286    .8432119
nodeicov_seniority |  -.0043719   .0016676    -2.62   0.009    -.0076403   -.0011035
           gwesp_1 |   .3242339   .0380017     8.53   0.000     .2497519    .3987159
------------------------------------------------------------------------------------

MCMLE converged after 5 iteration(s).
...
Log-likelihood: -1666.0944 (df = 5)   AIC:    3342.2   BIC:    3374.7   (MC std. err. =  .11364)

Both values give a clearly positive closure effect and similar other coefficients, but the two gwesp coefficients cannot be compared by size, because the statistic is scaled differently. Compare the models through the log-likelihood, AIC and BIC (see Tutorial 4): here -1667.5 for decay 0.5 and -1666.1 for decay 1, a small difference. To let the data choose the decay, the curved term gwespfree() estimates it as a parameter.

Adding a degree term

Terms for the degree distribution (gwidegree(), gwodegree(), degree(), kstar() and others) are added in the same way:

. nwergm lazega_fr, edges mutual nodematch(prac) nodeicov(seniority) gwesp(0.5) gwidegree(0.5) seed(1)
...
------------------------------------------------------------------------------------
         lazega_fr | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------------+----------------------------------------------------------------
             edges |  -3.360077   .1502866   -22.36   0.000    -3.654633    -3.06552
            mutual |   .8002415   .1747992     4.58   0.000     .4576415    1.142842
    nodematch_prac |   .7077244    .080161     8.83   0.000     .5506118     .864837
nodeicov_seniority |  -.0046583   .0018977    -2.45   0.014    -.0083778   -.0009389
         gwesp_0.5 |   .5075481   .0700989     7.24   0.000     .3701568    .6449395
     gwidegree_0.5 |    1.78157   2.037619     0.87   0.382    -2.212089     5.77523
------------------------------------------------------------------------------------

MCMLE converged after 6 iteration(s).
...
Log-likelihood: -1665.6798 (df = 6)   AIC:    3343.4   BIC:    3382.4   (MC std. err. =  .12044)

The coefficient of the in-degree term (1.78) is small relative to its standard error (2.04), so it adds nothing here. Keep a term only if it answers your question or improves the model.

Things to try

  • Replace nodematch(prac) by nodematchdiff(prac) and see whether homophily differs between the two practices.
  • Add nodeocov(seniority) (the effect on sending ties).
  • Fit the Lazega model with gwesp(0.25) and with gwesp(0.75) and compare AIC with estimates stats.
  • Try edgecov(lazega_cow) to ask whether lawyers who are co-workers are friends; a dyadic covariate is another network in memory.
  • help nwergm lists all term options; Terms is a map of the families.

Where next

Tutorial 3 shows how to check that a Monte Carlo fit can be trusted and how well the fitted model reproduces the network.


Back to top

nwcommands is free software under the GNU General Public License, version 3, as are the model packages nwsaom, nwergm, nwdynam and nwrem. Citing and licenses · Get help · GitHub. Issues with the core go to the nwcommands repository; issues with a model package go to that package's own repository.

This site uses Just the Docs, a documentation theme for Jekyll.