Simulation studies

Simulation study interface

We are currently working on an interface for simulation studies. Until we are finished with this, this page is just a collection of tips.

Replace observed data

In simulation studies, a common task is fitting the same model to many different datasets. It would be a waste of resources to reconstruct the complete model for each dataset. We therefore provide the function replace_observed to change the observed part of a model, without necessarily reconstructing the other parts.

For the A first model, you would use it as

data = example_data("political_democracy")

data_1 = data[1:30, :]

data_2 = data[31:75, :]

model = Sem(
    specification = partable,
    data = data_1
)

model_updated = replace_observed(model; data = data_2, specification = partable)
Structural Equation Model 
- Loss Functions 
   SemML
- Fields 
   observed:    SemObservedData 
   implied:     RAM 

If you are building your models by parts, you can also update each part seperately with the function update_observed. For example,

new_observed = SemObservedData(;data = data_2, specification = partable)

my_optimizer = SemOptimizerOptim()

new_optimizer = update_observed(my_optimizer, new_observed)
SemOptimizerOptim
   algorithm: Optim.LBFGS{Nothing, LineSearches.InitialStatic{Float64}, LineSearches.HagerZhang{Float64, Base.RefValue{Bool}}, Optim.var"#19#21"}
   options: Optim.Options{Float64, Nothing}

Multithreading

Thread safety

This is only relevant when you are planning to fit updated models in parallel

Models generated by replace_observed may share the same objects in memory (e.g. some parts of model and model_updated are the same objects in memory.) Therefore, fitting both of these models in parallel will lead to race conditions, possibly crashing your computer. To avoid these problems, you should copy model before updating it.

Taking into account the warning above, fitting multiple models in parallel becomes as easy as:

model1 = Sem(
    specification = partable,
    data = data_1
)

model2 = deepcopy(replace_observed(model; data = data_2, specification = partable))

models = [model1, model2]
fits = Vector{SemFit}(undef, 2)

Threads.@threads for i in 1:2
    fits[i] = sem_fit(models[i])
end

API

StructuralEquationModels.replace_observedFunction
(1) replace_observed(model::AbstractSemSingle; kwargs...)

(2) replace_observed(model::AbstractSemSingle, observed; kwargs...)

Return a new model with swaped observed part.

Arguments

  • model::AbstractSemSingle: model to swap the observed part of.
  • kwargs: additional keyword arguments; typically includes data = ...
  • observed: Either an object of subtype of SemObserved or a subtype of SemObserved

Examples

See the online documentation on Replace observed data.

source
StructuralEquationModels.update_observedFunction
update_observed(to_update, observed::SemObserved; kwargs...)

Update a SemImplied, SemLossFunction or SemOptimizer object to use a SemObserved object.

Examples

See the online documentation on Replace observed data.

Implementation

You can provide a method for this function when defining a new type, for more information on this see the online developer documentation on Update observed data.

source