Documentation
¶
Overview ¶
Package sem is the structural equation model (SEM) estimator behind MAT_SEM: a lavaan / semopy model description fitted by maximum likelihood to a sample covariance matrix.
Its default setup is semopy 2.3.11's default covariance-structure model (semopy.Model, obj="MLW", solver="SLSQP", mimic_lavaan=False): the same variable classification, parameter set and fixings, the same Wishart ML objective minimised by SciPy's SLSQP (package optimize) with semopy's settings, the same expected-information standard errors and the same fit statistics — so a fit over the same data gives semopy's numbers, its early stop at ftol included. Options select a converging Fisher-scoring solver and the rank-2 derivative computation instead.
A mean structure (ModelOptions.MeanStructure, or a `~ 1` statement) is a lavaan-only feature: the model gains intercepts and latent means, and the fit follows lavaan's conventions instead (Model.Lavaan: Fisher scoring to the optimum, unbounded variances, lavaan's statistics and Wald intervals), reproducing lavaan's ML fit.
The package reads only a covariance matrix and a row count (and the sample means under a mean structure); it is no-execute safe (stdlib, gonum, linalg/detmath, internal/statdist) and imported by both the resolver (internal/vectors: model validation at predict time) and the engine (internal/processing: the finalizer).
Index ¶
- Constants
- Variables
- func BivariateNormalCDF(h, k, r float64) float64
- func ComputeStats(fit *Fit, desc string) error
- func GroupEqualValues() []string
- func GroupFreeRows(model *Model, levels int) (int, error)
- func HasDefined(desc string) bool
- func HasGroupModifiers(desc string) bool
- func HasIntercepts(desc string) bool
- func PositiveDefinite(s *mat.SymDense) bool
- func ScoreMethods() []string
- func ThresholdScores(th []float64, c int, out []float64)
- type Bootstrap
- type BootstrapError
- type BootstrapOptions
- type BootstrapOrdinal
- type BootstrapSample
- type ConstraintError
- type DefinedError
- type EBMScorer
- type Effects
- type Estimate
- type Estimator
- type Fit
- func FitCov(m *Model, s *mat.SymDense, n float64, opt Options) (*Fit, error)
- func FitCovNearest(m *Model, adj, raw *mat.SymDense, n float64, opt Options) (*Fit, error)
- func FitMoments(m *Model, s, raw *mat.SymDense, mean []float64, n float64, opt Options) (*Fit, error)
- func FitOrdinal(m *Model, in TwoStepInput, est Estimator, opt Options) (*Fit, error)
- type Gamma
- type GroupFit
- type GroupMoments
- type GroupSpecError
- type Information
- type Model
- func (m *Model) Arity() int
- func (m *Model) CheckGroupCount(n int) error
- func (m *Model) DefinedCount() int
- func (m *Model) DefinedReads() map[string][]string
- func (m *Model) IsOrdered(v string) bool
- func (m *Model) Latents() []string
- func (m *Model) Lavaan() bool
- func (m *Model) LevelLabels(level int) []string
- func (m *Model) Ordered() []string
- type ModelOptions
- type Mult
- type Nearest
- type Options
- type OrdinalError
- type OrdinalFit
- type OrdinalGroup
- type OrdinalKind
- type OrdinalSpecError
- type PairEstimate
- type PairKind
- type PairScore
- type Params
- type ScaledStats
- type ScoreLayout
- type ScoreMethod
- type Scorer
- type Solver
- type Stats
- type TwoStepInput
- type TwoStepStats
Constants ¶
const ( DefinedReasonSyntax = "syntax" DefinedReasonUnknownLabel = "unknown_label" DefinedReasonForwardRef = "forward_reference" DefinedReasonDuplicate = "duplicate" )
Defined-parameter refusal reasons (DefinedError.Reason).
const ( OrdinalSpecNotObserved = "not_observed" OrdinalSpecNotOutput = "not_output" OrdinalSpecExogenous = "exogenous_observed" OrdinalSpecIntercept = "ordered_intercept" OrdinalSpecVariance = "ordered_variance" )
Reasons of an OrdinalSpecError.
const ( PolychoricBound = 0.999 PolyserialBound = 0.995 )
Bounds of the bivariate estimates (lavaan's nlminb boxes): the polychoric and Pearson searches stay in ±0.999, the polyserial in ±0.995. A maximum outside the box is reported on its edge (PairEstimate.Bound).
const ( // ReasonNoData: no row, or a total weight that is not positive. ReasonNoData = "no_data" // ReasonInvalidInput: a ragged row, a non-finite value, a code // outside 0..Levels-1, a negative or non-finite weight, or a kind / // level spec that does not describe the columns. ReasonInvalidInput = "invalid_input" // ReasonConstant: a variable without spread — an ordered one with a // single category (Levels 1, or every weight on one code), a numeric // one with zero variance. ReasonConstant = "constant" // ReasonEmptyCategory: an ordered variable with a declared category // no row (no positive weight) falls in — the lavaan refusal "some // categories of variable are empty in group g", reached when a // category observed in the pooled data is missing from one group. ReasonEmptyCategory = "empty_category" // ReasonTooManyCategories: an ordered variable declaring more than // MaxOrderedCategories categories (Levels) — one threshold per // category boundary and a Γ of matching size, so a high-cardinality // numeric column declared ordered is refused, never fitted. ReasonTooManyCategories = "too_many_categories" )
Reasons of an OrdinalError.
const ( OpRegression = "~" OpMeasurement = "=~" OpCovariance = "~~" // OpIntercept is a "~ 1" term: an observed variable's intercept or // a latent variable's mean (lavaan's mean-structure syntax). It // switches the fit to lavaan conventions (Model.Lavaan). OpIntercept = "~1" // OpThreshold is an ordered variable's threshold row ("x | t1"): // never model syntax, only an ordinal fit's estimates (FitOrdinal). OpThreshold = "|" // OpScale is an ordered variable's scale-factor row ("x ~*~ x", // the delta parameterization's Δ): never model syntax, only a // multi-group ordinal fit's estimates (FitOrdinalGroups). OpScale = "~*~" )
Operators of the model syntax.
const BootstrapMinSuccesses = 10
BootstrapMinSuccesses is the fewest successful replicates a bootstrap reports from.
const GroupEqualThresholds = "thresholds"
GroupEqualThresholds is the group_equal value holding every ordered variable's thresholds equal across groups (an ordinal fit only).
const MaxOrderedCategories = 32
MaxOrderedCategories is the most categories one ordered variable may declare (Levels; MaxOrderedCategories − 1 thresholds). A rating scale sits far below it — a 0–10 scale has 11, and lavaan already warns above 12 — so a column past it is a continuous measure declared ordered by mistake: its thresholds and Γ (rows and columns per threshold, per group) would grow with its distinct values.
const NearestThreshold = 1e-2
NearestThreshold is the eigenvalue floor semopy passes to cov_nearest.
const OpDefined = ":="
OpDefined is a defined parameter's estimate-row operator: lavaan's ":=". The row's LVal is the name, RVal the expression without whitespace (lavaan's rhs).
const ReasonSingular = "singular"
ReasonSingular is an OrdinalError reason: the asymptotic covariance is undefined — a univariate information block or a correlation's information does not invert, or a figure is not finite (a correlation at ±1).
Variables ¶
var ErrEBMResidualVariance = errors.New("a residual variance is not positive; ordinal (EBM) factor scores are undefined")
ErrEBMResidualVariance refuses EBM scores of a fit with a residual variance (an ordered indicator's delta residual, a numeric indicator's Θ_ii) that is not positive: the indicator's density is undefined (lavaan refuses the same).
var ErrScoreSingular = errors.New("the fit's implied covariance is singular; factor scores need its inverse")
ErrScoreSingular reports a fit whose scores are undefined: the implied covariance (or Bartlett's ΛᵀΣ⁻¹Λ) cannot be inverted.
Functions ¶
func BivariateNormalCDF ¶
BivariateNormalCDF is P(X ≤ h, Y ≤ k) for a standard bivariate normal pair with correlation r (pbivnorm(h, k, r)). An infinite limit reduces exactly to the univariate CDF (or 0); |r| > 1 or a NaN argument is NaN.
func ComputeStats ¶
ComputeStats fills fit.Stats; desc is the model description, used to fit semopy's baseline (independence) model on the same covariance. A lavaan-convention fit (Model.Lavaan) gets lavaan's figures instead (lavaanStats); desc is then unused.
func GroupEqualValues ¶
func GroupEqualValues() []string
GroupEqualValues are the accepted group_equal values, lavaan's group.equal vocabulary (thresholds needs an ordinal estimator).
func GroupFreeRows ¶
GroupFreeRows is how many parameter-table rows carry a free parameter across a multi-group fit of model (NewGroupModel) over levels groups (the first the reference): every group's free rows, the specification's non-reference freeing and equality fixing applied. The rows a member multiplicity block corrects, less the := rows.
func HasDefined ¶
HasDefined reports whether a description parses and carries any := line — a defined parameter, so lavaan conventions.
func HasGroupModifiers ¶
HasGroupModifiers reports whether a description parses and carries any per-group modifier c(...) — a multi-group construct.
func HasIntercepts ¶
HasIntercepts reports whether a description parses and carries any `~ 1` statement — a mean structure, so lavaan conventions.
func PositiveDefinite ¶
PositiveDefinite reports whether s factors by Cholesky — the test semopy's load_cov applies (LAPACK dpotrf) before falling back to CovNearest.
func ThresholdScores ¶
ThresholdScores writes the casewise threshold scores of one row in category c (lav_uvord_sc: ∂ log π_c / ∂τ_k, two non-zero entries — the category's upper threshold +φ(τ_c)/π_c, its lower −φ(τ_{c−1})/π_c) into out (len(th) values).
Types ¶
type Bootstrap ¶
Bootstrap is a bootstrap's per-row figures, index-aligned with the full fit's table rows (BootstrapRows): SE and the percentile bounds, NaN on a row Apply leaves alone.
func RunBootstrap ¶
func RunBootstrap(m *Model, samples []BootstrapSample, opt Options, bo BootstrapOptions, full []Estimate) (*Bootstrap, error)
RunBootstrap bootstraps the fit whose table rows are full (BootstrapRows / BootstrapGroupRows): one sample is a single-group fit (FitMoments), two or more a multi-group fit (FitGroups) of m, every replicate with opt. A replicate's moments are its rows' mean and biased (divisor n) covariance, as the full fit's.
type BootstrapError ¶
type BootstrapError struct {
Requested, Attempted, Succeeded int
}
BootstrapError is a bootstrap with fewer than BootstrapMinSuccesses successful replicates: Attempted replicates ran (fewer than Requested after the early stop) and Succeeded of them refitted.
func (*BootstrapError) Error ¶
func (e *BootstrapError) Error() string
type BootstrapOptions ¶
type BootstrapOptions struct {
// Iters is the replicate count B (positive).
Iters int
// Seed seeds the replicate draws.
Seed uint64
// Level is the percentile interval's level, in (0, 1).
Level float64
// Standardize fits every replicate to its rows z-scored with the
// population SD — the correlation matrix and zero means — as the
// full fit of a standardizing vector is.
Standardize bool
// Ctx, when non-nil, is read before every replicate: a deadline or a
// cancel stops the bootstrap between two refits with ctx's own
// error.
Ctx context.Context
// Ordinal, when non-nil, refits every replicate by an ordinal
// estimator (FitOrdinal, or FitOrdinalGroups over two or more
// samples) from the replicate's own two-step statistics: the
// samples' rows hold the category codes of the full fit's coding,
// which every replicate keeps, so a replicate that loses a category
// (in any group) fails and is skipped — lavaan's bootstrap of a
// categorical fit.
Ordinal *BootstrapOrdinal
}
BootstrapOptions configure Bootstrap.
type BootstrapOrdinal ¶
type BootstrapOrdinal struct {
Estimator Estimator
Kinds []OrdinalKind
Levels []int
}
BootstrapOrdinal is an ordinal bootstrap's refit: the estimator and the full fit's column kinds and category counts.
type BootstrapSample ¶
BootstrapSample is one group's rows for resampling: row-major over the model's Observed order (len(Rows) a multiple of len(Observed)), plus the group's place in a multi-group fit (GroupMoments' Label, Level and Reference; ignored on a single-group fit).
type ConstraintError ¶
type ConstraintError struct {
Op, Line string
}
ConstraintError is a refused lavaan constraint line (==, <, >): only equality through shared labels is supported. Op is the operator.
func (*ConstraintError) Error ¶
func (e *ConstraintError) Error() string
type DefinedError ¶
type DefinedError struct {
Name, Reason, Ref, Msg string
}
DefinedError is a refused := line: Name the defined parameter ("" when the line has none), Reason one of the DefinedReason* values and Ref the offending reference (unknown_label, forward_reference).
func (*DefinedError) Error ¶
func (e *DefinedError) Error() string
type EBMScorer ¶
type EBMScorer struct {
// contains filtered or unexported fields
}
EBMScorer is one group's EBM scoring rule (NewEBMScorer).
func NewEBMScorer ¶
NewEBMScorer builds the EBM rule of latent from one group's parameters p of the ordinal model m (ModelOptions.Ordered; p carries the thresholds, Params.Thresholds). An observed inner variable is a dummy latent (the file comment); ErrScoreSingular when the latents' implied covariance is not positive definite; ErrEBMResidualVariance for a non-positive residual variance (an observed inner variable's Ψ_dd included).
type Effects ¶
type Effects struct {
// contains filtered or unexported fields
}
Effects maps operator -> left variable -> right variable -> multiplier, keeping first-seen order at every level (semopy iterates dicts in insertion order, which fixes its parameter order).
func Parse ¶
Parse reads a model description in semopy / lavaan syntax: one statement per line, `#` comments, `=~` (measurement), `~` (regression) and `~~` (covariance), comma-separated left sides, `+`-separated right sides and optional `mult*` prefixes (a number, a label, NA, or lavaan's per-group list c(m1, m2, ...)). A `1` term on a `~` right side (`x ~ 1`, `x ~ 0*1`, `x ~ a*1`, `y ~ 1 + x`) is an intercept / latent mean, kept under OpIntercept. A `name := expr` line is a defined parameter (defined.go); a lavaan constraint line (==, <, >) is a *ConstraintError. semopy's operation commands (START, BOUND, DEFINE, ...) are not supported.
type Estimate ¶
type Estimate struct {
LVal, Op, RVal string
Value float64
StdValue float64
Free bool
SE, Z, P float64
CILower, CIUpper float64
Param string
// Label is the parameter's label in the description ("a*x"), ""
// for an unlabelled one (whose Param is an auto name).
Label string
}
Estimate is one row of the parameter table, laid out like semopy's Model.inspect(std_est=True): lval op rval, the estimate, the standardized estimate, and (free parameters only) SE, z and p.
An intercept / latent mean row has Op OpIntercept and an empty RVal. CILower / CIUpper are the Wald interval of a free parameter under lavaan conventions (Model.Lavaan), NaN otherwise.
func BootstrapGroupRows ¶
BootstrapGroupRows is a multi-group fit's table rows in table order: every group's estimates in fit order, then the := rows.
func BootstrapRows ¶
BootstrapRows is a fit's parameter-table rows in table order: the estimates, then the := rows.
func SpecifiedDefined ¶
SpecifiedDefined lists the model's defined-parameter rows with every figure NaN (SpecifiedRows' := half).
func SpecifiedRows ¶
SpecifiedRows lists the parameter-table rows of an unfitted model, in Fit.Estimates' order, with every figure NaN: the rows an undefined input still reports.
type Estimator ¶
type Estimator string
Estimator is a MAT_SEM estimator: maximum likelihood (the default) or one of lavaan's ordinal estimators.
const ( // EstimatorML is maximum likelihood on the covariance (and means). EstimatorML Estimator = "ml" // EstimatorDWLS is lavaan's estimator = "DWLS": diagonally weighted // least squares on the two-step statistics, robust (sandwich) // standard errors, the standard test. EstimatorDWLS Estimator = "dwls" // EstimatorWLSMV is lavaan's estimator = "WLSMV": DWLS plus the // mean-and-variance adjusted (scaled-shifted) test. EstimatorWLSMV Estimator = "wlsmv" )
type Fit ¶
type Fit struct {
Model *Model
N float64
Objective float64 // the minimised Wishart ML discrepancy F
Iterations int
Converged bool
Status string // the solver's exit message
Options Options
Sample *mat.SymDense // S over Model.Observed
Implied *mat.SymDense // Σ(θ̂)
// SampleMean and ImpliedMean are ȳ and μ(θ̂) over Model.Observed
// (Model.MeanStructure only; nil otherwise).
SampleMean, ImpliedMean []float64
Estimates []Estimate
// Defined are the := rows (defined.go), in description order, after
// Estimates in every table; nil without a := line.
Defined []Estimate
Stats Stats
// Ordinal is an ordinal (DWLS / WLSMV) fit's stage-1 pieces and
// estimator intermediates (FitOrdinal); nil on an ML fit.
Ordinal *OrdinalFit
// contains filtered or unexported fields
}
Fit is a fitted model.
func FitCov ¶
FitCov fits the model to a sample covariance matrix S (over m.Observed, divisor N — semopy's biased covariance) from n rows.
func FitCovNearest ¶
FitCovNearest fits the model to adj, the CovNearest substitute for the data's covariance raw, as semopy fits it after load_cov's fallback: the objective, the Psi / Theta starts and every statistic read adj (semopy's mx_cov), while the Lambda starts are linregress slopes over the rows (mx_data), so they read raw.
func FitMoments ¶
func FitMoments(m *Model, s, raw *mat.SymDense, mean []float64, n float64, opt Options) (*Fit, error)
FitMoments fits the model to the sample moments: S (adjusted, as FitCovNearest's adj, or the data's), the data's covariance raw and the sample mean (over m.Observed; required under a mean structure, ignored otherwise). A covariance-only model fits exactly as FitCovNearest.
func FitOrdinal ¶
FitOrdinal fits m (a model with ModelOptions.Ordered) by DWLS or WLSMV to in, the listwise-complete rows over m.Observed (an ordered column holds its category code 0..Levels-1, Kinds KindOrdered exactly on m's ordered variables; Weights frequency weights). A refused input is the two-step statistics' *OrdinalError.
func (*Fit) Params ¶
Params returns the fit's parameter matrices (a copy); false when the fit carries none (a fit not produced by this package's fitters). SampleMean is the fit's under a mean structure and nil otherwise — a covariance-only fit never reads the means, so a scorer's caller sets the fit rows' mean.
type Gamma ¶
type Gamma struct {
// Inner is Σ w·s·sᵀ (Size × Size).
Inner [][]float64
// A11 is the univariate information (Cor × Cor, block diagonal by
// variable); A21 the correlation rows' cross information (pairs ×
// Cor); A22 the correlations' own information (one per pair).
A11 [][]float64
A21 [][]float64
A22 []float64
// WLSW is lavaan's WLS.W: the asymptotic covariance of WLSObs
// (Size × Size). NACOV is N·WLSW.
WLSW [][]float64
// N is the total weight Σw.
N float64
}
Gamma is one group's asymptotic covariance of the two-step statistics and its pieces, every matrix in ScoreLayout coordinates (WLS.obs order: thresholds and numeric means, numeric variances, then the pairs).
type GroupFit ¶
type GroupFit struct {
// Labels are the groups' labels, in fit order.
Labels []string
// Groups are the per-group fits, index-aligned with Labels: each
// one's Model, N (n_g), Objective (F_g), sample and implied moments
// and Estimates (standard errors from the joint information). Each
// group's Stats are zero; the joint figures are GroupFit.Stats.
Groups []*Fit
// N is the total row count Σ n_g.
N float64
// Objective is the minimised joint discrepancy Σ (n_g/N) F_g (twice
// lavaan's fmin).
Objective float64
Iterations int
Converged bool
Status string
Options Options
// Stats are the joint statistics (lavaan's, over every group).
Stats Stats
// Chi2Group are the per-group chi-squares n_g F_g, summing to
// Stats.Chi2.
Chi2Group []float64
// Defined are the := rows over the joint free vector and its
// covariance (a label resolves to its group's parameter; a shared
// one is one parameter), in description order; nil without a :=
// line.
Defined []Estimate
// VCov is an ordinal fit's robust covariance of the joint free
// vector (each group's OrdinalFit.Joint indexes it), and TraceUG /
// TraceUG2 WLSMV's tr(UΓ) and tr((UΓ)²); nil and 0 on an ML fit.
VCov *mat.SymDense
TraceUG, TraceUG2 float64
// contains filtered or unexported fields
}
GroupFit is a fitted multi-group model.
func FitGroups ¶
func FitGroups(model *Model, groups []GroupMoments, opt Options) (*GroupFit, error)
FitGroups fits model (NewGroupModel) jointly to every group's moments (at least two groups): the joint ML fit under lavaan's conventions — Fisher scoring to the optimum by default, standard errors from the joint expected information, lavaan's multiple-group statistics (ComputeStats is not needed).
func FitOrdinalGroups ¶
func FitOrdinalGroups(model *Model, groups []OrdinalGroup, est Estimator, opt Options) (*GroupFit, error)
FitOrdinalGroups fits model (NewGroupModel with ModelOptions.Ordered) by DWLS or WLSMV jointly to every group's rows (at least two groups). A refused input is the group's two-step *OrdinalError (its Group the group's position in groups), a group_partial threshold row the data do not hold a *GroupSpecError.
type GroupMoments ¶
type GroupMoments struct {
Label string
S, Raw *mat.SymDense
Mean []float64
N float64
Level int
Reference bool
}
GroupMoments are one group's sample moments: S (adjusted, as FitMoments' s, or the data's), the data's covariance Raw, the sample mean and the row count, all over the model's Observed order. Level is the group's position in the per-group modifiers c(...) (its level index: a group without rows leaves its position unused); Reference marks the group whose latent means stay fixed at 0 and whose marker loadings stay fixed (lavaan's first group; none marked: the first).
type GroupSpecError ¶
type GroupSpecError struct {
Param, Value, Msg string
}
GroupSpecError is a refused multi-group equality spec: Param is the knob at fault (group_equal or group_partial), Value the entry.
func (*GroupSpecError) Error ¶
func (e *GroupSpecError) Error() string
type Information ¶
type Information string
Information selects how the expected information tr(Σ⁻¹∂Σ_kΣ⁻¹∂Σ_l) and the gradient are computed. Both give the same figures up to rounding.
const ( // InformationDense forms every ∂Σ_k as a dense matrix, as semopy // does (the default). InformationDense Information = "dense" // InformationRank2 uses ∂Σ_k = Σ(a·bᵀ + b·aᵀ): every trace reduces // to dot products of Σ⁻¹-transformed vectors, O(k²·p) instead of // O(k·p³ + k²·p²). InformationRank2 Information = "rank2" )
type Model ¶
type Model struct {
// Observed is the model's observed variables in semopy's order: the
// sorted outputs (variables with no outgoing arrow), then the other
// observed variables sorted. Sample and implied covariances use it.
Observed []string
// Inner is the non-output variables: sorted latents, then sorted
// observed inner variables (Beta and Psi index it).
Inner []string
// MeanStructure is set when the fit models the means too
// (ModelOptions.MeanStructure, or any `~ 1` statement): observed
// intercepts (Nu, and Alpha for observed inner variables) and latent
// means (Alpha) join the parameters, and the objective gains the
// mean term.
MeanStructure bool
// contains filtered or unexported fields
}
Model is a parsed, specified SEM: the variable classification and the parameter table, before any data is seen.
func NewGroupModel ¶
func NewGroupModel(desc string, opt ModelOptions) (*Model, error)
NewGroupModel specifies desc for a multi-group fit: the model every group's copy follows (the first group's per-group modifiers), with a mean structure and lavaan conventions whatever opt says, and opt's group_equal / group_partial validated (a *GroupSpecError).
func NewModel ¶
NewModel specifies the model a description describes, with semopy's defaults (variances of every endogenous and latent variable free, observed exogenous (co)variances fixed to the sample, exogenous latents free to covary, the first indicator of each latent fixed to 1). baseline builds semopy's independence model instead.
func NewModelWithOptions ¶
func NewModelWithOptions(desc string, opt ModelOptions) (*Model, error)
NewModelWithOptions specifies the model a description describes with the features opt selects (ModelOptions); NewModel(desc, false) is NewModelWithOptions(desc, ModelOptions{}).
func (*Model) Arity ¶
Arity is the per-group modifiers' length: the group count a description with c(...) lists fits (0: no per-group modifier).
func (*Model) CheckGroupCount ¶
CheckGroupCount refuses per-group modifiers whose length is not the group count n.
func (*Model) DefinedCount ¶
DefinedCount is the model's := lines: the estimate rows a fit appends after the parameter table.
func (*Model) DefinedReads ¶
DefinedReads maps each := name to the labels it reads, directly or through an earlier := line, sorted.
func (*Model) Lavaan ¶
Lavaan reports whether the model follows lavaan's conventions rather than semopy's: true whenever a lavaan-only feature (a mean structure, a := defined parameter, ModelOptions.Lavaan — a bootstrap) is in play. Such a fit converges to the optimum (the default solver is Fisher scoring), leaves variances unbounded, and reports lavaan's chi-square, degrees of freedom, fit indices, log-likelihood and Wald intervals (ComputeStats); a covariance-only model keeps semopy's.
func (*Model) LevelLabels ¶
LevelLabels lists the labels a multi-group model names at per-group position level — each c(...) list's level-th entry and every label outside one — sorted; nil when level is past the per-group lists or the description does not parse. The labels of a level that holds no rows are absent from the fit, so a := reading one is null.
type ModelOptions ¶
type ModelOptions struct {
// MeanStructure models the means: every observed intercept free
// (an observed exogenous variable's mean fixed to its sample mean,
// lavaan's fixed.x), every latent mean fixed to 0 unless a `f ~ 1`
// statement frees it — lavaan's meanstructure = TRUE. A `~ 1`
// statement in the description sets it too.
MeanStructure bool
// GroupEqual and GroupPartial are a multi-group model's (NewGroupModel)
// lavaan group.equal values (GroupEqualValues) and group.partial
// rows ("lhs op rhs", e.g. "x1~1", "f=~x2", "x1~~x2"): the
// parameters of the named classes are one value across groups,
// except the partial rows.
GroupEqual, GroupPartial []string
// Lavaan switches a covariance-only model to lavaan's conventions
// (Model.Lavaan) with no lavaan-only syntax in the description: a
// bootstrap (RunBootstrap) is lavaan's se = "bootstrap".
Lavaan bool
// Ordered names the ordered (ordinal) observed variables of a DWLS
// / WLSMV fit (FitOrdinal), lavaan's ordered =, under the delta
// parameterization: each is an indicator or an outcome (no outgoing
// arrow) whose latent response has intercept 0 and implied variance
// 1 — its residual variance is no parameter (the remainder) and
// thresholds replace its mean. The model then follows lavaan's
// conventions with a mean structure (lavaan's categorical default).
// An observed exogenous variable is refused (lavaan conditions on it,
// conditional.x), as are a `x ~ 1` or `x ~~ x` line on an ordered x.
// Validated with an *OrdinalSpecError.
Ordered []string
// contains filtered or unexported fields
}
ModelOptions select the features beyond semopy's default covariance-structure model. The zero value is that model.
type Mult ¶
type Mult struct {
Set bool
Fixed bool
Value float64
Label string
Groups []Mult
// contains filtered or unexported fields
}
Mult is the multiplier written before a right-hand variable: none (a free parameter), a fixed number ("0.5*x"), a parameter label ("a*x", equality across every place the label is used) or lavaan's NA ("NA*x": free, unlabelled — Set without Fixed or Label). A per-group modifier ("c(a1,a2)*x", "c(0.5,NA)*x") carries one of those per group in Groups, in level order; the model of group g reads Groups[g] (selectGroup).
type Nearest ¶
type Nearest struct {
// Cov is the adjusted covariance (S's diagonal, to rounding).
Cov *mat.SymDense
// MinEigenvalue is the smallest eigenvalue of S's correlation form,
// before the clip.
MinEigenvalue float64
// Clipped reports whether any eigenvalue was below the threshold
// (false: Cov is S rescaled through its correlation form unchanged).
Clipped bool
}
Nearest is a cov_nearest result.
func CovNearest ¶
CovNearest is statsmodels' cov_nearest(s, method="clipped", threshold) (above). Every diagonal entry of s must be positive and finite: statsmodels' correlation form is undefined otherwise (its eigendecomposition of the NaN it produces fails).
type Options ¶
type Options struct {
// Solver is the optimiser (default SolverSLSQP).
Solver Solver
// Information is the derivative computation (default
// InformationDense).
Information Information
// Ftol is SLSQP's ftol (default 1e-6, SciPy's and semopy's).
Ftol float64
// MaxIter caps the iterations (default 10000 for SLSQP — semopy's
// setting — and 500 for Fisher scoring).
MaxIter int
// GradTol is Fisher scoring's stop: every free gradient entry below
// it in absolute value (default 1e-10).
GradTol float64
// Level is the Wald interval's level (lavaan's level), in (0, 1);
// 0 is 0.95. It sets ci_lower / ci_upper only (a lavaan-convention
// fit's), never an estimate, SE or p.
Level float64
}
Options configure the fit. The zero value is semopy's default setup.
type OrdinalError ¶
OrdinalError is a refused two-step input: Var is the column at fault (-1 for the whole input), Group the group index (-1 ungrouped), Reason one of the Reason* codes, Freq an ordered column's weighted category frequencies when they are the reason.
func (*OrdinalError) Error ¶
func (e *OrdinalError) Error() string
type OrdinalFit ¶
type OrdinalFit struct {
// Estimator is the fit's estimator.
Estimator Estimator
// Stats are the two-step statistics; Gamma their asymptotic
// covariance.
Stats *TwoStepStats
Gamma *Gamma
// Obs is WLS.obs; Est the model's WLS.est at the estimate; Weight
// the diagonal weight 1/diag(NACOV).
Obs, Est, Weight []float64
// Delta is ∂WLS.est/∂θ at the estimate (rows Obs, columns the free
// vector: the model's free parameters then the thresholds).
Delta [][]float64
// VCov is the free vector's robust covariance.
VCov *mat.SymDense
// TraceUG and TraceUG2 are tr(UΓ) and tr((UΓ)²) (WLSMV).
TraceUG, TraceUG2 float64
// FreeKeys are the free vector's row keys (Estimate.Key of each
// parameter's first row; the thresholds "x | tk"; a grouped fit's
// free scale factors "x ~*~ x").
FreeKeys []string
// Joint is a grouped fit's map from this group's free vector to the
// joint one (GroupFit.VCov's coordinates; a shared parameter one
// joint index); nil ungrouped, where Delta and VCov are the fit's
// own.
Joint []int
}
OrdinalFit is an ordinal fit's stage-1 pieces.
type OrdinalGroup ¶
type OrdinalGroup struct {
Label string
In TwoStepInput
Level int
Reference bool
}
OrdinalGroup is one group's rows for FitOrdinalGroups: the listwise-complete rows over the model's Observed order (every group's Kinds and Levels the same — the pooled coding), plus the group's place in the fit (GroupMoments' Label, Level and Reference).
type OrdinalKind ¶
type OrdinalKind uint8
OrdinalKind is a two-step variable's measurement level.
const ( // KindNumeric is a continuous variable (a mean and a variance). KindNumeric OrdinalKind = iota // KindOrdered is an ordinal variable: integer category codes // 0..Levels-1, read as a cut normal latent response. KindOrdered )
type OrdinalSpecError ¶
type OrdinalSpecError struct {
Param, Var, Reason, Msg string
}
OrdinalSpecError is a refused ordinal specification (ModelOptions.Ordered): Param is the params key at fault ("ordered" or "model"), Var the variable, Reason a short code.
func (*OrdinalSpecError) Error ¶
func (e *OrdinalSpecError) Error() string
type PairEstimate ¶
type PairEstimate struct {
I, J int
Kind PairKind
Rho float64
// Bound reports an estimate pinned on its box edge (±0.999 /
// ±0.995): the likelihood still rose toward ±1.
Bound bool
// ZeroCells reports a polychoric table with an empty cell.
ZeroCells bool
// Closed reports a closed-form polychoric (a 2 × 2 table with
// proportional margins, two empty cells, or both thresholds 0;
// lavaan's lav_bvord_cor_twostep_fit shortcuts).
Closed bool
}
PairEstimate is one bivariate two-step correlation. Pairs are in lavaan's layout: column-major below the diagonal, (1,0), (2,0), …, (p-1,0), (2,1), …, so I > J and the k-th pair is lavaan's k-th correlation (its WLS.obs order).
type PairScore ¶
PairScore is one row's casewise scores of a bivariate log-likelihood (lavaan's lav_m84_pair_sc): Rho is ∂/∂ρ; ThI / ThJ are ∂/∂ the thresholds of column I / J (a numeric column: its mean, one value); VarI / VarJ are ∂/∂ a numeric column's variance (NaN for an ordered one).
type Params ¶
type Params struct {
Lambda, Beta, Psi, Theta [][]float64
Nu, Alpha []float64
SampleMean []float64
// Thresholds are an ordinal fit's raw thresholds τ per Observed
// variable (an ordered variable's Levels − 1, nil for a numeric
// one); nil for an ML fit. Theta's ordered diagonal is then the
// delta parameterization's residual 1/Δ² − common (EBM scores,
// NewEBMScorer).
Thresholds [][]float64
}
Params are one group's parameter matrices at the estimate — Lambda (Observed × Inner), Beta and Psi (Inner × Inner), Theta (Observed × Observed), Nu (Observed) and Alpha (Inner), the fixed values included — and the fit's sample mean over Observed (the center of a covariance-only fit's scores). Every slice is the fit's own copy.
type ScaledStats ¶
type ScaledStats struct {
Chi2, Chi2P float64
ScalingFactor, ShiftParameter float64
Chi2Baseline float64
BaselineScalingFactor float64
CFI, TLI, RMSEA float64
}
ScaledStats are WLSMV's scaled-shifted test and the indices it scales (lavaan's chisq.scaled, chisq.scaling.factor, shift.parameter, baseline.chisq.scaled, cfi.scaled, tli.scaled, rmsea.scaled).
type ScoreLayout ¶
type ScoreLayout struct {
// Th[v] is column v's first threshold (or mean) index; NTh[v] its
// count (Levels-1, or 1 for a numeric column).
Th, NTh []int
// VarIdx[v] is a numeric column's variance index (-1 for ordered).
VarIdx []int
// Cor is the first correlation index; Size the total width.
Cor, Size int
}
ScoreLayout is the column layout of Scores, lavaan's SC: the threshold block (each ordered column's Levels-1 thresholds, a numeric column's mean, in column order), then each numeric column's variance, then the correlations in Pairs order.
type ScoreMethod ¶
type ScoreMethod string
ScoreMethod is a factor-score method.
const ( ScoreRegression ScoreMethod = "regression" ScoreBartlett ScoreMethod = "bartlett" )
The lavPredict methods.
type Scorer ¶
Scorer is one latent's linear scoring rule in one group: score = Base + Σ_i Weights[i]·(y_i − Center[i]), y over Observed.
type Solver ¶
type Solver string
Solver selects the optimiser.
const ( // SolverSLSQP is SciPy's SLSQP as semopy calls it (the default): the // same iterates, the same early stop at ftol, the same result. SolverSLSQP Solver = "slsqp" // SolverFisher is damped Fisher scoring (Levenberg–Marquardt on the // expected information): converges to the optimum to GradTol. SolverFisher Solver = "fisher" )
type Stats ¶
type Stats struct {
DoF float64
DoFBaseline float64
Chi2 float64
Chi2P float64
Chi2Baseline float64
CFI, GFI float64
AGFI, NFI float64
TLI, RMSEA float64
AIC, BIC float64
LogLik float64
NParams int
// Scaled is WLSMV's scaled-shifted test and scaled indices (nil on
// every other fit).
Scaled *ScaledStats
}
Stats are semopy.calc_stats' figures, with semopy's definitions — including its conventions: LogLik is the minimised discrepancy F (semopy's calc_likelihood returns obj_mlw), AIC = 2(k − F), BIC = ln(N)·k − 2F, and GFI equals NFI.
type TwoStepInput ¶
type TwoStepInput struct {
// Kinds is each column's measurement level.
Kinds []OrdinalKind
// Levels is each ordered column's category count (codes
// 0..Levels-1; ignored for a numeric column). Every declared
// category must hold weight (ReasonEmptyCategory).
Levels []int
// Rows are the complete observations, one value per column; an
// ordered column holds its integer code.
Rows [][]float64
// Weights are per-row frequency weights; nil weighs every row 1.
Weights []float64
}
TwoStepInput is one group's data for TwoStep.
type TwoStepStats ¶
type TwoStepStats struct {
// N is the total weight Σw; Rows the row count.
N float64
Rows int
// Kinds and Levels echo the input.
Kinds []OrdinalKind
Levels []int
// Thresholds are each ordered column's Levels-1 thresholds (nil for
// a numeric column); Freq its weighted category frequencies.
Thresholds [][]float64
Freq [][]float64
// Mean and Var are a numeric column's mean and ML variance (Σw
// divisor); an ordered column's latent response is standardised (0
// and 1).
Mean, Var []float64
// Cor is the full symmetric correlation matrix (unit diagonal).
Cor [][]float64
// Pairs are the bivariate estimates in lavaan's order.
Pairs []PairEstimate
}
TwoStepStats is one group's two-step sample statistics.
func TwoStep ¶
func TwoStep(in TwoStepInput) (*TwoStepStats, error)
TwoStep computes one group's thresholds, means, variances and pairwise correlations.
func TwoStepGroups ¶
func TwoStepGroups(in TwoStepInput, group []int, levels int) ([]*TwoStepStats, error)
TwoStepGroups computes the statistics per group: group[i] in 0..levels-1 is row i's group, and every group shares in's Kinds and Levels, so a category the pooled data holds but one group lacks is that group's ReasonEmptyCategory refusal (as lavaan refuses it).
func (*TwoStepStats) Gamma ¶
func (s *TwoStepStats) Gamma(in TwoStepInput) (*Gamma, error)
Gamma computes the asymptotic covariance of s from in, the rows (and weights) s was computed from. A univariate block or a correlation information that does not invert, or a non-finite figure, is an OrdinalError with ReasonSingular.
func (*TwoStepStats) Layout ¶
func (s *TwoStepStats) Layout() ScoreLayout
Layout returns the Scores layout of s.
func (*TwoStepStats) PairScores ¶
func (s *TwoStepStats) PairScores(k int, row []float64) PairScore
PairScores returns row's casewise scores for Pairs[k].
func (*TwoStepStats) Scores ¶
func (s *TwoStepStats) Scores(row, out []float64) error
Scores writes row's casewise score vector (ScoreLayout order; the univariate blocks are each column's own score, the correlation block each pair's ρ-score) into out, which must hold Layout().Size values.
func (*TwoStepStats) WLSObs ¶
func (s *TwoStepStats) WLSObs() []float64
WLSObs returns the sample statistics in lavaan's WLS.obs layout (ScoreLayout order): each ordered column's thresholds and a numeric column's NEGATED mean, the numeric variances, then every pair's covariance — the correlation times the standard deviations, so an ordered × ordered pair's is its polychoric correlation as is.