Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# kaefa Architecture

Last updated: 2026-02-14
Last updated: 2026-08-25

## Purpose

`kaefa` is an R package for automated exploratory factor analysis (AEFA).
Accepted decisions already true on this branch are recorded in `docs/adr/`.
It provides:

- core AEFA execution (`aefa`, `engineAEFA`),
Expand Down
202 changes: 103 additions & 99 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -15,143 +15,147 @@ knitr::opts_chunk$set(

# kaefa

The goal of kaefa is to improve researchers' ability to identify unexplained factor structures in complex, cross-classified multilevel data in R. It uses an automated exploratory factor analysis (aefa) framework.
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ContextualWisdomLab/kaefa)

## Algorithm
**Automated exploratory IRT/factor-model search for complex assessment data in
R.**

The automated exploratory factor analysis (aefa) framework implements a **greedy search algorithm** to efficiently explore the model space and find improved model configurations. The algorithm iteratively:
kaefa helps researchers explore uncertain factor structures without manually
rebuilding every candidate model. Its AEFA workflow coordinates candidate
estimation, information-criterion comparison, item-fit review, and iterative
refinement while keeping the fitted `mirt` model artifacts available for
scientific inspection.

1. Evaluates multiple model candidates with different factor structures and item response models
2. Selects the best model using AIC by default, with AICc, BIC, and sample-size-adjusted BIC available. DIC is used only when a fitted model actually supplies posterior DIC; it is never approximated with AIC.
3. Assesses item fit and removes poorly fitting items one at a time
4. Re-estimates the model until convergence to a locally optimal solution
## Where kaefa fits

This greedy approach enables efficient exploration of the model space while seeking improved solutions through iterative refinement. The method aligns with model selection and exploratory factor analysis research (Preacher, Zhang, Kim, & Mels, 2013; Jennrich & Bentler, 2011).
Use kaefa when the factor structure is not fully known in advance and you need a
repeatable exploratory search over supported IRT/factor-model candidates. The
package is aimed at psychometric and applied measurement work, including data
with multilevel or cross-classified structure where supported by the underlying
model path.

**References:**
kaefa does not turn an exploratory search into confirmatory evidence. Factor
interpretation, model adequacy, recovery, sampling assumptions, and downstream
score-use decisions still require domain review and appropriate validation.

- Preacher, K. J., Zhang, G., Kim, C., & Mels, G. (2013). Choosing the optimal number of factors in exploratory factor analysis: A model selection perspective. Multivariate Behavioral Research, 48(1), 28-56. https://doi.org/10.1080/00273171.2012.710386
- Jennrich, R. I., & Bentler, P. M. (2011). Exploratory bi-factor analysis. Psychometrika, 76(4), 537-549. https://doi.org/10.1007/s11336-011-9218-4
- Hurvich, C. M., & Tsai, C.-L. (1989). Regression and time series model selection in small samples. Biometrika, 76(2), 297-307. https://doi.org/10.1093/biomet/76.2.297
- Spiegelhalter, D. J., Best, N. G., Carlin, B. P., & van der Linde, A. (2002). Bayesian measures of model complexity and fit. Journal of the Royal Statistical Society: Series B, 64(4), 583-639. https://doi.org/10.1111/1467-9868.00353
## Core workflow

## Installation
1. Provide an item-response data set or supported model inputs.
2. Run `aefa()` with the candidate/search settings appropriate to the study.
3. kaefa evaluates candidate models through `engineAEFA()` and the configured
fit/search policy.
4. Review the selected model, item-fit evidence, convergence diagnostics, and
retained search history before interpreting the result.

You can install kaefa from github with:
A minimal scientific API example is:

```{r gh-installation, eval = FALSE}
# install.packages("devtools")
devtools::install_github("seonghobae/kaefa")
```{r example, eval = FALSE}
library(kaefa)

