Run and Optimize Cross-Situational Word Learning Models
Overview
A collection of cognitive models of cross-situational word learning, together with methods and datasets for fitting and cross-validating them against experimental and corpus data, and for plotting the results.
New Features
- Added
uncfam_elimination(), a variant ofuncfam()with learning by elimination (mutual exclusivity). Each on-trial pair's mutual confidenceP(o|w) * P(w|o)is computed from the current associations, and a pair gets *elimination support* to the extent that the trial's other words and objects are already accounted for by each other. That support, weighted by a free parametereps, is added touncfam()'s familiarity-and-uncertainty share of the trial's associative weight before renormalizing;eps = 0reproducesuncfam()exactly. Inuncfam(), an already-known pair on a trial draws weight *away* from the trial's other pairs; with elimination, knowing one word directs learning to the remaining word-object pairing. Motivated by the initial-accuracy experiment, where learners were more accurate on an initially mis-paired word the more of its study trials it shared with an initially accurate word. Registered inshow_models()/xsl_model_registry() - Added
uncfam_gamma(), a variant ofuncfam()that decouples familiarity's contribution to a trial's attentional allocation from uncertainty's.uncfam()'s allocation weight isexp(B * entropy) * assocs-- entropy gets a free exponent (B), but familiarity (assocs) enters linearly with an implicit weight of 1 and no free parameter of its own.uncfam_gamma()adds one parameter,gamma, raising familiarity to a free power instead (assocs^gamma);gamma = 1reproducesuncfam()exactly. Cross-validated against all ofxsl_datasets, it beats plainuncfam()in every fold of a 5-fold split (mean test SSE 0.48 vs. 0.56), with a best-fitgammaaround 0.3 (familiarity's pull *dampens* with diminishing returns). A separate analysis fitting this same free-gammasubstrate to active cross-situational word learning (learners choosing which items to see named next, rather than a fixed passive sequence) instead found a best-fitgammaaround 2 (amplified, not dampened) -- see?uncfam_gammafor the full comparison - Added
minerva2(),todam(), andrem(), three distributed/episodic memory models ported from standalone prototypes that predated this package (Hintzman's MINERVA2, 1984/1986; Murdock's TODAM, 1982; Shiffrin & Steyvers' REM, 1997) and were never wired into it or tested. All three represent words/objects as random feature vectors rather than tallying a single word-by-object association, and turn their native similarity/odds score into a Luce-choice-ready matrix via an exponentiated (X-temperature) or likelihood-ratio-based choice rule so they plug intoget_perf()/mafc_test()like every other model here. Porting surfaced real bugs in the prototypes, fixed along the way (see each model's@details/source comments):minerva2()'s prototype compared a 2D echo-content vector against D-dim object vectors (silent recycling, not an error) instead of just the echo's object half;todam()'s prototype computed trial-1 attention weights ascos_sim(item, 0)= NaN, poisoning memory from the first trial on, and bothtodam()prototypes called the long-removedas.real();rem()'s prototype never actually implemented REM at all (it declared a geometric feature-vector generator but its model/test functions were an unmodified copy of the MINERVA2 prototype's continuous-Gaussian code) --rem()here is a fresh adaptation of Shiffrin & Steyvers' storage/odds equations to this package's associative task. Benchmarking (see?minerva2/?todam/?remperformance notes) foundrem()'s raw per-simulation likelihood-ratio odds span several orders of magnitude (a lucky match on one rare feature value can dominate), which would otherwise let a single lucky simulation hijackxsl_run()'s sum-across-simulations aggregation;rem()now row-normalizes each simulation's choice weights before returning them. All three are registered inshow_models()/xsl_model_registry(), fitting only their choice-rule temperature (X) or storage parameters (g,u,c) by default --D/w(feature-vector dimensionality) are fixed representational hyperparameters, not free cognitive parameters. Speed varies widely: on the fullxsl_datasets(53 conditions) atn_sim = 500,minerva2()takes ~30s,todam()~8 min, andrem()~20 min --todam()/rem()are impractical toxsl_fit()at full DEoptim settings (NP = 100, itermax = 100would be tens of thousands of evaluations) without sharply reducingn_sim/NP/itermax, as the package's own fitting examples already do for slow models - Added 3 more temporal-contiguity conditions to
xsl_datasetsfrom Kachergis, Yu, & Shiffrin (2009) -- the same paper behind the existing1_max_temp_spat_cont_orig/4_no_spat_orig_max_tcconditions.data-raw/XSL-dataset-fields.csvdocumented 6 "overlap" conditions (3 matched pairs of a control and non-control order at the same overlap degree) that were never pulled in; only the 3 control-order ones (1olap3tr_contr,temp_cont_1olap2tr_contr,temp_cont_2olap2tr_contr) have real subject-level accuracy data findable anywhere in the repo (indata-raw/agg_data/x13_1-21.txt, perexport_data.R's own comments mapping its generic condition labels to these named orders). The other 3 have order files but no discoverable human data, and are deliberately left out rather than guessed. Seedata-raw/add_temporal_contiguity_overlap.R - Added a fifth standalone dataset,
benitez2020(a named list of 7xslDataobjects, one per condition x age-group combination) from Benitez et al. (2020), "The temporal structure of naming events differentially affects children's and adults' cross-situational word learning" (data: osf.io/2hmxr).data-raw/Benitez2020-rep/Benitez2020_XSLdata_extraction.Ralready extracted training orders, 2AFC test trials, and response-count matrices from the raw OSF data but stopped short of buildingxslDataobjects (a literal# ToDoin the file);data-raw/add_benitez2020.Rpicks up from there. 8 symmetric word-object pairs, 12 training trials, 8-item 2AFC test; unlike the other standalone datasets, real per-word accuracy is recoverable directly from the provided response matrices (not just an overall mean) -- structurally it could joinxsl_datasetsdirectly, but is kept standalone by choice, as held-out generalization-test data (seexsl_holdout_datasets) - Added
xsl_holdout_datasets, a registry of every dataset in the package that is *not* part ofxsl_datasetsand therefore never seen byget_group_model_fit()/get_crossvalidated_model_fit()-- i.e. everything available for testing a fitted model's generalization to genuinely held-out data, along with how to score each one (most need a different scoring approach thanxsl_datasets's standard diagonal convention, which is exactly why they're standalone;benitez2020andkachergis_initial_accuracyare the two directly-scorable exceptions, kept out of the fitting pool specifically to serve as held-out data) - Added a fourth standalone dataset,
vlach_debrock2017(Vlach & DeBrock, 2017, *Journal of Memory and Language*, "Remember dax? Relations between children's cross-situational word learning, memory, and language abilities"). 12 symmetric word-object pairs, 2 pairs per training trial, 36 trials, with pairs varying in whether their 6 repetitions are massed or spaced (n = 47 children, ages 2-5). The source only reports an overall mean/SD across all pairs and participants, not a per-word breakdown, soaccuracyisNAthroughout rather than fabricated -- kept standalone (not part ofxsl_datasets) for the same reason askachergis2012_highlighting/gangwani2011_category. See?vlach_debrock2017anddata-raw/add_vlach_debrock2017.R - Added a third standalone dataset,
gangwani2011_category(Experiment 1 of Gangwani, Kachergis & Yu, "Simultaneous Cross-situational Learning of Category and Object Names"; an undergraduate-journal version is Gangwani & Kachergis, *Indiana Undergraduate Journal of Cognitive Science* 5, 2010). A hierarchical design: each training trial shows 2 objects and names 3 words -- the two objects' own 1-to-1 names plus one 1-to-many "category" label naming those two objects and two others seen on other trials -- so every object carries both a basic name and a category label, and the paper's finding is that learners violate mutual exclusivity by learning both. A named list of threexslDataobjects (one per training block: ad hoc / natural / ad hoc), sharing one 36-trial co-occurrence schedule. Its 15 x 12 (word x object) association matrix breaksxslData's diagonal-scoring convention the same waykachergis2012_highlightingdoes, so it is kept standalone; score it withscore_gangwani2011_category()in the newtests/bakeoff_comparison/gangwani2011_category_fit.R, which reads 12-AFC name accuracy, 3-AFC category accuracy, and the paper's headline ME-violation measure straight off any model's matrix. See?gangwani2011_categoryanddata-raw/add_gangwani2011_category.R
Other changes
control$start_matrixis no longer silently ignored. Only some models initialized from it; the rest dropped it without warning (so e.g. a familiarization phase passed as a start matrix simply vanished for them). Models now declaresupports_start_matrixinxslMod(), andxsl_run()errors if a start matrix is given to one that doesn't, or if it doesn't match the training data's dimensions.baseline(),decay(),rescorla_wagner(),softmax_rl(),uncfam_sampling(), andmulti_sampling()now support it, joining theuncfam()family,propose_but_verify(), andpursuit(). The remaining models (fazly(),guess_and_test(),tilles(),bayesian_decay(),kalman_filter(),fgt2009()/fgt2009_rsa(),minerva2()/todam()/rem()) have no single association matrix a start matrix maps onto (or would need a model-specific convention, e.g. a variance as well as a mean), so prior learning should be passed to them as training trials, askachergis_initial_accuracydoes. A custom model built withxslMod()must setsupports_start_matrix = TRUEto receive one. Runs without a start matrix are unchanged
Documentation
Show all changes in 0.4.0Hide the rest of the changes in 0.4.0
- The main vignette now covers every model and dataset added since 0.3.0 (
uncfam_gamma(),uncfam_elimination(),minerva2()/todam()/rem();vlach_debrock2017,benitez2020,xsl_holdout_datasets), and adds two sections: passing prior learning to a model as training trials vs. astart_matrix, and testing a fitted model's generalization on the held-out datasets. Its description of the dataset structure used field names (trials,objs,perf) that no longer exist -- so itscreate_cooc_matrix()example was silently printing an empty matrix -- and said words/objects must be referred to by index, which no longer holds
Bug Fixes
xsl_fit()with a parallel DEoptim backend (DEoptim.control(parallelType = "parallel")) silently returnedbestval = Infwhencontrolwas passed as a variable (e.g.ctrl <- xslControl(n_sim = 100); xsl_fit(..., control = ctrl)):controlwas never forced, so the objective shipped to the worker processes carried an unevaluated promise that each worker tried to evaluate in its own empty global environment, every evaluation errored, and the error was converted toInf.controlis now forced before fitting, andxsl_fit()warns when every evaluation of a fit failed instead of returning an all-Infresult silently. Serial fits were unaffected.create_cooc_matrix()looped over the number of distinct *words* rather than the number of trials: with more words than trials it errored, and with fewer (e.g. its own documented example,xsl_datasets[[1]]: 18 words, 36 trials) it silently tallied only the first trials. It also indexed by raw label (the same issue as #14). Both fixed;plot_training_trials()now indexes by label too. No model uses either function, so no fits changepropose_but_verify()andpursuit()drew new hypotheses withsample(tr_o, ...). On a trial with a single object,tr_ois one value, and when that value is an integerk, R'ssample(k, n)draws from1:krather than returningk-- so a word seen alone with an object usually hypothesized a *different* object, one not even on the trial (propose_but_verify()hypothesized the right object ~1/8 of the time in an 8-object toy). Both now index intotr_o(tr_o[sample.int(length(tr_o), n, replace = TRUE)], asguess_and_test()already did). Noxsl_datasetscondition has single-object trials, so fits to it are unchanged;kachergis_initial_accuracy(18 single-object familiarization trials per condition),kachergis2012_highlighting's words-as-cues condition (28 trials naming two words with one object), and the naturalistic corpora (rollins_corpus,fm_corpus) are affected. Integer-labelled data (e.g.kachergis_initial_accuracy) was affected before this release too; the corpora were not -- they reached these models as string labels, for whichsample()behaves as intended -- until #14 began handing models integer positions, so for the corpora this is a regression in 0.4.0.- Models indexed their association matrices by raw word/object value (
m[tr_w, tr_o]) rather than by position in the sorted vocabulary, which is only correct for labels that are exactly1..N(#14): a vocabulary with a gap crashed ("subscript out of bounds"), and a raw value that still fell in range silently updated the wrong row. Fixed once, inxsl_run(): models now receive each dataset's words/objects as positions, and the original labels are restored on the returned matrix,perf, and trajectory. Test trials are scored by label, and astart_matrixwith dimnames is aligned to the data by label. Checked against every registry model on every bundled dataset (23 models x 75 datasets, fixed seed): 1721 of 1725 runs are bit-identical, including all ofxsl_datasetsand the standalone datasets, whose labels are already1..N. The 4 that differ arepropose_but_verify()andpursuit()onrollins_corpus/fm_corpus, where the fix corrects a real error: both compared a column *position* against the trial's object *labels*, which can never match for character labels, so on the corpora every hypothesis was treated as disconfirmed and none was ever verified. (Handing these models integer positions also exposed the single-objectsample()bug above on the same corpora; both fixes are needed for correct corpus results.) Thepropose_but_verifyandpursuitresults previously intests/bakeoff_comparison/corpus_report.mdwere therefore invalid (including pursuit's reported collapse on FM); the report andvignette("corpora")have been rerun on the fixed code uncfam_predictive()now caps associations atbeta(1), its stated maximum, as well as flooring them at 0. Its unnormalized update could overshoot far abovebetaon a word's first exposure: the prediction error is then ~beta, and it is scaled byexp(B * entropy)of the word's row, whichupdate_known()spreads over every object seen so far -- so a word first seen after many others could reach an association in the thousands in a single trial (e.g. ~4600 for the 18th of 18 sequentially introduced words at X = .8, B = 1.6, C = .7). That association then dominated the word's row and collapsed its entropy, locking in the first pairing it was seen with; in the initial-accuracy study this made the model predict learners would choose an initially inaccurate word's familiarization referent 3-4x as often as they did. **This changesuncfam_predictive()'s fits** wherever the overshoot occurred, including the corpus-fit gains reported for it intests/bakeoff_comparison/corpus_report.md(not rerun here)get_perf()now treats negative associations as 0 before applying the Luce choice rule (aspredict_referent()already did), and answers a word whose associations are then all 0 at chance (1 / ncol(m)) rather than returningNaN. Error-driven models (rescorla_wagner(),kalman_filter()) can learn negative associations, for whichdiag(m) / rowSums(m)gave per-item "probabilities" outside [0, 1] -- which DEoptim could exploit when fitting. In the initial-accuracy study, fittedrescorla_wagner()had negative associations for about half of participants and out-of-range predictions for 25 of 61. *
The NEWS section is longer than shown here.
From NEWS.md in the release
Install
Health
- OK12 OKNow
- OK7 OK2026-10-19
Documentation
- Help pages
- 62 (5 internal)includes a package overview page
- Examples that run
- 98%46 run in a plain check · 1 only when donttest examples are enabled (R CMD check --as-cran)
- Exported functions with examples
- 85%
- Documented parameters
- 93%
- Return-value docs
- 100%
- Help pages citing references
- 0%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- 26
- Median days to close, 50 most recently updated closed PRs
- 0
8 development-tooling and community-health practices detected across 5 families in the upstream repository
Checks run against github.com/kachergis/xslmodels on 2026-10-22.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-16 · The repository has a site deploy workflow
pkgdown site last built 2026-10-16, before release 0.4.0 (2026-10-18)
Show all practicesHide 1 practice
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-07-11Pull request it wrote: opened by a project memberCommits: at least 55 crediting it in the message
- Claude Sonnet 531 commits · Jul to Oct 2026
- Claude Opus 5.524 commits · Sep to Oct 2026
Dependencies
Code & Tests
Datasets
People & History
- 0.4.0Latest2026-10-18 · current release ·
11 days in CRAN's queue
Listed in CRAN's incoming queue from 2026-10-07 20:22 to 2026-10-18 12:19 UTC, in 55 readings. - RR 4.6.0 released · 2026-04-24
Package metadata
- First published
- 2026-10-18
- Total releases
- 1 / 1 yrs
- License
- GPL (>= 3) OSI
- Minimum R
- ≥ 4.1.0
- Bundled data
- 59 KB / 9 files
- Download size
- 268 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("XSLmodels")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-23, which the citation names so these numbers can be found later. More on citing and the projects behind them.