What we compared against, and where it differed
Statory results compared against SPSS and Amos output on the same data. Every number below is read automatically from the comparison records in the repository, so this page cannot be edited by hand; the records themselves are version-controlled.
323 values compared · 292 agree · 0 disagree
Summary
| Analysis family | Engines | Values compared | Agree | Convention differs | Not comparable |
|---|---|---|---|---|---|
| Named by the comparison run | 7 | 93 | 93 | 0 | 0 |
| Difference | 14 | 84 | 74 | 0 | 10 |
| Relationship | 5 | 28 | 19 | 3 | 6 |
| Structural | 2 | 13 | 7 | 2 | 4 |
| Basic Analysis | 2 | 10 | 8 | 0 | 2 |
| Prediction | 2 | 6 | 2 | 0 | 4 |
| Basic Statistics | 1 | 3 | 3 | 0 | 0 |
| IBM SPSS Statistics | 33 | 237 | 206 | 5 | 26 |
| IBM SPSS Amos | 2 | 86 | 86 | 0 | 0 |
Record: docs/parity/spss_diff.md · docs/parity/amos_diff.md
Text & decision — what we compared against
SPSS and Amos do not produce these numbers, so instead of “do the values agree?” we record what each engine was compared against — an external reference, a same-library reproduction, an accuracy measured on a labelled public sample, or nothing comparable yet.
| Engine | Verdict | Against what · how |
|---|---|---|
| ahp | Matches an external reference | For a perfectly consistent matrix (a_ij = w_i/w_j) the answer follows from the definition — weights = w, lambda-max = n, CI = 0, CR = 0 (Saaty's consistency definition). Group aggregation is computed separately with numpy as the element-wise geometric mean (AIJ) and compared. |
| collocation | Matches an external reference | NLTK 3.x `BigramAssocMeasures.pmi` (Church & Hanks, 1990) — the two implementations are run side by side on the same tokens and the same window (4) and compared. |
| dea | Matches an external reference | The envelopment engine is solved again in its **dual multiplier form** and compared — CCR (1978), BCC (1984). |
| dominant_strategy | Matches an external reference | Dominance is a one-line definition, so it is worked out by hand and compared — standard textbook definition. |
| electre | Matches an external reference | Concordance and discordance indices worked out by hand and compared — ELECTRE I, Roy (1968). |
| fuzzy_topsis | Matches an external reference | Chen, C.-T. (2000). "Extensions of the TOPSIS for group decision-making under fuzzy environment." *Fuzzy Sets and Systems*, 114(1), 1–9. — the formulation in that paper is set up and solved independently inside this file (the engine is not imported). |
| nash_equilibrium | Matches an external reference | Equilibria solved independently with nashpy and compared — Nash (1950). |
| promethee | Matches an external reference | Values compared against pymcdm `PROMETHEE_II` (usual preference function) — Brans & Vincke (1985). |
| saw | Matches an external reference | Simple additive weighting is a one-line definition, so it is worked out by hand and compared — MacCrimmon (1968). |
| sentiment_en_accuracy | Measured on a labelled sample | Measured on a labelled sample - UCI Sentiment Labelled Sentences, 500 sentences (250 positive, 250 negative, CC BY 4.0) - accuracy 66.0%, positive F1 0.786, negative F1 0.678, 106 judged neutral. Kotzias (2015). The domain is product, movie and restaurant reviews, which differs from interview and survey text, and the sample carries no neutral label - read it as a reference figure. |
| sentiment_ko_accuracy | Measured on a labelled sample | Accuracy sample - NSMC, 500 labelled reviews (250 positive, 250 negative, CC0) - accuracy 48.4%, positive F1 0.714, negative F1 0.496, 216 judged neutral. The domain is movie reviews, which differs from interview and survey text - read it as a reference figure. |
| sequential_game | Matches an external reference | Backward induction worked out by hand and compared — subgame-perfect equilibrium, Selten (1965). |
| shapley_value | Matches an external reference | Shapley values computed independently from the permutation-average definition and compared — Shapley (1953). |
| social_choice | Matches an external reference | Borda and Condorcet worked out by hand from their definitions and compared — Borda (1781), Condorcet (1785). |
| sociometry | Matches an external reference | Degree, reciprocal choices and isolates counted independently with NetworkX and compared — Moreno (1934). |
| text_comprehensive | Same-library reproduction | Each component measure (frequency, TF-IDF, sentiment) calls the same library again — a reproduction. There is no outside standard for the bundle as a whole. |
| topic_modeling | Same-library reproduction | The engine and the reference both call scikit-learn `LatentDirichletAllocation` — this is a reproduction of the same library, not a comparison against an outside standard. |
| topsis | Matches an external reference | Values compared against pymcdm `TOPSIS` (vector normalization) — Hwang & Yoon (1981). |
| vikor | Matches an external reference | Values compared against pymcdm `VIKOR` (v = 0.5) — Opricovic & Tzeng (2004). |
| Total | 19 | Matches an external reference 15 · Same-library reproduction 2 · Measured on a labelled sample 2 |
Record: backend/tests/parity/family_reference.json
Values not counted as agreeing — and why
These values were not counted as agreeing. "Convention differs" means the values are supposed to differ (the tools compute them differently); "not comparable" means the reference tool does not report that value, or we could not extract it.
Show details (31)
- Not comparable
descriptive · medianSPSS DESCRIPTIVES does not report the median — "not comparable" is the normal outcome here
- Not comparable
reliability · standardized αSPSS does not report standardized α from /MODEL=ALPHA alone
- Not comparable
multiple_regression · X_IND VIFnot comparable · the frozen SPSS output has no collinearity column (COLLIN was not requested) — the Statory value is the textbook VIF, measured with the constant column in place
- Not comparable
multiple_regression · X_MOD VIFnot comparable · the frozen SPSS output has no collinearity column (COLLIN was not requested) — the Statory value is the textbook VIF, measured with the constant column in place
- Not comparable
multiple_regression · MEDIATOR VIFnot comparable · the frozen SPSS output has no collinearity column (COLLIN was not requested) — the Statory value is the textbook VIF, measured with the constant column in place
- Not comparable
paired_ttest · degrees of freedomthe engine's paired-samples table has no df column (it carries N only)
- Not comparable
one_sample_ttest · tnot comparable · the two frozen SPSS outputs contain no such table (the Statory value itself is fine)
- Not comparable
one_sample_ttest · p valuethe p tolerance bottoms out at 0.0005 (3 decimal places shown)
- Not comparable
one_sample_ttest · degrees of freedomthe engine's one-sample table has no df column (it carries N only)
- Not comparable
logistic_regression · X_IND Bnot comparable · the two frozen SPSS outputs contain no such table (the Statory value itself is fine)
- Not comparable
logistic_regression · X_IND p valuethe p tolerance bottoms out at 0.0005 (3 decimal places shown)
- Not comparable
logistic_regression · X_IND Exp(B)not comparable · the two frozen SPSS outputs contain no such table (the Statory value itself is fine)
- Convention differs
logistic_regression · X_IND WaldSPSS carries Wald χ² (= Z²) while the engine carries Wald Z
- Convention differs
moderation · interaction BMR-6 ③ · FIX-4 ④ — the SPSS syntax multiplies z-standardized terms while the engine multiplies mean-centered terms (B_SPSS = B_engine × σ_x × σ_w)
- Convention differs
moderation · interaction betaMR-6 ③ — the engine multiplies standardized variables (z_x·z_w, Aiken & West) while the SPSS syntax standardizes the product term itself
- Not comparable
wilcoxon · p valuethe p tolerance bottoms out at 0.0005 (3 decimal places shown)
- Not comparable
wilcoxon · effect size rSPSS does not report the Wilcoxon effect size r
- Not comparable
friedman · p valuethe p tolerance bottoms out at 0.0005 (3 decimal places shown)
- Not comparable
friedman · Kendall WNPAR TESTS /FRIEDMAN does not report Kendall W
- Not comparable
mcnemar · discordant cell bthe SPSS test-statistics table has no discordant cell counts (they are in the crosstab)
- Not comparable
mann_whitney · p valuethe p tolerance bottoms out at 0.0005 (3 decimal places shown)
- Not comparable
cluster_analysis · X_IND Fcluster numbers may differ from SPSS, but the per-variable F does not depend on the numbering
- Not comparable
cluster_analysis · X_MOD Fcluster numbers may differ from SPSS, but the per-variable F does not depend on the numbering
- Not comparable
cluster_analysis · MEDIATOR Fcluster numbers may differ from SPSS, but the per-variable F does not depend on the numbering
- Not comparable
cluster_analysis · cases per clusterthere is no guarantee the cluster numbering matches SPSS, so we do not match them up by number
- Convention differs
discriminant · group A centroiddiscriminant function direction — all eight cells carry the opposite sign (the magnitudes agree). The SPSS sign rule is unconfirmed because the output has no unstandardized coefficients — awaiting a decision
- Convention differs
discriminant · group B centroiddiscriminant function direction — the same flip as above
- Not comparable
survival_km · mean survival time0 decimal places shown — the tolerance is widened to the rounding width 0.5
- Not comparable
survival_km · median survival timenot comparable · neither side has it — the SPSS output does not carry it and the engine does not report it. It is a standard reporting item, so it is a candidate for the Statory side to add
- Not comparable
survival_cox · X_IND Bnot comparable · the engine does not export the coefficient B (it computes it but carries only the hazard ratio HR) — awaiting an engine addition
- Not comparable
survival_cox · overall chi-squarenot comparable · neither side has it — the SPSS output does not carry it and the engine does not report it. It is a standard reporting item, so it is a candidate for the Statory side to add
By reference tool
IBM SPSS Statistics — 237 values compared · 206 agree · 0 disagree
ancova | 5 | 5 | 0 | 0 |
cluster_analysis | 5 | 1 | 0 | 4 |
correlation | 1 | 1 | 0 | 0 |
crosstab | 3 | 3 | 0 | 0 |
descriptive | 8 | 7 | 0 | 1 |
discriminant | 8 | 6 | 2 | 0 |
efa_paf_varimax | 39 | 39 | 0 | 0 |
efa_pc_varimax | 41 | 41 | 0 | 0 |
friedman | 4 | 2 | 0 | 2 |
hierarchical_regression | 4 | 4 | 0 | 0 |
independent_ttest | 3 | 3 | 0 | 0 |
kruskal_wallis | 4 | 4 | 0 | 0 |
logistic_regression | 4 | 0 | 1 | 3 |
mann_whitney | 3 | 2 | 0 | 1 |
manova | 8 | 8 | 0 | 0 |
mcnemar | 3 | 2 | 0 | 1 |
mediation_step2_a | 2 | 2 | 0 | 0 |
mediation_step3_b_cprime | 3 | 3 | 0 | 0 |
mixed_anova | 21 | 21 | 0 | 0 |
moderation | 3 | 1 | 2 | 0 |
multiple_regression | 16 | 13 | 0 | 3 |
one_sample_ttest | 3 | 0 | 0 | 3 |
one_way_anova | 8 | 8 | 0 | 0 |
one_way_anova(agri) | 5 | 5 | 0 | 0 |
ordinal_regression | 2 | 2 | 0 | 0 |
paired_ttest | 4 | 3 | 0 | 1 |
reliability | 2 | 1 | 0 | 1 |
repeated_measures_anova | 7 | 7 | 0 | 0 |
spearman_correlation | 1 | 1 | 0 | 0 |
survival_cox | 4 | 2 | 0 | 2 |
survival_km | 2 | 0 | 0 | 2 |
two_way_anova | 8 | 8 | 0 | 0 |
wilcoxon | 3 | 1 | 0 | 2 |
IBM SPSS Amos — 86 values compared · 86 agree · 0 disagree
measurement | 41 | 41 | 0 | 0 |
structural | 45 | 45 | 0 | 0 |
Engine grades
Grades are derived automatically from golden tests (fixed inputs with frozen expected outputs) and invariance checks (the same data changed in ways that should not matter — does the answer move?). No one assigns them by hand.
Conditional — which engines, and on what condition
These engines matched the reference values, but one condition remains. You can use the result as long as you know the condition. The conditions are read from the measurement records in the repository — nobody can edit them by hand.
- AutoMLRow order changes the result slightly (splits and starting points follow the order)
- Bootstrap Confidence IntervalRow order changes the result slightly (splits and starting points follow the order)
- Cluster AnalysisRow order changes the result slightly (splits and starting points follow the order)
- Decision TreeRow order changes the result slightly (splits and starting points follow the order)
- Gradient BoostingRow order changes the result slightly (splits and starting points follow the order)
- Index GeneratorWhich cases the table shows follows input order (the computed values are the same)
- MCMC DiagnosticsRow order changes the result slightly (splits and starting points follow the order)
- Multidimensional ScalingRow order changes the result slightly (splits and starting points follow the order)
- Mediation AnalysisRow order changes the result slightly (splits and starting points follow the order)
- ML ClassificationRow order changes the result slightly (splits and starting points follow the order)
- ML RegressionRow order changes the result slightly (splits and starting points follow the order)
- Moderated MediationRow order changes the result slightly (splits and starting points follow the order)
- Multiple MediationRow order changes the result slightly (splits and starting points follow the order)
- Permutation TestRow order changes the result slightly (splits and starting points follow the order)
- Text Comprehensive AnalysisRow order changes the result slightly (splits and starting points follow the order)
- Topic ModelingRow order changes the result slightly (splits and starting points follow the order)
Corrections — engines we fixed, and results to run again
These engines once produced wrong numbers in the places described, and were fixed. If you kept a result from one of them that you ran before the date shown, please run it again. The same note is in the change log.
- Comparison Analysis2026-10-20 · v1.6.45Comparison analysis read every group’s indicator means as 0 when the group column held number codes (1, 2, 3) — the table, best/worst and overall rank had nothing to do with the data. Groups are now matched as text and the real means are counted (blank group cells are left out, text cells in an indicator are missing). When one group has no countable value for an indicator, it stops and says why.If you ran comparison analysis over MCP (the Claude or ChatGPT connection) with a number-coded group column before this date, please run it again.
- IV Regression · Centrality · Difference-in-Differences2026-10-19 · v1.6.44The standard errors of IV regression (2SLS) were computed from residuals built with the first-stage fitted values, so they came out too small — p-values too small and confidence intervals too narrow. They now use the structural residuals built with the original endogenous variable (the same values as statsmodels IV2SLS), and the confidence interval uses the t distribution. A footnote marks a weak instrument when the first-stage F is below 10. Closeness in centrality ignored the strength of the links — distance is now 1/|r| (the same distance as betweenness). Difference-in-differences gave numbers such as 0 on data where the estimate does not exist (an empty treated/control × before/after cell, a constant outcome and so on) — it now stops and says why. It also read time and group levels alphabetically, so with pre/post or before/after the before and after periods swapped and the sign of the effect flipped — they are now read by meaning (number-like text in number order).If you ran IV regression, centrality (closeness) or difference-in-differences (above all with text time levels such as pre/post) before this date, please run it again. An IV result that was significant may no longer be.
- IV Regression · Centrality · Hierarchical Regression2026-10-19 · v1.6.43The "first-stage F" of IV regression was the F of the whole first-stage regression, so it included what the covariates explain — a weak instrument could look strong and "Weak instrument?" could read "No". It is now the partial F of the instrument alone, controlling for the covariates (the same value when there are no covariates). Betweenness in centrality used the correlation r itself as path length, so a strong link became a long path and a negative correlation a negative length — distance is now 1/|r|. Hierarchical regression counted number-coded variables whose measurement level is "nominal" by the size of their codes — they now enter their block as dummy columns (the smallest code is the reference).If you ran IV regression with covariates, centrality with three or more variables, or hierarchical regression with a number-coded nominal variable before this date, please run it again.
- Multiple Regression · Logistic Regression2026-10-18 · v1.6.42A nominal variable coded as numbers (sex or region as 1/2/3) used as a predictor was counted by the size of its codes (3 as three times 1). A variable whose measurement level is "nominal" in variable settings is now entered as dummy columns (the smallest code is the reference), the coefficient table shows coefficients against the reference such as "region=2", and a line under the result table says what was changed. A variable with no measurement level set is still counted as a number, and the result says so.If you ran it before this date with a number-coded variable whose measurement level is nominal as a predictor, please run it again.
- ML Classification · Gradient Boosting · AutoML · Decision Tree · ML Regression2026-10-17 · v1.6.39A nominal variable coded as numbers (sex or region as 1/2/3) used as a predictor was counted by the size of its codes (3 as three times 1). A variable whose measurement level is "nominal" in variable settings is now entered as dummy columns (the smallest code is the reference), and a line under the result table says what was changed. A variable with no measurement level set is still counted as a number, and the result says so.If you ran it before this date with a number-coded variable whose measurement level is nominal as a predictor, please run it again.
- ML Regression2026-10-17 · v1.6.39Choosing the target variable as a predictor as well let the target predict itself, so R² came out inflated. Rows with full-width digits were dropped without a word, and nothing said that non-numeric cells had been left out. The same variable in two roles now stops the run, full-width digits are read as numbers, and the result says how many non-numeric cells were treated as missing.If you ran it before this date with the target also chosen as a predictor, or on data with full-width digits, please run it again.
- ML Classification · Gradient Boosting · AutoML · Decision Tree2026-10-17 · v1.6.39When the target column held the same value written in different ways (1, "1", " 1 ", "1.0", full-width digits), the run stopped with a server error, or, when every cell was text, the same value was split into several classes. Regression runs stopped on text in the target. The notation is now merged into one value, a genuine mix of text and numeric values (a word and 1) stops with the data-shape notice, and text in a regression target is treated as missing and noted in the result.If you ran it before this date on data whose target values were written in more than one way, please run it again.
- ML Classification · Gradient Boosting · AutoML · Decision Tree2026-10-17 · v1.6.38When a predictor cell held text that is not a number (for example a word or a score written with a unit), the cell was calculated as 0 and the missing-data line counted the row as valid. Such cells are now treated as missing, the row is left out, and the result says how many cells were dropped. A variable made only of text is refused with advice to recode it in Prep. Full-width digits are read as numbers.If you ran it before this date on data with text in a predictor column, please run it again.
- One-Way ANOVA2026-10-16 · v1.6.37A blank group cell that arrived as an empty string entered the calculation as a "blank group" (F and post hoc pairs), and the missing-data line said 0. Rows with a blank group cell are now left out.If you ran it before this date on data with blank group cells, please run it again.
- ML Classification · Gradient Boosting · AutoML · Decision Tree2026-10-16 · v1.6.37When a blank cell arrived as an empty string, a predictor cell was filled with 0, a blank outcome became a class of its own, and the missing-data line counted those rows as valid. Rows with blanks are now left out.If you ran it before this date on data with blank cells, please run it again.
- Two-Way ANOVA2026-10-16 · v1.6.37A blank factor cell that arrived as an empty string entered the calculation as a "blank level", and the missing-data line said 0. Rows with blanks are now left out (the same rule as N-way ANOVA).If you ran it before this date on data with blank factor cells, please run it again.
- N-Way ANOVA2026-10-15 · v1.6.36The Type III sums of squares on the main-effect rows used reference-category coding, so they meant something different from SPSS (in a model with an interaction), and a blank cell could enter the calculation as a level of its own. It now uses effect (sum-to-zero) coding and leaves out rows with blanks.If you ran N-way ANOVA before this date, please run it again.
How each engine was verified
Every engine has at least one form of evidence. Counts by kind:
| Compared against a reference implementation | 150 |
| Checked by hand calculation | 56 |
| Golden test exists, reference not attributable | 22 |
| Compared against a textbook example | 16 |
| Compared against IBM SPSS Statistics output | 7 |
| Compared against IBM SPSS Amos output | 2 |
How to cite Statory
Copy the line below into your paper or report.
Statory. (2026). Statory (Version 1.6.64) [Statistical analysis software]. https://www.statory.org
Reproducibility — will the same result come back
- Each analysis records “which engine” ran it and “with which options”, alongside the result.
- Norms are stored under a “version name” (e.g. 20260906), so you can trace which norm a past result used.
- The comparison records themselves are frozen in the repository and re-run on every release — if a value changes, the release is blocked.
SPSS and Amos are trademarks of their respective owners. Statory is not affiliated with, sponsored by, or endorsed by them. This page reports the output each tool produced from the same data, side by side.