result <- kaefa::aefa(mirt::Science)
result
```

## Example
The current numerical estimation boundary is `mirt`; kaefa orchestrates model
search and supporting diagnostics rather than owning an independent IRT
likelihood engine.

This is a basic example which shows you how to solve a common problem:
## Model-search behavior

```{r example, eval = FALSE}
## basic example code
library('kaefa')
mod1 <- kaefa::aefa(mirt::Science)
mod1
```
The AEFA loop uses a greedy candidate-search strategy. AIC is the default
selection criterion, with AICc, BIC, and sample-size-adjusted BIC available where
the fitted model supplies the required quantities. DIC is used only when a
fitted model actually supplies posterior DIC; it is not approximated with AIC.

## Remote Execution (Optional)
Item-fit/search behavior and accepted `mirt` fit-search decisions are documented
in [`docs/adr/`](docs/adr/). The research/provenance index is maintained in
[`docs/papers/README.md`](docs/papers/README.md).

You can preconfigure remote hosts and SSH keys for `aefaInit()`:

```{r remote-ssh, eval = FALSE}
options(kaefaServers = c("node1", "node2"))
ssh_keys <- c(
normalizePath("~/.ssh/kaefa_node1"),
normalizePath("~/.ssh/kaefa_node2")
)
init <- aefaInit(sshKeyPath = ssh_keys)
```
## Product surfaces

Security checklist:
kaefa currently remains one R package with three explicit product boundaries:

- Use absolute paths (expand `~` with `normalizePath()`).
- Restrict key permissions (for example, `chmod 600 ~/.ssh/kaefa_node1`).
- Store keys in encrypted storage or a secrets manager; never commit them.
- Rotate keys regularly (for example, quarterly) and limit access to required users or groups.
- **kaefa-core** — `aefa()`, `engineAEFA()`, model selection, item-fit evaluation,
theta-prior utilities, and scientific/recovery evidence.
- **kaefa-studio** — the optional bundled Shiny interface launched with
`launchAEFA()`.
- **kaefa-runner** — the future hosted/container/remote execution boundary; it
is not a separately released product today.

## Local vs Remote Execution Sizing Guide
Optional remote execution is configured through `aefaInit()`. Local execution
remains the default. SSH keys and other credentials must stay outside the
repository and be supplied through appropriately protected local/hosted
configuration.

Use these default thresholds when deciding whether to run `aefa()` on a local
workstation or a remote server.
## Evaluate the source

| Workload profile | Suggested runtime | Recommended environment |
| --- | --- | --- |
| Up to ~5,000 respondents and up to ~60 items | Usually under 30 minutes | Local machine (8+ CPU threads, 16GB+ RAM) |
| ~5,000-20,000 respondents or ~60-150 items | About 30-120 minutes | Remote VM/cluster node (16+ CPU threads, 32GB+ RAM) |
| Over ~20,000 respondents or over ~150 items | Often over 2 hours | Remote cluster/HPC (32+ CPU threads, 64GB+ RAM) |
The repository does not currently publish a GitHub Release. Source metadata is
`0.1.428`; that value and a passing development check are not immutable release
or support evidence.

These are empirical guidelines. Runtime and memory can vary by hardware,
`aefa()` options (for example, rotation/estimation choices), and parallel job
count.
For maintainers working in an isolated dependency/license-review environment,
run the repository package checks against the checkout rather than relying on
historical `seonghobae/kaefa`, Travis CI, or AppVeyor instructions:

Operational notes:
```bash
R CMD build .
R CMD check --no-manual kaefa_*.tar.gz
```

- Prefer local runs for exploratory tuning and small pilot datasets.
- Prefer remote runs when model-search cycles are long, memory usage spikes, or
multiple analyses must run in parallel.
- If you see repeated slow convergence, monitor RAM/CPU and move the workload
to remote infrastructure before increasing model complexity.
The exact supported R/dependency environment and hosted evidence are defined by
current repository workflows and package metadata, not by historical badges in
this README.

## Interactive Shiny Interface
## Interactive studio

For applied psychologists who prefer a point-and-click interface without writing code, kaefa now includes an interactive Shiny web application:
The Shiny surface exposes the same underlying package responsibility for users
who prefer an interactive workflow:

```{r shiny-launch, eval = FALSE}
# Launch the interactive interface
library('kaefa')
library(kaefa)
launchAEFA()
```

The Shiny interface provides:

- **Easy data upload**: Upload your item response data in CSV or RDS format
- **Simple configuration**: Configure factor extraction, rotation methods, and model selection criteria through dropdown menus
- **Visual results**: View factor loadings, item fit statistics, and model fit indices in an organized interface
- **Export results**: Download complete results and summary reports

This makes kaefa accessible to researchers without programming experience while maintaining all the powerful automated factor analysis capabilities.

## New Feature: fitdistrplus Integration for Theta Priors
Treat UI output as analysis evidence to review, not as an automatic scientific
or operational decision.

kaefa now supports setting theta priors based on empirical raw score distributions using the `fitdistrplus` package. This feature allows you to:
## Architecture and verification

1. Fit distributions to raw scores to inform theta priors
2. Test if calibration works for non-nominal models
3. Validate model calibration against empirical distributions
The current runtime flow is:

Example usage:
`aefa()` -> candidate search -> `engineAEFA()` / `mirt` estimation -> model
comparison -> item-fit/refinement -> selected model + diagnostics.

```{r fitdistrplus-example, eval = FALSE}
# Fit a distribution to raw scores
fit <- fitThetaPrior(mirt::Science, dist = "norm")

