Skip to content

4. MCMSEM results

Michel Nivard edited this page Sep 12, 2024 · 1 revision

MCM results

Now that we have successfully fitted our model, it is time to work with the results. For the purposes of this wiki we will continue with the following:

base_model <- MCMmodel(data_summary, n_latent=2)
my_result <- MCMfit(base_model, data_summary, optim_iters=c(500, 25))

MCM result

The resulting MCM result object displays the estimates when printed.

      a1   a2 b1_2 b1_3 b1_4 b1_5 b2_1 b2_3 ...
est 0.03 0.10 0.06 0.28 0.05 0.11 0.24 0.24 ...
se  0.37 0.16 0.03 0.03 0.03 0.03 0.03 0.03 ...

Though this makes it look like a dataframe, it is in fact a custom object. If you want to continue working with this dataframe yourself you can obtain it via

my_result_df <- as.data.frame(my_result)

Visualization

Similar to the base MCM model, you can now generate a qgraph of your result with path weights:

plot(my_result)

Figure 4

You can customize the layout of this plot via the included layout argument, or pass additional arguments to plot as they are passed to qraph see qgraph documentation for more information.

Advanced

In addition to this dataframe the MCM result object contains the following:

  • my_result$history$loss: Loss history of optimization (this includes bounds scaling if use_bounds was set to TRUE)
  • my_result$observed$M#: Observed co-moment matrix: M2, M3 or M4
  • my_result$predicted$M#: Predicted co-moment matrix: M2, M3 or M4
  • my_result$loss: Final loss (this does not include bounds scaling)
  • my_result$info: List of MCMSEM version and arguments used
  • my_reulst$model: Deep copy of the model used for this result object
  • my_result$runtimes: Runtimes of preparation, optimizer, SE, and total runtime
  • my_result$gradients: Object of type mcmmultigradientclass, containing one mcmgradientclass object per parameter matrix (A, S, etc), containing only the last gradient when monitor_grads=FALSE, and the full gradient history when monitor_grads=TRUE

MCM summary

In addition to the raw result you can use the summary function to obtain more information about the parameters, and the model:

result_summary <- summary(my_result)
print(result_summary)

Which will print the following:

|--------------------------------------|
| MCM Result Summary (MCMSEM v0.25.0)  |
|--------------------------------------|
device         : cuda
N phenotypes   : 5
N latents      : 2
N observations : 25000
N parameters   : 37
SE type        : asymptotic

Fit statistics
loss  : 0.00295985536649823
chisq : 73.9963841624558
BIC   : 448.681735004918

Parameters summary
   label lhs edge rhs        est         se            p        last_gradient
1     a1  f1   =~  x1 0.03239270 0.37390858 9.309635e-01 0.000241369605646469
2     a1  f1   =~  x2 0.03239270 0.37390858 9.309635e-01 0.000241369605646469
3     a1  f1   =~  x3 0.03239270 0.37390858 9.309635e-01 0.000241369605646469
4     a1  f1   =~  x4 0.03239270 0.37390858 9.309635e-01 0.000241369605646469
5     a1  f1   =~  x5 0.03239270 0.37390858 9.309635e-01 0.000241369605646469
6     a2  f2   =~  x2 0.09732123 0.16192873 5.478315e-01  0.00041480315849185
7     a2  f2   =~  x3 0.09732123 0.16192873 5.478315e-01  0.00041480315849185
8     a2  f2   =~  x4 0.09732123 0.16192873 5.478315e-01  0.00041480315849185
9     a2  f2   =~  x5 0.09732123 0.16192873 5.478315e-01  0.00041480315849185
10  b1_2  x1   ~>  x2 0.05685243 0.03255957 8.079268e-02 0.000364131759852171
11  b1_3  x1   ~>  x3 0.27605972 0.02615226 4.772342e-26 0.000394926639273763
12  b1_4  x1   ~>  x4 0.04821920 0.03338192 1.486066e-01 0.000532981939613819
13  b1_5  x1   ~>  x5 0.10852847 0.03054933 3.814956e-04 0.000610843300819397
14  b2_1  x2   ~>  x1 0.23778147 0.02895773 2.187507e-16 0.000488257966935635
15  b2_3  x2   ~>  x3 0.24205866 0.03366879 6.507252e-13 0.000322819221764803
... Print capped at 15 rows, use: as.data.frame([summary_object], estimates='parameters')

Variances summary
  label lhs edge rhs       est         se             p        last_gradient
1    s1  x1   ~~  x1 0.6735761 0.01995140 7.412499e-250 0.000159237533807755
2    s2  x2   ~~  x2 0.6972904 0.02905010 2.585631e-127  9.1212335973978e-05
3    s3  x3   ~~  x3 0.6293085 0.02704741 9.602638e-120 7.44964927434921e-05
4    s4  x4   ~~  x4 0.8520687 0.04314821  8.431090e-87 0.000129235442727804
5    s5  x5   ~~  x5 0.8891585 0.03726947 8.453556e-126 0.000109544023871422

Skewness summary
  label edge v1 v2 v3         est         se            p         last_gradient
1   sk1  ~~~ x1 x1 x1  0.40390298 0.03187758 8.622936e-37  2.28442950174212e-05
2   sk2  ~~~ x2 x2 x2 -0.02151221 0.05525198 6.970192e-01 -2.17645429074764e-05
3   sk3  ~~~ x3 x3 x3  0.57086051 0.04185439 2.341092e-42 -1.66784739121795e-05
4   sk4  ~~~ x4 x4 x4  0.29352975 0.04550542 1.115300e-10  1.67917460203171e-05
5   sk5  ~~~ x5 x5 x5  0.27265000 0.04567548 2.382932e-09  3.51385679095984e-05

Kurtosis summary
  label edge v1 v2 v3 v4      est        se            p         last_gradient
1    k1 ~~~~ x1 x1 x1 x1 1.758213 0.1560593 1.924610e-29  4.72782994620502e-05
2    k2 ~~~~ x2 x2 x2 x2 2.272933 0.2718033 6.144515e-17   4.3971580453217e-05
3    k3 ~~~~ x3 x3 x3 x3 1.984582 0.3418947 6.449767e-09 -5.92215801589191e-05
4    k4 ~~~~ x4 x4 x4 x4 2.568231 0.2518315 2.019551e-24  8.13488732092083e-05
5    k5 ~~~~ x5 x5 x5 x5 2.806049 0.2535872 1.845983e-28  -4.8876361688599e-05

These matrices are capped at 15 rows purely to prevent flooding the console when printing. You can obtain the full matrices as dataframes by running the following

parameters_df <- as.data.frame(result_summary, estimates='parameters')
variances_df <- as.data.frame(result_summary, estimates='variances')
skewness_df <- as.data.frame(result_summary, estimates='skewness')
kurtosis_df <- as.data.frame(result_summary, estimates='kurtosis')

The loss, chisq and bic can be obtained via result_summary$loss, result_summary$chisq and result_summary$bic. Note that this loss value does not include bound scaling.