rasch-per
Rasch model and Classical Test Theory (CTT) psychometric analysis for education research, built for physics / STEM / discipline-based education researchers (PER / DBER).
Feed it a CSV of dichotomous (0/1) item responses and get person abilities, item difficulties, fit statistics, dimensionality checks, DIF analysis, and a full self-contained HTML validity report.
Status: implemented and validated (119 tests, ~97% coverage). The library is Beta; the public API is stable for the analyses listed below.
Quickstart (CLI)
pip install rasch-per
rasch-per simulate --output demo.csv
rasch-per analyze demo.csv --output report.html
simulate writes a synthetic response CSV (with a person_id index). analyze
reads it back (the first column is the person index), runs the full pipeline,
and writes a self-contained HTML report.
# With differential item functioning (DIF) by a group column
rasch-per analyze demo.csv --groups groups.csv --dif-group gender \
--reference Man --focal Non-man --output report.html
Python API
import pandas as pd
from rasch_per import (
ResponseData,
CTTAnalysis,
RaschModel,
DIFAnalysis,
generate_report,
)
# Load a response matrix (persons as rows, items as columns)
df = pd.read_csv("responses.csv", index_col=0)
data = ResponseData(df)
# Classical Test Theory
ctt = CTTAnalysis(data).run()
print(ctt.summary())
print(ctt.reliability.cronbach_alpha) # attribute, not a method
# Rasch (MML is the default estimator)
model = RaschModel().fit(data, estimator="MML")
print(model.item_difficulties) # pandas Series indexed by item name
print(model.fit_statistics()) # infit / outfit mean-squares
# Differential Item Functioning
groups = pd.read_csv("groups.csv", index_col=0)["gender"].reindex(data.person_ids)
dif = DIFAnalysis(model, groups=groups.to_numpy(), reference="Man", focal="Non-man").analyze()
print(dif.summary()) # ETS delta classification + BH flags
# Self-contained HTML validity report
generate_report(
df,
output="validity_report.html",
groups=groups.to_numpy(),
reference="Man",
focal="Non-man",
)
Notes on the API:
generate_reporttakes apandas.DataFrame, not aResponseData. When you passgroups, they must be aligned to the DataFrame's row order (here, the person index).CTTResults.reliabilityis an attribute (cronbach_alpha,mcdonald_omega,ferguson_delta), not a callable.DIFAnalysisis run with.analyze()(it returns aDIFResults).
What's inside
- CTT: item difficulty (p-values), discrimination (corrected item-total, rest-score based) with bootstrap SEs; Cronbach's alpha, McDonald's omega, Ferguson's delta.
- Rasch: JML and MML estimation (MML default), standard errors.
- Fit: infit/outfit mean-square with low-stakes/high-stakes presets; Yen's Q3 local independence check.
- Dimensionality: PCAR first-contrast eigenvalue diagnostic.
- DIF: Lord's chi-square, mean/mean linking, ETS delta effect sizes, Benjamini-Hochberg correction.
- Report: single-file HTML validity report with embedded plots.
Methodology & References
This package implements standard, published psychometric methods used throughout physics / discipline-based education research:
- Rasch model (Rasch, 1960; Wright & Stone, 1979)
- Joint and marginal maximum likelihood estimation (e.g., as in R packages
TAM,eRm) - Infit/outfit mean-square fit statistics (Smith, 2000; Linacre, 2002)
- Yen's Q3 local independence statistic (Yen, 1984)
- Principal components analysis of residuals (Linacre, 1998)
- Lord's chi-square DIF test (Lord, 1980)
- ETS delta scale DIF classification (ETS categories A/B/C)
- Benjamini-Hochberg false discovery rate control (Benjamini & Hochberg, 1995)
- Cronbach's alpha (Cronbach, 1951), McDonald's omega (McDonald, 1999), Ferguson's delta (Ferguson, 1949)
No third-party assessment content or data is included; all examples use synthetic data from the package's own simulator.
Documentation & Examples
- API and usage docs:
mkdocs serve(source indocsrc/, requires thedocsextra:pip install "rasch-per[docs]"). - Worked notebooks:
examples/notebooks/quickstart.ipynbandexamples/notebooks/report_walkthrough.ipynb. - Optional analyses (PDF export, CFA, Stocking-Lord linking, R cross-validation)
live in
scripts/and use thepdf/cfaextras where needed.
Screenshots
Key diagnostic plots produced by the package's plotting API on simulated data (500 persons, 20 items, seed 42):
| Plot | Description |
|---|---|
| Person ability vs item difficulty (Wright map) | |
| Test information and standard error of measurement across the ability scale | |
| Item characteristic curve with empirical overlay (item 1) | |
| CTT item difficulty with bootstrap standard-error bars | |
| CTT item point-biserial discrimination | |
| DIF contrasts with ETS A/B/C classification |
The figures are generated from simulate_rasch_data and the analysis pipeline
(CTT, Rasch MML, DIF).
Development
See CONTRIBUTING.md. Validation loop: ./.validation.sh.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rasch_per-0.1.0.tar.gz.
File metadata
- Download URL: rasch_per-0.1.0.tar.gz
- Upload date:
- Size: 246.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8579af4b38d7bf3325c665615e8f6855caebecfa14240a7666a16aa099630cd
|
|
| MD5 |
af247b3b9c6d6b7444ae28baac25a713
|
|
| BLAKE2b-256 |
bc24e5695c6e4812f815f5f8eea779ebf10734183bbd91df015cd3317d892e57
|
Provenance
The following attestation bundles were made for rasch_per-0.1.0.tar.gz:
Publisher:
publish.yml on aditya-an1l/rasch-per
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rasch_per-0.1.0.tar.gz -
Subject digest:
b8579af4b38d7bf3325c665615e8f6855caebecfa14240a7666a16aa099630cd - Sigstore transparency entry: 2641995016
- Sigstore integration time:
-
Permalink:
aditya-an1l/rasch-per@c7e91132b482e703e04dbcbacaf0f3dac426c70d -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/aditya-an1l
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c7e91132b482e703e04dbcbacaf0f3dac426c70d -
Trigger Event:
push
-
Statement type:
File details
Details for the file rasch_per-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rasch_per-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19bc3038aba0b614fb259b0bac981db438a250eb3254db5ea197ddcb4fa7970a
|
|
| MD5 |
4195ae37d09efa1ff7bd07f86ad51931
|
|
| BLAKE2b-256 |
187356e24582427bbee078a703c19b717ca6199c9fd89f2a0b5235242923ee6c
|
Provenance
The following attestation bundles were made for rasch_per-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on aditya-an1l/rasch-per
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rasch_per-0.1.0-py3-none-any.whl -
Subject digest:
19bc3038aba0b614fb259b0bac981db438a250eb3254db5ea197ddcb4fa7970a - Sigstore transparency entry: 2641995097
- Sigstore integration time:
-
Permalink:
aditya-an1l/rasch-per@c7e91132b482e703e04dbcbacaf0f3dac426c70d -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/aditya-an1l
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c7e91132b482e703e04dbcbacaf0f3dac426c70d -
Trigger Event:
push
-
Statement type: