Skip to main content

Python port of the seminr R package: PLS-SEM and covariance-based SEM (CBSEM/CFA)

Project description

seminr (Python)

A Python port of the seminr R package for structural equation modeling: PLS-SEM (partial least squares) and CBSEM/CFA (covariance-based SEM / confirmatory factor analysis).

The goal is numerical parity with seminr on the bundled mobi dataset — 1e-5 against R-generated golden fixtures for PLS quantities, and tiered tolerances for CBSEM (which reimplements lavaan's ML/MLR estimator from scratch, matching lavaan 0.6-21). The public API mirrors seminr's R names.

Built one vertical slice at a time; the port is now functionally complete.

Installation

pip install seminr          # or: uv add seminr
pip install "seminr[pandas]"  # optional: pandas DataFrame input + .to_dataframe()

Requires Python 3.11+. Runtime dependencies are NumPy and SciPy only.

Status

Functionally complete. The full non-plotting seminr surface is implemented and matches seminr on the bundled mobi dataset (1e-5 for PLS quantities; tiered tolerances for CBSEM):

  • Specification DSL — constructs, composite/reflective/higher-order composites, all three interaction methods (product-indicator, orthogonal, two-stage) and quadratic terms, item-error associations, as_reflective / higher_reflective, and csem2seminr / lavaan2seminr syntax import.
  • PLS-SEMestimate_pls (PLSc for reflective constructs, two-stage higher-order constructs, interactions), bootstrap_model (with t-values, percentile CIs, mediation helpers), and rerun.
  • Assessmentsummarize() for every model kind, reliability (alpha / rhoA / rhoC / AVE), validity (HTMT, Fornell-Larcker, cross-loadings, VIFs), f², AIC/BIC, and descriptives.
  • PLSpredict (predict_pls, direct predict) and PLS-MGA (estimate_pls_mga).
  • CBSEM / CFAestimate_cbsem / estimate_cfa, a from-scratch ML/MLR estimator matching lavaan::sem/cfa(std.lv=TRUE): LISREL model, analytic gradient, ~21 fit measures, Huber-White robust SEs, Yuan-Bentler-Mplus scaled test, and ten Berge factor scores.

Bootstrap, PLSpredict, and MGA accept an opt-in cores= argument for multiprocess parallelism. Out of scope: the plotting/presentation layer. See .claude/plans/PLAN.port-seminr.md for the full slice-by-slice history and .claude/FUTURE.md for deferred items.

Usage

from seminr import (
    constructs, composite, multi_items,
    relationships, paths, interaction_term,
    estimate_pls, bootstrap_model,
)

# The ECSI mobi dataset ships with the package:
from seminr.datasets import load_mobi
mobi = load_mobi()
# ...or bring your own as a pandas DataFrame or a (column_names, 2-D array) pair.

measurement_model = constructs(
    composite("Image", multi_items("IMAG", [1, 2, 3, 4, 5])),
    composite("Expectation", multi_items("CUEX", [1, 2, 3])),
    composite("Satisfaction", multi_items("CUSA", [1, 2, 3])),
    interaction_term("Image", "Expectation"),  # a product-indicator moderation
)

structural_model = relationships(
    paths(["Image", "Expectation", "Image*Expectation"], "Satisfaction"),
)

model = estimate_pls(mobi, measurement_model, structural_model)
image_path = model.path_coef.get("Image", "Satisfaction")   # path coefficient
r2 = model.r_squared.get("Rsq", "Satisfaction")             # structural R-squared

# Bootstrap for standard errors and t-values (see the reproducibility note below).
boot = bootstrap_model(model, nboot=200, seed=123)
boot_sd = boot.paths_descriptives.get("Image", "Satisfaction Boot SD")
t_value = image_path / boot_sd

Result matrices are NamedMatrix values: index them by row/column name with .get(row, col), or reach the underlying float64 array via .values.

Attribution

  • seminr (R, GPL-3.0) by Soumya Ray, Nicholas Danks, and contributors — the authoritative reference for behavior and the source of every golden fixture in this repository.
  • seminr-ts (TypeScript, GPL-3.0) — a completed, fixture-verified port of the same package. Its module layout, algorithm digests, and fixtures are reused directly here.

Bootstrap reproducibility

bootstrap_model(model, nboot=..., seed=...) uses a default resampler backed by NumPy's Generator(PCG64(seed)). It is deterministic within Python for a given seed, but it is not identical to seminr's R Mersenne-Twister resampling, so its replication indices — and therefore the resulting bootstrap descriptives — differ from R even at the same nominal seed. For exact parity with a specific R run, inject the resample indices directly: bootstrap_model(model, nboot=n, indices=matrix), where matrix is an nboot x n array of 0-based row indices (the parity tests feed R's exported index matrix this way). A custom resampler can also be supplied. This mirrors the seminr-ts port's decision (its plan Q3/Q5).

Performance

The numerical kernel is backed by NumPy/SciPy (BLAS), so estimation, bootstrap, PLSpredict, and MGA run faster than seminr's R implementation on the mobi benchmarks — including seminr's own optimized branch — with no hand-tuned Python. bootstrap_model, predict_pls, and estimate_pls_mga accept an opt-in cores=N argument that fans replications/folds/groups out across processes; results are bit-identical to the sequential path. Note that on small models (like mobi, where a single estimation is sub-millisecond) the process pool's start-up and pickling overhead can make cores= slower than the default sequential path — reach for it when nboot, the sample size, or the per-replication cost is large enough to amortize that overhead. The measurement harness lives in benchmark/.

License

GPL-3.0-only, as a derivative work of the GPL-3 seminr package.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seminr-0.1.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

seminr-0.1.0-py3-none-any.whl (132.7 kB view details)

Uploaded Python 3

File details

Details for the file seminr-0.1.0.tar.gz.

File metadata

  • Download URL: seminr-0.1.0.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seminr-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7a039ae6710cd89bc38cbd71030de0809a695b38da935237cd506af055693c83
MD5 0e52d255f19bccd045ecc32082124219
BLAKE2b-256 78f89d6a2e7f14cce2c67928406b81ae2074553ea3cb2680ae22ef4334b8eba6

See more details on using hashes here.

Provenance

The following attestation bundles were made for seminr-0.1.0.tar.gz:

Publisher: release.yml on sem-in-r/seminr-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seminr-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: seminr-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 132.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seminr-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc323e746e1e755539bc70c83033acb4e32657e3335e12d5eacd94809cd1afa4
MD5 141e36b901094dcc5c763e8d1f2d0da9
BLAKE2b-256 a168eef6efdd88725f464e2f82c6583594d81c3e9b91c10df424491619c9ee0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for seminr-0.1.0-py3-none-any.whl:

Publisher: release.yml on sem-in-r/seminr-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page