With StructuralEquationModels.jl, you can fit weighted sums of structural equation models.
The most common use case for this are Multigroup models.
Another use case may be optimizing the sum of loss functions for some of which you do know the analytic gradient, but not for others.
In this case, FiniteDiffWrapper can generate a wrapper around the specific SemLoss term. The wrapper loss term will
only use the objective of the original term to calculate its gradient using finite difference approximation.
loss_1 = SemML(observed_1, implied_1)
loss_2 = SemML(observed_2, implied_2)
loss_2_findiff = FiniteDiffWrapper(loss_2)To construct Sem from the the individual SemLoss (or other AbstractLoss) terms, they are
just passed to the Sem constructor:
model = Sem(loss_1, loss_2)
model_findiff = Sem(loss_1, loss_2_findiff)It is also possible to use finite difference for the entire Sem model:
model_findiff2 = FiniteDiffWrapper(model)The weighting scheme of the SEM loss terms is specified using default_set_weights argument of the Sem constructor.
The :nsamples scheme (the default) weights SEM terms by N_{term}/N_{total}, i.e. each term is weighted by the number
of observations in its data (which matches the formula for multigroup models).
The weights for the loss terms (both SEM and regularization) can be explicitly specified the pair syntax loss => weight:
model_weighted = Sem(loss_1 => 0.5, loss_2 => 1.0)Sem support assigning unique identifier to each loss term, which is essential for complex multi-term model.
The syntax is id => loss, or id => loss => weight:
model2 = Sem(:main => loss_1, :alt => loss_2)
model2_weighted = Sem(:main => loss_1 => 0.5, :alt => loss_2 => 1.0)Sem
LossTerm
FiniteDiffWrapper