# Test calibration with distribution fit
testResult <- testThetaPriorCalibration(mirt::Science, dist = "norm")

# Apply theta prior during calibration
model <- applyThetaPrior(mirt::Science, fit, minExtraction = 1, maxExtraction = 1)
```
See [ARCHITECTURE.md](ARCHITECTURE.md) for repository layout, runtime flow,
remote-execution boundaries, and quality gates. Scientific changes should carry
focused regression/recovery evidence; documentation-only checks do not prove
parameter recovery or model validity.

For more examples and detailed documentation, see the `examples/` directory.
## Commercial licensing status

## Software Quality Information
**Not currently cleared for ContextualWisdomLab commercial
intake/distribution.**

## Continuous Integration (Ubuntu, macOS, Windows)
[![R-CMD-check](https://github.com/seonghobae/kaefa/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/seonghobae/kaefa/actions/workflows/R-CMD-check.yaml)
`DESCRIPTION` declares kaefa itself as `GPL-3` and directly imports `mirt`, a
GPL-family runtime dependency, plus additional R dependencies that require a
complete current license inventory. There is no root Apache-2.0/MIT `LICENSE`
file that overrides those terms.

### Ubuntu and Mac environment
[![Travis-CI Build Status](https://travis-ci.org/seonghobae/kaefa.svg?branch=master)](https://travis-ci.org/seonghobae/kaefa)
Issue #83 owns the first-party provenance/relicensing review and replacement of
the GPL-family runtime/build dependency boundary while preserving intentionally
supported scientific behavior. Until that work is integrated and verified, do
not present kaefa as Apache-2.0/MIT-cleared or commercially policy-compliant.

### windows environment
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/seonghobae/kaefa?branch=master&svg=true)](https://ci.appveyor.com/project/seonghobae/kaefa)
## Documentation and contribution

<!-- ### code quality -->
<!-- [![Coverage Status](https://img.shields.io/codecov/c/github/seonghobae/kaefa/master.svg?maxAge=3600)](https://codecov.io/github/seonghobae/kaefa?branch=master) -->
- [Architecture](ARCHITECTURE.md) — product/runtime ownership boundaries.
- [Architecture decisions](docs/adr/README.md) — accepted fit/search decisions.
- [Research sources](docs/papers/README.md) — formula and literature provenance.
- [Contributor Code of Conduct](CONDUCT.md) — collaboration expectations.
- [Ask DeepWiki](https://deepwiki.com/ContextualWisdomLab/kaefa) —
repository-aware navigation.

[Contributor Code of Conduct](CONDUCT.md)
For scientific behavior changes, include the estimand/model assumption being
changed and reproducible recovery/regression evidence. For documentation or
operability changes, keep user-facing claims tied to current protected source
and exact-head checks.
Loading
Loading