Nothing
sfa_semk(): sem-k, a learned retention rule
for embedding similarity matrices with validated error rates. The rule
(a random-forest hybrid in the factor-forest lineage) was trained on a
planted-truth corpus of ~700 LLM-written item sets with known factor
structure spanning construct proximity, redundancy, reverse-keying,
cross-loadings, and minor-factor contamination, and reaches 65.7%
exact / 73.9% within-25% accuracy on held-out configurations under
the default encoder, with 61.6-69.0% exact replicated across nine
encoders from six providers. Every verdict carries a 90%
split-conformal interval (empirical coverage 91-96%).sfa() gains n_factors_method = "semk"; the fitted object stores
the full verdict (interval, floor, battery votes) under $semk.sfa_nfactors() gains methods = "semk".semk-v1 GitHub release and
cached under tools::R_user_dir("semanticfa", "cache"), with sha256
verification; the feature-extraction pipeline is vendored under
inst/python/semk/ and driven through reticulate (numpy, scipy,
scikit-learn pinned to the artifact's training series (1.8.*), and
joblib, declared via py_require() on first use).
Per-encoder register-floor calibration files ship as release assets
(pass floor= for non-default encoders).rotate = "leximax" in sfa(): orients factor axes
toward the construct lexicon by maximizing nameability, the mean cosine
between each factor's naming target and its retrieved construct term.
The optimizer alternates the package's deterministic naming machinery
with oblique target rotation (GPArotation) from multiple seeded starts,
returns the best self-consistent (recurrent) orientation, and re-names
the winner through the canonical pool path. Model fit is invariant by
construction.sfa_leximax(): post-hoc leximax rotation of any fitted solution
(an sfa fit, a psych::fa fit, or a plain pattern matrix with item
texts), for rotating existing solutions without refitting.sfa_lexmap() and sfa_nameability(): the reusable pool-by-item
lexical map, and the retrieved labels plus nameability of any
orientation of the mapped items (also the engine for Monte Carlo
calibration of nameability).sfa_nameability() and sfa_leximax() gain optional baseline and
baseline_sd arguments for surprise scoring: word scores are centered
(and optionally standardized) against a per-word null target cosine,
which suppresses words that sit close to every factor's target rather
than to one in particular. Both default to NULL, leaving the raw
cosine scoring unchanged.sfa_coverage() now calibrates both headline numbers against an ideal
same-length scale under a single 95% convention. The coverage radius is
the 95% quantile of the matched-size null (radius_q = 0.95; an ideal
scale's construct coverage is ~0.95), and each item's corroboration
count (construct texts within its radius) gets an empirical p-value
against the ideal-item null, flagged at alpha = 0.05 (an ideal
scale's item relevance is also ~0.95). The identity behind the
convention: 1 - radius_q and alpha are per-decision Type I error
rates of Monte Carlo tests.k_precision) is retired: corroboration
counts grow linearly with region size, so a fixed threshold rewarded
sampling more construct text. The calibrated critical count rescales
with the region, making item relevance region-size invariant.
k_precision is ignored with a warning; delta_q maps to radius_q
with a warning.radius, radius_q, item_relevance,
corroboration, p_values, relevant_items, critical_count,
ideal_relevance.p_adjust = "BH" flags items by Benjamini-Hochberg false discovery
rate across the scale instead of per-item alpha.plot(audit) draws a proportional Euler diagram: two
equal disks whose overlap area equals the measured construct coverage,
filled with the real texts (dots) and items (triangles) placed by their
full-space verdicts - a constructed diagram, not a projection (no 2-d
projection of the embedding space preserves these fractions).
plot(audit, type = "relevance") draws the per-item chart:
corroboration counts on a log axis, empirical p-values on every bar,
the calibrated critical count as a reference line, flagged items in
red. The pre-0.3.0 curve plot remains as type = "curve".factor column, sfa_coverage() runs one audit per
subscale - content validity is a property of an (item set, construct
claim) pair, and a battery makes one claim per subscale - returning an
"sfa_coverage_battery" (a named list of audits with a compact
per-factor print table). region accepts a list named by factor so each
subscale is audited against its own construct region; the factor
argument restricts the battery to a subset or a single factor.cross = TRUE audits every factor against every region and returns an
"sfa_coverage_cross" matrix of audits - the content analogue of a
multitrait matrix, with no data collection: items should be relevant to
their own construct's region (convergent) and irrelevant to their
siblings' (discriminant). sfa_cross_matrix() extracts the numeric
relevance or coverage matrix; the print method marks own-construct
cells and states the caveat that off-diagonal relevance is floored by
how separable the constructs are in language, not by zero.sfa_build_regions() builds many construct regions in one corpus pass
(word-boundary variant matching, so compositional components like "care"
never match "career"; embeddings = FALSE defers encoding);
sfa_reembed_region() re-embeds one extraction under any encoder (the
encoder-ladder workflow: regions differ only in embedding space, never
in text); sfa_build_bank() pre-embeds items, definitions, and planned
narrowings; and sfa_embedding_bank() turns a saved bank into an
embed = function so every audit runs from published embeddings with
no encoder loaded. Heavy steps run on any GPU machine with the same R
calls (encoders drive through reticulate, including large models via
the manual transformers fallback).sfa_build_region() warns below the ~200-sentence
saturation threshold (estimates noisy, coverage biased favorable) and
errors below the 25-sentence audit minimum; print() on regions and
audits carries a NOTE/CAUTION line; audits store small_region.relevance_ci (was precision_ci).sfa_name() labels the factors of an sfa fit with psychological
construct names retrieved from a 368k-term pre-filtered candidate pool
using instruction-conditioned embeddings. Deterministic; returns the
label, its provenance rule, and a leave-one-out candidate set per factor
(the method's error bar). Labels name the pole toward which the factor's
positive loadings point.sfa_name(fit, model = ...) names with a different
(typically larger) embedding model than the one used for extraction.sfa_pool() fetches pre-generated pool embeddings for the supported
models (downloaded once into the user cache) or builds a pool locally for
any sentence-transformers model. Default precision is int8 (half-size
downloads); relative to fp16 it changes 3 of 75 benchmark labels, all on
weak factors, all to near-synonyms ("stress resilience" -> "resilience";
two analogous changes under the large naming model). Pass
precision = "fp16" for exact parity with the research pipeline.sfa(..., label_factors = TRUE) runs naming inline and stores the result
as fit$labels.sfa_naming_instruction() exposes the naming instruction; overriding it
is supported but warned (label robustness was validated under the
default).sfa_embed() call,
and loading a different model releases the previous one (so an
extraction model and a large naming model never co-occupy GPU memory).semanticfa.torch_dtype ("float16", "bfloat16", or
"float32") controls the weight dtype of sentence-transformers models.
Large naming encoders do not fit common GPUs at float32.sfa_ekc(): the empirical Kaiser criterion (Braeken &
van Assen, 2017) with the embedding dimension in the sample-size role. Its
serial reference-eigenvalue correction addresses the classical
parallel-analysis weakness that reference values ignore variance already
captured by real factors. Available in sfa_nfactors() via
methods = "EKC".sfa_nfactors() default methods changed from
c("parallel", "kaiser", "TEFI") to "parallel" alone. Retention defaults
should match the field's conventional expectation (parallel analysis), and
the old default's silent votes carried known biases (the latent-root rule
is liberal by construction; TEFI runs low on embedding similarity
matrices, so the old bare-call consensus could tie-break down to its
value). The full battery is opt-in, as in the package demonstration
(c("parallel", "kaiser", "TEFI", "EGA", "EKC")), and print() now shows
the consensus line only when two or more methods ran.sfa_map(): Velicer's (1976) minimum average partial.
Available in sfa_nfactors() via methods = "MAP" but deliberately not a
default vote: on embedding similarity matrices MAP tracks reliable minor
structure well past the interpretable factor count.sfa_cd(): a comparison-data misfit profile adapting Ruscio
& Roche (2012), with print and plot methods. It reports how well k-factor
comparison populations reproduce the observed eigenvalue spectrum as k
grows, rather than a single retention verdict: response data with a crisp
factor boundary show a sharp elbow, while embedding similarity matrices
decline smoothly. Ruscio & Roche's sequential significance rule is opt-in
(alpha =) because it saturates at n_factors_max on embedding matrices
(the k-factor comparison model cannot reproduce the anisotropic spectral
tail, so every added factor keeps helping).data(big5) now ships 50 x 4096 Qwen3-Embedding-8B
item embeddings (rounded to 4 decimal places), replacing the 50 x 384
all-MiniLM-L6-v2 sentence-BERT embeddings of 0.1.0. Analyses run on the
bundled data will differ from 0.1.0.sfa_item_fit() now compares candidates against unflipped (topical)
construct centroids, matching sfa_anchor() and sfa_simplify(). The
previous behavior sign-flipped reverse-keyed reference items into anti-topic
vectors, which depressed the item-similarity profile of constructs with many
reverse-keyed items and could misassign candidates. reverse_key = TRUE
still flips the candidate itself.sfa_congruence()'s disattenuated metric now returns NA with a warning
when either similarity matrix's split-half reliability is not positive
(e.g., the checkerboard sign pattern of atomic_reversed), instead of
failing with an unhelpful error.sfa_nli_matrix() reads the entailment/contradiction label order from the
cross-encoder's model config instead of assuming the
cross-encoder/nli-* order, so non-default NLI models score correctly (a
warning falls back to the default order when the config is unavailable).sfa_parallel() now applies Horn's sequential retention rule (count leading
eigenvalues until the first falls below its null percentile) instead of
counting all eigenvalues above their pointwise percentiles, and its
documentation cites the embedding-benchmark precedent (Garrido et al.).sfa_dimselect() default encoding is now "atomic", matching sfa().$transformed_embeddings
(previously $embeddings, which was easy to confuse with
$input_embeddings).digest moved from Suggests to Imports: embedding cache keys are now always
SHA-256 (the previous fallback hash could collide).sfa_anchor() help no longer claims items are
sign-aligned before anchoring (they never were in this release line, by
design), the big5 item-code range reads E1--O50, the README encoding table
marks atomic as keying-free, and README/vignette references to the bundled
data name the Qwen3 embeddings.sfa() function for semantic factor analysis.atomic_reversed, atomic, squid, mean_centered_pearson.sfa_parallel()).sfa_nfactors()).sfa_congruence()).Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.