MyNixOS website logo
Description

Semantic Factor Analysis of Language Model Embeddings.

Performs exploratory factor analysis on language model embeddings of psychological scale items. Embeds item text with sentence transformers or other language models, transforms the embeddings into item-by-item similarity matrices, and extracts latent factor structure via standard exploratory factor analysis. Supports embedding-adapted parallel analysis, several similarity transforms (atomic reversed, SQuID centering, mean-centered Pearson), and fit diagnostics tailored to embedding matrices (TEFI, RMSR, CAF, McDonald's omega). The underlying methods are documented with full citations in the corresponding function help pages. Returns objects compatible with 'psych' and 'EFAtools' workflows.

semanticfa

Response-free semantic analysis of psychometric scales.

semanticfa reads the meaning of a scale's item wording with a language model and recovers, interprets, and refines the scale's latent structure — entirely from the items, with no human response data. Factor analysis on the item embeddings is the centerpiece, but the package is a full toolkit for working with a scale before (or without) collecting data: building semantic similarity matrices, deciding how many factors to keep, reading a semantic "loadings" table, comparing the recovered structure to theory, flagging redundant items, building short forms, vetting brand-new candidate items, detecting jingle/jangle fallacies across scales, and visualizing the item space.

Installation

# from CRAN (once available):
install.packages("semanticfa")

# development version:
# install.packages("remotes")
remotes::install_github("devon7y/semanticfa")

The core of the package is pure R. Turning item text into embeddings on your machine uses Python via reticulate — needed only if you want the package to embed text for you (you can always bring your own embeddings):

sfa_install_python()   # one-time: provisions sentence-transformers

Two-dimensional item maps work out of the box (Rtsne and uwot are bundled). One optional package, EGAnet, powers EGA-based factor retention / dimension selection and the faithful UVA redundancy method — install it only if you use those parts.

Quick start

library(semanticfa)
data(big5)   # 50 IPIP Big-Five items + precomputed Qwen3-Embedding-8B embeddings

# one call: embed -> similarity -> retain -> extract -> diagnose
fit <- sfa(
  data.frame(code = big5$codes, item = big5$items,
             factor = big5$factors, scoring = big5$scoring),
  embeddings = big5$embeddings, nfactors = 5)
fit

# interpret and refine, all from the same fit
plot(fit, type = "scree")          # scree with parallel-analysis overlay
sfa_corplot(fit)                   # item-by-item similarity heatmap, grouped by factor
sfa_anchor(fit)                    # item-by-construct "belonging" (a semantic loadings table)
sfa_congruence(fit, target = big5$factors,    # agreement with theory (partition metrics)
               metrics = c("nmi", "ari"))
sfa_redundancy(fit)                # near-duplicate items

No respondents are involved at any step.

What's in the box

1. Embed text and build a similarity matrix

FunctionPurpose
sfa_embed()Embed item text — on-device sentence-transformers (Qwen3 models, default), the OpenAI API, or any custom function. Results are cached.
sfa_load_npz()Load pre-generated embeddings (e.g. a GPU job) from a NumPy .npz, no Python needed.
sfa_similarity()Item-by-item similarity matrix with a choice of four encodings (below).
sfa_nli_matrix()Signed, valence-aware similarity from natural-language inference (entailment − contradiction), so reverse-keyed items are handled directly.
sfa_install_python(), sfa_clear_cache()Provision the embedding environment / clear the cache.

2. Recover the factor structure

FunctionPurpose
sfa()The end-to-end pipeline: embed → similarity → retain → extract → diagnose. Accepts raw text, precomputed embeddings, an sfa_embeddings object, or a precomputed similarity matrix.
sfa_nfactors()How many factors to keep — parallel analysis, Kaiser, TEFI, and EGA in one call.
sfa_parallel()Embedding-adapted parallel analysis (random-unit-vector null; no sample size needed).
sfa_dimselect()Select the informative leading embedding coordinates ("depth") by EGA depth optimization.
as_psych()Hand the solution to psych (factor.congruence(), fa.sort(), …) as a standard fa object.

3. Interpret the structure

FunctionPurpose
sfa_anchor()An item-by-construct belonging matrix — a semantic loadings table — built from construct centroids and/or construct-name embeddings.
sfa_project()Place items on interpretable bipolar axes (e.g. mildsevere, passiveactive).
sfa_congruence()Compare the recovered structure to an empirical or theoretical one: Tucker φ, NMI, ARI, Frobenius, and disattenuated correlation.
sfa_jinglejangle()Flag jingle (same name, different content) and jangle (different name, same content) fallacies across multiple scales.

4. Refine the scale — before collecting data

FunctionPurpose
sfa_redundancy()Detect near-duplicate items via faithful Unique Variable Analysis (absolute wTO on an EBICglasso network) or a direct cosine criterion.
sfa_simplify()Build response-free short forms by selecting the most representative items per factor.
sfa_item_fit()Vet a brand-new candidate item: how well does it match the construct name and the other items, and is it redundant with any of them?

5. Visualize

FunctionPurpose
sfa_corplot()Heatmap of the item-by-item similarity matrix, grouped/ordered by factor (order accepts factor-name abbreviations, e.g. c("D","A","S")).
sfa_itemplot()2-D item map via t-SNE, UMAP, PCA, or MDS (sfa_tsneplot() is a deprecated alias).
plot(fit, "scree")Scree plot with the parallel-analysis overlay.

Fit diagnostics

Every sfa() fit reports KMO, a real partition-based TEFI (negative; lower is better), RMSR, CAF, McDonald's ω, and — when theoretical factors are supplied — a factor-to-theory alignment matrix (DAAL). summary(fit) adds the full breakdown, and calibrate = TRUE adds a Monte Carlo null reference for the diagnostics.

Encoding methods (sfa_similarity(..., encoding=))

MethodDescriptionKeying
"atomic" (default)L2-normalize, cosine similaritykeying-free (scoring ignored)
"atomic_reversed"Sign-flip reverse-keyed items, L2-normalize, cosineuses scoring sign-flip
"squid"Subtract the questionnaire-mean embedding, then cosinekeying-free
"mean_centered_pearson"Mean-center → cosine = Pearson correlationkeying-free

Bundled data

data(big5) — the 50-item IPIP Big-Five markers (public domain) with precomputed Qwen3-Embedding-8B embeddings (rounded to 4 decimal places), so every example runs without Python or network access.

Learn more

A getting-started tour, worked end-to-end on the bundled Big Five inventory, is in the package vignette (vignette("introduction", package = "semanticfa")).

References

  • Milano, N., Luongo, M., Ponticorvo, M., & Marocco, D. (2025). Semantic analysis of test items through large language model embeddings predicts a-priori factorial structure of personality tests. Current Research in Behavioral Sciences, 8, 100168. doi:10.1016/j.crbeha.2025.100168
  • Casella, M., Luongo, M., Marocco, D., Milano, N., & Ponticorvo, M. (2024). LLM embeddings on test items predict post hoc loadings in personality tests. Ital-IA 2024, CEUR Workshop Proceedings.
  • Guenole, N., D'Urso, E. D., Samo, A., Sun, T., & Haslbeck, J. M. B. (preprint). Enhancing Scale Development: Pseudo Factor Analysis of Language Embedding Similarity Matrices. OSF: https://osf.io/3mpzb/
  • Pellert, M., Lechner, C. M., Sen, I., & Strohmaier, M. (2026). Neural network embeddings recover value dimensions from psychometric survey items on par with human data (SQuID). Findings of the ACL: EACL 2026, 5738–5752.
  • Pokropek, A. (2026). From keyword-based text measures to latent variables: Confirmatory factor analysis with word embeddings. EPJ Data Science. doi:10.1140/epjds/s13688-026-00654-1
  • Kmetty, Z., Koltai, J., & Rudas, T. (2021). The presence of occupational structure in online texts based on word embedding NLP models. EPJ Data Science, 10, 55. doi:10.1140/epjds/s13688-021-00311-9
  • Christensen, A. P., Garrido, L. E., & Golino, H. (2023). Unique Variable Analysis: A network psychometrics method to detect local dependence. Multivariate Behavioral Research, 58(6), 1165–1182. doi:10.1080/00273171.2023.2194606
  • Golino, H. (2026). Optimizing the landscape of LLM embeddings with Dynamic Exploratory Graph Analysis for generative psychometrics. arXiv:2601.17010.
  • Grand, G., Blank, I. A., Pereira, F., & Fedorenko, E. (2022). Semantic projection recovers rich human knowledge of multiple object features from word embeddings. Nature Human Behaviour, 6(7), 975–987. doi:10.1038/s41562-022-01316-8
  • Wulff, D. U., & Mata, R. (2025). Semantic embeddings reveal and address taxonomic incommensurability in psychological measurement. Nature Human Behaviour, 9(5), 944–954. doi:10.1038/s41562-024-02089-y
  • Wulff, D. U., & Mata, R. (2026). Escaping the jingle-jangle jungle: Increasing conceptual clarity in psychology using large language models. Current Directions in Psychological Science, 35(2), 59–65. doi:10.1177/09637214251382083
  • Hommel, B. E., & Arslan, R. C. (2025). Language models accurately infer correlations between psychological items and scales from text alone. Advances in Methods and Practices in Psychological Science, 8(4). doi:10.1177/25152459251377093
  • Jung, S.-J., & Seo, J.-W. (2025). A transformer-based embedding approach to developing short-form psychological measures. Frontiers in Psychology, 16, 1640864. doi:10.3389/fpsyg.2025.1640864
  • Wang, B., Zhang, Y., Hu, Y., Hou, H., Peng, K., & Ni, S. (2026). Discovering semantic latent structures in psychological scales: A response-free pathway to efficient simplification. arXiv:2602.12575.

License

GPL (>= 3)

Metadata

Version

0.1.1

License

Unknown

Platforms (79)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    wasip1
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arc-linux
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • sh4-linux
  • vc4-none
  • wasm32-wasip1
  • wasm64-wasip1
  • x86_64-cygwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows