Naming the factors

knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = FALSE)

Semantic factor analysis extracts factors from the meaning of scale items. sfa_name() completes the workflow by giving each factor a verbal label — the name of the psychological construct its items express — retrieved deterministically from a pre-filtered pool of ~370,000 candidate terms (every WordNet entry and filtered Wikipedia title that qualifies as a psychological-attribute noun phrase, completed against five open construct inventories). Nothing is generated: the label is the nearest eligible term to the factor in the embedding space, under an instruction that asks the model to represent each item as the construct it measures.

Basic use

library(semanticfa)

fit <- sfa(big5$items, nfactors = 5)
labels <- sfa_name(fit)
labels
#> Factor labels (Qwen/Qwen3-Embedding-0.6B)
#>
#>   F1   emotional instability  [emotional instability, neuroticism]
#>   F2   conscientiousness
#>   ...

The first call downloads the candidate pool for your embedding model into the user cache (a one-time download; see sfa_pool()); afterwards everything is local and deterministic.

Or inline with the fit:

fit <- sfa(big5$items, nfactors = 5, label_factors = TRUE)
fit$labels

What you get

One row per factor:

Labels name the pole toward which the factor's positive loadings point: a factor defined by reverse-worded sociability items may be labeled "social withdrawal" — that is the faithful reading of its loadings, not an error.

Using a larger model for naming

Extraction and naming reward different model properties: factor structure is recovered well by compact encoders, but label abstraction (choosing "anxiety" over a symptom word like "palpitation") improves with larger naming models. sfa_name() therefore accepts its own model:

labels <- sfa_name(fit, model = "microsoft/harrier-oss-v1-27b")

The factor structure stays exactly as fitted; only the naming space changes. Note the model itself is downloaded on first use and is large (~54 GB for the example above) — a GPU machine is strongly recommended for this option.

Rotating toward nameable factors

Naming reads whatever orientation the rotation happened to produce. If you would rather choose the orientation that is most nameable in the first place, sfa_leximax() rotates the solution toward the construct lexicon, maximizing the agreement between each factor's naming target and the term retrieved for it:

# rotate an existing fit
rot <- sfa_leximax(fit)
rot$labels

# or fit and rotate in one call
fit_lex <- sfa(big5$items, nfactors = 5, rotate = "leximax")

This is a rotation, so model fit is invariant: communalities and the reproduced correlation matrix are unchanged, and only the axes move. sfa_nameability() reports how nameable any given orientation is, which is what lets you compare a leximax solution against the oblimin one you started with.

Both need the naming word pool, so fetch it once with sfa_pool(model, download = TRUE) before working offline.

Reproducibility notes



Try the semanticfa package in your browser

Any scripts or data that you put into this service are public.

semanticfa documentation built on Sept. 2, 2026, 1:07 a.m.